Version 2.13.0-103.0.dev
Merge commit 'e9f4d5dbb1ea95e7fac59189dc36474953d58e4a' into 'dev'
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 4c4e74d..0d2f50f 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 ConstantEvaluator extends RecursiveResultVisitor<Constant> {
+class ConstantEvaluator extends ExpressionVisitor<Constant> {
final ConstantsBackend backend;
final NumberSemantics numberSemantics;
ConstantIntFolder intFolder;
@@ -1157,7 +1157,7 @@
}
@override
- Constant defaultTreeNode(Node node) {
+ Constant defaultExpression(Expression node) {
// Only a subset of the expression language is valid for constant
// evaluation.
return createInvalidExpressionConstant(
@@ -2738,20 +2738,21 @@
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);
if (constant is AbortConstant) return constant;
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 92ac343..3017856 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 @@
Library library = libraryBuilder.library;
List<TypeArgumentIssue> 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 e3158d4..e409ff0 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 @@
TypeArgumentIssue,
findTypeArgumentIssues,
findTypeArgumentIssuesForInvocation,
- getGenericTypeName,
- isGenericFunctionTypeOrAlias;
+ getGenericTypeName;
import 'package:kernel/type_algebra.dart' show Substitution, substitute;
@@ -2923,15 +2922,17 @@
bool haveErroneousBounds = false;
if (!inErrorRecovery) {
- for (int i = 0; i < variables.length; ++i) {
- TypeVariableBuilder variable = variables[i];
- List<TypeBuilder> genericFunctionTypes = <TypeBuilder>[];
- 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<TypeBuilder> genericFunctionTypes = <TypeBuilder>[];
+ findGenericFunctionTypes(variable.bound,
+ result: genericFunctionTypes);
+ if (genericFunctionTypes.length > 0) {
+ haveErroneousBounds = true;
+ addProblem(messageGenericFunctionTypeInBound, variable.charOffset,
+ variable.name.length, variable.fileUri);
+ }
}
}
@@ -3170,7 +3171,7 @@
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 @@
}
}
+ // 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 @@
// Check in bounds of own type variables.
for (TypeParameter parameter in typeParameters) {
List<TypeArgumentIssue> 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 @@
continue;
}
- if (isGenericFunctionTypeOrAlias(argument)) {
+ if (issue.isGenericTypeAsArgumentIssue) {
reportTypeArgumentIssue(
messageGenericFunctionTypeUsedAsActualTypeArgument,
fileUri,
@@ -3382,13 +3388,14 @@
}
if (!skipReturnType && returnType != null) {
List<TypeArgumentIssue> 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 @@
// 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 @@
DartType type, TypeEnvironment typeEnvironment, Uri fileUri, int offset,
{bool inferred, bool allowSuperBounded = true}) {
List<TypeArgumentIssue> 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 @@
? const NeverType.nonNullable()
: const NullType();
List<TypeArgumentIssue> 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 @@
? const NeverType.nonNullable()
: const NullType();
List<TypeArgumentIssue> 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 3968363..aafc70c 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<String> 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 0000000..5a51904
--- /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 0000000..6388442
--- /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<T extends core::Function* = core::Function*> extends core::Object {
+ generic-covariant-impl field self::Class1::T* field;
+ constructor •(self::Class1::T* field) → self::Class1<self::Class1::T*>*
+ : 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<T extends (core::int*) →* core::String* = (core::int*) →* core::String*> extends core::Object {
+ generic-covariant-impl field self::Class2::T* field;
+ constructor •(self::Class2::T* field) → self::Class2<self::Class2::T*>*
+ : 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 0000000..c64ec6b
--- /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<X> {}
+
+A<Y> foo<Y>(Y y) => throw 42;
+
+test() {
+ var x = foo(<Z>(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 0000000..19d9303
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+static method foo<Y extends core::Object? = dynamic>(self::foo::Y% y) → self::A<self::foo::Y%>
+ return throw 42;
+static method test() → dynamic {
+ self::A<<Z extends core::Object? = dynamic>(dynamic) → Never> x = self::foo<<Z extends core::Object? = dynamic>(dynamic) → Never>(<Z extends core::Object? = dynamic>(dynamic Z) → Never => throw 42);
+ core::List<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> y = <<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>[#C1];
+ core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> z = block {
+ final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = col::LinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
+ #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 0000000..82c52ba
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+static method foo<Y extends core::Object? = dynamic>(self::foo::Y% y) → self::A<self::foo::Y%>
+ return throw 42;
+static method test() → dynamic {
+ self::A<<Z extends core::Object? = dynamic>(dynamic) → Never> x = self::foo<<Z extends core::Object? = dynamic>(dynamic) → Never>(<Z extends core::Object? = dynamic>(dynamic Z) → Never => throw 42);
+ core::List<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> y = core::_GrowableList::_literal1<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>(#C1);
+ core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> z = block {
+ final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = new col::_CompactLinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
+ #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 0000000..15f399b
--- /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<X> {}
+
+A<Y> foo<Y>(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 0000000..1bbbdaf
--- /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<Y> foo<Y>(Y y) => throw 42;
+
+class A<X> {}
+
+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 0000000..19d9303
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+static method foo<Y extends core::Object? = dynamic>(self::foo::Y% y) → self::A<self::foo::Y%>
+ return throw 42;
+static method test() → dynamic {
+ self::A<<Z extends core::Object? = dynamic>(dynamic) → Never> x = self::foo<<Z extends core::Object? = dynamic>(dynamic) → Never>(<Z extends core::Object? = dynamic>(dynamic Z) → Never => throw 42);
+ core::List<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> y = <<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>[#C1];
+ core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> z = block {
+ final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = col::LinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
+ #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 0000000..e9d3b90
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ ;
+}
+static method foo<Y extends core::Object? = dynamic>(self::foo::Y% y) → self::A<self::foo::Y%>
+ ;
+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 0000000..82c52ba
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+static method foo<Y extends core::Object? = dynamic>(self::foo::Y% y) → self::A<self::foo::Y%>
+ return throw 42;
+static method test() → dynamic {
+ self::A<<Z extends core::Object? = dynamic>(dynamic) → Never> x = self::foo<<Z extends core::Object? = dynamic>(dynamic) → Never>(<Z extends core::Object? = dynamic>(dynamic Z) → Never => throw 42);
+ core::List<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> y = core::_GrowableList::_literal1<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>(#C1);
+ core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> z = block {
+ final core::Set<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>> #t1 = new col::_CompactLinkedHashSet::•<<Y extends core::Object? = dynamic>(Y%) → self::A<Y%>>();
+ #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 0000000..7f7f46e
--- /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<X> {}
+
+A<Function<Y>(Y)> foo(A<Function<Y>(Y)> x) => throw 42;
+
+class B extends A<Function<Y>(Y)> {}
+
+class C<Z extends Function<Y>(Y)> {}
+
+bar<V extends Function<Y>(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 0000000..0777872
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..0777872
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..8acc194
--- /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<X> {}
+
+A<Function<Y>(Y)> foo(A<Function<Y>(Y)> x) => throw 42;
+
+class B extends A<Function<Y>(Y)> {}
+
+class C<Z extends Function<Y>(Y)> {}
+
+bar<V extends Function<Y>(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 0000000..d712596
--- /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<Function<Y>(Y)> foo(A<Function<Y>(Y)> x) => throw 42;
+bar<V extends Function<Y>(Y)>() => throw 42;
+
+class A<X> {}
+
+class B extends A<Function<Y>(Y)> {}
+
+class C<Z extends Function<Y>(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 0000000..0777872
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..13fcc95
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ ;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..0777872
--- /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<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..3c977a6
--- /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>(Y);
+
+class A<X> {}
+
+A<F> foo(A<F> x) => throw 42;
+
+class B extends A<F> {}
+
+class C<Z extends F> {}
+
+bar<V extends F>() => 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 0000000..dd20ce4
--- /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 extends core::Object? = dynamic>(Y%) → dynamic;
+class A<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..dd20ce4
--- /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 extends core::Object? = dynamic>(Y%) → dynamic;
+class A<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..23b49a3
--- /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>(Y);
+
+class A<X> {}
+
+A<F> foo(A<F> x) => throw 42;
+
+class B extends A<F> {}
+
+class C<Z extends F> {}
+
+bar<V extends F>() => 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 0000000..7ff1fb8
--- /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<F> foo(A<F> x) => throw 42;
+bar<V extends F>() => throw 42;
+
+class A<X> {}
+
+class B extends A<F> {}
+
+class C<Z extends F> {}
+
+main() {}
+typedef F = Function<Y>(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 0000000..dd20ce4
--- /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 extends core::Object? = dynamic>(Y%) → dynamic;
+class A<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..1fbe2f1
--- /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 extends core::Object? = dynamic>(Y%) → dynamic;
+class A<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ ;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..dd20ce4
--- /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 extends core::Object? = dynamic>(Y%) → dynamic;
+class A<X extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X%>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<Z extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = dynamic>(Y%) → dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::Z>
+ : super core::Object::•()
+ ;
+}
+static method foo(self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic> x) → self::A<<Y extends core::Object? = dynamic>(Y%) → dynamic>
+ return throw 42;
+static method bar<V extends <Y extends core::Object? = dynamic>(Y%) → dynamic = <Y extends core::Object? = 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 0000000..15684fc
--- /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>(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 extends core::Object* = dynamic>(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>(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 0000000..06724dc
--- /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 0000000..6bbacdb
--- /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 0000000..6bbacdb
--- /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 0000000..12098d9
--- /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 0000000..21bb579
--- /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 0000000..6bbacdb
--- /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 0000000..95b5a36
--- /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 0000000..6bbacdb
--- /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 91180e9..3aabae1 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/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/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_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_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 95656fe..779ddea 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -22,11 +22,9 @@
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_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 449a9a3..2a16ee8 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -284,16 +284,13 @@
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 f5a3b7f..6505325 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -237,9 +237,11 @@
/// 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 @@
// 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<TypeArgumentIssue> findTypeArgumentIssues(Library library, DartType type,
+List<TypeArgumentIssue> 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<TypeParameter> variables = const <TypeParameter>[];
List<DartType> arguments = const <DartType>[];
List<TypeArgumentIssue> typedefRhsResult = const <TypeArgumentIssue>[];
@@ -291,8 +300,10 @@
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 @@
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 @@
new Map<TypeParameter, DartType>.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 @@
}
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 @@
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 @@
// details see Dart Language Specification, Section 14.3.2 The Instantiation to
// Bound Algorithm.
List<TypeArgumentIssue> findTypeArgumentIssuesForInvocation(
- Library library,
List<TypeParameter> parameters,
List<DartType> 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<TypeArgumentIssue> result = <TypeArgumentIssue>[];
Map<TypeParameter, DartType> substitutionMap = <TypeParameter, DartType>{};
for (int i = 0; i < arguments.length; ++i) {
@@ -452,13 +482,17 @@
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 @@
}
result.addAll(findTypeArgumentIssues(
- library, argument, typeEnvironment, subtypeCheckMode,
- allowSuperBounded: true));
+ argument, typeEnvironment, subtypeCheckMode,
+ allowSuperBounded: true,
+ isNonNullableByDefault: isNonNullableByDefault,
+ areGenericArgumentsAllowed: areGenericArgumentsAllowed));
}
return result;
}
@@ -486,11 +522,14 @@
/// [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 c5deeaf..7e0ad34 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -76,15 +76,29 @@
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 @@
return new PropertySet(tuple.first, tuple.second, tuple.third);
}
+TextSerializer<InstanceGet> instanceGetSerializer = new Wrapped<
+ Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>,
+ InstanceGet>(
+ unwrapInstanceGet,
+ wrapInstanceGet,
+ new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
+ nameSerializer, const CanonicalNameSerializer(), dartTypeSerializer));
+
+Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
+ unwrapInstanceGet(InstanceGet expression) {
+ return new Tuple5(expression.kind, expression.receiver, expression.name,
+ expression.interfaceTargetReference.canonicalName, expression.resultType);
+}
+
+InstanceGet wrapInstanceGet(
+ Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
+ tuple) {
+ return new InstanceGet.byReference(tuple.first, tuple.second, tuple.third,
+ interfaceTargetReference: tuple.fourth.getReference(),
+ resultType: tuple.fifth);
+}
+
+TextSerializer<InstanceSet> instanceSetSerializer = new Wrapped<
+ Tuple5<InstanceAccessKind, Expression, Name, Expression, CanonicalName>,
+ InstanceSet>(
+ unwrapInstanceSet,
+ wrapInstanceSet,
+ new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
+ nameSerializer, expressionSerializer, const CanonicalNameSerializer()));
+
+Tuple5<InstanceAccessKind, Expression, Name, Expression, CanonicalName>
+ unwrapInstanceSet(InstanceSet expression) {
+ return new Tuple5(expression.kind, expression.receiver, expression.name,
+ expression.value, expression.interfaceTargetReference.canonicalName);
+}
+
+InstanceSet wrapInstanceSet(
+ Tuple5<InstanceAccessKind, Expression, Name, Expression, CanonicalName>
+ tuple) {
+ return new InstanceSet.byReference(
+ tuple.first, tuple.second, tuple.third, tuple.fourth,
+ interfaceTargetReference: tuple.fifth.getReference());
+}
+
+TextSerializer<DynamicGet> dynamicGetSerializer =
+ new Wrapped<Tuple3<DynamicAccessKind, Expression, Name>, DynamicGet>(
+ unwrapDynamicGet,
+ wrapDynamicGet,
+ new Tuple3Serializer(
+ dynamicAccessKindSerializer, expressionSerializer, nameSerializer));
+
+Tuple3<DynamicAccessKind, Expression, Name> unwrapDynamicGet(
+ DynamicGet expression) {
+ return new Tuple3(expression.kind, expression.receiver, expression.name);
+}
+
+DynamicGet wrapDynamicGet(Tuple3<DynamicAccessKind, Expression, Name> tuple) {
+ return new DynamicGet(tuple.first, tuple.second, tuple.third);
+}
+
+TextSerializer<DynamicSet> dynamicSetSerializer = new Wrapped<
+ Tuple4<DynamicAccessKind, Expression, Name, Expression>, DynamicSet>(
+ unwrapDynamicSet,
+ wrapDynamicSet,
+ new Tuple4Serializer(dynamicAccessKindSerializer, expressionSerializer,
+ nameSerializer, expressionSerializer));
+
+Tuple4<DynamicAccessKind, Expression, Name, Expression> unwrapDynamicSet(
+ DynamicSet expression) {
+ return new Tuple4(
+ expression.kind, expression.receiver, expression.name, expression.value);
+}
+
+DynamicSet wrapDynamicSet(
+ Tuple4<DynamicAccessKind, Expression, Name, Expression> tuple) {
+ return new DynamicSet(tuple.first, tuple.second, tuple.third, tuple.fourth);
+}
+
+TextSerializer<InstanceTearOff> instanceTearOffSerializer = new Wrapped<
+ Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>,
+ InstanceTearOff>(
+ unwrapInstanceTearOff,
+ wrapInstanceTearOff,
+ new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
+ nameSerializer, const CanonicalNameSerializer(), dartTypeSerializer));
+
+Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
+ unwrapInstanceTearOff(InstanceTearOff expression) {
+ return new Tuple5(expression.kind, expression.receiver, expression.name,
+ expression.interfaceTargetReference.canonicalName, expression.resultType);
+}
+
+InstanceTearOff wrapInstanceTearOff(
+ Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
+ tuple) {
+ return new InstanceTearOff.byReference(tuple.first, tuple.second, tuple.third,
+ interfaceTargetReference: tuple.fourth.getReference(),
+ resultType: tuple.fifth);
+}
+
+TextSerializer<FunctionTearOff> functionTearOffSerializer =
+ new Wrapped<Expression, FunctionTearOff>(
+ unwrapFunctionTearOff, wrapFunctionTearOff, expressionSerializer);
+
+Expression unwrapFunctionTearOff(FunctionTearOff expression) {
+ return expression.receiver;
+}
+
+FunctionTearOff wrapFunctionTearOff(Expression expression) {
+ return new FunctionTearOff(expression);
+}
+
TextSerializer<SuperPropertyGet> superPropertyGetSerializer =
new Wrapped(unwrapSuperPropertyGet, wrapSuperPropertyGet, nameSerializer);
@@ -468,6 +594,198 @@
return new MethodInvocation(tuple.first, tuple.second, tuple.third);
}
+const Map<InstanceAccessKind, String> instanceAccessKindToName = const {
+ InstanceAccessKind.Instance: "instance",
+ InstanceAccessKind.Object: "object",
+ InstanceAccessKind.Nullable: "nullable",
+ InstanceAccessKind.Inapplicable: "inapplicable",
+};
+
+class InstanceAccessKindTagger implements Tagger<InstanceAccessKind> {
+ const InstanceAccessKindTagger();
+
+ String tag(InstanceAccessKind kind) {
+ return instanceAccessKindToName[kind] ??
+ (throw StateError("Unknown InstanceAccessKind flag value: ${kind}."));
+ }
+}
+
+TextSerializer<InstanceAccessKind> instanceAccessKindSerializer =
+ Case(InstanceAccessKindTagger(), convertFlagsMap(instanceAccessKindToName));
+
+TextSerializer<InstanceInvocation> instanceInvocationSerializer = new Wrapped<
+ Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
+ DartType>,
+ InstanceInvocation>(
+ unwrapInstanceInvocation,
+ wrapInstanceInvocation,
+ new Tuple6Serializer(
+ instanceAccessKindSerializer,
+ expressionSerializer,
+ nameSerializer,
+ argumentsSerializer,
+ const CanonicalNameSerializer(),
+ dartTypeSerializer));
+
+Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName, DartType>
+ unwrapInstanceInvocation(InstanceInvocation expression) {
+ return new Tuple6(
+ expression.kind,
+ expression.receiver,
+ expression.name,
+ expression.arguments,
+ expression.interfaceTargetReference.canonicalName,
+ expression.functionType);
+}
+
+InstanceInvocation wrapInstanceInvocation(
+ Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
+ DartType>
+ tuple) {
+ return new InstanceInvocation.byReference(
+ tuple.first, tuple.second, tuple.third, tuple.fourth,
+ interfaceTargetReference: tuple.fifth.getReference(),
+ functionType: tuple.sixth);
+}
+
+const Map<DynamicAccessKind, String> dynamicAccessKindToName = const {
+ DynamicAccessKind.Dynamic: "dynamic",
+ DynamicAccessKind.Never: "never",
+ DynamicAccessKind.Invalid: "invalid",
+ DynamicAccessKind.Unresolved: "unresolved",
+};
+
+class DynamicAccessKindTagger implements Tagger<DynamicAccessKind> {
+ const DynamicAccessKindTagger();
+
+ String tag(DynamicAccessKind kind) {
+ return dynamicAccessKindToName[kind] ??
+ (throw StateError("Unknown DynamicAccessKind flag value: ${kind}."));
+ }
+}
+
+TextSerializer<DynamicAccessKind> dynamicAccessKindSerializer =
+ Case(DynamicAccessKindTagger(), convertFlagsMap(dynamicAccessKindToName));
+
+TextSerializer<DynamicInvocation> dynamicInvocationSerializer = new Wrapped<
+ Tuple4<DynamicAccessKind, Expression, Name, Arguments>,
+ DynamicInvocation>(
+ unwrapDynamicInvocation,
+ wrapDynamicInvocation,
+ new Tuple4Serializer(dynamicAccessKindSerializer, expressionSerializer,
+ nameSerializer, argumentsSerializer));
+
+Tuple4<DynamicAccessKind, Expression, Name, Arguments> unwrapDynamicInvocation(
+ DynamicInvocation expression) {
+ return new Tuple4(expression.kind, expression.receiver, expression.name,
+ expression.arguments);
+}
+
+DynamicInvocation wrapDynamicInvocation(
+ Tuple4<DynamicAccessKind, Expression, Name, Arguments> tuple) {
+ return new DynamicInvocation(
+ tuple.first, tuple.second, tuple.third, tuple.fourth);
+}
+
+const Map<FunctionAccessKind, String> functionAccessKindToName = const {
+ FunctionAccessKind.Function: "function",
+ FunctionAccessKind.FunctionType: "function-type",
+ FunctionAccessKind.Inapplicable: "inapplicable",
+ FunctionAccessKind.Nullable: "nullable",
+};
+
+class FunctionAccessKindTagger implements Tagger<FunctionAccessKind> {
+ const FunctionAccessKindTagger();
+
+ String tag(FunctionAccessKind kind) {
+ return functionAccessKindToName[kind] ??
+ (throw StateError("Unknown FunctionAccessKind flag value: ${kind}."));
+ }
+}
+
+TextSerializer<FunctionAccessKind> functionAccessKindSerializer =
+ Case(FunctionAccessKindTagger(), convertFlagsMap(functionAccessKindToName));
+
+TextSerializer<FunctionInvocation> functionInvocationSerializer = new Wrapped<
+ Tuple4<FunctionAccessKind, Expression, Arguments, DartType>,
+ FunctionInvocation>(
+ unwrapFunctionInvocation,
+ wrapFunctionInvocation,
+ new Tuple4Serializer(functionAccessKindSerializer, expressionSerializer,
+ argumentsSerializer, new Optional(dartTypeSerializer)));
+
+Tuple4<FunctionAccessKind, Expression, Arguments, DartType>
+ unwrapFunctionInvocation(FunctionInvocation expression) {
+ return new Tuple4(expression.kind, expression.receiver, expression.arguments,
+ expression.functionType);
+}
+
+FunctionInvocation wrapFunctionInvocation(
+ Tuple4<FunctionAccessKind, Expression, Arguments, DartType> tuple) {
+ return new FunctionInvocation(tuple.first, tuple.second, tuple.third,
+ functionType: tuple.fourth);
+}
+
+TextSerializer<LocalFunctionInvocation> localFunctionInvocationSerializer =
+ new Wrapped<Tuple3<VariableDeclaration, Arguments, DartType>,
+ LocalFunctionInvocation>(
+ unwrapLocalFunctionInvocation,
+ wrapLocalFunctionInvocation,
+ new Tuple3Serializer(const ScopedUse<VariableDeclaration>(),
+ argumentsSerializer, dartTypeSerializer));
+
+Tuple3<VariableDeclaration, Arguments, DartType> unwrapLocalFunctionInvocation(
+ LocalFunctionInvocation expression) {
+ return new Tuple3(
+ expression.variable, expression.arguments, expression.functionType);
+}
+
+LocalFunctionInvocation wrapLocalFunctionInvocation(
+ Tuple3<VariableDeclaration, Arguments, DartType> tuple) {
+ return new LocalFunctionInvocation(tuple.first, tuple.second,
+ functionType: tuple.third);
+}
+
+TextSerializer<EqualsNull> equalsNullSerializer =
+ new Wrapped<Tuple2<Expression, bool>, EqualsNull>(
+ unwrapEqualsNull,
+ wrapEqualsNull,
+ new Tuple2Serializer(expressionSerializer, const DartBool()));
+
+Tuple2<Expression, bool> unwrapEqualsNull(EqualsNull expression) {
+ return new Tuple2(expression.expression, expression.isNot);
+}
+
+EqualsNull wrapEqualsNull(Tuple2<Expression, bool> tuple) {
+ return new EqualsNull(tuple.first, isNot: tuple.second);
+}
+
+TextSerializer<EqualsCall> equalsCallSerializer = new Wrapped<
+ Tuple5<Expression, Expression, bool, CanonicalName, DartType>,
+ EqualsCall>(
+ unwrapEqualsCall,
+ wrapEqualsCall,
+ new Tuple5Serializer(expressionSerializer, expressionSerializer,
+ const DartBool(), const CanonicalNameSerializer(), dartTypeSerializer));
+
+Tuple5<Expression, Expression, bool, CanonicalName, DartType> unwrapEqualsCall(
+ EqualsCall expression) {
+ return new Tuple5(
+ expression.left,
+ expression.right,
+ expression.isNot,
+ expression.interfaceTargetReference.canonicalName,
+ expression.functionType);
+}
+
+EqualsCall wrapEqualsCall(
+ Tuple5<Expression, Expression, bool, CanonicalName, DartType> tuple) {
+ return new EqualsCall.byReference(tuple.first, tuple.second,
+ isNot: tuple.third,
+ interfaceTargetReference: tuple.fourth.getReference(),
+ functionType: tuple.fifth);
+}
+
TextSerializer<SuperMethodInvocation> superMethodInvocationSerializer =
new Wrapped(unwrapSuperMethodInvocation, wrapSuperMethodInvocation,
new Tuple2Serializer(nameSerializer, argumentsSerializer));
@@ -553,6 +871,17 @@
return new StaticGet.byReference(name.getReference());
}
+const TextSerializer<StaticTearOff> 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<StaticSet> staticSetSerializer = new Wrapped(
unwrapStaticSet,
wrapStaticSet,
@@ -2153,14 +2482,27 @@
"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 e1365df..2d6bb5e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 13
PATCH 0
-PRERELEASE 102
+PRERELEASE 103
PRERELEASE_PATCH 0
\ No newline at end of file