From fe28924e0c67c1ea41770b53838fb0357f3d8e68 Mon Sep 17 00:00:00 2001 From: Dave Holoway Date: Tue, 16 Jun 2020 23:47:16 +0100 Subject: [PATCH] parse try-with-resources --- langserver/java/body-parser3.js | 45 +++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/langserver/java/body-parser3.js b/langserver/java/body-parser3.js index a032b08..bebb200 100644 --- a/langserver/java/body-parser3.js +++ b/langserver/java/body-parser3.js @@ -425,6 +425,7 @@ class Block extends Statement { statements = []; } class TryStatement extends Statement { + resources = []; block = null; catches = []; } @@ -1089,8 +1090,7 @@ function statementKeyword(tokens, mdecls, method, imports, typemap) { case 'try': tokens.inc(); s = new TryStatement(); - s.block = statementBlock(tokens, mdecls, method, imports, typemap); - catchFinallyBlocks(s, tokens, mdecls, method, imports, typemap); + tryStatement(s, tokens, mdecls, method, imports, typemap); break; case 'return': tokens.inc(); @@ -1162,6 +1162,44 @@ function nonVarDeclStatement(tokens, mdecls, method, imports, typemap) { return s; } +/** +* @param {TryStatement} s +* @param {TokenList} tokens +* @param {MethodDeclarations} mdecls +* @param {SourceMC} method +* @param {ResolvedImport[]} imports +* @param {Map} typemap +*/ +function tryStatement(s, tokens, mdecls, method, imports, typemap) { + mdecls.pushScope(); + let is_try_with_resources = false; + if (tokens.isValue('(')) { + // try-with-resources + is_try_with_resources = true; + for (;;) { + const x = expression_or_var_decl(tokens, mdecls, method, imports, typemap); + s.resources.push(x); + if (Array.isArray(x)) { + mdecls.locals.push(...x); + } + if (tokens.isValue(';')) { + if (tokens.current.value !== ')') { + continue; + } + } + break; + } + tokens.expectValue(')') + } + s.block = statementBlock(tokens, mdecls, method, imports, typemap); + if (/^(catch|finally)$/.test(tokens.current.value)) { + catchFinallyBlocks(s, tokens, mdecls, method, imports, typemap); + } else if (!is_try_with_resources) { + addproblem(tokens, ParseProblem.Error(tokens.current, `Missing catch/finally block`)); + } + mdecls.popScope(); +} + /** * @param {ForStatement} s * @param {TokenList} tokens @@ -1306,9 +1344,6 @@ function catchFinallyBlocks(s, tokens, mdecls, method, imports, typemap) { mdecls.popScope(); continue; } - if (!s.catches.length) { - addproblem(tokens, ParseProblem.Error(tokens.current, `Missing catch or finally block`)); - } const first_finally_idx = s.catches.findIndex(c => c instanceof Block); if (first_finally_idx >= 0) { if (s.catches.slice(first_finally_idx).find(c => !(c instanceof Block))) {