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

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

Issue 2926953004: Various semantic checks on formal parameters. (Closed)
Patch Set: Created 3 years, 6 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
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,
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
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
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
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
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
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
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
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);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698