Chromium Code Reviews| 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 |