Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: pkg/front_end/lib/src/fasta/parser/parser.dart

Issue 2804753003: Parse type substitution comments /*=T*/ in variable declarations with Fasta. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/analyzer/test/generated/parser_fasta_test.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 fasta.parser.parser; 5 library fasta.parser.parser;
6 6
7 import '../fasta_codes.dart' 7 import '../fasta_codes.dart'
8 show 8 show
9 FastaCode, 9 FastaCode,
10 FastaMessage, 10 FastaMessage,
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 } else { 719 } else {
720 return expect(']', token); 720 return expect(']', token);
721 } 721 }
722 } 722 }
723 723
724 Token parseTypeOpt(Token token) { 724 Token parseTypeOpt(Token token) {
725 if (isGeneralizedFunctionType(token)) { 725 if (isGeneralizedFunctionType(token)) {
726 // Function type without return type. 726 // Function type without return type.
727 return parseType(token); 727 return parseType(token);
728 } 728 }
729 token = _injectGenericCommentTypeAssign(token);
ahe 2017/04/06 08:58:38 Methods in the parser needs to be public so they c
ahe 2017/04/06 10:04:42 See CL 2799043004 for a detailed explanation.
scheglov 2017/04/06 16:15:55 I moved these methods to Listener.
729 Token peek = peekAfterIfType(token); 730 Token peek = peekAfterIfType(token);
730 if (peek != null && (peek.isIdentifier() || optional('this', peek))) { 731 if (peek != null && (peek.isIdentifier() || optional('this', peek))) {
731 return parseType(token); 732 return parseType(token);
732 } 733 }
733 listener.handleNoType(token); 734 listener.handleNoType(token);
734 return token; 735 return token;
735 } 736 }
736 737
737 bool isValidTypeReference(Token token) { 738 bool isValidTypeReference(Token token) {
738 final kind = token.kind; 739 final kind = token.kind;
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after
2398 } 2399 }
2399 2400
2400 Token parseExpressionStatementOrDeclaration(Token token) { 2401 Token parseExpressionStatementOrDeclaration(Token token) {
2401 if (!inPlainSync && optional("await", token)) { 2402 if (!inPlainSync && optional("await", token)) {
2402 return parseExpressionStatement(token); 2403 return parseExpressionStatement(token);
2403 } 2404 }
2404 assert(token.isIdentifier() || identical(token.stringValue, 'void')); 2405 assert(token.isIdentifier() || identical(token.stringValue, 'void'));
2405 Token identifier = peekIdentifierAfterType(token); 2406 Token identifier = peekIdentifierAfterType(token);
2406 if (identifier != null) { 2407 if (identifier != null) {
2407 assert(identifier.isIdentifier()); 2408 assert(identifier.isIdentifier());
2409
2410 // If the identifier token has a type substitution comment /*=T*/,
2411 // then the set of tokens type tokens should be replaced with the
2412 // tokens parsed from the comment.
2413 token = _replaceTokenWithGenericCommentTypeAssign(token, identifier);
2414
2408 Token afterId = identifier.next; 2415 Token afterId = identifier.next;
2409 int afterIdKind = afterId.kind; 2416 int afterIdKind = afterId.kind;
2410 if (identical(afterIdKind, EQ_TOKEN) || 2417 if (identical(afterIdKind, EQ_TOKEN) ||
2411 identical(afterIdKind, SEMICOLON_TOKEN) || 2418 identical(afterIdKind, SEMICOLON_TOKEN) ||
2412 identical(afterIdKind, COMMA_TOKEN)) { 2419 identical(afterIdKind, COMMA_TOKEN)) {
2413 // We are looking at "type identifier" followed by '=', ';', ','. 2420 // We are looking at "type identifier" followed by '=', ';', ','.
2414 return parseVariablesDeclaration(token); 2421 return parseVariablesDeclaration(token);
2415 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) { 2422 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) {
2416 // We are looking at "type identifier '('". 2423 // We are looking at "type identifier '('".
2417 BeginGroupToken beginParen = afterId; 2424 BeginGroupToken beginParen = afterId;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 } 2489 }
2483 } 2490 }
2484 return parseExpressionStatement(token); 2491 return parseExpressionStatement(token);
2485 } 2492 }
2486 2493
2487 Token parseExpressionStatementOrConstDeclaration(Token token) { 2494 Token parseExpressionStatementOrConstDeclaration(Token token) {
2488 assert(identical(token.stringValue, 'const')); 2495 assert(identical(token.stringValue, 'const'));
2489 if (isModifier(token.next)) { 2496 if (isModifier(token.next)) {
2490 return parseVariablesDeclaration(token); 2497 return parseVariablesDeclaration(token);
2491 } 2498 }
2499 _injectGenericCommentTypeAssign(token.next);
2492 Token identifier = peekIdentifierAfterOptionalType(token.next); 2500 Token identifier = peekIdentifierAfterOptionalType(token.next);
2493 if (identifier != null) { 2501 if (identifier != null) {
2494 assert(identifier.isIdentifier()); 2502 assert(identifier.isIdentifier());
2495 Token afterId = identifier.next; 2503 Token afterId = identifier.next;
2496 int afterIdKind = afterId.kind; 2504 int afterIdKind = afterId.kind;
2497 if (identical(afterIdKind, EQ_TOKEN) || 2505 if (identical(afterIdKind, EQ_TOKEN) ||
2498 identical(afterIdKind, SEMICOLON_TOKEN) || 2506 identical(afterIdKind, SEMICOLON_TOKEN) ||
2499 identical(afterIdKind, COMMA_TOKEN)) { 2507 identical(afterIdKind, COMMA_TOKEN)) {
2500 // We are looking at "const type identifier" followed by '=', ';', or 2508 // We are looking at "const type identifier" followed by '=', ';', or
2501 // ','. 2509 // ','.
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
3303 3311
3304 Token parseVariablesDeclarationNoSemicolon(Token token) { 3312 Token parseVariablesDeclarationNoSemicolon(Token token) {
3305 // Only called when parsing a for loop, so this is for parsing locals. 3313 // Only called when parsing a for loop, so this is for parsing locals.
3306 return parseVariablesDeclarationMaybeSemicolon(token, false); 3314 return parseVariablesDeclarationMaybeSemicolon(token, false);
3307 } 3315 }
3308 3316
3309 Token parseVariablesDeclarationMaybeSemicolon( 3317 Token parseVariablesDeclarationMaybeSemicolon(
3310 Token token, bool endWithSemicolon) { 3318 Token token, bool endWithSemicolon) {
3311 int count = 1; 3319 int count = 1;
3312 token = parseMetadataStar(token); 3320 token = parseMetadataStar(token);
3321
3322 // If the next token has a type substitution comment /*=T*/, then
3323 // the current 'var' token should be repealed and replaced.
3324 if (token.keyword == Keyword.VAR) {
ahe 2017/04/06 08:58:38 Use this method to match keywords: optional('var'
ahe 2017/04/06 10:04:42 See lines 178-184.
scheglov 2017/04/06 16:15:55 Done.
3325 token = _replaceTokenWithGenericCommentTypeAssign(token, token.next);
3326 }
3327
3313 token = parseModifiers(token); 3328 token = parseModifiers(token);
3314 token = parseTypeOpt(token); 3329 token = parseTypeOpt(token);
3315 listener.beginVariablesDeclaration(token); 3330 listener.beginVariablesDeclaration(token);
3316 token = parseOptionallyInitializedIdentifier(token); 3331 token = parseOptionallyInitializedIdentifier(token);
3317 while (optional(',', token)) { 3332 while (optional(',', token)) {
3318 token = parseOptionallyInitializedIdentifier(token.next); 3333 token = parseOptionallyInitializedIdentifier(token.next);
3319 ++count; 3334 ++count;
3320 } 3335 }
3321 if (endWithSemicolon) { 3336 if (endWithSemicolon) {
3322 Token semicolon = token; 3337 Token semicolon = token;
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
3796 return reportUnrecoverableError( 3811 return reportUnrecoverableError(
3797 token, () => code.format(uri, token.charOffset, token)); 3812 token, () => code.format(uri, token.charOffset, token));
3798 } 3813 }
3799 3814
3800 Token reportUnrecoverableErrorCodeWithString( 3815 Token reportUnrecoverableErrorCodeWithString(
3801 Token token, FastaCode<StringArgument> code, String string) { 3816 Token token, FastaCode<StringArgument> code, String string) {
3802 return reportUnrecoverableError( 3817 return reportUnrecoverableError(
3803 token, () => code.format(uri, token.charOffset, string)); 3818 token, () => code.format(uri, token.charOffset, string));
3804 } 3819 }
3805 3820
3821 /// Matches a generic comment type substitution and injects it into the token
3822 /// stream before the given [token].
3823 Token _injectGenericCommentTypeAssign(Token token) {
3824 return _injectGenericComment(token, GENERIC_METHOD_TYPE_ASSIGN, 3);
3825 }
3826
3806 /// Matches a generic comment type parameters or type arguments and injects 3827 /// Matches a generic comment type parameters or type arguments and injects
3807 /// them into the token stream before the given [token]. 3828 /// them into the token stream before the given [token].
3808 Token _injectGenericCommentTypeList(Token token) { 3829 Token _injectGenericCommentTypeList(Token token) {
3809 return _injectGenericComment(token, GENERIC_METHOD_TYPE_LIST, 2); 3830 return _injectGenericComment(token, GENERIC_METHOD_TYPE_LIST, 2);
3810 } 3831 }
3811 3832
3812 /// Check if the given [token] has a comment token with the given [info], 3833 /// Check if the given [token] has a comment token with the given [info],
3813 /// which should be either [GENERIC_METHOD_TYPE_ASSIGN] or 3834 /// which should be either [GENERIC_METHOD_TYPE_ASSIGN] or
3814 /// [GENERIC_METHOD_TYPE_LIST]. If found, parse the comment into tokens and 3835 /// [GENERIC_METHOD_TYPE_LIST]. If found, parse the comment into tokens and
3815 /// inject into the token stream before the [token]. 3836 /// inject into the token stream before the [token].
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3848 Token lastToken = firstToken; 3869 Token lastToken = firstToken;
3849 while (lastToken.next.info != EOF_INFO) { 3870 while (lastToken.next.info != EOF_INFO) {
3850 lastToken = lastToken.next; 3871 lastToken = lastToken.next;
3851 } 3872 }
3852 // Inject these new tokens into the stream. 3873 // Inject these new tokens into the stream.
3853 Token previous = beforeToken.previous; 3874 Token previous = beforeToken.previous;
3854 lastToken.setNext(beforeToken); 3875 lastToken.setNext(beforeToken);
3855 previous.setNext(firstToken); 3876 previous.setNext(firstToken);
3856 beforeToken = firstToken; 3877 beforeToken = firstToken;
3857 } 3878 }
3879
3880 /// If the [tokenWithComment] has a type substitution comment /*=T*/, then
3881 /// the comment should be scanned into new tokens, and these tokens inserted
3882 /// instead of tokens from the [tokenToStartReplacing] to the
3883 /// [tokenWithComment]. Returns the first newly inserted token, or the
3884 /// original [tokenWithComment].
3885 Token _replaceTokenWithGenericCommentTypeAssign(
3886 Token tokenToStartReplacing, Token tokenWithComment) {
3887 Token injected = _injectGenericCommentTypeAssign(tokenWithComment);
3888 if (!identical(injected, tokenWithComment)) {
3889 Token prev = tokenToStartReplacing.previous;
3890 prev.setNextWithoutSettingPrevious(injected);
3891 tokenToStartReplacing = injected;
3892 tokenToStartReplacing.previous = prev;
3893 }
3894 return tokenToStartReplacing;
3895 }
3858 } 3896 }
3859 3897
3860 typedef FastaMessage NoArgument(Uri uri, int charOffset); 3898 typedef FastaMessage NoArgument(Uri uri, int charOffset);
3861 3899
3862 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); 3900 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token);
3863 3901
3864 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); 3902 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string);
OLDNEW
« no previous file with comments | « pkg/analyzer/test/generated/parser_fasta_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698