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), |