| Index: pkg/front_end/lib/src/fasta/parser/parser.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| index 7b11fe708f4fc37258e0fd36c437822aed3a9dfd..744924433cb155dd50efe09743b85b961002833d 100644
|
| --- a/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| +++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| @@ -65,10 +65,7 @@ import '../scanner/precedence.dart'
|
| ASSIGNMENT_PRECEDENCE,
|
| AS_INFO,
|
| CASCADE_PRECEDENCE,
|
| - EOF_INFO,
|
| EQUALITY_PRECEDENCE,
|
| - GENERIC_METHOD_TYPE_ASSIGN,
|
| - GENERIC_METHOD_TYPE_LIST,
|
| GT_INFO,
|
| IS_INFO,
|
| MINUS_MINUS_INFO,
|
| @@ -86,7 +83,6 @@ import '../scanner/precedence.dart'
|
| import '../scanner/token.dart'
|
| show
|
| BeginGroupToken,
|
| - CommentToken,
|
| KeywordToken,
|
| SymbolToken,
|
| Token,
|
| @@ -117,7 +113,6 @@ import '../scanner/token_constants.dart'
|
| STRING_TOKEN;
|
|
|
| import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET;
|
| -import '../scanner/string_scanner.dart';
|
|
|
| import '../util/link.dart' show Link;
|
|
|
| @@ -189,8 +184,6 @@ class Parser {
|
|
|
| bool mayParseFunctionExpressions = true;
|
|
|
| - bool parseGenericMethodComments = false;
|
| -
|
| /// Represents parser state: what asynchronous syntax is allowed in the
|
| /// function being currently parsed. In rare situations, this can be set by
|
| /// external clients, for example, to parse an expression outside a function.
|
| @@ -640,7 +633,7 @@ class Parser {
|
| }
|
| }
|
|
|
| - token = _injectGenericCommentTypeList(token);
|
| + token = listener.injectGenericCommentTypeList(token);
|
| if (optional('(', token)) {
|
| Token inlineFunctionTypeStart = token;
|
| listener.beginFunctionTypedFormalParameter(token);
|
| @@ -726,6 +719,7 @@ class Parser {
|
| // Function type without return type.
|
| return parseType(token);
|
| }
|
| + token = listener.injectGenericCommentTypeAssign(token);
|
| Token peek = peekAfterIfType(token);
|
| if (peek != null && (peek.isIdentifier() || optional('this', peek))) {
|
| return parseType(token);
|
| @@ -1118,7 +1112,7 @@ class Parser {
|
| /// TODO(ahe): Clean this up.
|
| Token parseStuff(Token token, Function beginStuff, Function stuffParser,
|
| Function endStuff, Function handleNoStuff) {
|
| - token = _injectGenericCommentTypeList(token);
|
| + token = listener.injectGenericCommentTypeList(token);
|
| if (optional('<', token)) {
|
| Token begin = token;
|
| beginStuff(begin);
|
| @@ -2405,6 +2399,13 @@ class Parser {
|
| Token identifier = peekIdentifierAfterType(token);
|
| if (identifier != null) {
|
| assert(identifier.isIdentifier());
|
| +
|
| + // If the identifier token has a type substitution comment /*=T*/,
|
| + // then the set of tokens type tokens should be replaced with the
|
| + // tokens parsed from the comment.
|
| + token =
|
| + listener.replaceTokenWithGenericCommentTypeAssign(token, identifier);
|
| +
|
| Token afterId = identifier.next;
|
| int afterIdKind = afterId.kind;
|
| if (identical(afterIdKind, EQ_TOKEN) ||
|
| @@ -2489,6 +2490,7 @@ class Parser {
|
| if (isModifier(token.next)) {
|
| return parseVariablesDeclaration(token);
|
| }
|
| + listener.injectGenericCommentTypeAssign(token.next);
|
| Token identifier = peekIdentifierAfterOptionalType(token.next);
|
| if (identifier != null) {
|
| assert(identifier.isIdentifier());
|
| @@ -2797,7 +2799,7 @@ class Parser {
|
| }
|
|
|
| Token parsePrimary(Token token, IdentifierContext context) {
|
| - token = _injectGenericCommentTypeList(token);
|
| + token = listener.injectGenericCommentTypeList(token);
|
| final kind = token.kind;
|
| if (kind == IDENTIFIER_TOKEN) {
|
| return parseSendOrFunctionLiteral(token, context);
|
| @@ -3090,7 +3092,7 @@ class Parser {
|
| Token parseConstExpression(Token token) {
|
| Token constKeyword = token;
|
| token = expect('const', token);
|
| - token = _injectGenericCommentTypeList(token);
|
| + token = listener.injectGenericCommentTypeList(token);
|
| final String value = token.stringValue;
|
| if ((identical(value, '[')) || (identical(value, '[]'))) {
|
| listener.beginConstLiteral(token);
|
| @@ -3213,7 +3215,7 @@ class Parser {
|
| Token beginToken = token;
|
| listener.beginSend(token);
|
| token = parseIdentifier(token, context);
|
| - token = _injectGenericCommentTypeList(token);
|
| + token = listener.injectGenericCommentTypeList(token);
|
| if (isValidMethodTypeArguments(token)) {
|
| token = parseTypeArgumentsOpt(token);
|
| } else {
|
| @@ -3319,6 +3321,14 @@ class Parser {
|
| Token token, bool endWithSemicolon) {
|
| int count = 1;
|
| token = parseMetadataStar(token);
|
| +
|
| + // If the next token has a type substitution comment /*=T*/, then
|
| + // the current 'var' token should be repealed and replaced.
|
| + if (identical('var', token.stringValue)) {
|
| + token =
|
| + listener.replaceTokenWithGenericCommentTypeAssign(token, token.next);
|
| + }
|
| +
|
| token = parseModifiers(token);
|
| token = parseTypeOpt(token);
|
| listener.beginVariablesDeclaration(token);
|
| @@ -3811,59 +3821,6 @@ class Parser {
|
| return reportUnrecoverableError(
|
| token, () => code.format(uri, token.charOffset, string));
|
| }
|
| -
|
| - /// Matches a generic comment type parameters or type arguments and injects
|
| - /// them into the token stream before the given [token].
|
| - Token _injectGenericCommentTypeList(Token token) {
|
| - return _injectGenericComment(token, GENERIC_METHOD_TYPE_LIST, 2);
|
| - }
|
| -
|
| - /// Check if the given [token] has a comment token with the given [info],
|
| - /// which should be either [GENERIC_METHOD_TYPE_ASSIGN] or
|
| - /// [GENERIC_METHOD_TYPE_LIST]. If found, parse the comment into tokens and
|
| - /// inject into the token stream before the [token].
|
| - Token _injectGenericComment(Token token, PrecedenceInfo info, int prefixLen) {
|
| - if (parseGenericMethodComments) {
|
| - CommentToken t = token.precedingCommentTokens;
|
| - for (; t != null; t = t.next) {
|
| - if (t.info == info) {
|
| - String code = t.lexeme.substring(prefixLen, t.lexeme.length - 2);
|
| - Token tokens = _scanGenericMethodComment(code, t.offset + prefixLen);
|
| - if (tokens != null) {
|
| - // Remove the token from the comment stream.
|
| - t.remove();
|
| - // Insert the tokens into the stream.
|
| - _injectTokenList(token, tokens);
|
| - return tokens;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - return token;
|
| - }
|
| -
|
| - /// Scans the given [code], and returns the tokens, otherwise returns `null`.
|
| - Token _scanGenericMethodComment(String code, int offset) {
|
| - var scanner = new SubStringScanner(offset, code);
|
| - Token firstToken = scanner.tokenize();
|
| - if (scanner.hasErrors) {
|
| - return null;
|
| - }
|
| - return firstToken;
|
| - }
|
| -
|
| - void _injectTokenList(Token beforeToken, Token firstToken) {
|
| - // Scanner creates a cyclic EOF token.
|
| - Token lastToken = firstToken;
|
| - while (lastToken.next.info != EOF_INFO) {
|
| - lastToken = lastToken.next;
|
| - }
|
| - // Inject these new tokens into the stream.
|
| - Token previous = beforeToken.previous;
|
| - lastToken.setNext(beforeToken);
|
| - previous.setNext(firstToken);
|
| - beforeToken = firstToken;
|
| - }
|
| }
|
|
|
| typedef FastaMessage NoArgument(Uri uri, int charOffset);
|
|
|