| 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 |