Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.parser; | 5 library dart2js.parser; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../tokens/keyword.dart' show | 8 import '../tokens/keyword.dart' show |
| 9 Keyword; | 9 Keyword; |
| 10 import '../tokens/precedence.dart' show | 10 import '../tokens/precedence.dart' show |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 final String type; | 65 final String type; |
| 66 const FormalParameterType(this.type); | 66 const FormalParameterType(this.type); |
| 67 bool get isRequired => this == REQUIRED; | 67 bool get isRequired => this == REQUIRED; |
| 68 bool get isPositional => this == POSITIONAL; | 68 bool get isPositional => this == POSITIONAL; |
| 69 bool get isNamed => this == NAMED; | 69 bool get isNamed => this == NAMED; |
| 70 static final REQUIRED = const FormalParameterType('required'); | 70 static final REQUIRED = const FormalParameterType('required'); |
| 71 static final POSITIONAL = const FormalParameterType('positional'); | 71 static final POSITIONAL = const FormalParameterType('positional'); |
| 72 static final NAMED = const FormalParameterType('named'); | 72 static final NAMED = const FormalParameterType('named'); |
| 73 } | 73 } |
| 74 | 74 |
| 75 /// Options used for parsing. | |
| 76 /// | |
| 77 /// Use this to conditionally support certain constructs, e.g., | |
| 78 /// experimental ones. | |
| 79 class ParserOptions { | |
| 80 final bool enableConditionalDirectives; | |
| 81 const ParserOptions({this.enableConditionalDirectives: false}); | |
|
Johnni Winther
2016/03/11 13:43:39
Nit: Add an empty line before the constructor.
eernst
2016/03/21 13:03:34
Done.
| |
| 82 } | |
| 83 | |
| 75 /** | 84 /** |
| 76 * An event generating parser of Dart programs. This parser expects | 85 * An event generating parser of Dart programs. This parser expects |
| 77 * all tokens in a linked list (aka a token stream). | 86 * all tokens in a linked list (aka a token stream). |
| 78 * | 87 * |
| 79 * The class [Scanner] is used to generate a token stream. See the | 88 * The class [Scanner] is used to generate a token stream. See the |
| 80 * file scanner.dart. | 89 * file scanner.dart. |
| 81 * | 90 * |
| 82 * Subclasses of the class [Listener] are used to listen to events. | 91 * Subclasses of the class [Listener] are used to listen to events. |
| 83 * | 92 * |
| 84 * Most methods of this class belong in one of two major categories: | 93 * Most methods of this class belong in one of two major categories: |
| 85 * parse metods and peek methods. Parse methods all have the prefix | 94 * parse metods and peek methods. Parse methods all have the prefix |
| 86 * parse, and peek methods all have the prefix peek. | 95 * parse, and peek methods all have the prefix peek. |
| 87 * | 96 * |
| 88 * Parse methods generate events (by calling methods on [listener]) | 97 * Parse methods generate events (by calling methods on [listener]) |
| 89 * and return the next token to parse. Peek methods do not generate | 98 * and return the next token to parse. Peek methods do not generate |
| 90 * events (except for errors) and may return null. | 99 * events (except for errors) and may return null. |
| 91 * | 100 * |
| 92 * Parse methods are generally named parseGrammarProductionSuffix. The | 101 * Parse methods are generally named parseGrammarProductionSuffix. The |
| 93 * suffix can be one of "opt", or "star". "opt" means zero or one | 102 * suffix can be one of "opt", or "star". "opt" means zero or one |
| 94 * matches, "star" means zero or more matches. For example, | 103 * matches, "star" means zero or more matches. For example, |
| 95 * [parseMetadataStar] corresponds to this grammar snippet: [: | 104 * [parseMetadataStar] corresponds to this grammar snippet: [: |
| 96 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. | 105 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. |
| 97 */ | 106 */ |
| 98 class Parser { | 107 class Parser { |
| 99 final Listener listener; | 108 final Listener listener; |
| 109 final ParserOptions parserOptions; | |
| 100 bool mayParseFunctionExpressions = true; | 110 bool mayParseFunctionExpressions = true; |
| 101 final bool enableConditionalDirectives; | |
| 102 bool asyncAwaitKeywordsEnabled; | 111 bool asyncAwaitKeywordsEnabled; |
| 103 | 112 |
| 104 Parser(this.listener, | 113 Parser(this.listener, this.parserOptions, |
| 105 {this.enableConditionalDirectives: false, | 114 {this.asyncAwaitKeywordsEnabled: false}); |
| 106 this.asyncAwaitKeywordsEnabled: false}); | |
| 107 | 115 |
| 108 Token parseUnit(Token token) { | 116 Token parseUnit(Token token) { |
| 109 listener.beginCompilationUnit(token); | 117 listener.beginCompilationUnit(token); |
| 110 int count = 0; | 118 int count = 0; |
| 111 while (!identical(token.kind, EOF_TOKEN)) { | 119 while (!identical(token.kind, EOF_TOKEN)) { |
| 112 token = parseTopLevelDeclaration(token); | 120 token = parseTopLevelDeclaration(token); |
| 113 listener.endTopLevelDeclaration(token); | 121 listener.endTopLevelDeclaration(token); |
| 114 count++; | 122 count++; |
| 115 } | 123 } |
| 116 listener.endCompilationUnit(count, token); | 124 listener.endCompilationUnit(count, token); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 Token semicolon = token; | 181 Token semicolon = token; |
| 174 token = expect(';', token); | 182 token = expect(';', token); |
| 175 listener.endImport(importKeyword, deferredKeyword, asKeyword, semicolon); | 183 listener.endImport(importKeyword, deferredKeyword, asKeyword, semicolon); |
| 176 return token; | 184 return token; |
| 177 } | 185 } |
| 178 | 186 |
| 179 /// if (test) uri | 187 /// if (test) uri |
| 180 Token parseConditionalUris(Token token) { | 188 Token parseConditionalUris(Token token) { |
| 181 listener.beginConditionalUris(token); | 189 listener.beginConditionalUris(token); |
| 182 int count = 0; | 190 int count = 0; |
| 183 if (enableConditionalDirectives) { | 191 if (parserOptions.enableConditionalDirectives) { |
| 184 while (optional('if', token)) { | 192 while (optional('if', token)) { |
| 185 count++; | 193 count++; |
| 186 token = parseConditionalUri(token); | 194 token = parseConditionalUri(token); |
| 187 } | 195 } |
| 188 } | 196 } |
| 189 listener.endConditionalUris(count); | 197 listener.endConditionalUris(count); |
| 190 return token; | 198 return token; |
| 191 } | 199 } |
| 192 | 200 |
| 193 Token parseConditionalUri(Token token) { | 201 Token parseConditionalUri(Token token) { |
| (...skipping 2584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2778 } | 2786 } |
| 2779 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 2787 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 2780 return expectSemicolon(token); | 2788 return expectSemicolon(token); |
| 2781 } | 2789 } |
| 2782 | 2790 |
| 2783 Token parseEmptyStatement(Token token) { | 2791 Token parseEmptyStatement(Token token) { |
| 2784 listener.handleEmptyStatement(token); | 2792 listener.handleEmptyStatement(token); |
| 2785 return expectSemicolon(token); | 2793 return expectSemicolon(token); |
| 2786 } | 2794 } |
| 2787 } | 2795 } |
| OLD | NEW |