mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:17:14 +00:00
[cfe] Handle dynamic invocation
Change-Id: I13ca160a2dd5862d558928826adee7bcacf67d04 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117731 Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
18e4f6ba8d
commit
2777806901
|
@ -716,7 +716,9 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
new InstrumentationValueForMember(target.member));
|
||||
}
|
||||
|
||||
if (target.isUnresolved && includeExtensionMethods) {
|
||||
if (target.isUnresolved &&
|
||||
receiverType is! DynamicType &&
|
||||
includeExtensionMethods) {
|
||||
Member otherMember =
|
||||
_getInterfaceMember(classNode, name, !setter, fileOffset);
|
||||
if (otherMember != null) {
|
||||
|
|
31
pkg/front_end/testcases/extensions/dynamic_invoke.dart
Normal file
31
pkg/front_end/testcases/extensions/dynamic_invoke.dart
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) 2019, 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 Class {
|
||||
noSuchMethod(Invocation i) => 123;
|
||||
}
|
||||
|
||||
extension ClassExtension on Class {
|
||||
int method() => 42;
|
||||
}
|
||||
|
||||
extension Extension on dynamic {
|
||||
int method() => 87;
|
||||
}
|
||||
|
||||
main() {
|
||||
dynamic c0 = new Class();
|
||||
Object c1 = new Class();
|
||||
Class c2 = new Class();
|
||||
|
||||
expect(123, c0.method());
|
||||
expect(87, c1.method());
|
||||
expect(42, c2.method());
|
||||
}
|
||||
|
||||
expect(expected, actual) {
|
||||
if (expected != actual) {
|
||||
throw 'Mismatch: expected=$expected, actual=$actual';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Class extends core::Object {
|
||||
synthetic constructor •() → self::Class*
|
||||
;
|
||||
method noSuchMethod(core::Invocation* i) → dynamic
|
||||
;
|
||||
}
|
||||
extension ClassExtension on self::Class* {
|
||||
method method = self::ClassExtension|method;
|
||||
tearoff method = self::ClassExtension|get#method;
|
||||
}
|
||||
extension Extension on dynamic {
|
||||
method method = self::Extension|method;
|
||||
tearoff method = self::Extension|get#method;
|
||||
}
|
||||
static method ClassExtension|method(final self::Class* #this) → core::int*
|
||||
;
|
||||
static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
|
||||
return () → core::int* => self::ClassExtension|method(#this);
|
||||
static method Extension|method(final dynamic #this) → core::int*
|
||||
;
|
||||
static method Extension|get#method(final dynamic #this) → () →* core::int*
|
||||
return () → core::int* => self::Extension|method(#this);
|
||||
static method main() → dynamic
|
||||
;
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic
|
||||
;
|
|
@ -0,0 +1,40 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Class extends core::Object {
|
||||
synthetic constructor •() → self::Class*
|
||||
: super core::Object::•()
|
||||
;
|
||||
method noSuchMethod(core::Invocation* i) → dynamic
|
||||
return 123;
|
||||
}
|
||||
extension ClassExtension on self::Class* {
|
||||
method method = self::ClassExtension|method;
|
||||
tearoff method = self::ClassExtension|get#method;
|
||||
}
|
||||
extension Extension on dynamic {
|
||||
method method = self::Extension|method;
|
||||
tearoff method = self::Extension|get#method;
|
||||
}
|
||||
static method ClassExtension|method(final self::Class* #this) → core::int*
|
||||
return 42;
|
||||
static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
|
||||
return () → core::int* => self::ClassExtension|method(#this);
|
||||
static method Extension|method(final dynamic #this) → core::int*
|
||||
return 87;
|
||||
static method Extension|get#method(final dynamic #this) → () →* core::int*
|
||||
return () → core::int* => self::Extension|method(#this);
|
||||
static method main() → dynamic {
|
||||
dynamic c0 = new self::Class::•();
|
||||
core::Object* c1 = new self::Class::•();
|
||||
self::Class* c2 = new self::Class::•();
|
||||
self::expect(123, c0.method());
|
||||
self::expect(87, self::Extension|method(c1));
|
||||
self::expect(42, self::ClassExtension|method(c2));
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
throw "Mismatch: expected=${expected}, actual=${actual}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Class extends core::Object {
|
||||
synthetic constructor •() → self::Class*
|
||||
: super core::Object::•()
|
||||
;
|
||||
method noSuchMethod(core::Invocation* i) → dynamic
|
||||
return 123;
|
||||
}
|
||||
extension ClassExtension on self::Class* {
|
||||
method method = self::ClassExtension|method;
|
||||
tearoff method = self::ClassExtension|get#method;
|
||||
}
|
||||
extension Extension on dynamic {
|
||||
method method = self::Extension|method;
|
||||
tearoff method = self::Extension|get#method;
|
||||
}
|
||||
static method ClassExtension|method(final self::Class* #this) → core::int*
|
||||
return 42;
|
||||
static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
|
||||
return () → core::int* => self::ClassExtension|method(#this);
|
||||
static method Extension|method(final dynamic #this) → core::int*
|
||||
return 87;
|
||||
static method Extension|get#method(final dynamic #this) → () →* core::int*
|
||||
return () → core::int* => self::Extension|method(#this);
|
||||
static method main() → dynamic {
|
||||
dynamic c0 = new self::Class::•();
|
||||
core::Object* c1 = new self::Class::•();
|
||||
self::Class* c2 = new self::Class::•();
|
||||
self::expect(123, c0.method());
|
||||
self::expect(87, self::Extension|method(c1));
|
||||
self::expect(42, self::ClassExtension|method(c2));
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
throw "Mismatch: expected=${expected}, actual=${actual}";
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ extensions/compounds: TextSerializationFailure
|
|||
extensions/conflicts: TextSerializationFailure
|
||||
extensions/direct_instance_access: TextSerializationFailure
|
||||
extensions/direct_static_access: TextSerializationFailure
|
||||
extensions/dynamic_invoke: TextSerializationFailure
|
||||
extensions/explicit_extension_access: TextSerializationFailure
|
||||
extensions/explicit_extension_inference: TextSerializationFailure
|
||||
extensions/explicit_generic_extension_access: TextSerializationFailure
|
||||
|
|
Loading…
Reference in a new issue