Clean up the stack when a constructor initializer is found (issue 38674)

Change-Id: I219586288a8588298cef94f80be8030581907556
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/119680
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Brian Wilkerson
2019-10-02 17:11:40 +00:00
committed by commit-bot@chromium.org
parent eaf1c308ab
commit 33cd343374
3 changed files with 180 additions and 142 deletions
@@ -1747,6 +1747,15 @@ class AstBuilder extends StackListener {
// extensions. They are invalid and the parser has already reported an
// error at this point. In the future, we should include them in order
// to get navigation, search, etc.
pop(); // body
pop(); // initializers
pop(); // separator
pop(); // parameters
pop(); // typeParameters
pop(); // name
pop(); // returnType
pop(); // modifiers
pop(); // metadata
}
@override
+170 -142
View File
@@ -1681,6 +1681,34 @@ class ExtensionMethodsParserTest_Fasta extends FastaParserTestCase {
expect(extension.members, hasLength(0));
}
void test_constructor_named() {
var unit = parseCompilationUnit('''
extension E on C {
E.named();
}
class C {}
''', errors: [
expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
]);
expect(unit.declarations, hasLength(2));
var extension = unit.declarations[0] as ExtensionDeclaration;
expect(extension.members, hasLength(0));
}
void test_constructor_unnamed() {
var unit = parseCompilationUnit('''
extension E on C {
E();
}
class C {}
''', errors: [
expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
]);
expect(unit.declarations, hasLength(2));
var extension = unit.declarations[0] as ExtensionDeclaration;
expect(extension.members, hasLength(0));
}
void test_missing_on() {
var unit = parseCompilationUnit('extension E', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
@@ -1802,133 +1830,6 @@ class ExtensionMethodsParserTest_Fasta extends FastaParserTestCase {
}
}
@reflectiveTest
class VarianceParserTest_Fasta extends FastaParserTestCase {
@override
CompilationUnit parseCompilationUnit(String content,
{List<ErrorCode> codes,
List<ExpectedError> errors,
FeatureSet featureSet}) {
return super.parseCompilationUnit(content,
codes: codes,
errors: errors,
featureSet: featureSet ??
FeatureSet.forTesting(
sdkVersion: '2.5.0',
additionalFeatures: [Feature.variance],
));
}
void test_class_enabled_single() {
var unit = parseCompilationUnit('class A<in T> { }');
expect(unit.declarations, hasLength(1));
var classDecl = unit.declarations[0] as ClassDeclaration;
expect(classDecl.name.name, 'A');
expect(classDecl.typeParameters.typeParameters, hasLength(1));
expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
}
void test_class_enabled_multipleVariances() {
var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
]);
expect(unit.declarations, hasLength(1));
var classDecl = unit.declarations[0] as ClassDeclaration;
expect(classDecl.name.name, 'A');
expect(classDecl.typeParameters.typeParameters, hasLength(1));
expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
}
void test_class_disabled_single() {
parseCompilationUnit('class A<out T> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_class_disabled_multiple() {
parseCompilationUnit('class A<in T, inout U, out V> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_mixin_enabled_single() {
var unit = parseCompilationUnit('mixin A<inout T> { }');
expect(unit.declarations, hasLength(1));
var mixinDecl = unit.declarations[0] as MixinDeclaration;
expect(mixinDecl.name.name, 'A');
expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
}
void test_mixin_disabled_single() {
parseCompilationUnit('mixin A<inout T> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_mixin_disabled_multiple() {
parseCompilationUnit('mixin A<inout T, out U> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_typedef_enabled() {
parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
]);
}
void test_typedef_disabled() {
parseCompilationUnit('typedef A<inout X> = X Function(X);',
errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_list_enabled() {
parseCompilationUnit('List<out String> stringList = [];', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
]);
}
void test_list_disabled() {
parseCompilationUnit('List<out String> stringList = [];',
errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_function_enabled() {
parseCompilationUnit('void A(in int value) {}', errors: [
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
]);
}
void test_function_disabled() {
parseCompilationUnit('void A(in int value) {}',
errors: [
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
}
/**
* Implementation of [AbstractParserTestCase] specialized for testing the
* Fasta parser.
@@ -2959,6 +2860,21 @@ main() {
parseCompilationUnit('f() { var x = g!.x + 7; }');
}
void test_nullCheckBeforeIndex() {
// https://github.com/dart-lang/sdk/issues/37708
var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
var funct = unit.declarations[0] as FunctionDeclaration;
var body = funct.functionExpression.body as BlockFunctionBody;
var statement = body.block.statements[0] as ExpressionStatement;
var expression = statement.expression as IndexExpression;
expect(expression.index.toSource(), 'arg');
var propertyAccess = expression.target as PropertyAccess;
expect(propertyAccess.propertyName.toSource(), 'baz');
var target = propertyAccess.target as PostfixExpression;
expect(target.operand.toSource(), 'foo.bar');
expect(target.operator.lexeme, '!');
}
void test_nullCheckBeforeMethodCall() {
parseCompilationUnit('f() { var x = g!.m() + 7; }');
}
@@ -3119,21 +3035,6 @@ main() {
expect(target.operand.toSource(), "foo");
}
void test_nullCheckBeforeIndex() {
// https://github.com/dart-lang/sdk/issues/37708
var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
var funct = unit.declarations[0] as FunctionDeclaration;
var body = funct.functionExpression.body as BlockFunctionBody;
var statement = body.block.statements[0] as ExpressionStatement;
var expression = statement.expression as IndexExpression;
expect(expression.index.toSource(), 'arg');
var propertyAccess = expression.target as PropertyAccess;
expect(propertyAccess.propertyName.toSource(), 'baz');
var target = propertyAccess.target as PostfixExpression;
expect(target.operand.toSource(), 'foo.bar');
expect(target.operator.lexeme, '!');
}
void test_nullCheckOnLiteral_disabled() {
parseCompilationUnit('f() { var x = 0!; }',
errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 15, 1)],
@@ -4356,3 +4257,130 @@ mixin A {
expect(declarationList.variables, hasLength(1));
}
}
@reflectiveTest
class VarianceParserTest_Fasta extends FastaParserTestCase {
@override
CompilationUnit parseCompilationUnit(String content,
{List<ErrorCode> codes,
List<ExpectedError> errors,
FeatureSet featureSet}) {
return super.parseCompilationUnit(content,
codes: codes,
errors: errors,
featureSet: featureSet ??
FeatureSet.forTesting(
sdkVersion: '2.5.0',
additionalFeatures: [Feature.variance],
));
}
void test_class_disabled_multiple() {
parseCompilationUnit('class A<in T, inout U, out V> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_class_disabled_single() {
parseCompilationUnit('class A<out T> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_class_enabled_multipleVariances() {
var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
]);
expect(unit.declarations, hasLength(1));
var classDecl = unit.declarations[0] as ClassDeclaration;
expect(classDecl.name.name, 'A');
expect(classDecl.typeParameters.typeParameters, hasLength(1));
expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
}
void test_class_enabled_single() {
var unit = parseCompilationUnit('class A<in T> { }');
expect(unit.declarations, hasLength(1));
var classDecl = unit.declarations[0] as ClassDeclaration;
expect(classDecl.name.name, 'A');
expect(classDecl.typeParameters.typeParameters, hasLength(1));
expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
}
void test_function_disabled() {
parseCompilationUnit('void A(in int value) {}',
errors: [
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_function_enabled() {
parseCompilationUnit('void A(in int value) {}', errors: [
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
]);
}
void test_list_disabled() {
parseCompilationUnit('List<out String> stringList = [];',
errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_list_enabled() {
parseCompilationUnit('List<out String> stringList = [];', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
]);
}
void test_mixin_disabled_multiple() {
parseCompilationUnit('mixin A<inout T, out U> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_mixin_disabled_single() {
parseCompilationUnit('mixin A<inout T> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_mixin_enabled_single() {
var unit = parseCompilationUnit('mixin A<inout T> { }');
expect(unit.declarations, hasLength(1));
var mixinDecl = unit.declarations[0] as MixinDeclaration;
expect(mixinDecl.name.name, 'A');
expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
}
void test_typedef_disabled() {
parseCompilationUnit('typedef A<inout X> = X Function(X);',
errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
],
featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
}
void test_typedef_enabled() {
parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
]);
}
}
@@ -56,6 +56,7 @@ extension E {
}
''', [
error(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
error(CompileTimeErrorCode.UNDEFINED_CLASS, 12, 0),
error(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 1),
error(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 16, 1),
]);