Преглед на файлове

添加 try with resources 支持

kj863257 преди 3 години
родител
ревизия
c801835c1e
променени са 2 файла, в които са добавени 45 реда и са изтрити 5 реда
  1. 3 2
      magic-editor/src/console/src/scripts/parsing/ast.js
  2. 42 3
      magic-editor/src/console/src/scripts/parsing/parser.js

+ 3 - 2
magic-editor/src/console/src/scripts/parsing/ast.js

@@ -372,16 +372,17 @@ class UnaryOperation extends Node {
 }
 
 class TryStatement extends Node {
-    constructor(span, exceptionVarNode, tryBlock, catchBlock, finallyBlock) {
+    constructor(span, exceptionVarNode, tryBlock, tryResources, catchBlock, finallyBlock) {
         super(span)
         this.exceptionVarNode = exceptionVarNode;
         this.tryBlock = tryBlock;
+        this.tryResources = tryResources;
         this.catchBlock = catchBlock;
         this.finallyBlock = finallyBlock;
     }
 
     expressions() {
-        return [...this.tryBlock, ...this.catchBlock, ...this.finallyBlock]
+        return [...this.tryBlock, ...this.tryResources, ...this.catchBlock, ...this.finallyBlock]
     }
 }
 

+ 42 - 3
magic-editor/src/console/src/scripts/parsing/parser.js

@@ -128,7 +128,7 @@ export class Parser {
         let result = null;
         if (this.stream.match("import", false)) {
             result = this.parseImport();
-        } else if (this.stream.match(["var", "let", "const"], false)) {
+        } else if (this.matchVarDefine()) {
             result = this.parseVarDefine();
         } else if (this.stream.match("if", false)) {
             result = this.parseIfStatement();
@@ -154,7 +154,7 @@ export class Parser {
             result = this.parseAssert();
         } else {
             let index = this.stream.makeIndex();
-            if (this.stream.match(TokenType.Identifier, true) && this.stream.match(TokenType.Identifier, false)) {
+            if (this.matchTypeDefine()) {
                 this.stream.resetIndex(index);
                 result = this.parseVarDefine();
             }
@@ -169,6 +169,14 @@ export class Parser {
         return result;
     }
 
+    matchTypeDefine() {
+        return this.stream.match(TokenType.Identifier, true) && this.stream.match(TokenType.Identifier, false);
+    }
+
+    matchVarDefine() {
+        return this.stream.match(["var", "let", "const"], false);
+    }
+
     checkKeyword(span) {
         if (keywords.indexOf(span.getText()) > -1) {
             throw new ParseException('变量名不能定义为关键字', span);
@@ -350,6 +358,37 @@ export class Parser {
 
     parseTryStatement() {
         let opening = this.stream.expect("try");
+        let tryResources = [];
+        if (this.stream.match("(", true)) {
+            if (this.stream.match(")", false)) {
+                // 空的 try-with-resource
+            } else {
+                while (!this.stream.match(")", false)) {
+                    if (this.stream.match(";", true)) {
+                        continue;
+                    }
+                    let result = null;
+                    if (this.matchVarDefine()) {
+                        result = this.parseVarDefine();
+                    } else {
+                        if (this.stream.matchAny(keywords, false)) {
+                            throw new ParseException("try 括号中只允许写赋值语句", this.stream.consume().getSpan());
+                        }
+                        let index = this.stream.makeIndex();
+                        if (this.matchTypeDefine()) {
+                            this.stream.resetIndex(index);
+                            result = this.parseVarDefine();
+                        }
+                        if (result == null) {
+                            this.stream.resetIndex(index);
+                            throw new ParseException("try 括号中只允许写赋值语句", this.stream.consume().getSpan());
+                        }
+                    }
+                    tryResources.push(result);
+                }
+            }
+            this.stream.expect(")");
+        }
         let tryBlocks = this.parseFunctionBody();
         let catchBlocks = [];
         let finallyBlocks = [];
@@ -364,7 +403,7 @@ export class Parser {
         if (this.stream.match("finally", true)) {
             finallyBlocks = finallyBlocks.concat(this.parseFunctionBody());
         }
-        return new TryStatement(new Span(opening.getSpan(), this.stream.getPrev().getSpan()), exception, tryBlocks, catchBlocks, finallyBlocks);
+        return new TryStatement(new Span(opening.getSpan(), this.stream.getPrev().getSpan()), exception, tryBlocks, tryResources, catchBlocks, finallyBlocks);
     }
 
     parseWhileStatement() {