diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart index 4c4e74d6ceb1b..0d2f50f85eaf7 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart @@ -811,7 +811,7 @@ class ConstantsTransformer extends RemovingTransformer { } } -class ConstantEvaluator extends RecursiveResultVisitor { +class ConstantEvaluator extends ExpressionVisitor { final ConstantsBackend backend; final NumberSemantics numberSemantics; ConstantIntFolder intFolder; @@ -1157,7 +1157,7 @@ class ConstantEvaluator extends RecursiveResultVisitor { } @override - Constant defaultTreeNode(Node node) { + Constant defaultExpression(Expression node) { // Only a subset of the expression language is valid for constant // evaluation. return createInvalidExpressionConstant( @@ -2738,19 +2738,20 @@ class ConstantEvaluator extends RecursiveResultVisitor { if (value is AbortConstant) return value; env.addVariableValue(parameter, value); } - return function.body.accept(this); + Statement body = function.body; + if (body is ReturnStatement) { + if (!enableConstFunctions) { + return createInvalidExpressionConstant( + node, "Return statements are not supported."); + } + return body.expression.accept(this); + } else { + return createInvalidExpressionConstant( + node, "Unsupported statement: ${body.runtimeType}."); + } }); } - @override - Constant visitReturnStatement(ReturnStatement node) { - if (!enableConstFunctions) { - return createInvalidExpressionConstant( - node, "Return statements are not supported."); - } - return node.expression.accept(this); - } - @override Constant visitAsExpression(AsExpression node) { final Constant constant = _evaluateSubexpression(node.operand); diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart index 92ac3433d1ff0..3017856f80ab5 100644 --- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart @@ -425,19 +425,21 @@ class SourceClassBuilder extends ClassBuilderImpl Library library = libraryBuilder.library; List issues = findTypeArgumentIssues( - library, new InterfaceType( supertype.classNode, library.nonNullable, supertype.typeArguments), typeEnvironment, libraryBuilder.isNonNullableByDefault ? SubtypeCheckMode.withNullabilities : SubtypeCheckMode.ignoringNullabilities, - allowSuperBounded: false); + allowSuperBounded: false, + isNonNullableByDefault: library.isNonNullableByDefault, + areGenericArgumentsAllowed: + libraryBuilder.enableGenericMetadataInLibrary); for (TypeArgumentIssue issue in issues) { DartType argument = issue.argument; TypeParameter typeParameter = issue.typeParameter; bool inferred = libraryBuilder.inferredTypes.contains(argument); - if (isGenericFunctionTypeOrAlias(argument)) { + if (issue.isGenericTypeAsArgumentIssue) { if (inferred) { // Supertype can't be or contain super-bounded types, so null is // passed for super-bounded hint here. diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart index e3158d4109461..e409ff007e2f5 100644 --- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart @@ -32,8 +32,7 @@ import 'package:kernel/src/bounds_checks.dart' TypeArgumentIssue, findTypeArgumentIssues, findTypeArgumentIssuesForInvocation, - getGenericTypeName, - isGenericFunctionTypeOrAlias; + getGenericTypeName; import 'package:kernel/type_algebra.dart' show Substitution, substitute; @@ -2923,15 +2922,17 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { bool haveErroneousBounds = false; if (!inErrorRecovery) { - for (int i = 0; i < variables.length; ++i) { - TypeVariableBuilder variable = variables[i]; - List genericFunctionTypes = []; - findGenericFunctionTypes(variable.bound, - result: genericFunctionTypes); - if (genericFunctionTypes.length > 0) { - haveErroneousBounds = true; - addProblem(messageGenericFunctionTypeInBound, variable.charOffset, - variable.name.length, variable.fileUri); + if (!enableGenericMetadataInLibrary) { + for (int i = 0; i < variables.length; ++i) { + TypeVariableBuilder variable = variables[i]; + List genericFunctionTypes = []; + findGenericFunctionTypes(variable.bound, + result: genericFunctionTypes); + if (genericFunctionTypes.length > 0) { + haveErroneousBounds = true; + addProblem(messageGenericFunctionTypeInBound, variable.charOffset, + variable.name.length, variable.fileUri); + } } } @@ -3170,7 +3171,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { inferredTypes.contains(argument); offset = typeArgumentsInfo?.getOffsetForIndex(issue.index, offset) ?? offset; - if (isGenericFunctionTypeOrAlias(argument)) { + if (issue.isGenericTypeAsArgumentIssue) { if (issueInferred) { message = templateGenericFunctionTypeInferredAsActualTypeArgument .withArguments(argument, isNonNullableByDefault); @@ -3221,10 +3222,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { } } + // Don't show the hint about an attempted super-bounded type if the issue + // with the argument is that it's generic. reportTypeArgumentIssue(message, fileUri, offset, typeParameter: typeParameter, - superBoundedAttempt: issue.enclosingType, - superBoundedAttemptInverted: issue.invertedType); + superBoundedAttempt: + issue.isGenericTypeAsArgumentIssue ? null : issue.enclosingType, + superBoundedAttemptInverted: + issue.isGenericTypeAsArgumentIssue ? null : issue.invertedType); } } @@ -3306,13 +3311,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { // Check in bounds of own type variables. for (TypeParameter parameter in typeParameters) { List issues = findTypeArgumentIssues( - library, parameter.bound, typeEnvironment, isNonNullableByDefault ? SubtypeCheckMode.withNullabilities : SubtypeCheckMode.ignoringNullabilities, - allowSuperBounded: true); + allowSuperBounded: true, + isNonNullableByDefault: library.isNonNullableByDefault, + areGenericArgumentsAllowed: enableGenericMetadataInLibrary); for (TypeArgumentIssue issue in issues) { DartType argument = issue.argument; TypeParameter typeParameter = issue.typeParameter; @@ -3325,7 +3331,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { continue; } - if (isGenericFunctionTypeOrAlias(argument)) { + if (issue.isGenericTypeAsArgumentIssue) { reportTypeArgumentIssue( messageGenericFunctionTypeUsedAsActualTypeArgument, fileUri, @@ -3382,13 +3388,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { } if (!skipReturnType && returnType != null) { List issues = findTypeArgumentIssues( - library, returnType, typeEnvironment, isNonNullableByDefault ? SubtypeCheckMode.withNullabilities : SubtypeCheckMode.ignoringNullabilities, - allowSuperBounded: true); + allowSuperBounded: true, + isNonNullableByDefault: library.isNonNullableByDefault, + areGenericArgumentsAllowed: enableGenericMetadataInLibrary); for (TypeArgumentIssue issue in issues) { DartType argument = issue.argument; TypeParameter typeParameter = issue.typeParameter; @@ -3396,7 +3403,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { // We don't need to check if [argument] was inferred or specified // here, because inference in return types boils down to instantiate- // -to-bound, and it can't provide a type that violates the bound. - if (isGenericFunctionTypeOrAlias(argument)) { + if (issue.isGenericTypeAsArgumentIssue) { reportTypeArgumentIssue( messageGenericFunctionTypeUsedAsActualTypeArgument, fileUri, @@ -3490,13 +3497,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { DartType type, TypeEnvironment typeEnvironment, Uri fileUri, int offset, {bool inferred, bool allowSuperBounded = true}) { List issues = findTypeArgumentIssues( - library, type, typeEnvironment, isNonNullableByDefault ? SubtypeCheckMode.withNullabilities : SubtypeCheckMode.ignoringNullabilities, - allowSuperBounded: allowSuperBounded); + allowSuperBounded: allowSuperBounded, + isNonNullableByDefault: library.isNonNullableByDefault, + areGenericArgumentsAllowed: enableGenericMetadataInLibrary); reportTypeArgumentIssues(issues, fileUri, offset, inferred: inferred); } @@ -3554,14 +3562,15 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { ? const NeverType.nonNullable() : const NullType(); List issues = findTypeArgumentIssuesForInvocation( - library, parameters, arguments, typeEnvironment, isNonNullableByDefault ? SubtypeCheckMode.withNullabilities : SubtypeCheckMode.ignoringNullabilities, - bottomType); + bottomType, + isNonNullableByDefault: library.isNonNullableByDefault, + areGenericArgumentsAllowed: enableGenericMetadataInLibrary); if (issues.isNotEmpty) { DartType targetReceiver; if (klass != null) { @@ -3631,14 +3640,15 @@ class SourceLibraryBuilder extends LibraryBuilderImpl { ? const NeverType.nonNullable() : const NullType(); List issues = findTypeArgumentIssuesForInvocation( - library, instantiatedMethodParameters, arguments.types, typeEnvironment, isNonNullableByDefault ? SubtypeCheckMode.withNullabilities : SubtypeCheckMode.ignoringNullabilities, - bottomType); + bottomType, + isNonNullableByDefault: library.isNonNullableByDefault, + areGenericArgumentsAllowed: enableGenericMetadataInLibrary); reportTypeArgumentIssues(issues, fileUri, offset, typeArgumentsInfo: getTypeArgumentsInfo(arguments), targetReceiver: receiverType, diff --git a/pkg/front_end/test/unit_test_suites.dart b/pkg/front_end/test/unit_test_suites.dart index 39683632ae61d..aafc70c1cb826 100644 --- a/pkg/front_end/test/unit_test_suites.dart +++ b/pkg/front_end/test/unit_test_suites.dart @@ -8,4 +8,13 @@ // By marking this file (the entry) as non-nnbd, it becomes weak mode which // is required because many of the imports are not (yet) nnbd. -export 'unit_test_suites_impl.dart'; +import 'unit_test_suites_impl.dart' as impl; + +/// Work around https://github.com/dart-lang/sdk/issues/45192. +/// +/// TODO(paulberry): once #45192 is fixed, we can switch the `import` directive +/// above to an `export` and remove this method, and this file will still be +/// considered by the analysis server to be runnable. +main(List args) { + impl.main(args); +} diff --git a/pkg/front_end/testcases/general/bug21938.dart.weak.transformed.expect b/pkg/front_end/testcases/general/bug21938.dart.weak.transformed.expect new file mode 100644 index 0000000000000..5a519043435d6 --- /dev/null +++ b/pkg/front_end/testcases/general/bug21938.dart.weak.transformed.expect @@ -0,0 +1,48 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/bug21938.dart:8:4: Error: The method 'call' isn't defined for the class 'Object'. +// - 'Object' is from 'dart:core'. +// Try correcting the name to the name of an existing method, or defining a method named 'call'. +// x(); +// ^ +// +// pkg/front_end/testcases/general/bug21938.dart:9:4: Error: The method 'call' isn't defined for the class 'Object'. +// - 'Object' is from 'dart:core'. +// Try correcting the name to the name of an existing method, or defining a method named 'call'. +// x(3); +// ^ +// +// pkg/front_end/testcases/general/bug21938.dart:11:5: Error: The method 'call' isn't defined for the class 'Object'. +// - 'Object' is from 'dart:core'. +// Try correcting the name to the name of an existing method, or defining a method named 'call'. +// x.call(); +// ^^^^ +// +import self as self; +import "dart:core" as core; + +static method test() → dynamic { + core::Object* x; + core::Function* f; + invalid-expression "pkg/front_end/testcases/general/bug21938.dart:8:4: Error: The method 'call' isn't defined for the class 'Object'. + - 'Object' is from 'dart:core'. +Try correcting the name to the name of an existing method, or defining a method named 'call'. + x(); + ^"; + invalid-expression "pkg/front_end/testcases/general/bug21938.dart:9:4: Error: The method 'call' isn't defined for the class 'Object'. + - 'Object' is from 'dart:core'. +Try correcting the name to the name of an existing method, or defining a method named 'call'. + x(3); + ^"; + f.call(5, 2); + invalid-expression "pkg/front_end/testcases/general/bug21938.dart:11:5: Error: The method 'call' isn't defined for the class 'Object'. + - 'Object' is from 'dart:core'. +Try correcting the name to the name of an existing method, or defining a method named 'call'. + x.call(); + ^^^^"; + f.call; + f.call(5, 2); +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/callable_type_variable.dart.weak.transformed.expect b/pkg/front_end/testcases/general/callable_type_variable.dart.weak.transformed.expect new file mode 100644 index 0000000000000..63884422a9728 --- /dev/null +++ b/pkg/front_end/testcases/general/callable_type_variable.dart.weak.transformed.expect @@ -0,0 +1,72 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/callable_type_variable.dart:25:19: Error: Too few positional arguments: 1 required, 0 given. +// var v1 = field(); // error +// ^ +// +// pkg/front_end/testcases/general/callable_type_variable.dart:28:24: Error: Too few positional arguments: 1 required, 0 given. +// var v4 = field.call(); // error +// ^ +// +import self as self; +import "dart:core" as core; + +class Class1 extends core::Object { + generic-covariant-impl field self::Class1::T* field; + constructor •(self::Class1::T* field) → self::Class1* + : self::Class1::field = field, super core::Object::•() + ; + method method() → dynamic { + dynamic v1 = this.{self::Class1::field}.call(); + dynamic v2 = let final core::int* #t1 = 0 in this.{self::Class1::field}.call(#t1); + self::Class1::T* v3 = this.{self::Class1::field}.call; + dynamic v4 = this.{self::Class1::field}.call(); + dynamic v5 = this.{self::Class1::field}.call(0); + } + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class Class2 extends core::Object { + generic-covariant-impl field self::Class2::T* field; + constructor •(self::Class2::T* field) → self::Class2* + : self::Class2::field = field, super core::Object::•() + ; + method method() → dynamic { + invalid-type v1 = let final Never* #t2 = invalid-expression "pkg/front_end/testcases/general/callable_type_variable.dart:25:19: Error: Too few positional arguments: 1 required, 0 given. + var v1 = field(); // error + ^" in this.{self::Class2::field}.call(); + core::String* v2 = let final core::int* #t3 = 0 in this.{self::Class2::field}.call(#t3); + self::Class2::T* v3 = this.{self::Class2::field}.call; + invalid-type v4 = let final Never* #t4 = invalid-expression "pkg/front_end/testcases/general/callable_type_variable.dart:28:24: Error: Too few positional arguments: 1 required, 0 given. + var v4 = field.call(); // error + ^" in this.{self::Class2::field}.call(); + core::String* v5 = this.{self::Class2::field}.call(0); + } + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +static method main() → dynamic {} + + +Extra constant evaluation status: +Evaluated: VariableGet @ org-dartlang-testcase:///callable_type_variable.dart:12:20 -> IntConstant(0) +Evaluated: VariableGet @ org-dartlang-testcase:///callable_type_variable.dart:26:20 -> IntConstant(0) +Extra constant evaluation: evaluated: 38, effectively constant: 2 diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart new file mode 100644 index 0000000000000..c64ec6b944345 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart @@ -0,0 +1,15 @@ +// 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 A {} + +A foo(Y y) => throw 42; + +test() { + var x = foo((Z) => throw 42); + var y = [foo]; + var z = {y.first}; +} + +main() {} diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.expect new file mode 100644 index 0000000000000..19d93039acd6c --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:collection" as col; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +static method foo(self::foo::Y% y) → self::A + return throw 42; +static method test() → dynamic { + self::A<(dynamic) → Never> x = self::foo<(dynamic) → Never>((dynamic Z) → Never => throw 42); + core::List<(Y%) → self::A> y = <(Y%) → self::A>[#C1]; + core::Set<(Y%) → self::A> z = block { + final core::Set<(Y%) → self::A> #t1 = col::LinkedHashSet::•<(Y%) → self::A>(); + #t1.{core::Set::add}{Invariant}(y.{core::Iterable::first}); + } =>#t1; +} +static method main() → dynamic {} + +constants { + #C1 = tearoff self::foo +} diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect new file mode 100644 index 0000000000000..82c52ba72c63a --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:collection" as col; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +static method foo(self::foo::Y% y) → self::A + return throw 42; +static method test() → dynamic { + self::A<(dynamic) → Never> x = self::foo<(dynamic) → Never>((dynamic Z) → Never => throw 42); + core::List<(Y%) → self::A> y = core::_GrowableList::_literal1<(Y%) → self::A>(#C1); + core::Set<(Y%) → self::A> z = block { + final core::Set<(Y%) → self::A> #t1 = new col::_CompactLinkedHashSet::•<(Y%) → self::A>(); + #t1.{core::Set::add}{Invariant}(y.{core::Iterable::first}); + } =>#t1; +} +static method main() → dynamic {} + +constants { + #C1 = tearoff self::foo +} diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.textual_outline.expect new file mode 100644 index 0000000000000..15f399b577996 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.textual_outline.expect @@ -0,0 +1,5 @@ +class A {} + +A foo(Y y) => throw 42; +test() {} +main() {} diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect new file mode 100644 index 0000000000000..1bbbdaf917db7 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect @@ -0,0 +1,6 @@ +A foo(Y y) => throw 42; + +class A {} + +main() {} +test() {} diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.expect new file mode 100644 index 0000000000000..19d93039acd6c --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:collection" as col; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +static method foo(self::foo::Y% y) → self::A + return throw 42; +static method test() → dynamic { + self::A<(dynamic) → Never> x = self::foo<(dynamic) → Never>((dynamic Z) → Never => throw 42); + core::List<(Y%) → self::A> y = <(Y%) → self::A>[#C1]; + core::Set<(Y%) → self::A> z = block { + final core::Set<(Y%) → self::A> #t1 = col::LinkedHashSet::•<(Y%) → self::A>(); + #t1.{core::Set::add}{Invariant}(y.{core::Iterable::first}); + } =>#t1; +} +static method main() → dynamic {} + +constants { + #C1 = tearoff self::foo +} diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.outline.expect new file mode 100644 index 0000000000000..e9d3b9044ca98 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.outline.expect @@ -0,0 +1,14 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + ; +} +static method foo(self::foo::Y% y) → self::A + ; +static method test() → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect new file mode 100644 index 0000000000000..82c52ba72c63a --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/inferred_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:collection" as col; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +static method foo(self::foo::Y% y) → self::A + return throw 42; +static method test() → dynamic { + self::A<(dynamic) → Never> x = self::foo<(dynamic) → Never>((dynamic Z) → Never => throw 42); + core::List<(Y%) → self::A> y = core::_GrowableList::_literal1<(Y%) → self::A>(#C1); + core::Set<(Y%) → self::A> z = block { + final core::Set<(Y%) → self::A> #t1 = new col::_CompactLinkedHashSet::•<(Y%) → self::A>(); + #t1.{core::Set::add}{Invariant}(y.{core::Iterable::first}); + } =>#t1; +} +static method main() → dynamic {} + +constants { + #C1 = tearoff self::foo +} diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart new file mode 100644 index 0000000000000..7f7f46ec284c6 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart @@ -0,0 +1,15 @@ +// 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 A {} + +A(Y)> foo(A(Y)> x) => throw 42; + +class B extends A(Y)> {} + +class C(Y)> {} + +bar(Y)>() => throw 42; + +main() {} diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.strong.expect new file mode 100644 index 0000000000000..07778728d6105 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.strong.expect @@ -0,0 +1,24 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect new file mode 100644 index 0000000000000..07778728d6105 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect @@ -0,0 +1,24 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.textual_outline.expect new file mode 100644 index 0000000000000..8acc1946ae5a0 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.textual_outline.expect @@ -0,0 +1,10 @@ +class A {} + +A(Y)> foo(A(Y)> x) => throw 42; + +class B extends A(Y)> {} + +class C(Y)> {} + +bar(Y)>() => throw 42; +main() {} diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect new file mode 100644 index 0000000000000..d712596facaee --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect @@ -0,0 +1,10 @@ +A(Y)> foo(A(Y)> x) => throw 42; +bar(Y)>() => throw 42; + +class A {} + +class B extends A(Y)> {} + +class C(Y)> {} + +main() {} diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.expect new file mode 100644 index 0000000000000..07778728d6105 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.expect @@ -0,0 +1,24 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.outline.expect new file mode 100644 index 0000000000000..13fcc95377b31 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.outline.expect @@ -0,0 +1,22 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + ; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect new file mode 100644 index 0000000000000..07778728d6105 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/simple_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect @@ -0,0 +1,24 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart new file mode 100644 index 0000000000000..3c977a6df4238 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart @@ -0,0 +1,17 @@ +// 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. + +typedef F = Function(Y); + +class A {} + +A foo(A x) => throw 42; + +class B extends A {} + +class C {} + +bar() => throw 42; + +main() {} diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.strong.expect b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.strong.expect new file mode 100644 index 0000000000000..dd20ce4e76541 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.strong.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +typedef F = (Y%) → dynamic; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect new file mode 100644 index 0000000000000..dd20ce4e76541 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.strong.transformed.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +typedef F = (Y%) → dynamic; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.textual_outline.expect new file mode 100644 index 0000000000000..23b49a3666a40 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.textual_outline.expect @@ -0,0 +1,12 @@ +typedef F = Function(Y); + +class A {} + +A foo(A x) => throw 42; + +class B extends A {} + +class C {} + +bar() => throw 42; +main() {} diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect new file mode 100644 index 0000000000000..7ff1fb882795c --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.textual_outline_modelled.expect @@ -0,0 +1,11 @@ +A foo(A x) => throw 42; +bar() => throw 42; + +class A {} + +class B extends A {} + +class C {} + +main() {} +typedef F = Function(Y); diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.expect b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.expect new file mode 100644 index 0000000000000..dd20ce4e76541 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +typedef F = (Y%) → dynamic; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.outline.expect b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.outline.expect new file mode 100644 index 0000000000000..1fbe2f17a55a4 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.outline.expect @@ -0,0 +1,23 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +typedef F = (Y%) → dynamic; +class A extends core::Object { + synthetic constructor •() → self::A + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + ; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect new file mode 100644 index 0000000000000..dd20ce4e76541 --- /dev/null +++ b/pkg/front_end/testcases/generic_metadata/typedef_generic_types_in_arguments_and_bounds.dart.weak.transformed.expect @@ -0,0 +1,25 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +typedef F = (Y%) → dynamic; +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +class B extends self::A<(Y%) → dynamic> { + synthetic constructor •() → self::B + : super self::A::•() + ; +} +class C(Y%) → dynamic = (Y%) → dynamic> extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; +} +static method foo(self::A<(Y%) → dynamic> x) → self::A<(Y%) → dynamic> + return throw 42; +static method bar(Y%) → dynamic = (Y%) → dynamic>() → dynamic + return throw 42; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.weak.transformed.expect new file mode 100644 index 0000000000000..15684fc005856 --- /dev/null +++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.weak.transformed.expect @@ -0,0 +1,18 @@ +library test; +// +// Problems in library: +// +// pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:10:12: Error: A value of type 'T Function(T)' can't be assigned to a variable of type 'int Function(int)'. +// func = f.call; +// ^ +// +import self as self; +import "dart:core" as core; + +static method test((T*) →* T* f) → void { + (core::int*) →* core::int* func; + func = let final Never* #t1 = invalid-expression "pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:10:12: Error: A value of type 'T Function(T)' can't be assigned to a variable of type 'int Function(int)'. + func = f.call; + ^" in f.call as{TypeError} (core::int*) →* core::int*; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart new file mode 100644 index 0000000000000..06724dc156d5a --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart @@ -0,0 +1,35 @@ +// 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.md file. + +class Class { + int? field; + int? getter => null; + void setter(int? value) {} + void method() {} +} + +test(Class c, dynamic d, Function f1, void Function() f2) { + c.field = c.field; + c.setter = c.getter; + c.method; + c.method(); + d.field = d.field; + d.setter = d.getter; + d.method; + d.method(); + f1(); + f1.call; + f2(); + f2.call; + local() {} + local(); + c == d; + c != d; + c == null; + c != null; + d == null; + d != null; +} + +main() {} diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.expect new file mode 100644 index 0000000000000..6bbacdb399439 --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.expect @@ -0,0 +1,55 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:7:8: Error: A method declaration needs an explicit list of parameters. +// Try adding a parameter list to the method declaration. +// int? getter => null; +// ^^^^^^ +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. +// - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +// Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. +// c.setter = c.getter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + field core::int? field = null; + synthetic constructor •() → self::Class + : super core::Object::•() + ; + method getter() → core::int? + return null; + method setter(core::int? value) → void {} + method method() → void {} +} +static method test(self::Class c, dynamic d, core::Function f1, () → void f2) → dynamic { + c.{self::Class::field} = c.{self::Class::field}{core::int?}; + invalid-expression "pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. + - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. + c.setter = c.getter; + ^^^^^^"; + c.{self::Class::method}{() → void}; + c.{self::Class::method}(){() → void}; + d{dynamic}.field = d{dynamic}.field; + d{dynamic}.setter = d{dynamic}.getter; + d{dynamic}.method; + d{dynamic}.method(); + f1(); + f1.call; + f2(){() → void}; + f2.call; + function local() → Null {} + local(){() → Null}; + c =={core::Object::==}{(core::Object) → core::bool} d; + c !={core::Object::==}{(core::Object) → core::bool} d; + c == null; + c != null; + d == null; + d != null; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.transformed.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.transformed.expect new file mode 100644 index 0000000000000..6bbacdb399439 --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.strong.transformed.expect @@ -0,0 +1,55 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:7:8: Error: A method declaration needs an explicit list of parameters. +// Try adding a parameter list to the method declaration. +// int? getter => null; +// ^^^^^^ +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. +// - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +// Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. +// c.setter = c.getter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + field core::int? field = null; + synthetic constructor •() → self::Class + : super core::Object::•() + ; + method getter() → core::int? + return null; + method setter(core::int? value) → void {} + method method() → void {} +} +static method test(self::Class c, dynamic d, core::Function f1, () → void f2) → dynamic { + c.{self::Class::field} = c.{self::Class::field}{core::int?}; + invalid-expression "pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. + - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. + c.setter = c.getter; + ^^^^^^"; + c.{self::Class::method}{() → void}; + c.{self::Class::method}(){() → void}; + d{dynamic}.field = d{dynamic}.field; + d{dynamic}.setter = d{dynamic}.getter; + d{dynamic}.method; + d{dynamic}.method(); + f1(); + f1.call; + f2(){() → void}; + f2.call; + function local() → Null {} + local(){() → Null}; + c =={core::Object::==}{(core::Object) → core::bool} d; + c !={core::Object::==}{(core::Object) → core::bool} d; + c == null; + c != null; + d == null; + d != null; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.textual_outline.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.textual_outline.expect new file mode 100644 index 0000000000000..12098d9001f11 --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.textual_outline.expect @@ -0,0 +1,9 @@ +class Class { + int? field; + int? getter() => null; + void setter(int? value) {} + void method() {} +} + +test(Class c, dynamic d, Function f1, void Function() f2) {} +main() {} diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.textual_outline_modelled.expect new file mode 100644 index 0000000000000..21bb5795b708a --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.textual_outline_modelled.expect @@ -0,0 +1,9 @@ +class Class { + int? field; + int? getter() => null; + void method() {} + void setter(int? value) {} +} + +main() {} +test(Class c, dynamic d, Function f1, void Function() f2) {} diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.expect new file mode 100644 index 0000000000000..6bbacdb399439 --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.expect @@ -0,0 +1,55 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:7:8: Error: A method declaration needs an explicit list of parameters. +// Try adding a parameter list to the method declaration. +// int? getter => null; +// ^^^^^^ +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. +// - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +// Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. +// c.setter = c.getter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + field core::int? field = null; + synthetic constructor •() → self::Class + : super core::Object::•() + ; + method getter() → core::int? + return null; + method setter(core::int? value) → void {} + method method() → void {} +} +static method test(self::Class c, dynamic d, core::Function f1, () → void f2) → dynamic { + c.{self::Class::field} = c.{self::Class::field}{core::int?}; + invalid-expression "pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. + - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. + c.setter = c.getter; + ^^^^^^"; + c.{self::Class::method}{() → void}; + c.{self::Class::method}(){() → void}; + d{dynamic}.field = d{dynamic}.field; + d{dynamic}.setter = d{dynamic}.getter; + d{dynamic}.method; + d{dynamic}.method(); + f1(); + f1.call; + f2(){() → void}; + f2.call; + function local() → Null {} + local(){() → Null}; + c =={core::Object::==}{(core::Object) → core::bool} d; + c !={core::Object::==}{(core::Object) → core::bool} d; + c == null; + c != null; + d == null; + d != null; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.outline.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.outline.expect new file mode 100644 index 0000000000000..95b5a369e4448 --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.outline.expect @@ -0,0 +1,27 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:7:8: Error: A method declaration needs an explicit list of parameters. +// Try adding a parameter list to the method declaration. +// int? getter => null; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + field core::int? field; + synthetic constructor •() → self::Class + ; + method getter() → core::int? + ; + method setter(core::int? value) → void + ; + method method() → void + ; +} +static method test(self::Class c, dynamic d, core::Function f1, () → void f2) → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.transformed.expect b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.transformed.expect new file mode 100644 index 0000000000000..6bbacdb399439 --- /dev/null +++ b/pkg/front_end/testcases/none/new_method_invocation_encodings.dart.weak.transformed.expect @@ -0,0 +1,55 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:7:8: Error: A method declaration needs an explicit list of parameters. +// Try adding a parameter list to the method declaration. +// int? getter => null; +// ^^^^^^ +// +// pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. +// - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +// Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. +// c.setter = c.getter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + field core::int? field = null; + synthetic constructor •() → self::Class + : super core::Object::•() + ; + method getter() → core::int? + return null; + method setter(core::int? value) → void {} + method method() → void {} +} +static method test(self::Class c, dynamic d, core::Function f1, () → void f2) → dynamic { + c.{self::Class::field} = c.{self::Class::field}{core::int?}; + invalid-expression "pkg/front_end/testcases/none/new_method_invocation_encodings.dart:14:5: Error: The setter 'setter' isn't defined for the class 'Class'. + - 'Class' is from 'pkg/front_end/testcases/none/new_method_invocation_encodings.dart'. +Try correcting the name to the name of an existing setter, or defining a setter or field named 'setter'. + c.setter = c.getter; + ^^^^^^"; + c.{self::Class::method}{() → void}; + c.{self::Class::method}(){() → void}; + d{dynamic}.field = d{dynamic}.field; + d{dynamic}.setter = d{dynamic}.getter; + d{dynamic}.method; + d{dynamic}.method(); + f1(); + f1.call; + f2(){() → void}; + f2.call; + function local() → Null {} + local(){() → Null}; + c =={core::Object::==}{(core::Object) → core::bool} d; + c !={core::Object::==}{(core::Object) → core::bool} d; + c == null; + c != null; + d == null; + d != null; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status index 91180e91ae368..3aabae158689c 100644 --- a/pkg/front_end/testcases/text_serialization.status +++ b/pkg/front_end/testcases/text_serialization.status @@ -6,7 +6,6 @@ # the round trip for Kernel textual serialization where the initial binary # Kernel files are produced by compiling Dart code via Fasta. -dartdevc/private_covariant: TextSerializationFailure extension_types/simple: ExpectationFileMismatchSerialized # Expected. extension_types/simple_method_resolution: ExpectationFileMismatchSerialized # Expected. extensions/call_methods: TypeCheckError @@ -19,15 +18,11 @@ general/abstract_members: TypeCheckError general/accessors: RuntimeError general/ambiguous_exports: RuntimeError general/await_in_non_async: RuntimeError -general/bug21938: TypeCheckError general/bug30695: TypeCheckError general/bug31124: RuntimeError general/call: TypeCheckError -general/callable_type_variable: TypeCheckError general/candidate_found: TypeCheckError general/cascade: RuntimeError -general/constants/with_unevaluated_agnostic/const_asserts: TextSerializationFailure -general/constants/with_unevaluated_agnostic/various: TextSerializationFailure general/constructor_initializer_invalid: RuntimeError general/covariant_field: TypeCheckError general/covariant_generic: RuntimeError @@ -98,8 +93,6 @@ general/type_variable_as_super: RuntimeError general/unsound_promotion: TypeCheckError general/void_methods: RuntimeError general/with_dependencies/issue_43084/issue_43084: RuntimeError -implicit_getter_calls/getter_call: TextSerializationFailure -implicit_getter_calls/this_field_call: TextSerializationFailure inference/constructors_infer_from_arguments_argument_not_assignable: TypeCheckError inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: TypeCheckError inference/downwards_inference_for_each: RuntimeError @@ -113,7 +106,6 @@ inference/infer_method_missing_params: TypeCheckError inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError inference/infer_types_on_generic_instantiations_4: RuntimeError inference/infer_types_on_generic_instantiations_infer: TypeCheckError -inference/instantiate_tearoff_of_call: TypeCheckError # Issue #31746 inference/instantiate_to_bounds_generic_has_bound_defined_after transform: RuntimeError inference/mixin_inference_outwards_3: TypeCheckError inference/mixin_inference_outwards_4: TypeCheckError @@ -153,12 +145,9 @@ nnbd_mixed/messages_with_types_opt_in: TypeCheckError nnbd_mixed/messages_with_types_opt_out: TypeCheckError none/equals: TypeCheckError none/method_invocation: TypeCheckError -none/mixin_covariant: TextSerializationFailure -none/mixin_super: TextSerializationFailure none/operator: TypeCheckError none/property_get: TypeCheckError none/property_set: TypeCheckError -none/tearoff_opt_out: TextSerializationFailure rasta/abstract_constructor: RuntimeError rasta/bad_constructor_redirection: RuntimeError rasta/bad_continue: RuntimeError diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status index 95656fe68ae6e..779ddeaac6aef 100644 --- a/pkg/front_end/testcases/weak.status +++ b/pkg/front_end/testcases/weak.status @@ -22,11 +22,9 @@ general/abstract_members: TypeCheckError general/accessors: RuntimeError general/ambiguous_exports: RuntimeError # Expected, this file exports two main methods. general/await_in_non_async: RuntimeError # Expected. -general/bug21938: TypeCheckError general/bug30695: TypeCheckError general/bug31124: RuntimeError # Test has no main method (and we shouldn't add one). general/call: TypeCheckError -general/callable_type_variable: TypeCheckError general/candidate_found: TypeCheckError general/cascade: RuntimeError general/constructor_initializer_invalid: RuntimeError # Fails execution after recovery @@ -113,7 +111,6 @@ inference/infer_method_missing_params: TypeCheckError inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError inference/infer_types_on_generic_instantiations_4: RuntimeError inference/infer_types_on_generic_instantiations_infer: TypeCheckError -inference/instantiate_tearoff_of_call: TypeCheckError # Issue #31746 inference/instantiate_to_bounds_generic_has_bound_defined_after transform: RuntimeError inference/mixin_inference_outwards_3: TypeCheckError inference/mixin_inference_outwards_4: TypeCheckError diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart index 449a9a3ddcc31..2a16ee865790a 100644 --- a/pkg/kernel/lib/naive_type_checker.dart +++ b/pkg/kernel/lib/naive_type_checker.dart @@ -284,16 +284,13 @@ super method declares ${superParameter.type} return; } - // Permit any invocation on Function type. - if (receiver == environment.coreTypes.functionLegacyRawType && - where is InvocationExpression && - where.name.text == 'call') { - return; - } - - if (receiver is FunctionType && - where is InvocationExpression && - where.name.text == 'call') { + // Permit any invocation or tear-off of `call` on Function type. + if ((receiver == environment.coreTypes.functionLegacyRawType || + receiver == environment.coreTypes.functionNonNullableRawType || + receiver is FunctionType) && + (where is InvocationExpression && where.name.text == 'call') || + (where is PropertyGet && where.name.text == 'call') || + where is FunctionTearOff) { return; } diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart index f5a3b7f1493e8..6505325723c07 100644 --- a/pkg/kernel/lib/src/bounds_checks.dart +++ b/pkg/kernel/lib/src/bounds_checks.dart @@ -237,9 +237,11 @@ class TypeArgumentIssue { /// helpful to show the same type to the user. DartType? invertedType; + final bool isGenericTypeAsArgumentIssue; + TypeArgumentIssue( this.index, this.argument, this.typeParameter, this.enclosingType, - {this.invertedType}); + {this.invertedType, this.isGenericTypeAsArgumentIssue = false}); int get hashCode { int hash = 0x3fffffff & index; @@ -271,9 +273,16 @@ class TypeArgumentIssue { // checks for super-boundness for construction of the auxiliary type. For // details see Dart Language Specification, Section 14.3.2 The Instantiation to // Bound Algorithm. -List findTypeArgumentIssues(Library library, DartType type, +List findTypeArgumentIssues(DartType type, TypeEnvironment typeEnvironment, SubtypeCheckMode subtypeCheckMode, - {bool allowSuperBounded = false}) { + {bool allowSuperBounded = false, + required bool isNonNullableByDefault, + required bool areGenericArgumentsAllowed}) { + // ignore: unnecessary_null_comparison + assert(isNonNullableByDefault != null); + // ignore: unnecessary_null_comparison + assert(areGenericArgumentsAllowed != null); + List variables = const []; List arguments = const []; List typedefRhsResult = const []; @@ -291,8 +300,10 @@ List findTypeArgumentIssues(Library library, DartType type, requiredParameterCount: functionType.requiredParameterCount, typedefType: null); typedefRhsResult = findTypeArgumentIssues( - library, cloned, typeEnvironment, subtypeCheckMode, - allowSuperBounded: true); + cloned, typeEnvironment, subtypeCheckMode, + allowSuperBounded: true, + isNonNullableByDefault: isNonNullableByDefault, + areGenericArgumentsAllowed: areGenericArgumentsAllowed); type = functionType.typedefType!; } @@ -307,25 +318,33 @@ List findTypeArgumentIssues(Library library, DartType type, for (TypeParameter parameter in type.typeParameters) { result.addAll(findTypeArgumentIssues( - library, parameter.bound!, typeEnvironment, subtypeCheckMode, - allowSuperBounded: true)); + parameter.bound!, typeEnvironment, subtypeCheckMode, + allowSuperBounded: true, + isNonNullableByDefault: isNonNullableByDefault, + areGenericArgumentsAllowed: areGenericArgumentsAllowed)); } for (DartType formal in type.positionalParameters) { result.addAll(findTypeArgumentIssues( - library, formal, typeEnvironment, subtypeCheckMode, - allowSuperBounded: true)); + formal, typeEnvironment, subtypeCheckMode, + allowSuperBounded: true, + isNonNullableByDefault: isNonNullableByDefault, + areGenericArgumentsAllowed: areGenericArgumentsAllowed)); } for (NamedType named in type.namedParameters) { result.addAll(findTypeArgumentIssues( - library, named.type, typeEnvironment, subtypeCheckMode, - allowSuperBounded: true)); + named.type, typeEnvironment, subtypeCheckMode, + allowSuperBounded: true, + isNonNullableByDefault: isNonNullableByDefault, + areGenericArgumentsAllowed: areGenericArgumentsAllowed)); } result.addAll(findTypeArgumentIssues( - library, type.returnType, typeEnvironment, subtypeCheckMode, - allowSuperBounded: true)); + type.returnType, typeEnvironment, subtypeCheckMode, + allowSuperBounded: true, + isNonNullableByDefault: isNonNullableByDefault, + areGenericArgumentsAllowed: areGenericArgumentsAllowed)); return result; } else if (type is FutureOrType) { @@ -348,12 +367,13 @@ List findTypeArgumentIssues(Library library, DartType type, new Map.fromIterables(variables, arguments); for (int i = 0; i < arguments.length; ++i) { DartType argument = arguments[i]; - if (isGenericFunctionTypeOrAlias(argument)) { + if (!areGenericArgumentsAllowed && isGenericFunctionTypeOrAlias(argument)) { // Generic function types aren't allowed as type arguments either. - result.add(new TypeArgumentIssue(i, argument, variables[i], type)); + result.add(new TypeArgumentIssue(i, argument, variables[i], type, + isGenericTypeAsArgumentIssue: true)); } else if (variables[i].bound is! InvalidType) { DartType bound = substitute(variables[i].bound!, substitutionMap); - if (!library.isNonNullableByDefault) { + if (!isNonNullableByDefault) { bound = legacyErasure(bound); } if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) { @@ -365,8 +385,10 @@ List findTypeArgumentIssues(Library library, DartType type, } argumentsResult.addAll(findTypeArgumentIssues( - library, argument, typeEnvironment, subtypeCheckMode, - allowSuperBounded: true)); + argument, typeEnvironment, subtypeCheckMode, + allowSuperBounded: true, + isNonNullableByDefault: isNonNullableByDefault, + areGenericArgumentsAllowed: areGenericArgumentsAllowed)); } result.addAll(argumentsResult); result.addAll(typedefRhsResult); @@ -376,8 +398,9 @@ List findTypeArgumentIssues(Library library, DartType type, if (!allowSuperBounded) return result; bool isCorrectSuperBounded = true; - DartType? invertedType = - convertSuperBoundedToRegularBounded(library, typeEnvironment, type); + DartType? invertedType = convertSuperBoundedToRegularBounded( + typeEnvironment, type, + isNonNullableByDefault: isNonNullableByDefault); // The auxiliary type is the same as [type]. At this point we know that // [type] is not regular-bounded, which means that the inverted type is also @@ -436,14 +459,21 @@ List findTypeArgumentIssues(Library library, DartType type, // details see Dart Language Specification, Section 14.3.2 The Instantiation to // Bound Algorithm. List findTypeArgumentIssuesForInvocation( - Library library, List parameters, List arguments, TypeEnvironment typeEnvironment, SubtypeCheckMode subtypeCheckMode, - DartType bottomType) { + DartType bottomType, + {required bool isNonNullableByDefault, + required bool areGenericArgumentsAllowed}) { + // ignore: unnecessary_null_comparison + assert(isNonNullableByDefault != null); + // ignore: unnecessary_null_comparison + assert(areGenericArgumentsAllowed != null); + assert(arguments.length == parameters.length); assert(bottomType == const NeverType.nonNullable() || bottomType is NullType); + List result = []; Map substitutionMap = {}; for (int i = 0; i < arguments.length; ++i) { @@ -452,13 +482,17 @@ List findTypeArgumentIssuesForInvocation( for (int i = 0; i < arguments.length; ++i) { DartType argument = arguments[i]; if (argument is TypeParameterType && argument.promotedBound != null) { + // TODO(dmitryas): Consider recognizing this case with a flag on the issue + // object. result.add(new TypeArgumentIssue(i, argument, parameters[i], null)); - } else if (isGenericFunctionTypeOrAlias(argument)) { + } else if (!areGenericArgumentsAllowed && + isGenericFunctionTypeOrAlias(argument)) { // Generic function types aren't allowed as type arguments either. - result.add(new TypeArgumentIssue(i, argument, parameters[i], null)); + result.add(new TypeArgumentIssue(i, argument, parameters[i], null, + isGenericTypeAsArgumentIssue: true)); } else if (parameters[i].bound is! InvalidType) { DartType bound = substitute(parameters[i].bound!, substitutionMap); - if (!library.isNonNullableByDefault) { + if (!isNonNullableByDefault) { bound = legacyErasure(bound); } if (!typeEnvironment.isSubtypeOf(argument, bound, subtypeCheckMode)) { @@ -467,8 +501,10 @@ List findTypeArgumentIssuesForInvocation( } result.addAll(findTypeArgumentIssues( - library, argument, typeEnvironment, subtypeCheckMode, - allowSuperBounded: true)); + argument, typeEnvironment, subtypeCheckMode, + allowSuperBounded: true, + isNonNullableByDefault: isNonNullableByDefault, + areGenericArgumentsAllowed: areGenericArgumentsAllowed)); } return result; } @@ -486,11 +522,14 @@ String getGenericTypeName(DartType type) { /// [BottomType] and all contravariant occurrences of `Null` and [BottomType] /// with `Object`. Returns null if the converted type is the same as [type]. DartType? convertSuperBoundedToRegularBounded( - Library clientLibrary, TypeEnvironment typeEnvironment, DartType type, - {int variance = Variance.covariant}) { + TypeEnvironment typeEnvironment, DartType type, + {int variance = Variance.covariant, required bool isNonNullableByDefault}) { + // ignore: unnecessary_null_comparison + assert(isNonNullableByDefault != null); + return type.accept1( new _SuperBoundedTypeInverter(typeEnvironment, - isNonNullableByDefault: clientLibrary.isNonNullableByDefault), + isNonNullableByDefault: isNonNullableByDefault), variance); } diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart index c5deeaf8d20a3..7e0ad34b6d825 100644 --- a/pkg/kernel/lib/text/text_serializer.dart +++ b/pkg/kernel/lib/text/text_serializer.dart @@ -76,15 +76,29 @@ class ExpressionTagger extends ExpressionVisitor String visitPropertyGet(PropertyGet _) => "get-prop"; String visitPropertySet(PropertySet _) => "set-prop"; + String visitInstanceGet(InstanceGet _) => "get-instance"; + String visitInstanceSet(InstanceSet _) => "set-instance"; + String visitDynamicGet(DynamicGet _) => "get-dynamic"; + String visitDynamicSet(DynamicSet _) => "set-dynamic"; + String visitInstanceTearOff(InstanceTearOff _) => "tearoff-instance"; + String visitFunctionTearOff(FunctionTearOff _) => "tearoff-function"; String visitSuperPropertyGet(SuperPropertyGet _) => "get-super"; String visitSuperPropertySet(SuperPropertySet _) => "set-super"; String visitMethodInvocation(MethodInvocation _) => "invoke-method"; + String visitInstanceInvocation(InstanceInvocation _) => "invoke-instance"; + String visitDynamicInvocation(DynamicInvocation _) => "invoke-dynamic"; + String visitFunctionInvocation(FunctionInvocation _) => "invoke-function"; + String visitLocalFunctionInvocation(LocalFunctionInvocation _) => + "invoke-local-function"; + String visitEqualsNull(EqualsNull _) => "equals-null"; + String visitEqualsCall(EqualsCall _) => "equals-call"; String visitSuperMethodInvocation(SuperMethodInvocation _) => "invoke-super"; String visitVariableGet(VariableGet _) => "get-var"; String visitVariableSet(VariableSet _) => "set-var"; String visitStaticGet(StaticGet _) => "get-static"; String visitStaticSet(StaticSet _) => "set-static"; + String visitStaticTearOff(StaticTearOff _) => "tearoff-static"; String visitStaticInvocation(StaticInvocation expression) { return expression.isConst ? "invoke-const-static" : "invoke-static"; } @@ -428,6 +442,118 @@ PropertySet wrapPropertySet(Tuple3 tuple) { return new PropertySet(tuple.first, tuple.second, tuple.third); } +TextSerializer instanceGetSerializer = new Wrapped< + Tuple5, + InstanceGet>( + unwrapInstanceGet, + wrapInstanceGet, + new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer, + nameSerializer, const CanonicalNameSerializer(), dartTypeSerializer)); + +Tuple5 + unwrapInstanceGet(InstanceGet expression) { + return new Tuple5(expression.kind, expression.receiver, expression.name, + expression.interfaceTargetReference.canonicalName, expression.resultType); +} + +InstanceGet wrapInstanceGet( + Tuple5 + tuple) { + return new InstanceGet.byReference(tuple.first, tuple.second, tuple.third, + interfaceTargetReference: tuple.fourth.getReference(), + resultType: tuple.fifth); +} + +TextSerializer instanceSetSerializer = new Wrapped< + Tuple5, + InstanceSet>( + unwrapInstanceSet, + wrapInstanceSet, + new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer, + nameSerializer, expressionSerializer, const CanonicalNameSerializer())); + +Tuple5 + unwrapInstanceSet(InstanceSet expression) { + return new Tuple5(expression.kind, expression.receiver, expression.name, + expression.value, expression.interfaceTargetReference.canonicalName); +} + +InstanceSet wrapInstanceSet( + Tuple5 + tuple) { + return new InstanceSet.byReference( + tuple.first, tuple.second, tuple.third, tuple.fourth, + interfaceTargetReference: tuple.fifth.getReference()); +} + +TextSerializer dynamicGetSerializer = + new Wrapped, DynamicGet>( + unwrapDynamicGet, + wrapDynamicGet, + new Tuple3Serializer( + dynamicAccessKindSerializer, expressionSerializer, nameSerializer)); + +Tuple3 unwrapDynamicGet( + DynamicGet expression) { + return new Tuple3(expression.kind, expression.receiver, expression.name); +} + +DynamicGet wrapDynamicGet(Tuple3 tuple) { + return new DynamicGet(tuple.first, tuple.second, tuple.third); +} + +TextSerializer dynamicSetSerializer = new Wrapped< + Tuple4, DynamicSet>( + unwrapDynamicSet, + wrapDynamicSet, + new Tuple4Serializer(dynamicAccessKindSerializer, expressionSerializer, + nameSerializer, expressionSerializer)); + +Tuple4 unwrapDynamicSet( + DynamicSet expression) { + return new Tuple4( + expression.kind, expression.receiver, expression.name, expression.value); +} + +DynamicSet wrapDynamicSet( + Tuple4 tuple) { + return new DynamicSet(tuple.first, tuple.second, tuple.third, tuple.fourth); +} + +TextSerializer instanceTearOffSerializer = new Wrapped< + Tuple5, + InstanceTearOff>( + unwrapInstanceTearOff, + wrapInstanceTearOff, + new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer, + nameSerializer, const CanonicalNameSerializer(), dartTypeSerializer)); + +Tuple5 + unwrapInstanceTearOff(InstanceTearOff expression) { + return new Tuple5(expression.kind, expression.receiver, expression.name, + expression.interfaceTargetReference.canonicalName, expression.resultType); +} + +InstanceTearOff wrapInstanceTearOff( + Tuple5 + tuple) { + return new InstanceTearOff.byReference(tuple.first, tuple.second, tuple.third, + interfaceTargetReference: tuple.fourth.getReference(), + resultType: tuple.fifth); +} + +TextSerializer functionTearOffSerializer = + new Wrapped( + unwrapFunctionTearOff, wrapFunctionTearOff, expressionSerializer); + +Expression unwrapFunctionTearOff(FunctionTearOff expression) { + return expression.receiver; +} + +FunctionTearOff wrapFunctionTearOff(Expression expression) { + return new FunctionTearOff(expression); +} + TextSerializer superPropertyGetSerializer = new Wrapped(unwrapSuperPropertyGet, wrapSuperPropertyGet, nameSerializer); @@ -468,6 +594,198 @@ MethodInvocation wrapMethodInvocation( return new MethodInvocation(tuple.first, tuple.second, tuple.third); } +const Map instanceAccessKindToName = const { + InstanceAccessKind.Instance: "instance", + InstanceAccessKind.Object: "object", + InstanceAccessKind.Nullable: "nullable", + InstanceAccessKind.Inapplicable: "inapplicable", +}; + +class InstanceAccessKindTagger implements Tagger { + const InstanceAccessKindTagger(); + + String tag(InstanceAccessKind kind) { + return instanceAccessKindToName[kind] ?? + (throw StateError("Unknown InstanceAccessKind flag value: ${kind}.")); + } +} + +TextSerializer instanceAccessKindSerializer = + Case(InstanceAccessKindTagger(), convertFlagsMap(instanceAccessKindToName)); + +TextSerializer instanceInvocationSerializer = new Wrapped< + Tuple6, + InstanceInvocation>( + unwrapInstanceInvocation, + wrapInstanceInvocation, + new Tuple6Serializer( + instanceAccessKindSerializer, + expressionSerializer, + nameSerializer, + argumentsSerializer, + const CanonicalNameSerializer(), + dartTypeSerializer)); + +Tuple6 + unwrapInstanceInvocation(InstanceInvocation expression) { + return new Tuple6( + expression.kind, + expression.receiver, + expression.name, + expression.arguments, + expression.interfaceTargetReference.canonicalName, + expression.functionType); +} + +InstanceInvocation wrapInstanceInvocation( + Tuple6 + tuple) { + return new InstanceInvocation.byReference( + tuple.first, tuple.second, tuple.third, tuple.fourth, + interfaceTargetReference: tuple.fifth.getReference(), + functionType: tuple.sixth); +} + +const Map dynamicAccessKindToName = const { + DynamicAccessKind.Dynamic: "dynamic", + DynamicAccessKind.Never: "never", + DynamicAccessKind.Invalid: "invalid", + DynamicAccessKind.Unresolved: "unresolved", +}; + +class DynamicAccessKindTagger implements Tagger { + const DynamicAccessKindTagger(); + + String tag(DynamicAccessKind kind) { + return dynamicAccessKindToName[kind] ?? + (throw StateError("Unknown DynamicAccessKind flag value: ${kind}.")); + } +} + +TextSerializer dynamicAccessKindSerializer = + Case(DynamicAccessKindTagger(), convertFlagsMap(dynamicAccessKindToName)); + +TextSerializer dynamicInvocationSerializer = new Wrapped< + Tuple4, + DynamicInvocation>( + unwrapDynamicInvocation, + wrapDynamicInvocation, + new Tuple4Serializer(dynamicAccessKindSerializer, expressionSerializer, + nameSerializer, argumentsSerializer)); + +Tuple4 unwrapDynamicInvocation( + DynamicInvocation expression) { + return new Tuple4(expression.kind, expression.receiver, expression.name, + expression.arguments); +} + +DynamicInvocation wrapDynamicInvocation( + Tuple4 tuple) { + return new DynamicInvocation( + tuple.first, tuple.second, tuple.third, tuple.fourth); +} + +const Map functionAccessKindToName = const { + FunctionAccessKind.Function: "function", + FunctionAccessKind.FunctionType: "function-type", + FunctionAccessKind.Inapplicable: "inapplicable", + FunctionAccessKind.Nullable: "nullable", +}; + +class FunctionAccessKindTagger implements Tagger { + const FunctionAccessKindTagger(); + + String tag(FunctionAccessKind kind) { + return functionAccessKindToName[kind] ?? + (throw StateError("Unknown FunctionAccessKind flag value: ${kind}.")); + } +} + +TextSerializer functionAccessKindSerializer = + Case(FunctionAccessKindTagger(), convertFlagsMap(functionAccessKindToName)); + +TextSerializer functionInvocationSerializer = new Wrapped< + Tuple4, + FunctionInvocation>( + unwrapFunctionInvocation, + wrapFunctionInvocation, + new Tuple4Serializer(functionAccessKindSerializer, expressionSerializer, + argumentsSerializer, new Optional(dartTypeSerializer))); + +Tuple4 + unwrapFunctionInvocation(FunctionInvocation expression) { + return new Tuple4(expression.kind, expression.receiver, expression.arguments, + expression.functionType); +} + +FunctionInvocation wrapFunctionInvocation( + Tuple4 tuple) { + return new FunctionInvocation(tuple.first, tuple.second, tuple.third, + functionType: tuple.fourth); +} + +TextSerializer localFunctionInvocationSerializer = + new Wrapped, + LocalFunctionInvocation>( + unwrapLocalFunctionInvocation, + wrapLocalFunctionInvocation, + new Tuple3Serializer(const ScopedUse(), + argumentsSerializer, dartTypeSerializer)); + +Tuple3 unwrapLocalFunctionInvocation( + LocalFunctionInvocation expression) { + return new Tuple3( + expression.variable, expression.arguments, expression.functionType); +} + +LocalFunctionInvocation wrapLocalFunctionInvocation( + Tuple3 tuple) { + return new LocalFunctionInvocation(tuple.first, tuple.second, + functionType: tuple.third); +} + +TextSerializer equalsNullSerializer = + new Wrapped, EqualsNull>( + unwrapEqualsNull, + wrapEqualsNull, + new Tuple2Serializer(expressionSerializer, const DartBool())); + +Tuple2 unwrapEqualsNull(EqualsNull expression) { + return new Tuple2(expression.expression, expression.isNot); +} + +EqualsNull wrapEqualsNull(Tuple2 tuple) { + return new EqualsNull(tuple.first, isNot: tuple.second); +} + +TextSerializer equalsCallSerializer = new Wrapped< + Tuple5, + EqualsCall>( + unwrapEqualsCall, + wrapEqualsCall, + new Tuple5Serializer(expressionSerializer, expressionSerializer, + const DartBool(), const CanonicalNameSerializer(), dartTypeSerializer)); + +Tuple5 unwrapEqualsCall( + EqualsCall expression) { + return new Tuple5( + expression.left, + expression.right, + expression.isNot, + expression.interfaceTargetReference.canonicalName, + expression.functionType); +} + +EqualsCall wrapEqualsCall( + Tuple5 tuple) { + return new EqualsCall.byReference(tuple.first, tuple.second, + isNot: tuple.third, + interfaceTargetReference: tuple.fourth.getReference(), + functionType: tuple.fifth); +} + TextSerializer superMethodInvocationSerializer = new Wrapped(unwrapSuperMethodInvocation, wrapSuperMethodInvocation, new Tuple2Serializer(nameSerializer, argumentsSerializer)); @@ -553,6 +871,17 @@ StaticGet wrapStaticGet(CanonicalName name) { return new StaticGet.byReference(name.getReference()); } +const TextSerializer staticTearOffSerializer = const Wrapped( + unwrapStaticTearOff, wrapStaticTearOff, const CanonicalNameSerializer()); + +CanonicalName unwrapStaticTearOff(StaticTearOff expression) { + return expression.targetReference.canonicalName; +} + +StaticTearOff wrapStaticTearOff(CanonicalName name) { + return new StaticTearOff.byReference(name.getReference()); +} + TextSerializer staticSetSerializer = new Wrapped( unwrapStaticSet, wrapStaticSet, @@ -2153,14 +2482,27 @@ void initializeSerializers() { "let": letSerializer, "get-prop": propertyGetSerializer, "set-prop": propertySetSerializer, + "get-instance": instanceGetSerializer, + "set-instance": instanceSetSerializer, + "get-dynamic": dynamicGetSerializer, + "set-dynamic": dynamicSetSerializer, + "tearoff-instance": instanceTearOffSerializer, + "tearoff-function": functionTearOffSerializer, "get-super": superPropertyGetSerializer, "set-super": superPropertySetSerializer, "invoke-method": methodInvocationSerializer, + "invoke-instance": instanceInvocationSerializer, + "invoke-dynamic": dynamicInvocationSerializer, + "invoke-function": functionInvocationSerializer, + "invoke-local-function": localFunctionInvocationSerializer, + "equals-null": equalsNullSerializer, + "equals-call": equalsCallSerializer, "invoke-super": superMethodInvocationSerializer, "get-var": variableGetSerializer, "set-var": variableSetSerializer, "get-static": staticGetSerializer, "set-static": staticSetSerializer, + "tearoff-static": staticGetSerializer, "invoke-static": staticInvocationSerializer, "invoke-const-static": constStaticInvocationSerializer, "invoke-constructor": constructorInvocationSerializer, diff --git a/tools/VERSION b/tools/VERSION index e1365dfaf9e0f..2d6bb5edc6706 100644 --- a/tools/VERSION +++ b/tools/VERSION @@ -27,5 +27,5 @@ CHANNEL dev MAJOR 2 MINOR 13 PATCH 0 -PRERELEASE 102 +PRERELEASE 103 PRERELEASE_PATCH 0 \ No newline at end of file