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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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); |
OLD | NEW |