mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:27:39 +00:00
[cfe] Support implicit this access to extension methods in extensions
Change-Id: Idad98ca0d0fb27010ef4a522593f283b97ecc873 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117720 Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
25166af3ea
commit
71896d5586
|
@ -661,9 +661,6 @@ class ThisPropertyAccessGenerator extends Generator {
|
|||
}
|
||||
|
||||
Expression _createRead() {
|
||||
if (getter == null) {
|
||||
_helper.warnUnresolvedGet(name, fileOffset);
|
||||
}
|
||||
return new PropertyGet(
|
||||
_forest.createThisExpression(fileOffset), name, getter)
|
||||
..fileOffset = fileOffset;
|
||||
|
@ -675,9 +672,6 @@ class ThisPropertyAccessGenerator extends Generator {
|
|||
}
|
||||
|
||||
Expression _createWrite(int offset, Expression value) {
|
||||
if (setter == null) {
|
||||
_helper.warnUnresolvedSet(name, fileOffset);
|
||||
}
|
||||
return new PropertySet(
|
||||
_forest.createThisExpression(fileOffset), name, value, setter)
|
||||
..fileOffset = fileOffset;
|
||||
|
@ -745,9 +739,6 @@ class ThisPropertyAccessGenerator extends Generator {
|
|||
@override
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
Member interfaceTarget = getter;
|
||||
if (interfaceTarget == null) {
|
||||
_helper.warnUnresolvedMethod(name, offset);
|
||||
}
|
||||
if (interfaceTarget is Field) {
|
||||
// TODO(ahe): In strong mode we should probably rewrite this to
|
||||
// `this.name.call(arguments)`.
|
||||
|
|
33
pkg/front_end/testcases/extensions/internal_resolution.dart
Normal file
33
pkg/front_end/testcases/extensions/internal_resolution.dart
Normal file
|
@ -0,0 +1,33 @@
|
|||
// 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 {
|
||||
int field;
|
||||
}
|
||||
|
||||
extension on Class {
|
||||
int get property1 => property2;
|
||||
void set property1(int value) => field = value;
|
||||
}
|
||||
|
||||
extension on Class {
|
||||
int get property2 => field;
|
||||
void set property2(int value) => property1 = value;
|
||||
}
|
||||
|
||||
main() {
|
||||
var c = new Class();
|
||||
expect(null, c.property1);
|
||||
expect(null, c.property2);
|
||||
expect(42, c.property1 = 42);
|
||||
expect(42, c.property2);
|
||||
expect(87, c.property2 = 87);
|
||||
expect(87, c.property1);
|
||||
}
|
||||
|
||||
expect(expected, actual) {
|
||||
if (expected != actual) {
|
||||
throw 'Mismatch: expected=$expected, actual=$actual';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Class extends core::Object {
|
||||
field core::int* field;
|
||||
synthetic constructor •() → self::Class*
|
||||
;
|
||||
}
|
||||
extension _extension#0 on self::Class* {
|
||||
get property1 = self::_extension#0|get#property1;
|
||||
set property1 = self::_extension#0|set#property1;
|
||||
}
|
||||
extension _extension#1 on self::Class* {
|
||||
get property2 = self::_extension#1|get#property2;
|
||||
set property2 = self::_extension#1|set#property2;
|
||||
}
|
||||
static method _extension#0|get#property1(final self::Class* #this) → core::int*
|
||||
;
|
||||
static method _extension#0|set#property1(final self::Class* #this, core::int* value) → void
|
||||
;
|
||||
static method _extension#1|get#property2(final self::Class* #this) → core::int*
|
||||
;
|
||||
static method _extension#1|set#property2(final self::Class* #this, core::int* value) → void
|
||||
;
|
||||
static method main() → dynamic
|
||||
;
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic
|
||||
;
|
|
@ -0,0 +1,46 @@
|
|||
library;
|
||||
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::•()
|
||||
;
|
||||
}
|
||||
extension _extension#0 on self::Class* {
|
||||
get property1 = self::_extension#0|get#property1;
|
||||
set property1 = self::_extension#0|set#property1;
|
||||
}
|
||||
extension _extension#1 on self::Class* {
|
||||
get property2 = self::_extension#1|get#property2;
|
||||
set property2 = self::_extension#1|set#property2;
|
||||
}
|
||||
static method _extension#0|get#property1(final self::Class* #this) → core::int*
|
||||
return self::_extension#1|get#property2(#this);
|
||||
static method _extension#0|set#property1(final self::Class* #this, core::int* value) → core::int* {
|
||||
final core::int* #t1 = value;
|
||||
return #this.{self::Class::field} = value;
|
||||
return #t1;
|
||||
}
|
||||
static method _extension#1|get#property2(final self::Class* #this) → core::int*
|
||||
return #this.{self::Class::field};
|
||||
static method _extension#1|set#property2(final self::Class* #this, core::int* value) → core::int* {
|
||||
final core::int* #t2 = value;
|
||||
return self::_extension#0|set#property1(#this, value);
|
||||
return #t2;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::Class* c = new self::Class::•();
|
||||
self::expect(null, self::_extension#0|get#property1(c));
|
||||
self::expect(null, self::_extension#1|get#property2(c));
|
||||
self::expect(42, self::_extension#0|set#property1(c, 42));
|
||||
self::expect(42, self::_extension#1|get#property2(c));
|
||||
self::expect(87, self::_extension#1|set#property2(c, 87));
|
||||
self::expect(87, self::_extension#0|get#property1(c));
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
throw "Mismatch: expected=${expected}, actual=${actual}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
library;
|
||||
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::•()
|
||||
;
|
||||
}
|
||||
extension _extension#0 on self::Class* {
|
||||
get property1 = self::_extension#0|get#property1;
|
||||
set property1 = self::_extension#0|set#property1;
|
||||
}
|
||||
extension _extension#1 on self::Class* {
|
||||
get property2 = self::_extension#1|get#property2;
|
||||
set property2 = self::_extension#1|set#property2;
|
||||
}
|
||||
static method _extension#0|get#property1(final self::Class* #this) → core::int*
|
||||
return self::_extension#1|get#property2(#this);
|
||||
static method _extension#0|set#property1(final self::Class* #this, core::int* value) → core::int* {
|
||||
final core::int* #t1 = value;
|
||||
return #this.{self::Class::field} = value;
|
||||
return #t1;
|
||||
}
|
||||
static method _extension#1|get#property2(final self::Class* #this) → core::int*
|
||||
return #this.{self::Class::field};
|
||||
static method _extension#1|set#property2(final self::Class* #this, core::int* value) → core::int* {
|
||||
final core::int* #t2 = value;
|
||||
return self::_extension#0|set#property1(#this, value);
|
||||
return #t2;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::Class* c = new self::Class::•();
|
||||
self::expect(null, self::_extension#0|get#property1(c));
|
||||
self::expect(null, self::_extension#1|get#property2(c));
|
||||
self::expect(42, self::_extension#0|set#property1(c, 42));
|
||||
self::expect(42, self::_extension#1|get#property2(c));
|
||||
self::expect(87, self::_extension#1|set#property2(c, 87));
|
||||
self::expect(87, self::_extension#0|get#property1(c));
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
throw "Mismatch: expected=${expected}, actual=${actual}";
|
||||
}
|
||||
}
|
|
@ -2,20 +2,12 @@ library;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:16:13: Error: Getter not found: 'onlySetter'.
|
||||
// print(onlySetter);
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
|
||||
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
|
||||
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
|
||||
// print(onlySetter);
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:25:11: Error: Getter not found: 'onlySetter'.
|
||||
// print(onlySetter);
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
|
||||
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
|
||||
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
|
||||
|
|
|
@ -2,20 +2,12 @@ library;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:16:13: Error: Getter not found: 'onlySetter'.
|
||||
// print(onlySetter);
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
|
||||
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
|
||||
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
|
||||
// print(onlySetter);
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:25:11: Error: Getter not found: 'onlySetter'.
|
||||
// print(onlySetter);
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
|
||||
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
|
||||
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
|
||||
|
|
|
@ -18,14 +18,6 @@ library;
|
|||
// for (c.untypedSuperInstanceField in []) {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/general/for_in_without_declaration.dart:37:10: Error: Setter not found: 'unresolved'.
|
||||
// for (unresolved in []) {}
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:10: Error: Getter not found: 'unresolved'.
|
||||
// for (unresolved.foo in []) {}
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
|
||||
// for (unresolved.foo in []) {}
|
||||
// ^
|
||||
|
|
|
@ -18,14 +18,6 @@ library;
|
|||
// for (c.untypedSuperInstanceField in []) {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/general/for_in_without_declaration.dart:37:10: Error: Setter not found: 'unresolved'.
|
||||
// for (unresolved in []) {}
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:10: Error: Getter not found: 'unresolved'.
|
||||
// for (unresolved.foo in []) {}
|
||||
// ^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
|
||||
// for (unresolved.foo in []) {}
|
||||
// ^
|
||||
|
|
|
@ -48,10 +48,6 @@ library;
|
|||
// C notEvenAConstructor(a) = h;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: Getter not found: 'h'.
|
||||
// C notEvenAConstructor(a) = h;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
|
||||
// - 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
|
||||
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
|
||||
|
|
|
@ -48,10 +48,6 @@ library;
|
|||
// C notEvenAConstructor(a) = h;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: Getter not found: 'h'.
|
||||
// C notEvenAConstructor(a) = h;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
|
||||
// - 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
|
||||
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
|
||||
|
|
|
@ -2,14 +2,6 @@ library;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: Getter not found: 'key'.
|
||||
// print(key);
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: Setter not found: 'key'.
|
||||
// for (key in x) {
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
|
||||
// for (Fisk in x) {
|
||||
// ^^^^
|
||||
|
@ -30,10 +22,6 @@ library;
|
|||
// for (1 in x) {
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: Getter not found: 'key'.
|
||||
// print(key);
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
|
||||
// for (1 in x) {
|
||||
// ^
|
||||
|
|
|
@ -2,14 +2,6 @@ library;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: Getter not found: 'key'.
|
||||
// print(key);
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: Setter not found: 'key'.
|
||||
// for (key in x) {
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
|
||||
// for (Fisk in x) {
|
||||
// ^^^^
|
||||
|
@ -30,10 +22,6 @@ library;
|
|||
// for (1 in x) {
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: Getter not found: 'key'.
|
||||
// print(key);
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
|
||||
// for (1 in x) {
|
||||
// ^
|
||||
|
|
|
@ -20,6 +20,7 @@ extensions/extension_methods: TextSerializationFailure
|
|||
extensions/implicit_extension_inference: TextSerializationFailure
|
||||
extensions/implicit_this: TextSerializationFailure
|
||||
extensions/index: TextSerializationFailure
|
||||
extensions/internal_resolution: TextSerializationFailure
|
||||
extensions/instance_access: TextSerializationFailure
|
||||
extensions/instance_access_of_static: TextSerializationFailure
|
||||
extensions/instance_members: TextSerializationFailure
|
||||
|
|
Loading…
Reference in a new issue