From 1972c11b4e973f621d47c98e67944be2ff408b2a Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Tue, 26 Oct 2021 10:02:54 +0000 Subject: [PATCH] [cfe] Support implicit super call Closes https://github.com/dart-lang/sdk/issues/47545 Change-Id: I7adc75c574fd6d0be17f2f53066d34efd5d54a08 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217922 Reviewed-by: Chloe Stefantsova Commit-Queue: Johnni Winther --- .../lib/src/messages/codes_generated.dart | 13 ++ .../lib/src/fasta/kernel/body_builder.dart | 70 ++++--- .../fasta/kernel/expression_generator.dart | 43 ++-- .../kernel/expression_generator_helper.dart | 5 +- pkg/front_end/messages.status | 1 - pkg/front_end/messages.yaml | 11 + .../general/implicit_super_call.dart | 116 +++++++++++ ...cit_super_call.dart.textual_outline.expect | 65 ++++++ ..._call.dart.textual_outline_modelled.expect | 65 ++++++ .../implicit_super_call.dart.weak.expect | 190 ++++++++++++++++++ ...plicit_super_call.dart.weak.outline.expect | 103 ++++++++++ ...it_super_call.dart.weak.transformed.expect | 137 +++++++++++++ .../testcases/general/implicit_this.dart | 2 + .../testcases/general/super_call.dart | 3 +- .../general/super_call.dart.weak.expect | 13 +- .../super_call.dart.weak.transformed.expect | 13 +- .../testcases/text_serialization.status | 1 + pkg/front_end/testcases/weak.status | 1 + 18 files changed, 771 insertions(+), 81 deletions(-) create mode 100644 pkg/front_end/testcases/general/implicit_super_call.dart create mode 100644 pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/general/implicit_super_call.dart.weak.expect create mode 100644 pkg/front_end/testcases/general/implicit_super_call.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/general/implicit_super_call.dart.weak.transformed.expect diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index 073c5da3ed3..0b96e0802c6 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -5058,6 +5058,19 @@ Message _withArgumentsImplicitMixinOverride( arguments: {'name': name, 'name2': name2, 'name3': name3}); } +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeImplicitSuperCallOfNonMethod = + messageImplicitSuperCallOfNonMethod; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageImplicitSuperCallOfNonMethod = const MessageCode( + "ImplicitSuperCallOfNonMethod", + analyzerCodes: ["IMPLICIT_CALL_OF_NON_METHOD"], + problemMessage: + r"""Cannot invoke `super` because it declares 'call' to be something other than a method.""", + correctionMessage: + r"""Try changing 'call' to a method or explicitly invoke 'call'."""); + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Code codeImportAfterPart = messageImportAfterPart; diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 4b2244dba4b..b13e27ca2f8 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -6980,9 +6980,7 @@ class BodyBuilder extends ScopeListener @override Expression buildMethodInvocation( Expression receiver, Name name, Arguments arguments, int offset, - {bool isConstantExpression: false, - bool isNullAware: false, - bool isSuper: false}) { + {bool isConstantExpression: false, bool isNullAware: false}) { if (constantContext != ConstantContext.none && !isConstantExpression && !enableConstFunctionsInLibrary) { @@ -6992,31 +6990,6 @@ class BodyBuilder extends ScopeListener offset, name.text.length); } - if (isSuper) { - // We can ignore [isNullAware] on super sends. - assert(forest.isThisExpression(receiver)); - Member? target = lookupInstanceMember(name, isSuper: true); - - if (target == null || (target is Procedure && !target.isAccessor)) { - if (target == null) { - warnUnresolvedMethod(name, offset, isSuper: true); - } else if (!areArgumentsCompatible(target.function!, arguments)) { - target = null; - addProblemErrorIfConst( - fasta.templateSuperclassMethodArgumentMismatch - .withArguments(name.text), - offset, - name.text.length); - } - return new SuperMethodInvocation(name, arguments, target as Procedure?) - ..fileOffset = offset; - } - - receiver = new SuperPropertyGet(name, target)..fileOffset = offset; - return forest.createExpressionInvocation( - arguments.fileOffset, receiver, arguments); - } - if (isNullAware) { VariableDeclarationImpl variable = createVariableDeclarationForValue(receiver); @@ -7033,6 +7006,47 @@ class BodyBuilder extends ScopeListener } } + @override + Expression buildSuperInvocation(Name name, Arguments arguments, int offset, + {bool isConstantExpression: false, + bool isNullAware: false, + bool isImplicitCall: false}) { + if (constantContext != ConstantContext.none && + !isConstantExpression && + !enableConstFunctionsInLibrary) { + return buildProblem( + fasta.templateNotConstantExpression + .withArguments('Method invocation'), + offset, + name.text.length); + } + Member? target = lookupInstanceMember(name, isSuper: true); + + if (target == null || (target is Procedure && !target.isAccessor)) { + if (target == null) { + warnUnresolvedMethod(name, offset, isSuper: true); + } else if (!areArgumentsCompatible(target.function!, arguments)) { + target = null; + addProblemErrorIfConst( + fasta.templateSuperclassMethodArgumentMismatch + .withArguments(name.text), + offset, + name.text.length); + } + return new SuperMethodInvocation(name, arguments, target as Procedure?) + ..fileOffset = offset; + } + if (isImplicitCall) { + return buildProblem( + fasta.messageImplicitSuperCallOfNonMethod, offset, noLength); + } else { + Expression receiver = new SuperPropertyGet(name, target) + ..fileOffset = offset; + return forest.createExpressionInvocation( + arguments.fileOffset, receiver, arguments); + } + } + @override void addProblem(Message message, int charOffset, int length, {bool wasHandled: false, diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart index 9347efa1bf5..ff0fb531496 100644 --- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart +++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart @@ -4480,12 +4480,16 @@ class ThisAccessGenerator extends Generator { if (isNullAware) { _reportNonNullableInNullAwareWarningIfNeeded(); } - return _helper.buildMethodInvocation( - _forest.createThisExpression(fileOffset), - name, - selector.arguments, - offsetForToken(selector.token), - isSuper: isSuper); + if (isSuper) { + return _helper.buildSuperInvocation( + name, selector.arguments, offsetForToken(selector.token)); + } else { + return _helper.buildMethodInvocation( + _forest.createThisExpression(fileOffset), + name, + selector.arguments, + offsetForToken(selector.token)); + } } else { if (isSuper) { Member? getter = _helper.lookupInstanceMember(name, isSuper: isSuper); @@ -4517,7 +4521,8 @@ class ThisAccessGenerator extends Generator { if (isInitializer) { return buildConstructorInitializer(offset, new Name(""), arguments); } else if (isSuper) { - return _helper.buildProblem(messageSuperAsExpression, offset, noLength); + return _helper.buildSuperInvocation(Name.callName, arguments, offset, + isImplicitCall: true); } else { return _helper.forest.createExpressionInvocation( offset, _forest.createThisExpression(fileOffset), arguments); @@ -4531,12 +4536,8 @@ class ThisAccessGenerator extends Generator { assert(isNot != null); if (isSuper) { int offset = offsetForToken(token); - Expression result = _helper.buildMethodInvocation( - _forest.createThisExpression(fileOffset), - equalsName, - _forest.createArguments(offset, [right]), - offset, - isSuper: true); + Expression result = _helper.buildSuperInvocation(equalsName, + _forest.createArguments(offset, [right]), offset); if (isNot) { result = _forest.createNot(offset, result); } @@ -4550,12 +4551,8 @@ class ThisAccessGenerator extends Generator { Token token, Name binaryName, Expression right) { if (isSuper) { int offset = offsetForToken(token); - return _helper.buildMethodInvocation( - _forest.createThisExpression(fileOffset), - binaryName, - _forest.createArguments(offset, [right]), - offset, - isSuper: true); + return _helper.buildSuperInvocation(binaryName, + _forest.createArguments(offset, [right]), offset); } return super.buildBinaryOperation(token, binaryName, right); } @@ -4564,12 +4561,8 @@ class ThisAccessGenerator extends Generator { Expression_Generator buildUnaryOperation(Token token, Name unaryName) { if (isSuper) { int offset = offsetForToken(token); - return _helper.buildMethodInvocation( - _forest.createThisExpression(fileOffset), - unaryName, - _forest.createArgumentsEmpty(offset), - offset, - isSuper: true); + return _helper.buildSuperInvocation( + unaryName, _forest.createArgumentsEmpty(offset), offset); } return super.buildUnaryOperation(token, unaryName); } diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart index 3d52030a403..42258ae5260 100644 --- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart +++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart @@ -114,9 +114,12 @@ abstract class ExpressionGeneratorHelper implements InferenceHelper { Expression buildMethodInvocation( Expression receiver, Name name, Arguments arguments, int offset, + {bool isConstantExpression: false, bool isNullAware: false}); + + Expression buildSuperInvocation(Name name, Arguments arguments, int offset, {bool isConstantExpression: false, bool isNullAware: false, - bool isSuper: false}); + bool isImplicitCall: false}); Expression buildConstructorInvocation( TypeDeclarationBuilder type, diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 308d0a64d88..b2174782bf7 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -422,7 +422,6 @@ ImplementsNever/analyzerCode: Fail # Feature not yet in analyzer. ImplementsNever/example: Fail # Feature not yet enabled by default. ImplementsVoid/analyzerCode: Fail # Feature not yet in analyzer. ImplementsVoid/example: Fail # Feature not yet enabled by default. -ImplicitCallOfNonMethod/example: Fail ImplicitMixinOverride/analyzerCode: Fail ImplicitMixinOverride/example: Fail ImplicitReturnNull/analyzerCode: Fail diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 3ab4a3ede6a..0ef4650566f 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -3922,6 +3922,17 @@ ImplicitCallOfNonMethod: problemMessage: "Cannot invoke an instance of '#type' because it declares 'call' to be something other than a method." correctionMessage: "Try changing 'call' to a method or explicitly invoke 'call'." analyzerCode: IMPLICIT_CALL_OF_NON_METHOD + script: | + class Class { void Function() get call => () {}; } + method(Class c) => c(); + +ImplicitSuperCallOfNonMethod: + problemMessage: "Cannot invoke `super` because it declares 'call' to be something other than a method." + correctionMessage: "Try changing 'call' to a method or explicitly invoke 'call'." + analyzerCode: IMPLICIT_CALL_OF_NON_METHOD + script: | + class Super { void Function() get call => () {}; } + class Class extends Super { void method() => super(); } ExpectedOneExpression: problemMessage: "Expected one expression, but found additional input." diff --git a/pkg/front_end/testcases/general/implicit_super_call.dart b/pkg/front_end/testcases/general/implicit_super_call.dart new file mode 100644 index 00000000000..56157424daa --- /dev/null +++ b/pkg/front_end/testcases/general/implicit_super_call.dart @@ -0,0 +1,116 @@ +// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class Super1 { + void call() {} +} + +class Class1 extends Super1 { + void method() { + super(); + super.call(); + } +} + +class Super2 { + int call(int a, [int? b]) => a; +} + +class Class2 extends Super2 { + void method() { + super(0); + super(0, 1); + super.call(0); + super.call(0, 1); + } +} + +class Super3 { + int call(int a, {int? b, int? c}) => a; +} + +class Class3 extends Super3 { + void method() { + super(0); + super(0, b: 1); + super(0, c: 1); + super(0, b: 1, c: 2); + super(0, c: 1, b: 2); + super.call(0); + super.call(0, b: 1); + super.call(0, c: 1); + super.call(0, b: 1, c: 2); + super.call(0, c: 1, b: 2); + } +} + +class Super4 { + T call(T a) => a; +} + +class Class4 extends Super4 { + void method() { + super(0); + super(0); + super.call(0); + super.call(0); + } +} + +class Super5 { + int Function(int) get call => (int a) => a; +} + +class Class5 extends Super5 { + void test() { + super(0); // error + } + + void method() { + super.call(0); // ok + } +} + +class Super6 { + int Function(int) call = (int a) => a; +} + +class Class6 extends Super6 { + void test() { + super(0); // error + } + + void method() { + super.call(0); // ok + } +} + +class Super7 { + void set call(int Function(int) value) {} +} + +class Class7 extends Super7 { + void test() { + super(0); // error + super.call(0); // error + } +} + +class Super8 {} + +class Class8 extends Super8 { + void test() { + super(); // error + super.call(); // error + } +} + +main() { + new Class1().method(); + new Class2().method(); + new Class3().method(); + new Class4().method(); + new Class5().method(); + new Class6().method(); +} diff --git a/pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline.expect new file mode 100644 index 00000000000..e6e9f879504 --- /dev/null +++ b/pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline.expect @@ -0,0 +1,65 @@ +class Super1 { + void call() {} +} + +class Class1 extends Super1 { + void method() {} +} + +class Super2 { + int call(int a, [int? b]) => a; +} + +class Class2 extends Super2 { + void method() {} +} + +class Super3 { + int call(int a, {int? b, int? c}) => a; +} + +class Class3 extends Super3 { + void method() {} +} + +class Super4 { + T call(T a) => a; +} + +class Class4 extends Super4 { + void method() {} +} + +class Super5 { + int Function(int) get call => (int a) => a; +} + +class Class5 extends Super5 { + void test() {} + void method() {} +} + +class Super6 { + int Function(int) call = (int a) => a; +} + +class Class6 extends Super6 { + void test() {} + void method() {} +} + +class Super7 { + void set call(int Function(int) value) {} +} + +class Class7 extends Super7 { + void test() {} +} + +class Super8 {} + +class Class8 extends Super8 { + void test() {} +} + +main() {} diff --git a/pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..4cb5718ad40 --- /dev/null +++ b/pkg/front_end/testcases/general/implicit_super_call.dart.textual_outline_modelled.expect @@ -0,0 +1,65 @@ +class Class1 extends Super1 { + void method() {} +} + +class Class2 extends Super2 { + void method() {} +} + +class Class3 extends Super3 { + void method() {} +} + +class Class4 extends Super4 { + void method() {} +} + +class Class5 extends Super5 { + void method() {} + void test() {} +} + +class Class6 extends Super6 { + void method() {} + void test() {} +} + +class Class7 extends Super7 { + void test() {} +} + +class Class8 extends Super8 { + void test() {} +} + +class Super1 { + void call() {} +} + +class Super2 { + int call(int a, [int? b]) => a; +} + +class Super3 { + int call(int a, {int? b, int? c}) => a; +} + +class Super4 { + T call(T a) => a; +} + +class Super5 { + int Function(int) get call => (int a) => a; +} + +class Super6 { + int Function(int) call = (int a) => a; +} + +class Super7 { + void set call(int Function(int) value) {} +} + +class Super8 {} + +main() {} diff --git a/pkg/front_end/testcases/general/implicit_super_call.dart.weak.expect b/pkg/front_end/testcases/general/implicit_super_call.dart.weak.expect new file mode 100644 index 00000000000..f6e3ccb2ffd --- /dev/null +++ b/pkg/front_end/testcases/general/implicit_super_call.dart.weak.expect @@ -0,0 +1,190 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/implicit_super_call.dart:67:5: Error: Cannot invoke `super` because it declares 'call' to be something other than a method. +// Try changing 'call' to a method or explicitly invoke 'call'. +// super(0); // error +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:81:5: Error: Cannot invoke `super` because it declares 'call' to be something other than a method. +// Try changing 'call' to a method or explicitly invoke 'call'. +// super(0); // error +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:95:5: Error: Superclass has no method named 'call'. +// super(0); // error +// ^^^^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:96:11: Error: Superclass has no method named 'call'. +// super.call(0); // error +// ^^^^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:104:5: Error: Superclass has no method named 'call'. +// super(); // error +// ^^^^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:105:11: Error: Superclass has no method named 'call'. +// super.call(); // error +// ^^^^ +// +import self as self; +import "dart:core" as core; + +class Super1 extends core::Object { + synthetic constructor •() → self::Super1 + : super core::Object::•() + ; + method call() → void {} +} +class Class1 extends self::Super1 { + synthetic constructor •() → self::Class1 + : super self::Super1::•() + ; + method method() → void { + super.{self::Super1::call}(); + super.{self::Super1::call}(); + } +} +class Super2 extends core::Object { + synthetic constructor •() → self::Super2 + : super core::Object::•() + ; + method call(core::int a, [core::int? b = #C1]) → core::int + return a; +} +class Class2 extends self::Super2 { + synthetic constructor •() → self::Class2 + : super self::Super2::•() + ; + method method() → void { + super.{self::Super2::call}(0); + super.{self::Super2::call}(0, 1); + super.{self::Super2::call}(0); + super.{self::Super2::call}(0, 1); + } +} +class Super3 extends core::Object { + synthetic constructor •() → self::Super3 + : super core::Object::•() + ; + method call(core::int a, {core::int? b = #C1, core::int? c = #C1}) → core::int + return a; +} +class Class3 extends self::Super3 { + synthetic constructor •() → self::Class3 + : super self::Super3::•() + ; + method method() → void { + super.{self::Super3::call}(0); + super.{self::Super3::call}(0, b: 1); + super.{self::Super3::call}(0, c: 1); + super.{self::Super3::call}(0, b: 1, c: 2); + super.{self::Super3::call}(0, c: 1, b: 2); + super.{self::Super3::call}(0); + super.{self::Super3::call}(0, b: 1); + super.{self::Super3::call}(0, c: 1); + super.{self::Super3::call}(0, b: 1, c: 2); + super.{self::Super3::call}(0, c: 1, b: 2); + } +} +class Super4 extends core::Object { + synthetic constructor •() → self::Super4 + : super core::Object::•() + ; + method call(self::Super4::call::T% a) → self::Super4::call::T% + return a; +} +class Class4 extends self::Super4 { + synthetic constructor •() → self::Class4 + : super self::Super4::•() + ; + method method() → void { + super.{self::Super4::call}(0); + super.{self::Super4::call}(0); + super.{self::Super4::call}(0); + super.{self::Super4::call}(0); + } +} +class Super5 extends core::Object { + synthetic constructor •() → self::Super5 + : super core::Object::•() + ; + get call() → (core::int) → core::int + return (core::int a) → core::int => a; +} +class Class5 extends self::Super5 { + synthetic constructor •() → self::Class5 + : super self::Super5::•() + ; + method test() → void { + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:67:5: Error: Cannot invoke `super` because it declares 'call' to be something other than a method. +Try changing 'call' to a method or explicitly invoke 'call'. + super(0); // error + ^"; + } + method method() → void { + super.{self::Super5::call}(0){(core::int) → core::int}; + } +} +class Super6 extends core::Object { + field (core::int) → core::int call = (core::int a) → core::int => a; + synthetic constructor •() → self::Super6 + : super core::Object::•() + ; +} +class Class6 extends self::Super6 { + synthetic constructor •() → self::Class6 + : super self::Super6::•() + ; + method test() → void { + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:81:5: Error: Cannot invoke `super` because it declares 'call' to be something other than a method. +Try changing 'call' to a method or explicitly invoke 'call'. + super(0); // error + ^"; + } + method method() → void { + super.{self::Super6::call}(0){(core::int) → core::int}; + } +} +class Super7 extends core::Object { + synthetic constructor •() → self::Super7 + : super core::Object::•() + ; + set call((core::int) → core::int value) → void {} +} +class Class7 extends self::Super7 { + synthetic constructor •() → self::Class7 + : super self::Super7::•() + ; + method test() → void { + super.call(0); + super.call(0); + } +} +class Super8 extends core::Object { + synthetic constructor •() → self::Super8 + : super core::Object::•() + ; +} +class Class8 extends self::Super8 { + synthetic constructor •() → self::Class8 + : super self::Super8::•() + ; + method test() → void { + super.call(); + super.call(); + } +} +static method main() → dynamic { + new self::Class1::•().{self::Class1::method}(){() → void}; + new self::Class2::•().{self::Class2::method}(){() → void}; + new self::Class3::•().{self::Class3::method}(){() → void}; + new self::Class4::•().{self::Class4::method}(){() → void}; + new self::Class5::•().{self::Class5::method}(){() → void}; + new self::Class6::•().{self::Class6::method}(){() → void}; +} + +constants { + #C1 = null +} diff --git a/pkg/front_end/testcases/general/implicit_super_call.dart.weak.outline.expect b/pkg/front_end/testcases/general/implicit_super_call.dart.weak.outline.expect new file mode 100644 index 00000000000..3f03f7ae8c4 --- /dev/null +++ b/pkg/front_end/testcases/general/implicit_super_call.dart.weak.outline.expect @@ -0,0 +1,103 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class Super1 extends core::Object { + synthetic constructor •() → self::Super1 + ; + method call() → void + ; +} +class Class1 extends self::Super1 { + synthetic constructor •() → self::Class1 + ; + method method() → void + ; +} +class Super2 extends core::Object { + synthetic constructor •() → self::Super2 + ; + method call(core::int a, [core::int? b]) → core::int + ; +} +class Class2 extends self::Super2 { + synthetic constructor •() → self::Class2 + ; + method method() → void + ; +} +class Super3 extends core::Object { + synthetic constructor •() → self::Super3 + ; + method call(core::int a, {core::int? b, core::int? c}) → core::int + ; +} +class Class3 extends self::Super3 { + synthetic constructor •() → self::Class3 + ; + method method() → void + ; +} +class Super4 extends core::Object { + synthetic constructor •() → self::Super4 + ; + method call(self::Super4::call::T% a) → self::Super4::call::T% + ; +} +class Class4 extends self::Super4 { + synthetic constructor •() → self::Class4 + ; + method method() → void + ; +} +class Super5 extends core::Object { + synthetic constructor •() → self::Super5 + ; + get call() → (core::int) → core::int + ; +} +class Class5 extends self::Super5 { + synthetic constructor •() → self::Class5 + ; + method test() → void + ; + method method() → void + ; +} +class Super6 extends core::Object { + field (core::int) → core::int call; + synthetic constructor •() → self::Super6 + ; +} +class Class6 extends self::Super6 { + synthetic constructor •() → self::Class6 + ; + method test() → void + ; + method method() → void + ; +} +class Super7 extends core::Object { + synthetic constructor •() → self::Super7 + ; + set call((core::int) → core::int value) → void + ; +} +class Class7 extends self::Super7 { + synthetic constructor •() → self::Class7 + ; + method test() → void + ; +} +class Super8 extends core::Object { + synthetic constructor •() → self::Super8 + ; +} +class Class8 extends self::Super8 { + synthetic constructor •() → self::Class8 + ; + method test() → void + ; +} +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/general/implicit_super_call.dart.weak.transformed.expect b/pkg/front_end/testcases/general/implicit_super_call.dart.weak.transformed.expect new file mode 100644 index 00000000000..b81cdfd9b60 --- /dev/null +++ b/pkg/front_end/testcases/general/implicit_super_call.dart.weak.transformed.expect @@ -0,0 +1,137 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/implicit_super_call.dart:11:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(); +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:22:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(0); +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:23:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(0, 1); +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:35:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(0); +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:36:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(0, b: 1); +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:37:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(0, c: 1); +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:38:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(0, b: 1, c: 2); +// ^ +// +// pkg/front_end/testcases/general/implicit_super_call.dart:39:5: Error: Can't use 'super' as an expression. +// To delegate a constructor to a super constructor, put the super call as an initializer. +// super(0, c: 1, b: 2); +// ^ +// +import self as self; +import "dart:core" as core; + +class Super1 extends core::Object { + synthetic constructor •() → self::Super1 + : super core::Object::•() + ; + method call() → void {} +} +class Class1 extends self::Super1 { + synthetic constructor •() → self::Class1 + : super self::Super1::•() + ; + method method() → void { + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:11:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(); + ^"; + super.{self::Super1::call}(); + } +} +class Super2 extends core::Object { + synthetic constructor •() → self::Super2 + : super core::Object::•() + ; + method call(core::int a, [core::int? b = #C1]) → core::int + return a; +} +class Class2 extends self::Super2 { + synthetic constructor •() → self::Class2 + : super self::Super2::•() + ; + method method() → void { + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:22:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(0); + ^"; + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:23:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(0, 1); + ^"; + super.{self::Super2::call}(0); + super.{self::Super2::call}(0, 1); + } +} +class Super3 extends core::Object { + synthetic constructor •() → self::Super3 + : super core::Object::•() + ; + method call(core::int a, {core::int? b = #C1, core::int? c = #C1}) → core::int + return a; +} +class Class3 extends self::Super3 { + synthetic constructor •() → self::Class3 + : super self::Super3::•() + ; + method method() → void { + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:35:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(0); + ^"; + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:36:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(0, b: 1); + ^"; + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:37:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(0, c: 1); + ^"; + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:38:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(0, b: 1, c: 2); + ^"; + invalid-expression "pkg/front_end/testcases/general/implicit_super_call.dart:39:5: Error: Can't use 'super' as an expression. +To delegate a constructor to a super constructor, put the super call as an initializer. + super(0, c: 1, b: 2); + ^"; + super.{self::Super3::call}(0); + super.{self::Super3::call}(0, b: 1); + super.{self::Super3::call}(0, c: 1); + super.{self::Super3::call}(0, b: 1, c: 2); + super.{self::Super3::call}(0, c: 1, b: 2); + } +} +static method main() → dynamic { + new self::Class1::•().{self::Class1::method}(){() → void}; + new self::Class2::•().{self::Class2::method}(){() → void}; + new self::Class3::•().{self::Class3::method}(){() → void}; +} + +constants { + #C1 = null +} diff --git a/pkg/front_end/testcases/general/implicit_this.dart b/pkg/front_end/testcases/general/implicit_this.dart index 8acf6926be1..289b96237da 100644 --- a/pkg/front_end/testcases/general/implicit_this.dart +++ b/pkg/front_end/testcases/general/implicit_this.dart @@ -1,7 +1,9 @@ // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. + // @dart=2.9 + class C { m() { print("Called m"); diff --git a/pkg/front_end/testcases/general/super_call.dart b/pkg/front_end/testcases/general/super_call.dart index 33cb6ae2144..0ba2666fcf8 100644 --- a/pkg/front_end/testcases/general/super_call.dart +++ b/pkg/front_end/testcases/general/super_call.dart @@ -12,8 +12,7 @@ class B extends A { int call(int x) => x * 3; int call_super() { - // Assumes that super() means super.call(). - // In reality, it is illegal to use it this way. + // super() means super.call(). return super(5); } } diff --git a/pkg/front_end/testcases/general/super_call.dart.weak.expect b/pkg/front_end/testcases/general/super_call.dart.weak.expect index 6c726a40d57..1e7e27c121b 100644 --- a/pkg/front_end/testcases/general/super_call.dart.weak.expect +++ b/pkg/front_end/testcases/general/super_call.dart.weak.expect @@ -1,12 +1,4 @@ library; -// -// Problems in library: -// -// pkg/front_end/testcases/general/super_call.dart:17:12: Error: Can't use 'super' as an expression. -// To delegate a constructor to a super constructor, put the super call as an initializer. -// return super(5); -// ^ -// import self as self; import "dart:core" as core; @@ -34,10 +26,7 @@ class B extends self::A { method call(core::int* x) → core::int* return x.{core::num::*}(3){(core::num*) →* core::int*}; method call_super() → core::int* { - return invalid-expression "pkg/front_end/testcases/general/super_call.dart:17:12: Error: Can't use 'super' as an expression. -To delegate a constructor to a super constructor, put the super call as an initializer. - return super(5); - ^"; + return super.{self::A::call}(5); } } static method main() → dynamic { diff --git a/pkg/front_end/testcases/general/super_call.dart.weak.transformed.expect b/pkg/front_end/testcases/general/super_call.dart.weak.transformed.expect index 6c726a40d57..1e7e27c121b 100644 --- a/pkg/front_end/testcases/general/super_call.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/super_call.dart.weak.transformed.expect @@ -1,12 +1,4 @@ library; -// -// Problems in library: -// -// pkg/front_end/testcases/general/super_call.dart:17:12: Error: Can't use 'super' as an expression. -// To delegate a constructor to a super constructor, put the super call as an initializer. -// return super(5); -// ^ -// import self as self; import "dart:core" as core; @@ -34,10 +26,7 @@ class B extends self::A { method call(core::int* x) → core::int* return x.{core::num::*}(3){(core::num*) →* core::int*}; method call_super() → core::int* { - return invalid-expression "pkg/front_end/testcases/general/super_call.dart:17:12: Error: Can't use 'super' as an expression. -To delegate a constructor to a super constructor, put the super call as an initializer. - return super(5); - ^"; + return super.{self::A::call}(5); } } static method main() → dynamic { diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status index f9b4d6dfb81..9306978ee62 100644 --- a/pkg/front_end/testcases/text_serialization.status +++ b/pkg/front_end/testcases/text_serialization.status @@ -76,6 +76,7 @@ general/expressions: RuntimeError general/getter_vs_setter_type: TypeCheckError general/incomplete_field_formal_parameter: RuntimeError general/infer_field_from_multiple: TypeCheckError +general/implicit_super_call: TypeCheckError general/implement_semi_stub: TypeCheckError general/invalid_operator: TypeCheckError general/invalid_operator_override: TypeCheckError diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status index 5b1bdb6dfff..3b2aaee7cff 100644 --- a/pkg/front_end/testcases/weak.status +++ b/pkg/front_end/testcases/weak.status @@ -79,6 +79,7 @@ general/error_recovery/yield_not_in_generator: RuntimeError general/expressions: RuntimeError general/getter_vs_setter_type: TypeCheckError general/implement_semi_stub: TypeCheckError +general/implicit_super_call: TypeCheckError general/incomplete_field_formal_parameter: RuntimeError general/infer_field_from_multiple: TypeCheckError general/invalid_operator: TypeCheckError