[vm, dart2wasm] Early lowering of FunctionTearOff nodes

FunctionTearOff node represents a tear-off of the 'call' method of
a Function, so it is basically a no-op:

  FunctionTearOff(receiver) == receiver

So we can remove this node early, during lowering transformation on
kernel AST and clean up handling of FunctionTearOff nodes from the VM
and dart2wasm compilation pipelines.

TEST=ci

Change-Id: Ia1500a066a0261076162e018ff0ab502258f606f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/325924
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Alexander Markov
2023-09-15 16:54:08 +00:00
committed by Commit Queue
parent 3ca05545fa
commit 4b9c7c05d4
25 changed files with 74 additions and 125 deletions
-3
View File
@@ -843,9 +843,6 @@ class _ExpressionTransformer extends Transformer {
@override
TreeNode visitInstanceTearOff(InstanceTearOff expr) => unary(expr);
@override
TreeNode visitFunctionTearOff(FunctionTearOff expr) => unary(expr);
@override
TreeNode visitSuperPropertySet(SuperPropertySet expr) => unary(expr);
-5
View File
@@ -2144,11 +2144,6 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
}
}
@override
w.ValueType visitFunctionTearOff(
FunctionTearOff node, w.ValueType expectedType) =>
wrap(node.receiver, expectedType);
@override
w.ValueType visitInstanceTearOff(
InstanceTearOff node, w.ValueType expectedType) {
+6
View File
@@ -710,6 +710,12 @@ class _WasmTransformer extends Transformer {
node.transformChildren(this);
return _listFactorySpecializer.transformStaticInvocation(node);
}
@override
visitFunctionTearOff(FunctionTearOff node) {
node.transformChildren(this);
return node.receiver;
}
}
class _AsyncStarFrame {
@@ -40,7 +40,7 @@ Try correcting the name to the name of an existing method, or defining a method
Try correcting the name to the name of an existing method, or defining a method named 'call'.
x.call();
^^^^" in x{<unresolved>}.call();
f.call;
f;
f(5, 2);
}
static method main() → dynamic {}
@@ -40,7 +40,7 @@ Try correcting the name to the name of an existing method, or defining a method
Try correcting the name to the name of an existing method, or defining a method named 'call'.
x.call();
^^^^" in x{<unresolved>}.call();
f.call;
f;
f(5, 2);
}
static method main() → dynamic {}
@@ -111,13 +111,13 @@ class CallableGetter extends core::Object {
static field (dynamic) → dynamic closure = (dynamic x) → dynamic => x;
static field dynamic int1 = self::closure(1){(dynamic) → dynamic};
static field dynamic int2 = self::closure(1){(dynamic) → dynamic};
static field dynamic int3 = self::closure.call(1){(dynamic) → dynamic};
static field dynamic int4 = self::closure.call.call(1){(dynamic) → dynamic};
static field dynamic int3 = self::closure(1){(dynamic) → dynamic};
static field dynamic int4 = self::closure(1){(dynamic) → dynamic};
static field self::Callable callable = new self::Callable::•();
static field dynamic string1 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic};
static field dynamic string2 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic};
static field dynamic string3 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic};
static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
static field self::CallableGetter callableGetter = new self::CallableGetter::•();
static field invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
@@ -135,10 +135,10 @@ var nothing2 = closure.call();
^" in self::closure{<inapplicable>}.();
static field invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given.
var nothing3 = closure.call.call();
^" in self::closure.call{<inapplicable>}.();
^" in self::closure{<inapplicable>}.();
static field invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given.
var nothing4 = closure.call.call.call();
^" in self::closure.call.call{<inapplicable>}.();
^" in self::closure{<inapplicable>}.();
static field invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given.
var nothing5 = callable();
^" in self::callable.{self::Callable::call}{<inapplicable>}.(){() → invalid-type};
@@ -150,7 +150,7 @@ var nothing7 = callable.call.call();
^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
static field invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given.
var nothing8 = callable.call.call.call();
^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}.call{<inapplicable>}.();
^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
static field invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
Try changing 'call' to a method or explicitly invoke 'call'.
@@ -163,13 +163,13 @@ static method main() → dynamic {
(dynamic) → dynamic closure = (dynamic x) → dynamic => x;
dynamic int1 = closure(1){(dynamic) → dynamic};
dynamic int2 = closure(1){(dynamic) → dynamic};
dynamic int3 = closure.call(1){(dynamic) → dynamic};
dynamic int4 = closure.call.call(1){(dynamic) → dynamic};
dynamic int3 = closure(1){(dynamic) → dynamic};
dynamic int4 = closure(1){(dynamic) → dynamic};
self::Callable callable = new self::Callable::•();
dynamic string1 = callable.{self::Callable::call}(1){(dynamic) → dynamic};
dynamic string2 = callable.{self::Callable::call}(1){(dynamic) → dynamic};
dynamic string3 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic};
dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
self::CallableGetter callableGetter = new self::CallableGetter::•();
invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:29:31: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
@@ -187,10 +187,10 @@ Try changing 'call' to a method or explicitly invoke 'call'.
^" in closure{<inapplicable>}.();
invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given.
var nothing3 = closure.call.call();
^" in closure.call{<inapplicable>}.();
^" in closure{<inapplicable>}.();
invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given.
var nothing4 = closure.call.call.call();
^" in closure.call.call{<inapplicable>}.();
^" in closure{<inapplicable>}.();
invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given.
var nothing5 = callable();
^" in callable.{self::Callable::call}{<inapplicable>}.(){() → invalid-type};
@@ -202,7 +202,7 @@ Try changing 'call' to a method or explicitly invoke 'call'.
^" in callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given.
var nothing8 = callable.call.call.call();
^" in callable.{self::Callable::call}{(dynamic) → dynamic}.call{<inapplicable>}.();
^" in callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:44:32: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
Try changing 'call' to a method or explicitly invoke 'call'.
@@ -217,4 +217,4 @@ Try changing 'call' to a method or explicitly invoke 'call'.
Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:30:37 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:64:35 -> IntConstant(1)
Extra constant evaluation: evaluated: 101, effectively constant: 2
Extra constant evaluation: evaluated: 93, effectively constant: 2
@@ -111,13 +111,13 @@ class CallableGetter extends core::Object {
static field (dynamic) → dynamic closure = (dynamic x) → dynamic => x;
static field dynamic int1 = self::closure(1){(dynamic) → dynamic};
static field dynamic int2 = self::closure(1){(dynamic) → dynamic};
static field dynamic int3 = self::closure.call(1){(dynamic) → dynamic};
static field dynamic int4 = self::closure.call.call(1){(dynamic) → dynamic};
static field dynamic int3 = self::closure(1){(dynamic) → dynamic};
static field dynamic int4 = self::closure(1){(dynamic) → dynamic};
static field self::Callable callable = new self::Callable::•();
static field dynamic string1 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic};
static field dynamic string2 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic};
static field dynamic string3 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic};
static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
static field self::CallableGetter callableGetter = new self::CallableGetter::•();
static field invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
@@ -135,10 +135,10 @@ var nothing2 = closure.call();
^" in self::closure{<inapplicable>}.();
static field invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given.
var nothing3 = closure.call.call();
^" in self::closure.call{<inapplicable>}.();
^" in self::closure{<inapplicable>}.();
static field invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given.
var nothing4 = closure.call.call.call();
^" in self::closure.call.call{<inapplicable>}.();
^" in self::closure{<inapplicable>}.();
static field invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given.
var nothing5 = callable();
^" in self::callable.{self::Callable::call}{<inapplicable>}.(){() → invalid-type};
@@ -150,7 +150,7 @@ var nothing7 = callable.call.call();
^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
static field invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given.
var nothing8 = callable.call.call.call();
^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}.call{<inapplicable>}.();
^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
static field invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
Try changing 'call' to a method or explicitly invoke 'call'.
@@ -163,13 +163,13 @@ static method main() → dynamic {
(dynamic) → dynamic closure = (dynamic x) → dynamic => x;
dynamic int1 = closure(1){(dynamic) → dynamic};
dynamic int2 = closure(1){(dynamic) → dynamic};
dynamic int3 = closure.call(1){(dynamic) → dynamic};
dynamic int4 = closure.call.call(1){(dynamic) → dynamic};
dynamic int3 = closure(1){(dynamic) → dynamic};
dynamic int4 = closure(1){(dynamic) → dynamic};
self::Callable callable = new self::Callable::•();
dynamic string1 = callable.{self::Callable::call}(1){(dynamic) → dynamic};
dynamic string2 = callable.{self::Callable::call}(1){(dynamic) → dynamic};
dynamic string3 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic};
dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic};
self::CallableGetter callableGetter = new self::CallableGetter::•();
invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:29:31: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
@@ -187,10 +187,10 @@ Try changing 'call' to a method or explicitly invoke 'call'.
^" in closure{<inapplicable>}.();
invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given.
var nothing3 = closure.call.call();
^" in closure.call{<inapplicable>}.();
^" in closure{<inapplicable>}.();
invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given.
var nothing4 = closure.call.call.call();
^" in closure.call.call{<inapplicable>}.();
^" in closure{<inapplicable>}.();
invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given.
var nothing5 = callable();
^" in callable.{self::Callable::call}{<inapplicable>}.(){() → invalid-type};
@@ -202,7 +202,7 @@ Try changing 'call' to a method or explicitly invoke 'call'.
^" in callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given.
var nothing8 = callable.call.call.call();
^" in callable.{self::Callable::call}{(dynamic) → dynamic}.call{<inapplicable>}.();
^" in callable.{self::Callable::call}{(dynamic) → dynamic}{<inapplicable>}.();
invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:44:32: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method.
- 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'.
Try changing 'call' to a method or explicitly invoke 'call'.
@@ -217,4 +217,4 @@ Try changing 'call' to a method or explicitly invoke 'call'.
Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:30:37 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:64:35 -> IntConstant(1)
Extra constant evaluation: evaluated: 101, effectively constant: 2
Extra constant evaluation: evaluated: 93, effectively constant: 2
@@ -21,7 +21,7 @@ class Class1<T extends core::Function> extends core::Object {
method method() → dynamic {
dynamic v1 = this.{self::Class1::field}{self::Class1::T}();
dynamic v2 = let final core::int #t1 = 0 in this.{self::Class1::field}{self::Class1::T}(#t1);
self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T}.call;
self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T};
dynamic v4 = this.{self::Class1::field}{self::Class1::T}();
dynamic v5 = this.{self::Class1::field}{self::Class1::T}(0);
}
@@ -36,7 +36,7 @@ class Class2<T extends (core::int) → core::String> extends core::Object {
var v1 = field(); // error
^" in this.{self::Class2::field}{self::Class2::T}{<inapplicable>}.();
core::String v2 = let final core::int #t2 = 0 in this.{self::Class2::field}{self::Class2::T}(#t2){(core::int) → core::String};
self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T}.call;
self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T};
invalid-type v4 = 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}{self::Class2::T}{<inapplicable>}.();
@@ -49,4 +49,4 @@ 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: 30, effectively constant: 2
Extra constant evaluation: evaluated: 28, effectively constant: 2
@@ -21,7 +21,7 @@ class Class1<T extends core::Function> extends core::Object {
method method() → dynamic {
dynamic v1 = this.{self::Class1::field}{self::Class1::T}();
dynamic v2 = let final core::int #t1 = 0 in this.{self::Class1::field}{self::Class1::T}(#t1);
self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T}.call;
self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T};
dynamic v4 = this.{self::Class1::field}{self::Class1::T}();
dynamic v5 = this.{self::Class1::field}{self::Class1::T}(0);
}
@@ -36,7 +36,7 @@ class Class2<T extends (core::int) → core::String> extends core::Object {
var v1 = field(); // error
^" in this.{self::Class2::field}{self::Class2::T}{<inapplicable>}.();
core::String v2 = let final core::int #t2 = 0 in this.{self::Class2::field}{self::Class2::T}(#t2){(core::int) → core::String};
self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T}.call;
self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T};
invalid-type v4 = 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}{self::Class2::T}{<inapplicable>}.();
@@ -49,4 +49,4 @@ 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: 30, effectively constant: 2
Extra constant evaluation: evaluated: 28, effectively constant: 2
@@ -17,6 +17,6 @@ static method test(<T extends core::Object* = dynamic>(T*) →* T* f) → void {
(core::int*) →* core::int* func;
func = invalid-expression "pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:12: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,ForLegacy} (core::int*) →* core::int*;
^" in f as{TypeError,ForLegacy} (core::int*) →* core::int*;
}
static method main() → dynamic {}
@@ -13,6 +13,6 @@ static method test(<T extends core::Object* = dynamic>(T*) →* T* f) → void {
(core::int*) →* core::int* func;
func = invalid-expression "pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:12: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,ForLegacy} (core::int*) →* core::int*;
^" in f as{TypeError,ForLegacy} (core::int*) →* core::int*;
}
static method main() → dynamic {}
@@ -507,7 +507,7 @@ static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/f
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var topLevelFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
^^^^" in self::nullableFunction;
static field void topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var topLevelFunctionTypeImplicitCall = nullableFunctionType();
@@ -519,7 +519,7 @@ var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var topLevelFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
^^^^" in self::nullableFunctionType;
static field dynamic topLevelFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?.call instead.
@@ -714,7 +714,7 @@ Try calling using ?. instead.
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var localFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
^^^^" in self::nullableFunction;
void localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var localFunctionTypeImplicitCall = nullableFunctionType();
@@ -726,7 +726,7 @@ Try calling using ?. instead.
() →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var localFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
^^^^" in self::nullableFunctionType;
dynamic localFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?.call instead.
@@ -507,7 +507,7 @@ static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/f
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var topLevelFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
^^^^" in self::nullableFunction;
static field void topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var topLevelFunctionTypeImplicitCall = nullableFunctionType();
@@ -519,7 +519,7 @@ var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var topLevelFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
^^^^" in self::nullableFunctionType;
static field dynamic topLevelFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?.call instead.
@@ -714,7 +714,7 @@ Try calling using ?. instead.
- 'Function' is from 'dart:core'.
Try accessing using ?. instead.
var localFunctionTearOff = nullableFunction.call;
^^^^" in self::nullableFunction.call;
^^^^" in self::nullableFunction;
void localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
var localFunctionTypeImplicitCall = nullableFunctionType();
@@ -726,7 +726,7 @@ Try calling using ?. instead.
() →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null.
Try accessing using ?. instead.
var localFunctionTypeTearOff = nullableFunctionType.call;
^^^^" in self::nullableFunctionType.call;
^^^^" in self::nullableFunctionType;
dynamic localFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null.
- 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'.
Try calling using ?.call instead.
@@ -227,7 +227,7 @@ static method objectPattern(dynamic o) → dynamic {
lowered core::int $1#case#1;
lowered core::String named#case#1;
invalid-type ambiguousField;
if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void}.call in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'.
if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'.
- 'Class' is from 'pkg/front_end/testcases/patterns/pattern_types.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'missing'.
case Class(: var missing): // Error: missing getter
@@ -228,7 +228,7 @@ static method objectPattern(dynamic o) → dynamic {
lowered core::int $1#case#1;
lowered core::String named#case#1;
invalid-type ambiguousField;
if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void}.call in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'.
if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'.
- 'Class' is from 'pkg/front_end/testcases/patterns/pattern_types.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'missing'.
case Class(: var missing): // Error: missing getter
@@ -147,7 +147,7 @@ Try calling using ?.call instead.
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t11 = record in #t11 == null ?{core::bool?} null : #t11{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t12 = record in #t12 == null ?{core::int?} null : #t12{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t13 = record in #t13 == null ?{core::bool?} null : #t13{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call;
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t15 = record in #t15 == null ?{() →? void} null : #t15{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t16 = list in #t16 == null ?{core::int?} null : #t16{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t17 = list in #t17 == null ?{core::String?} null : #t17{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String};
@@ -162,7 +162,7 @@ Try calling using ?.call instead.
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t26 = list in #t26 == null ?{core::bool?} null : #t26{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t27 = list in #t27 == null ?{core::int?} null : #t27{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t28 = list in #t28 == null ?{core::bool?} null : #t28{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call;
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t30 = list in #t30 == null ?{() →? void} null : #t30{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void};
}
static extension-member method _extension#0|call(lowered final core::int #this) → void {}
@@ -147,7 +147,7 @@ Try calling using ?.call instead.
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t11 = record in #t11 == null ?{core::bool?} null : #t11{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t12 = record in #t12 == null ?{core::int?} null : #t12{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t13 = record in #t13 == null ?{core::bool?} null : #t13{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call;
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void};
let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t15 = record in #t15 == null ?{() →? void} null : #t15{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t16 = list in #t16 == null ?{core::int?} null : #t16{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t17 = list in #t17 == null ?{core::String?} null : #t17{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String};
@@ -162,7 +162,7 @@ Try calling using ?.call instead.
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t26 = list in #t26 == null ?{core::bool?} null : #t26{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t27 = list in #t27 == null ?{core::int?} null : #t27{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t28 = list in #t28 == null ?{core::bool?} null : #t28{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call;
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void};
let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t30 = list in #t30 == null ?{() →? void} null : #t30{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void};
}
static extension-member method _extension#0|call(lowered final core::int #this) → void {}
+6
View File
@@ -126,4 +126,10 @@ class _Lowering extends Transformer {
return forInLowering.transformForInStatement(
node, _currentFunctionNode, _staticTypeContext);
}
@override
visitFunctionTearOff(FunctionTearOff node) {
node.transformChildren(this);
return node.receiver;
}
}
@@ -1898,11 +1898,6 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
node, node.receiver, node.interfaceTarget, node.name);
}
@override
TypeExpr visitFunctionTearOff(FunctionTearOff node) {
return _handlePropertyGet(node, node.receiver, null, Name('call'));
}
@override
TypeExpr visitDynamicGet(DynamicGet node) {
return _handlePropertyGet(node, node.receiver, null, node.name);
@@ -623,12 +623,6 @@ class AnnotateKernel extends RecursiveVisitor {
super.visitInstanceTearOff(node);
}
@override
visitFunctionTearOff(FunctionTearOff node) {
_annotateCallSite(node, null);
super.visitFunctionTearOff(node);
}
@override
visitDynamicGet(DynamicGet node) {
_annotateCallSite(node, null);
@@ -1368,17 +1362,6 @@ class _TreeShakerPass1 extends RemovingTransformer {
}
}
@override
TreeNode visitFunctionTearOff(
FunctionTearOff node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
} else {
return node;
}
}
@override
TreeNode visitInstanceSet(InstanceSet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
@@ -1055,7 +1055,9 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
case kInstanceTearOff:
return BuildInstanceTearOff(position);
case kFunctionTearOff:
return BuildFunctionTearOff(position);
// Removed by lowering kernel transformation.
UNREACHABLE();
break;
case kInstanceSet:
return BuildInstanceSet(position);
case kDynamicSet:
@@ -2304,40 +2306,6 @@ Fragment StreamingFlowGraphBuilder::BuildInstanceTearOff(TokenPosition* p) {
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildFunctionTearOff(TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
if (p != nullptr) *p = position;
const DirectCallMetadata direct_call =
direct_call_metadata_helper_.GetDirectTargetForPropertyGet(offset);
const InferredTypeMetadata result_type =
inferred_type_metadata_helper_.GetInferredType(offset);
Fragment instructions = BuildExpression(); // read receiver.
if (direct_call.check_receiver_for_null_) {
const auto receiver = MakeTemporary();
instructions += CheckNull(position, receiver, Symbols::GetCall());
}
if (!direct_call.target_.IsNull()) {
ASSERT(CompilerState::Current().is_aot());
instructions +=
StaticCall(position, direct_call.target_, 1, Array::null_array(),
ICData::kNoRebind, &result_type);
} else {
const intptr_t kTypeArgsLen = 0;
const intptr_t kNumArgsChecked = 1;
instructions += InstanceCall(position, Symbols::GetCall(), Token::kGET,
kTypeArgsLen, 1, Array::null_array(),
kNumArgsChecked, Function::null_function(),
Function::null_function(), &result_type);
}
return instructions;
}
Fragment StreamingFlowGraphBuilder::BuildInstanceSet(TokenPosition* p) {
const intptr_t offset = ReaderOffset() - 1; // Include the tag.
ReadByte(); // read kind.
@@ -282,7 +282,6 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
Fragment BuildInstanceGet(TokenPosition* position);
Fragment BuildDynamicGet(TokenPosition* position);
Fragment BuildInstanceTearOff(TokenPosition* position);
Fragment BuildFunctionTearOff(TokenPosition* position);
Fragment BuildInstanceSet(TokenPosition* position);
Fragment BuildDynamicSet(TokenPosition* position);
Fragment BuildAllocateInvocationMirrorCall(TokenPosition position,
@@ -421,9 +421,9 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() {
CalculateGetterNameFingerprint(); // read interface_target_reference.
return;
case kFunctionTearOff:
ReadPosition(); // read position.
CalculateExpressionFingerprint(); // read receiver.
return;
// Removed by lowering kernel transformation.
UNREACHABLE();
break;
case kInstanceSet:
ReadByte(); // read kind.
ReadPosition(); // read position.
@@ -2517,9 +2517,9 @@ void KernelReaderHelper::SkipExpression() {
SkipInterfaceMemberNameReference(); // read interface_target_reference.
return;
case kFunctionTearOff:
ReadPosition(); // read position.
SkipExpression(); // read receiver.
return;
// Removed by lowering kernel transformation.
UNREACHABLE();
break;
case kInstanceSet:
ReadByte(); // read kind.
ReadPosition(); // read position.
@@ -682,9 +682,9 @@ void ScopeBuilder::VisitExpression() {
helper_.SkipInterfaceMemberNameReference();
return;
case kFunctionTearOff:
helper_.ReadPosition(); // read position.
VisitExpression(); // read receiver.
return;
// Removed by lowering kernel transformation.
UNREACHABLE();
break;
case kInstanceSet:
helper_.ReadByte(); // read kind.
helper_.ReadPosition(); // read position.