| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.generated.parser; | 5 library analyzer.src.generated.parser; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 static String _AWAIT = Keyword.AWAIT.syntax; | 163 static String _AWAIT = Keyword.AWAIT.syntax; |
| 164 | 164 |
| 165 static String _HIDE = Keyword.HIDE.syntax; | 165 static String _HIDE = Keyword.HIDE.syntax; |
| 166 | 166 |
| 167 static String _SHOW = Keyword.SHOW.syntax; | 167 static String _SHOW = Keyword.SHOW.syntax; |
| 168 | 168 |
| 169 static String SYNC = Keyword.SYNC.syntax; | 169 static String SYNC = Keyword.SYNC.syntax; |
| 170 | 170 |
| 171 static String _YIELD = Keyword.YIELD.syntax; | 171 static String _YIELD = Keyword.YIELD.syntax; |
| 172 | 172 |
| 173 static const int _MAX_TREE_DEPTH = 300; |
| 174 |
| 173 /** | 175 /** |
| 174 * The source being parsed. | 176 * The source being parsed. |
| 175 */ | 177 */ |
| 176 final Source _source; | 178 final Source _source; |
| 177 | 179 |
| 178 /** | 180 /** |
| 179 * The error listener that will be informed of any errors that are found | 181 * The error listener that will be informed of any errors that are found |
| 180 * during the parse. | 182 * during the parse. |
| 181 */ | 183 */ |
| 182 final AnalysisErrorListener _errorListener; | 184 final AnalysisErrorListener _errorListener; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 208 * A flag indicating whether parser is to parse function bodies. | 210 * A flag indicating whether parser is to parse function bodies. |
| 209 */ | 211 */ |
| 210 bool _parseFunctionBodies = true; | 212 bool _parseFunctionBodies = true; |
| 211 | 213 |
| 212 /** | 214 /** |
| 213 * The next token to be parsed. | 215 * The next token to be parsed. |
| 214 */ | 216 */ |
| 215 Token _currentToken; | 217 Token _currentToken; |
| 216 | 218 |
| 217 /** | 219 /** |
| 220 * The depth of the current AST. When this depth is too high, so we're at the |
| 221 * risk of overflowing the stack, we stop parsing and report an error. |
| 222 */ |
| 223 int _treeDepth = 0; |
| 224 |
| 225 /** |
| 218 * A flag indicating whether the parser is currently in a function body marked | 226 * A flag indicating whether the parser is currently in a function body marked |
| 219 * as being 'async'. | 227 * as being 'async'. |
| 220 */ | 228 */ |
| 221 bool _inAsync = false; | 229 bool _inAsync = false; |
| 222 | 230 |
| 223 /** | 231 /** |
| 224 * A flag indicating whether the parser is currently in a function body marked | 232 * A flag indicating whether the parser is currently in a function body marked |
| 225 * (by a star) as being a generator. | 233 * (by a star) as being a generator. |
| 226 */ | 234 */ |
| 227 bool _inGenerator = false; | 235 bool _inGenerator = false; |
| (...skipping 1725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1953 } | 1961 } |
| 1954 directives.add(directive); | 1962 directives.add(directive); |
| 1955 } else if (type == TokenType.SEMICOLON) { | 1963 } else if (type == TokenType.SEMICOLON) { |
| 1956 // TODO(brianwilkerson) Consider moving this error detection into | 1964 // TODO(brianwilkerson) Consider moving this error detection into |
| 1957 // _parseCompilationUnitMember (in the places where EXPECTED_EXECUTABLE | 1965 // _parseCompilationUnitMember (in the places where EXPECTED_EXECUTABLE |
| 1958 // is being generated). | 1966 // is being generated). |
| 1959 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, | 1967 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, |
| 1960 [_currentToken.lexeme]); | 1968 [_currentToken.lexeme]); |
| 1961 _advance(); | 1969 _advance(); |
| 1962 } else { | 1970 } else { |
| 1963 CompilationUnitMember member = | 1971 CompilationUnitMember member; |
| 1964 parseCompilationUnitMember(commentAndMetadata); | 1972 try { |
| 1973 member = parseCompilationUnitMember(commentAndMetadata); |
| 1974 } on _TooDeepTreeError { |
| 1975 _reportErrorForToken(ParserErrorCode.STACK_OVERFLOW, _currentToken); |
| 1976 Token eof = new Token(TokenType.EOF, 0); |
| 1977 eof.previous = eof; |
| 1978 eof.setNext(eof); |
| 1979 return astFactory.compilationUnit(eof, null, null, null, eof); |
| 1980 } |
| 1965 if (member != null) { | 1981 if (member != null) { |
| 1966 declarations.add(member); | 1982 declarations.add(member); |
| 1967 } | 1983 } |
| 1968 } | 1984 } |
| 1969 if (identical(_currentToken, memberStart)) { | 1985 if (identical(_currentToken, memberStart)) { |
| 1970 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, | 1986 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, |
| 1971 [_currentToken.lexeme]); | 1987 [_currentToken.lexeme]); |
| 1972 _advance(); | 1988 _advance(); |
| 1973 while (!_matches(TokenType.EOF) && | 1989 while (!_matches(TokenType.EOF) && |
| 1974 !_couldBeStartOfCompilationUnitMember()) { | 1990 !_couldBeStartOfCompilationUnitMember()) { |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2705 /** | 2721 /** |
| 2706 * Parse an expression that might contain a cascade. Return the expression | 2722 * Parse an expression that might contain a cascade. Return the expression |
| 2707 * that was parsed. | 2723 * that was parsed. |
| 2708 * | 2724 * |
| 2709 * expression ::= | 2725 * expression ::= |
| 2710 * assignableExpression assignmentOperator expression | 2726 * assignableExpression assignmentOperator expression |
| 2711 * | conditionalExpression cascadeSection* | 2727 * | conditionalExpression cascadeSection* |
| 2712 * | throwExpression | 2728 * | throwExpression |
| 2713 */ | 2729 */ |
| 2714 Expression parseExpression2() { | 2730 Expression parseExpression2() { |
| 2715 Keyword keyword = _currentToken.keyword; | 2731 if (_treeDepth > _MAX_TREE_DEPTH) { |
| 2716 if (keyword == Keyword.THROW) { | 2732 throw new _TooDeepTreeError(); |
| 2717 return parseThrowExpression(); | |
| 2718 } else if (keyword == Keyword.RETHROW) { | |
| 2719 // TODO(brianwilkerson) Rethrow is a statement again. | |
| 2720 return parseRethrowExpression(); | |
| 2721 } | 2733 } |
| 2722 // | 2734 _treeDepth++; |
| 2723 // assignableExpression is a subset of conditionalExpression, so we can | 2735 try { |
| 2724 // parse a conditional expression and then determine whether it is followed | 2736 Keyword keyword = _currentToken.keyword; |
| 2725 // by an assignmentOperator, checking for conformance to the restricted | 2737 if (keyword == Keyword.THROW) { |
| 2726 // grammar after making that determination. | 2738 return parseThrowExpression(); |
| 2727 // | 2739 } else if (keyword == Keyword.RETHROW) { |
| 2728 Expression expression = parseConditionalExpression(); | 2740 // TODO(brianwilkerson) Rethrow is a statement again. |
| 2729 TokenType type = _currentToken.type; | 2741 return parseRethrowExpression(); |
| 2730 if (type == TokenType.PERIOD_PERIOD) { | 2742 } |
| 2731 List<Expression> cascadeSections = <Expression>[]; | 2743 // |
| 2732 do { | 2744 // assignableExpression is a subset of conditionalExpression, so we can |
| 2733 Expression section = parseCascadeSection(); | 2745 // parse a conditional expression and then determine whether it is followe
d |
| 2734 if (section != null) { | 2746 // by an assignmentOperator, checking for conformance to the restricted |
| 2735 cascadeSections.add(section); | 2747 // grammar after making that determination. |
| 2736 } | 2748 // |
| 2737 } while (_currentToken.type == TokenType.PERIOD_PERIOD); | 2749 Expression expression = parseConditionalExpression(); |
| 2738 return astFactory.cascadeExpression(expression, cascadeSections); | 2750 TokenType type = _currentToken.type; |
| 2739 } else if (type.isAssignmentOperator) { | 2751 if (type == TokenType.PERIOD_PERIOD) { |
| 2740 Token operator = getAndAdvance(); | 2752 List<Expression> cascadeSections = <Expression>[]; |
| 2741 _ensureAssignable(expression); | 2753 do { |
| 2742 return astFactory.assignmentExpression( | 2754 Expression section = parseCascadeSection(); |
| 2743 expression, operator, parseExpression2()); | 2755 if (section != null) { |
| 2756 cascadeSections.add(section); |
| 2757 } |
| 2758 } while (_currentToken.type == TokenType.PERIOD_PERIOD); |
| 2759 return astFactory.cascadeExpression(expression, cascadeSections); |
| 2760 } else if (type.isAssignmentOperator) { |
| 2761 Token operator = getAndAdvance(); |
| 2762 _ensureAssignable(expression); |
| 2763 return astFactory.assignmentExpression( |
| 2764 expression, operator, parseExpression2()); |
| 2765 } |
| 2766 return expression; |
| 2767 } finally { |
| 2768 _treeDepth--; |
| 2744 } | 2769 } |
| 2745 return expression; | |
| 2746 } | 2770 } |
| 2747 | 2771 |
| 2748 /** | 2772 /** |
| 2749 * Parse a list of expressions. Return the expression that was parsed. | 2773 * Parse a list of expressions. Return the expression that was parsed. |
| 2750 * | 2774 * |
| 2751 * expressionList ::= | 2775 * expressionList ::= |
| 2752 * expression (',' expression)* | 2776 * expression (',' expression)* |
| 2753 */ | 2777 */ |
| 2754 List<Expression> parseExpressionList() { | 2778 List<Expression> parseExpressionList() { |
| 2755 List<Expression> expressions = <Expression>[parseExpression2()]; | 2779 List<Expression> expressions = <Expression>[parseExpression2()]; |
| (...skipping 2032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4788 return parseStatement2(); | 4812 return parseStatement2(); |
| 4789 } | 4813 } |
| 4790 | 4814 |
| 4791 /** | 4815 /** |
| 4792 * Parse a statement. Return the statement that was parsed. | 4816 * Parse a statement. Return the statement that was parsed. |
| 4793 * | 4817 * |
| 4794 * statement ::= | 4818 * statement ::= |
| 4795 * label* nonLabeledStatement | 4819 * label* nonLabeledStatement |
| 4796 */ | 4820 */ |
| 4797 Statement parseStatement2() { | 4821 Statement parseStatement2() { |
| 4798 List<Label> labels = null; | 4822 if (_treeDepth > _MAX_TREE_DEPTH) { |
| 4799 while (_matchesIdentifier() && _currentToken.next.type == TokenType.COLON) { | 4823 throw new _TooDeepTreeError(); |
| 4800 Label label = parseLabel(isDeclaration: true); | 4824 } |
| 4825 _treeDepth++; |
| 4826 try { |
| 4827 List<Label> labels = null; |
| 4828 while ( |
| 4829 _matchesIdentifier() && _currentToken.next.type == TokenType.COLON) { |
| 4830 Label label = parseLabel(isDeclaration: true); |
| 4831 if (labels == null) { |
| 4832 labels = <Label>[label]; |
| 4833 } else { |
| 4834 labels.add(label); |
| 4835 } |
| 4836 } |
| 4837 Statement statement = parseNonLabeledStatement(); |
| 4801 if (labels == null) { | 4838 if (labels == null) { |
| 4802 labels = <Label>[label]; | 4839 return statement; |
| 4803 } else { | |
| 4804 labels.add(label); | |
| 4805 } | 4840 } |
| 4841 return astFactory.labeledStatement(labels, statement); |
| 4842 } finally { |
| 4843 _treeDepth--; |
| 4806 } | 4844 } |
| 4807 Statement statement = parseNonLabeledStatement(); | |
| 4808 if (labels == null) { | |
| 4809 return statement; | |
| 4810 } | |
| 4811 return astFactory.labeledStatement(labels, statement); | |
| 4812 } | 4845 } |
| 4813 | 4846 |
| 4814 /** | 4847 /** |
| 4815 * Parse a sequence of statements, starting with the given [token]. Return the | 4848 * Parse a sequence of statements, starting with the given [token]. Return the |
| 4816 * statements that were parsed, or `null` if the tokens do not represent a | 4849 * statements that were parsed, or `null` if the tokens do not represent a |
| 4817 * recognizable sequence of statements. | 4850 * recognizable sequence of statements. |
| 4818 */ | 4851 */ |
| 4819 List<Statement> parseStatements(Token token) { | 4852 List<Statement> parseStatements(Token token) { |
| 4820 _currentToken = token; | 4853 _currentToken = token; |
| 4821 return _parseStatementList(); | 4854 return _parseStatementList(); |
| (...skipping 3738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8560 } | 8593 } |
| 8561 if (modifiers.finalKeyword != null) { | 8594 if (modifiers.finalKeyword != null) { |
| 8562 _reportErrorForToken( | 8595 _reportErrorForToken( |
| 8563 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword); | 8596 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword); |
| 8564 } | 8597 } |
| 8565 if (modifiers.varKeyword != null) { | 8598 if (modifiers.varKeyword != null) { |
| 8566 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword); | 8599 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword); |
| 8567 } | 8600 } |
| 8568 } | 8601 } |
| 8569 } | 8602 } |
| 8603 |
| 8604 /** |
| 8605 * Instances of this class are thrown when the parser detects that AST has |
| 8606 * too many nested expressions to be parsed safely and avoid possibility of |
| 8607 * [StackOverflowError] in the parser or during later analysis. |
| 8608 */ |
| 8609 class _TooDeepTreeError {} |
| OLD | NEW |