From 33cd343374bd8a76afd58b21187ee2cb2d491bba Mon Sep 17 00:00:00 2001 From: Brian Wilkerson Date: Wed, 2 Oct 2019 17:11:40 +0000 Subject: [PATCH] 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 Commit-Queue: Brian Wilkerson --- pkg/analyzer/lib/src/fasta/ast_builder.dart | 9 + .../test/generated/parser_fasta_test.dart | 312 ++++++++++-------- .../resolution/extension_method_test.dart | 1 + 3 files changed, 180 insertions(+), 142 deletions(-) diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart index 2938cb22026..5b767143252 100644 --- a/pkg/analyzer/lib/src/fasta/ast_builder.dart +++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart @@ -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 diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart index c92e79da2ca..11a75d9e295 100644 --- a/pkg/analyzer/test/generated/parser_fasta_test.dart +++ b/pkg/analyzer/test/generated/parser_fasta_test.dart @@ -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 codes, - List 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 { }'); - 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 { }', 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 { }', - errors: [ - expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3), - ], - featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); - } - - void test_class_disabled_multiple() { - parseCompilationUnit('class A { }', - 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 { }'); - 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 { }', - errors: [ - expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5), - ], - featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); - } - - void test_mixin_disabled_multiple() { - parseCompilationUnit('mixin A { }', - 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 = X Function(X);', errors: [ - expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1), - ]); - } - - void test_typedef_disabled() { - parseCompilationUnit('typedef A = X Function(X);', - errors: [ - expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1), - ], - featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); - } - - void test_list_enabled() { - parseCompilationUnit('List stringList = [];', errors: [ - expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6), - ]); - } - - void test_list_disabled() { - parseCompilationUnit('List 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 codes, + List 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 { }', + 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 { }', + 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 { }', 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 { }'); + 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 stringList = [];', + errors: [ + expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6), + ], + featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); + } + + void test_list_enabled() { + parseCompilationUnit('List stringList = [];', errors: [ + expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6), + ]); + } + + void test_mixin_disabled_multiple() { + parseCompilationUnit('mixin A { }', + 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 { }', + 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 { }'); + 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 = X Function(X);', + errors: [ + expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1), + ], + featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); + } + + void test_typedef_enabled() { + parseCompilationUnit('typedef A = X Function(X);', errors: [ + expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1), + ]); + } +} diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart index 7c00d1f1358..1e9c3fb4f62 100644 --- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart @@ -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), ]);