parse try-with-resources

This commit is contained in:
Dave Holoway
2020-06-16 23:47:16 +01:00
parent dc39ae53b1
commit fe28924e0c

View File

@@ -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<string,CEIType>} 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))) {