Skip to content

Commit

Permalink
Fix more Analyzer tests
Browse files Browse the repository at this point in the history
* Add "usingFastaParser" accessor for Analyzer engine tests
* Update Analyzer compile time error code tests
* Add additional checks for async/await/yield as identifiers
* Update built-in as type variable error message
* Check for "this." in local declaration parameters
* Remove unnecessary asserts

and address comment in https://dart-review.googlesource.com/c/sdk/+/57022

Change-Id: I54b5ac22f912289dad6360646fae7eca717bbd98
Reviewed-on: https://dart-review.googlesource.com/57220
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
  • Loading branch information
danrubel authored and commit-bot@chromium.org committed May 31, 2018
1 parent fa9ff9a commit a53b585
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 32 deletions.
25 changes: 14 additions & 11 deletions pkg/analyzer/lib/src/fasta/ast_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1603,7 +1603,6 @@ class AstBuilder extends ScopeListener {
List<Configuration> configurations = pop();
StringLiteral uri = pop();
List<Annotation> metadata = pop();
assert(metadata == null); // TODO(paulberry): fix.
Comment comment = _findComment(metadata, importKeyword);

directives.add(ast.importDirective(
Expand Down Expand Up @@ -1654,7 +1653,6 @@ class AstBuilder extends ScopeListener {
List<Configuration> configurations = pop();
StringLiteral uri = pop();
List<Annotation> metadata = pop();
assert(metadata == null);
Comment comment = _findComment(metadata, exportKeyword);
directives.add(ast.exportDirective(comment, metadata, exportKeyword, uri,
configurations, combinators, semicolon));
Expand Down Expand Up @@ -2155,6 +2153,7 @@ class AstBuilder extends ScopeListener {
pop(); // separator before constructor initializers
}
FormalParameterList parameters = pop();
checkFieldFormalParameters(parameters);
SimpleIdentifier name = pop();
TypeAnnotation returnType = pop();
TypeParameterList typeParameters = pop();
Expand Down Expand Up @@ -2342,15 +2341,7 @@ class AstBuilder extends ScopeListener {
handleRecoverableError(
messageConstMethod, modifiers.constKeyword, modifiers.constKeyword);
}
if (parameters?.parameters != null) {
parameters.parameters.forEach((FormalParameter param) {
if (param is FieldFormalParameter) {
// This error is reported in the BodyBuilder.endFormalParameter.
handleRecoverableError(messageFieldInitializerOutsideConstructor,
param.thisKeyword, param.thisKeyword);
}
});
}
checkFieldFormalParameters(parameters);
classDeclaration.members.add(ast.methodDeclaration(
comment,
metadata,
Expand Down Expand Up @@ -2382,6 +2373,18 @@ class AstBuilder extends ScopeListener {
}
}

void checkFieldFormalParameters(FormalParameterList parameters) {
if (parameters?.parameters != null) {
parameters.parameters.forEach((FormalParameter param) {
if (param is FieldFormalParameter) {
// This error is reported in the BodyBuilder.endFormalParameter.
handleRecoverableError(messageFieldInitializerOutsideConstructor,
param.thisKeyword, param.thisKeyword);
}
});
}
}

@override
void handleInvalidMember(Token endToken) {
debugEvent("InvalidMember");
Expand Down
122 changes: 106 additions & 16 deletions pkg/analyzer/test/generated/compile_time_error_code_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,11 @@ class A {
A(static this.x);
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
assertErrors(
source,
usingFastaParser
? [ParserErrorCode.EXTRANEOUS_MODIFIER]
: [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
verify([source]);
}

Expand All @@ -637,7 +641,11 @@ class A {
f(static x) {
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
assertErrors(
source,
usingFastaParser
? [ParserErrorCode.EXTRANEOUS_MODIFIER]
: [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
verify([source]);
}

Expand Down Expand Up @@ -1350,14 +1358,28 @@ class A {
A(const this.x) {}
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
ParserErrorCode.EXTRANEOUS_MODIFIER
]
: [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
verify([source]);
}

test_constFormalParameter_simpleFormalParameter() async {
Source source = addSource("f(const x) {}");
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
ParserErrorCode.EXTRANEOUS_MODIFIER
]
: [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
verify([source]);
}

Expand Down Expand Up @@ -1706,31 +1728,55 @@ typedef F = int Function([Map<String, String> m = const {}]);
Source source = addSource("typedef F([x = 0]);");
await computeAnalysisResult(source);
assertErrors(
source, [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
source,
usingFastaParser
? [
CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
]
: [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
verify([source]);
}

test_defaultValueInFunctionTypeAlias_old_positional() async {
Source source = addSource("typedef F([x = 0]);");
await computeAnalysisResult(source);
assertErrors(
source, [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
source,
usingFastaParser
? [
CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
]
: [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
verify([source]);
}

test_defaultValueInFunctionTypedParameter_named() async {
Source source = addSource("f(g({p: null})) {}");
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
]
: [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
verify([source]);
}

test_defaultValueInFunctionTypedParameter_optional() async {
Source source = addSource("f(g([p = null])) {}");
await computeAnalysisResult(source);
assertErrors(source,
[CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
]
: [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
verify([source]);
}

Expand Down Expand Up @@ -3589,7 +3635,16 @@ class A {
set x(v) async {}
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
// TODO(danrubel): Investigate why error message is duplicated when
// using fasta parser.
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
]
: [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
verify([source]);
}

Expand All @@ -3599,7 +3654,14 @@ class A {
set x(v) async* {}
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
]
: [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
verify([source]);
}

Expand All @@ -3609,28 +3671,56 @@ class A {
set x(v) sync* {}
}''');
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
]
: [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
verify([source]);
}

test_invalidModifierOnSetter_topLevel_async() async {
Source source = addSource("set x(v) async {}");
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
]
: [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
verify([source]);
}

test_invalidModifierOnSetter_topLevel_asyncStar() async {
Source source = addSource("set x(v) async* {}");
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
]
: [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
verify([source]);
}

test_invalidModifierOnSetter_topLevel_syncStar() async {
Source source = addSource("set x(v) sync* {}");
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
assertErrors(
source,
usingFastaParser
? [
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
]
: [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
verify([source]);
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/analyzer/test/generated/test_support.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import 'analysis_context_factory.dart';
* The class `EngineTestCase` defines utility methods for making assertions.
*/
class EngineTestCase {
/**
* Flag indicating whether the fasta parser is being used.
*/
bool get usingFastaParser => Parser.useFasta;

/**
* Assert that the given collection has the same number of elements as the number of specified
* names, and that for each specified name, a corresponding element can be found in the given
Expand Down
20 changes: 15 additions & 5 deletions pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class ConstructorReferenceIdentifierContext extends IdentifierContext {
Token identifier = token.next;
assert(identifier.kind != IDENTIFIER_TOKEN);
if (identifier.isIdentifier) {
checkAsyncAwaitYieldAsIdentifier(identifier, parser);
return identifier;
}

Expand Down Expand Up @@ -369,6 +370,7 @@ class FormalParameterDeclarationIdentifierContext extends IdentifierContext {
Token identifier = token.next;
assert(identifier.kind != IDENTIFIER_TOKEN);
if (identifier.isIdentifier) {
checkAsyncAwaitYieldAsIdentifier(identifier, parser);
return identifier;
}

Expand Down Expand Up @@ -732,6 +734,7 @@ class NamedArgumentReferenceIdentifierContext extends IdentifierContext {
Token identifier = token.next;
assert(identifier.kind != IDENTIFIER_TOKEN);
if (identifier.isIdentifier) {
checkAsyncAwaitYieldAsIdentifier(identifier, parser);
return identifier;
}

Expand Down Expand Up @@ -902,18 +905,25 @@ class TypeVariableDeclarationIdentifierContext extends IdentifierContext {
}

// Recovery
parser.reportRecoverableErrorWithToken(
identifier, fasta.templateExpectedIdentifier);
const followingValues = const ['<', '>', ';', '}', 'extends', 'super'];
if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
looksLikeStartOfNextClassMember(identifier) ||
looksLikeStartOfNextStatement(identifier) ||
isOneOfOrEof(identifier, followingValues)) {
parser.reportRecoverableErrorWithToken(
identifier, fasta.templateExpectedIdentifier);
identifier = parser.rewriter.insertSyntheticIdentifier(token);
} else if (identifier.type.isBuiltIn) {
parser.reportRecoverableErrorWithToken(
identifier, fasta.templateBuiltInIdentifierInDeclaration);
} else {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
parser.reportRecoverableErrorWithToken(
identifier, fasta.templateExpectedIdentifier);
if (!identifier.isKeywordOrIdentifier) {
// When in doubt, consume the token to ensure we make progress
// but insert a synthetic identifier to satisfy listeners.
identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
}
}
return identifier;
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/front_end/lib/src/fasta/parser/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5480,6 +5480,17 @@ class Parser {
if (!exceptionName.isSynthetic) {
reportRecoverableError(comma, fasta.messageCatchSyntax);
}
// TODO(danrubel): Consider inserting synthetic identifier if
// exceptionName is a non-synthetic identifier followed by `.`.
// Then this
// } catch (
// e.f();
// will recover to
// } catch (_s_) {}
// e.f();
// rather than
// } catch (e) {}
// _s_.f();
if (openParens.endGroup.isSynthetic) {
// The scanner did not place the synthetic ')' correctly.
rewriter.moveSynthetic(exceptionName, openParens.endGroup);
Expand Down

0 comments on commit a53b585

Please sign in to comment.