Chromium Code Reviews| Index: pkg/analyzer/lib/src/generated/parser.dart |
| diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart |
| index 76f9dc7e76e32af10ddc3113de95be5c22ab1a81..1b54a465aed704ea374fb00cc00630b8de20c094 100644 |
| --- a/pkg/analyzer/lib/src/generated/parser.dart |
| +++ b/pkg/analyzer/lib/src/generated/parser.dart |
| @@ -196,6 +196,8 @@ Map<String, MethodTrampoline> methodTable_Parser = <String, MethodTrampoline>{ |
| 1, (Parser target, arg0) => target._parseCommentReferences(arg0)), |
| 'parseCompilationUnitMember_1': new MethodTrampoline( |
| 1, (Parser target, arg0) => target._parseCompilationUnitMember(arg0)), |
| + 'parseConfiguration_0': |
| + new MethodTrampoline(0, (Parser target) => target._parseConfiguration()), |
| 'parseConstExpression_0': new MethodTrampoline( |
| 0, (Parser target) => target._parseConstExpression()), |
| 'parseConstructor_8': new MethodTrampoline( |
| @@ -214,6 +216,8 @@ Map<String, MethodTrampoline> methodTable_Parser = <String, MethodTrampoline>{ |
| 0, (Parser target) => target._parseDocumentationComment()), |
| 'parseDoStatement_0': |
| new MethodTrampoline(0, (Parser target) => target._parseDoStatement()), |
| + 'parseDottedName_0': |
| + new MethodTrampoline(0, (Parser target) => target._parseDottedName()), |
| 'parseEmptyStatement_0': |
| new MethodTrampoline(0, (Parser target) => target._parseEmptyStatement()), |
| 'parseEnumConstantDeclaration_0': new MethodTrampoline( |
| @@ -745,6 +749,18 @@ class IncrementalParseDispatcher implements AstVisitor<AstNode> { |
| } |
| @override |
| + AstNode visitConfiguration(Configuration node) { |
| + if (identical(_oldNode, node.name)) { |
| + throw new InsufficientContextException(); |
| + } else if (identical(_oldNode, node.value)) { |
| + return _parser.parseStringLiteral(); |
| + } else if (identical(_oldNode, node.libraryUri)) { |
| + return _parser.parseStringLiteral(); |
| + } |
| + return _notAChild(node); |
| + } |
| + |
| + @override |
| AstNode visitConstructorDeclaration(ConstructorDeclaration node) { |
| if (identical(_oldNode, node.documentationComment)) { |
| throw new InsufficientContextException(); |
| @@ -829,6 +845,14 @@ class IncrementalParseDispatcher implements AstVisitor<AstNode> { |
| } |
| @override |
| + AstNode visitDottedName(DottedName node) { |
| + if (node.components.contains(_oldNode)) { |
| + throw new InsufficientContextException(); |
| + } |
| + return _notAChild(node); |
| + } |
| + |
| + @override |
| AstNode visitDoubleLiteral(DoubleLiteral node) => _notAChild(node); |
| @override |
| @@ -2118,6 +2142,12 @@ class Parser { |
| bool _inInitializer = false; |
| /** |
| + * A flag indicating whether the parser is to parse conditional directives |
| + * syntax. |
| + */ |
| + bool parseConditionalDirectives = false; |
| + |
| + /** |
| * A flag indicating whether the parser is to parse generic method syntax. |
| */ |
| bool parseGenericMethods = false; |
| @@ -5221,6 +5251,51 @@ class Parser { |
| } |
| /** |
| + * Parse a configuration in either an import or export directive. |
| + * |
| + * configuration ::= |
| + * 'if' '(' test ')' uri |
| + * |
| + * test ::= |
| + * dottedName ('==' stringLiteral)? |
| + * |
| + * dottedName ::= |
| + * identifier ('.' identifier)* |
| + */ |
| + Configuration _parseConfiguration() { |
| + Token ifKeyword = _expectKeyword(Keyword.IF); |
| + Token leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| + DottedName name = _parseDottedName(); |
| + Token equalToken = null; |
| + StringLiteral value = null; |
| + if (_matches(TokenType.EQ_EQ)) { |
| + equalToken = getAndAdvance(); |
| + value = parseStringLiteral(); |
|
Bob Nystrom
2015/10/22 00:24:47
This will allow interpolation, right? The proposal
Brian Wilkerson
2015/10/22 02:33:42
Good catch. Yes, it will allow string interpolatio
|
| + } |
| + Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| + StringLiteral libraryUri = _parseUri(); |
| + return new Configuration(ifKeyword, leftParenthesis, name, equalToken, |
| + value, rightParenthesis, libraryUri); |
| + } |
| + |
| + /** |
| + * Parse a list of configurations. If conditional directives are not |
| + * supported, return an empty list without attempting to parse anything. |
| + */ |
| + List<Configuration> _parseConfigurations() { |
| + List<Configuration> configurations = <Configuration>[]; |
| + if (parseConditionalDirectives) { |
| + while (_matchesKeyword(Keyword.IF)) { |
| + Configuration configuration = _parseConfiguration(); |
| + if (configuration != null) { |
|
Paul Berry
2015/10/21 17:10:47
This is unnecessarily defensive. _parseConfigurat
Brian Wilkerson
2015/10/21 20:05:23
Done
|
| + configurations.add(configuration); |
| + } |
| + } |
| + } |
| + return configurations; |
| + } |
| + |
| + /** |
| * Parse a const expression. Return the const expression that was parsed. |
| * |
| * constExpression ::= |
| @@ -5536,6 +5611,22 @@ class Parser { |
| } |
| /** |
| + * Parse a dotted name. Return the dotted name that was parsed. |
| + * |
| + * dottedName ::= |
| + * identifier ('.' identifier)* |
| + */ |
| + DottedName _parseDottedName() { |
| + List<SimpleIdentifier> components = new List<SimpleIdentifier>(); |
| + components.add(parseSimpleIdentifier()); |
| + while (_matches(TokenType.PERIOD)) { |
| + _advance(); |
| + components.add(parseSimpleIdentifier()); |
| + } |
| + return new DottedName(components); |
| + } |
| + |
| + /** |
| * Parse an empty statement. Return the empty statement that was parsed. |
| * |
| * emptyStatement ::= |
| @@ -5642,11 +5733,12 @@ class Parser { |
| * associated with the directive. Return the export directive that was parsed. |
| * |
| * exportDirective ::= |
| - * metadata 'export' stringLiteral combinator*';' |
| + * metadata 'export' stringLiteral configuration* combinator*';' |
| */ |
| ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) { |
| Token exportKeyword = _expectKeyword(Keyword.EXPORT); |
| StringLiteral libraryUri = _parseUri(); |
| + List<Configuration> configurations = _parseConfigurations(); |
| List<Combinator> combinators = _parseCombinators(); |
| Token semicolon = _expectSemicolon(); |
| return new ExportDirective( |
| @@ -5654,6 +5746,7 @@ class Parser { |
| commentAndMetadata.metadata, |
| exportKeyword, |
| libraryUri, |
| + configurations, |
| combinators, |
| semicolon); |
| } |
| @@ -6270,11 +6363,12 @@ class Parser { |
| * associated with the directive. Return the import directive that was parsed. |
| * |
| * importDirective ::= |
| - * metadata 'import' stringLiteral (deferred)? ('as' identifier)? combinator*';' |
| + * metadata 'import' stringLiteral configuration* (deferred)? ('as' identifier)? combinator*';' |
| */ |
| ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) { |
| Token importKeyword = _expectKeyword(Keyword.IMPORT); |
| StringLiteral libraryUri = _parseUri(); |
| + List<Configuration> configurations = _parseConfigurations(); |
| Token deferredToken = null; |
| Token asToken = null; |
| SimpleIdentifier prefix = null; |
| @@ -6310,6 +6404,7 @@ class Parser { |
| commentAndMetadata.metadata, |
| importKeyword, |
| libraryUri, |
| + configurations, |
| deferredToken, |
| asToken, |
| prefix, |
| @@ -9933,6 +10028,22 @@ class ResolutionCopier implements AstVisitor<bool> { |
| } |
| @override |
| + bool visitConfiguration(Configuration node) { |
| + Configuration toNode = this._toNode as Configuration; |
| + if (_and( |
| + _isEqualTokens(node.ifKeyword, toNode.ifKeyword), |
| + _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis), |
| + _isEqualNodes(node.name, toNode.name), |
| + _isEqualTokens(node.equalToken, toNode.equalToken), |
| + _isEqualNodes(node.value, toNode.value), |
| + _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis), |
| + _isEqualNodes(node.libraryUri, toNode.libraryUri))) { |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + @override |
| bool visitConstructorDeclaration(ConstructorDeclaration node) { |
| ConstructorDeclaration toNode = this._toNode as ConstructorDeclaration; |
| if (_and( |
| @@ -10028,6 +10139,12 @@ class ResolutionCopier implements AstVisitor<bool> { |
| } |
| @override |
| + bool visitDottedName(DottedName node) { |
| + DottedName toNode = this._toNode as DottedName; |
| + return _isEqualNodeLists(node.components, toNode.components); |
| + } |
| + |
| + @override |
| bool visitDoubleLiteral(DoubleLiteral node) { |
| DoubleLiteral toNode = this._toNode as DoubleLiteral; |
| if (_and(_isEqualTokens(node.literal, toNode.literal), |