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, |
11 codeAbstractNotSync, | 11 codeAbstractNotSync, |
12 codeAsciiControlCharacter, | 12 codeAsciiControlCharacter, |
13 codeAssertAsExpression, | 13 codeAssertAsExpression, |
14 codeAssertExtraneousArgument, | 14 codeAssertExtraneousArgument, |
15 codeAsyncAsIdentifier, | 15 codeAsyncAsIdentifier, |
16 codeAwaitAsIdentifier, | 16 codeAwaitAsIdentifier, |
17 codeAwaitForNotAsync, | 17 codeAwaitForNotAsync, |
18 codeAwaitNotAsync, | 18 codeAwaitNotAsync, |
19 codeBuiltInIdentifierAsType, | 19 codeBuiltInIdentifierAsType, |
20 codeBuiltInIdentifierInDeclaration, | 20 codeBuiltInIdentifierInDeclaration, |
| 21 codeCatchSyntax, |
21 codeEmptyNamedParameterList, | 22 codeEmptyNamedParameterList, |
22 codeEmptyOptionalParameterList, | 23 codeEmptyOptionalParameterList, |
23 codeEncoding, | 24 codeEncoding, |
24 codeExpectedBlockToSkip, | 25 codeExpectedBlockToSkip, |
25 codeExpectedBody, | 26 codeExpectedBody, |
26 codeExpectedButGot, | 27 codeExpectedButGot, |
27 codeExpectedClassBody, | 28 codeExpectedClassBody, |
28 codeExpectedClassBodyToSkip, | 29 codeExpectedClassBodyToSkip, |
29 codeExpectedDeclaration, | 30 codeExpectedDeclaration, |
30 codeExpectedExpression, | 31 codeExpectedExpression, |
31 codeExpectedFunctionBody, | 32 codeExpectedFunctionBody, |
32 codeExpectedIdentifier, | 33 codeExpectedIdentifier, |
33 codeExpectedOpenParens, | 34 codeExpectedOpenParens, |
34 codeExpectedString, | 35 codeExpectedString, |
35 codeExtraneousModifier, | 36 codeExtraneousModifier, |
36 codeFactoryNotSync, | 37 codeFactoryNotSync, |
| 38 codeFunctionTypeDefaultValue, |
37 codeGeneratorReturnsValue, | 39 codeGeneratorReturnsValue, |
| 40 codeGetterWithFormals, |
38 codeInvalidAwaitFor, | 41 codeInvalidAwaitFor, |
39 codeInvalidInlineFunctionType, | 42 codeInvalidInlineFunctionType, |
40 codeInvalidSyncModifier, | 43 codeInvalidSyncModifier, |
41 codeInvalidVoid, | 44 codeInvalidVoid, |
| 45 codeNoFormals, |
42 codeNonAsciiIdentifier, | 46 codeNonAsciiIdentifier, |
43 codeNonAsciiWhitespace, | 47 codeNonAsciiWhitespace, |
44 codeOnlyTry, | 48 codeOnlyTry, |
45 codePositionalParameterWithEquals, | 49 codePositionalParameterWithEquals, |
| 50 codePrivateNamedParameter, |
46 codeRequiredParameterWithDefault, | 51 codeRequiredParameterWithDefault, |
47 codeSetterNotSync, | 52 codeSetterNotSync, |
48 codeStackOverflow, | 53 codeStackOverflow, |
49 codeTypeAfterVar, | 54 codeTypeAfterVar, |
50 codeTypeRequired, | 55 codeTypeRequired, |
51 codeUnexpectedToken, | 56 codeUnexpectedToken, |
52 codeUnmatchedToken, | 57 codeUnmatchedToken, |
53 codeUnspecified, | 58 codeUnspecified, |
54 codeUnsupportedPrefixPlus, | 59 codeUnsupportedPrefixPlus, |
55 codeUnterminatedString, | 60 codeUnterminatedString, |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 listener.beginFormalParameter(token, memberKind); | 714 listener.beginFormalParameter(token, memberKind); |
710 | 715 |
711 bool inFunctionType = memberKind == MemberKind.GeneralizedFunctionType; | 716 bool inFunctionType = memberKind == MemberKind.GeneralizedFunctionType; |
712 token = parseModifiers(token, memberKind, parameterKind: parameterKind); | 717 token = parseModifiers(token, memberKind, parameterKind: parameterKind); |
713 bool isNamedParameter = parameterKind == FormalParameterType.NAMED; | 718 bool isNamedParameter = parameterKind == FormalParameterType.NAMED; |
714 | 719 |
715 Token thisKeyword = null; | 720 Token thisKeyword = null; |
716 Token nameToken; | 721 Token nameToken; |
717 if (inFunctionType) { | 722 if (inFunctionType) { |
718 if (isNamedParameter || token.isIdentifier) { | 723 if (isNamedParameter || token.isIdentifier) { |
| 724 nameToken = token; |
719 token = parseIdentifier( | 725 token = parseIdentifier( |
720 token, IdentifierContext.formalParameterDeclaration); | 726 token, IdentifierContext.formalParameterDeclaration); |
721 } else { | 727 } else { |
722 listener.handleNoName(token); | 728 listener.handleNoName(token); |
723 } | 729 } |
724 } else { | 730 } else { |
725 if (optional('this', token)) { | 731 if (optional('this', token)) { |
726 thisKeyword = token; | 732 thisKeyword = token; |
727 token = expect('.', token.next); | 733 token = expect('.', token.next); |
728 nameToken = token; | 734 nameToken = token; |
729 token = parseIdentifier(token, IdentifierContext.fieldInitializer); | 735 token = parseIdentifier(token, IdentifierContext.fieldInitializer); |
730 } else { | 736 } else { |
731 nameToken = token; | 737 nameToken = token; |
732 token = parseIdentifier( | 738 token = parseIdentifier( |
733 token, IdentifierContext.formalParameterDeclaration); | 739 token, IdentifierContext.formalParameterDeclaration); |
734 } | 740 } |
735 } | 741 } |
| 742 if (isNamedParameter && nameToken.lexeme.startsWith("_")) { |
| 743 reportRecoverableErrorCode(nameToken, codePrivateNamedParameter); |
| 744 } |
736 | 745 |
737 token = listener.injectGenericCommentTypeList(token); | 746 token = listener.injectGenericCommentTypeList(token); |
738 if (optional('(', token)) { | 747 if (optional('(', token)) { |
739 Token inlineFunctionTypeStart = token; | 748 Token inlineFunctionTypeStart = token; |
740 listener.beginFunctionTypedFormalParameter(token); | 749 listener.beginFunctionTypedFormalParameter(token); |
741 listener.handleNoTypeVariables(token); | 750 listener.handleNoTypeVariables(token); |
742 token = parseFormalParameters(token, MemberKind.FunctionTypedParameter); | 751 token = parseFormalParameters(token, MemberKind.FunctionTypedParameter); |
743 listener.endFunctionTypedFormalParameter(thisKeyword, parameterKind); | 752 listener.endFunctionTypedFormalParameter(thisKeyword, parameterKind); |
744 // Generalized function types don't allow inline function types. | 753 // Generalized function types don't allow inline function types. |
745 // The following isn't allowed: | 754 // The following isn't allowed: |
(...skipping 11 matching lines...) Expand all Loading... |
757 // Generalized function types don't allow inline function types. | 766 // Generalized function types don't allow inline function types. |
758 // The following isn't allowed: | 767 // The following isn't allowed: |
759 // int Function(int bar(String x)). | 768 // int Function(int bar(String x)). |
760 if (memberKind == MemberKind.GeneralizedFunctionType) { | 769 if (memberKind == MemberKind.GeneralizedFunctionType) { |
761 reportRecoverableErrorCode( | 770 reportRecoverableErrorCode( |
762 inlineFunctionTypeStart, codeInvalidInlineFunctionType); | 771 inlineFunctionTypeStart, codeInvalidInlineFunctionType); |
763 } | 772 } |
764 } | 773 } |
765 String value = token.stringValue; | 774 String value = token.stringValue; |
766 if ((identical('=', value)) || (identical(':', value))) { | 775 if ((identical('=', value)) || (identical(':', value))) { |
767 // TODO(ahe): Validate that these are only used for optional parameters. | |
768 Token equal = token; | 776 Token equal = token; |
769 token = parseExpression(token.next); | 777 token = parseExpression(token.next); |
770 listener.handleValuedFormalParameter(equal, token); | 778 listener.handleValuedFormalParameter(equal, token); |
771 if (parameterKind.isRequired) { | 779 if (parameterKind.isRequired) { |
772 reportRecoverableErrorCode(equal, codeRequiredParameterWithDefault); | 780 reportRecoverableErrorCode(equal, codeRequiredParameterWithDefault); |
773 } else if (parameterKind.isPositional && identical(':', value)) { | 781 } else if (parameterKind.isPositional && identical(':', value)) { |
774 reportRecoverableErrorCode(equal, codePositionalParameterWithEquals); | 782 reportRecoverableErrorCode(equal, codePositionalParameterWithEquals); |
| 783 } else if (inFunctionType || |
| 784 memberKind == MemberKind.FunctionTypeAlias || |
| 785 memberKind == MemberKind.FunctionTypedParameter) { |
| 786 reportRecoverableErrorCode(equal.next, codeFunctionTypeDefaultValue); |
775 } | 787 } |
776 } else { | 788 } else { |
777 listener.handleFormalParameterWithoutValue(token); | 789 listener.handleFormalParameterWithoutValue(token); |
778 } | 790 } |
779 listener.endFormalParameter( | 791 listener.endFormalParameter( |
780 thisKeyword, nameToken, parameterKind, memberKind); | 792 thisKeyword, nameToken, parameterKind, memberKind); |
781 return token; | 793 return token; |
782 } | 794 } |
783 | 795 |
784 Token parseOptionalFormalParameters( | 796 Token parseOptionalFormalParameters( |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 } | 1380 } |
1369 | 1381 |
1370 if (type == null) { | 1382 if (type == null) { |
1371 listener.handleNoType(name); | 1383 listener.handleNoType(name); |
1372 } else { | 1384 } else { |
1373 parseReturnTypeOpt(type); | 1385 parseReturnTypeOpt(type); |
1374 } | 1386 } |
1375 Token token = | 1387 Token token = |
1376 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); | 1388 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); |
1377 | 1389 |
| 1390 bool isGetter = false; |
1378 if (getOrSet == null) { | 1391 if (getOrSet == null) { |
1379 token = parseTypeVariablesOpt(token); | 1392 token = parseTypeVariablesOpt(token); |
1380 } else { | 1393 } else { |
| 1394 isGetter = optional("get", getOrSet); |
1381 listener.handleNoTypeVariables(token); | 1395 listener.handleNoTypeVariables(token); |
1382 } | 1396 } |
| 1397 checkFormals(isGetter, name, token); |
1383 token = parseFormalParametersOpt(token, MemberKind.TopLevelMethod); | 1398 token = parseFormalParametersOpt(token, MemberKind.TopLevelMethod); |
1384 AsyncModifier savedAsyncModifier = asyncState; | 1399 AsyncModifier savedAsyncModifier = asyncState; |
1385 Token asyncToken = token; | 1400 Token asyncToken = token; |
1386 token = parseAsyncModifier(token); | 1401 token = parseAsyncModifier(token); |
1387 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { | 1402 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { |
1388 reportRecoverableErrorCode(asyncToken, codeSetterNotSync); | 1403 reportRecoverableErrorCode(asyncToken, codeSetterNotSync); |
1389 } | 1404 } |
1390 token = parseFunctionBody(token, false, externalModifier != null); | 1405 token = parseFunctionBody(token, false, externalModifier != null); |
1391 asyncState = savedAsyncModifier; | 1406 asyncState = savedAsyncModifier; |
1392 Token endToken = token; | 1407 Token endToken = token; |
1393 token = token.next; | 1408 token = token.next; |
1394 listener.endTopLevelMethod(start, getOrSet, endToken); | 1409 listener.endTopLevelMethod(start, getOrSet, endToken); |
1395 return token; | 1410 return token; |
1396 } | 1411 } |
1397 | 1412 |
| 1413 void checkFormals(bool isGetter, Token name, Token token) { |
| 1414 if (optional("(", token)) { |
| 1415 if (isGetter) { |
| 1416 reportRecoverableErrorCode(token, codeGetterWithFormals); |
| 1417 } |
| 1418 } else if (!isGetter) { |
| 1419 reportRecoverableErrorCodeWithToken(name, codeNoFormals); |
| 1420 } |
| 1421 } |
| 1422 |
1398 /// Looks ahead to find the name of a member. Returns a link of the modifiers, | 1423 /// Looks ahead to find the name of a member. Returns a link of the modifiers, |
1399 /// set/get, (operator) name, and either the start of the method body or the | 1424 /// set/get, (operator) name, and either the start of the method body or the |
1400 /// end of the declaration. | 1425 /// end of the declaration. |
1401 /// | 1426 /// |
1402 /// Examples: | 1427 /// Examples: |
1403 /// | 1428 /// |
1404 /// int get foo; | 1429 /// int get foo; |
1405 /// results in | 1430 /// results in |
1406 /// [';', 'foo', 'get', 'int'] | 1431 /// [';', 'foo', 'get', 'int'] |
1407 /// | 1432 /// |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 token, codeExtraneousModifier); | 1712 token, codeExtraneousModifier); |
1688 } | 1713 } |
1689 typeRequired = false; | 1714 typeRequired = false; |
1690 } else if (optional("const", token)) { | 1715 } else if (optional("const", token)) { |
1691 if (!isVariable) { | 1716 if (!isVariable) { |
1692 reportRecoverableErrorCodeWithToken( | 1717 reportRecoverableErrorCodeWithToken( |
1693 token, codeExtraneousModifier); | 1718 token, codeExtraneousModifier); |
1694 } | 1719 } |
1695 typeRequired = false; | 1720 typeRequired = false; |
1696 } else if (optional("static", token)) { | 1721 } else if (optional("static", token)) { |
1697 if (memberKind == MemberKind.NonStaticMethod) { | 1722 if (parameterKind != null) { |
| 1723 reportRecoverableErrorCodeWithToken( |
| 1724 token, codeExtraneousModifier); |
| 1725 } else if (memberKind == MemberKind.NonStaticMethod) { |
1698 memberKind = MemberKind.StaticMethod; | 1726 memberKind = MemberKind.StaticMethod; |
1699 } else if (memberKind == MemberKind.NonStaticField) { | 1727 } else if (memberKind == MemberKind.NonStaticField) { |
1700 memberKind = MemberKind.StaticField; | 1728 memberKind = MemberKind.StaticField; |
1701 } else { | 1729 } else { |
1702 reportRecoverableErrorCodeWithToken( | 1730 reportRecoverableErrorCodeWithToken( |
1703 token, codeExtraneousModifier); | 1731 token, codeExtraneousModifier); |
1704 token = token.next; | 1732 token = token.next; |
1705 continue; | 1733 continue; |
1706 } | 1734 } |
1707 } else if (optional("covariant", token)) { | 1735 } else if (optional("covariant", token)) { |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2063 if (staticModifier != null) { | 2091 if (staticModifier != null) { |
2064 reportRecoverableErrorCodeWithToken( | 2092 reportRecoverableErrorCodeWithToken( |
2065 staticModifier, codeExtraneousModifier); | 2093 staticModifier, codeExtraneousModifier); |
2066 } | 2094 } |
2067 } else { | 2095 } else { |
2068 token = parseIdentifier(name, IdentifierContext.methodDeclaration); | 2096 token = parseIdentifier(name, IdentifierContext.methodDeclaration); |
2069 } | 2097 } |
2070 | 2098 |
2071 token = parseQualifiedRestOpt( | 2099 token = parseQualifiedRestOpt( |
2072 token, IdentifierContext.methodDeclarationContinuation); | 2100 token, IdentifierContext.methodDeclarationContinuation); |
| 2101 bool isGetter = false; |
2073 if (getOrSet == null) { | 2102 if (getOrSet == null) { |
2074 token = parseTypeVariablesOpt(token); | 2103 token = parseTypeVariablesOpt(token); |
2075 } else { | 2104 } else { |
| 2105 isGetter = optional("get", getOrSet); |
2076 listener.handleNoTypeVariables(token); | 2106 listener.handleNoTypeVariables(token); |
2077 } | 2107 } |
| 2108 checkFormals(isGetter, name, token); |
2078 token = parseFormalParametersOpt( | 2109 token = parseFormalParametersOpt( |
2079 token, | 2110 token, |
2080 staticModifier != null | 2111 staticModifier != null |
2081 ? MemberKind.StaticMethod | 2112 ? MemberKind.StaticMethod |
2082 : MemberKind.NonStaticMethod); | 2113 : MemberKind.NonStaticMethod); |
2083 token = parseInitializersOpt(token); | 2114 token = parseInitializersOpt(token); |
2084 AsyncModifier savedAsyncModifier = asyncState; | 2115 AsyncModifier savedAsyncModifier = asyncState; |
2085 Token asyncToken = token; | 2116 Token asyncToken = token; |
2086 token = parseAsyncModifier(token); | 2117 token = parseAsyncModifier(token); |
2087 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { | 2118 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { |
(...skipping 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3653 var onKeyword = null; | 3684 var onKeyword = null; |
3654 if (identical(value, 'on')) { | 3685 if (identical(value, 'on')) { |
3655 // on qualified catchPart? | 3686 // on qualified catchPart? |
3656 onKeyword = token; | 3687 onKeyword = token; |
3657 token = parseType(token.next); | 3688 token = parseType(token.next); |
3658 value = token.stringValue; | 3689 value = token.stringValue; |
3659 } | 3690 } |
3660 Token catchKeyword = null; | 3691 Token catchKeyword = null; |
3661 if (identical(value, 'catch')) { | 3692 if (identical(value, 'catch')) { |
3662 catchKeyword = token; | 3693 catchKeyword = token; |
3663 // TODO(ahe): Validate the "parameters". | 3694 Token openParens = catchKeyword.next; |
| 3695 Token exceptionName = openParens.next; |
| 3696 Token commaOrCloseParens = exceptionName.next; |
| 3697 Token traceName = commaOrCloseParens.next; |
| 3698 Token closeParens = traceName.next; |
| 3699 if (!optional("(", openParens)) { |
| 3700 // Handled below by parseFormalParameters. |
| 3701 } else if (!exceptionName.isIdentifier) { |
| 3702 reportRecoverableErrorCode(exceptionName, codeCatchSyntax); |
| 3703 } else if (optional(")", commaOrCloseParens)) { |
| 3704 // OK: `catch (identifier)`. |
| 3705 } else if (!optional(",", commaOrCloseParens)) { |
| 3706 reportRecoverableErrorCode(exceptionName, codeCatchSyntax); |
| 3707 } else if (!traceName.isIdentifier) { |
| 3708 reportRecoverableErrorCode(exceptionName, codeCatchSyntax); |
| 3709 } else if (!optional(")", closeParens)) { |
| 3710 reportRecoverableErrorCode(exceptionName, codeCatchSyntax); |
| 3711 } |
3664 token = parseFormalParameters(token.next, MemberKind.Catch); | 3712 token = parseFormalParameters(token.next, MemberKind.Catch); |
3665 } | 3713 } |
3666 listener.endCatchClause(token); | 3714 listener.endCatchClause(token); |
3667 token = parseBlock(token); | 3715 token = parseBlock(token); |
3668 ++catchCount; | 3716 ++catchCount; |
3669 listener.handleCatchBlock(onKeyword, catchKeyword); | 3717 listener.handleCatchBlock(onKeyword, catchKeyword); |
3670 value = token.stringValue; // while condition | 3718 value = token.stringValue; // while condition |
3671 } | 3719 } |
3672 | 3720 |
3673 Token finallyKeyword = null; | 3721 Token finallyKeyword = null; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3952 return reportUnrecoverableError( | 4000 return reportUnrecoverableError( |
3953 token, () => code.format(uri, token.charOffset, string)); | 4001 token, () => code.format(uri, token.charOffset, string)); |
3954 } | 4002 } |
3955 } | 4003 } |
3956 | 4004 |
3957 typedef FastaMessage NoArgument(Uri uri, int charOffset); | 4005 typedef FastaMessage NoArgument(Uri uri, int charOffset); |
3958 | 4006 |
3959 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); | 4007 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); |
3960 | 4008 |
3961 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); | 4009 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); |
OLD | NEW |