Skip to content

Commit fd9f79c

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Handle deferred explicit extension access
Change-Id: I53e13ac3b4f1bdcd26ccec86814fb4d708c5cceb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124542 Reviewed-by: Erik Ernst <eernst@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
1 parent 7c78ab7 commit fd9f79c

7 files changed

+229
-5
lines changed

pkg/front_end/lib/src/fasta/kernel/expression_generator.dart

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,11 +2806,15 @@ class DeferredAccessGenerator extends Generator {
28062806
}
28072807

28082808
@override
2809-
Expression doInvocation(int offset, Arguments arguments) {
2810-
return _helper.wrapInDeferredCheck(
2811-
suffixGenerator.doInvocation(offset, arguments),
2812-
prefixGenerator.prefix,
2813-
token.charOffset);
2809+
doInvocation(int offset, Arguments arguments) {
2810+
Object suffix = suffixGenerator.doInvocation(offset, arguments);
2811+
if (suffix is Expression) {
2812+
return _helper.wrapInDeferredCheck(
2813+
suffix, prefixGenerator.prefix, fileOffset);
2814+
} else {
2815+
return new DeferredAccessGenerator(
2816+
_helper, token, prefixGenerator, suffix);
2817+
}
28142818
}
28152819

28162820
@override
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'deferred_explicit_access_lib.dart' deferred as prefix;
6+
7+
main() async {
8+
await prefix.loadLibrary();
9+
expect(0, prefix.Extension.staticField);
10+
11+
expect(0, prefix.Extension(0).property);
12+
expect(42, prefix.Extension(0).property = 42);
13+
expect(84, prefix.Extension(42).property);
14+
expect(85, prefix.Extension(43).method());
15+
16+
expect(42, prefix.Extension.staticProperty);
17+
expect(87, prefix.Extension.staticProperty = 87);
18+
expect(87, prefix.Extension.staticMethod());
19+
}
20+
21+
expect(expected, actual) {
22+
if (expected != actual) throw 'Expected $expected, actual $actual';
23+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
library;
2+
import self as self;
3+
4+
import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;
5+
6+
static method main() → dynamic
7+
;
8+
static method expect(dynamic expected, dynamic actual) → dynamic
9+
;
10+
11+
library;
12+
import self as self2;
13+
import "dart:core" as core;
14+
15+
extension Extension on core::int* {
16+
static field staticField = self2::Extension|staticField;
17+
static get staticProperty = get self2::Extension|staticProperty;
18+
static method staticMethod = self2::Extension|staticMethod;
19+
get property = self2::Extension|get#property;
20+
method method = self2::Extension|method;
21+
tearoff method = self2::Extension|get#method;
22+
static set staticProperty = set self2::Extension|staticProperty;
23+
set property = self2::Extension|set#property;
24+
}
25+
static field core::int* Extension|staticField;
26+
static get Extension|staticProperty() → core::int*
27+
;
28+
static set Extension|staticProperty(core::int* value) → void
29+
;
30+
static method Extension|staticMethod() → core::int*
31+
;
32+
static method Extension|get#property(final core::int* #this) → core::int*
33+
;
34+
static method Extension|set#property(final core::int* #this, core::int* value) → void
35+
;
36+
static method Extension|method(final core::int* #this) → core::int*
37+
;
38+
static method Extension|get#method(final core::int* #this) → () →* core::int*
39+
return () → core::int* => self2::Extension|method(#this);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
library;
2+
import self as self;
3+
import "deferred_explicit_access_lib.dart" as def;
4+
import "dart:core" as core;
5+
6+
import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;
7+
8+
static method main() → dynamic async {
9+
await LoadLibrary(prefix);
10+
self::expect(0, let final dynamic #t1 = CheckLibraryIsLoaded(prefix) in def::Extension|staticField);
11+
self::expect(0, let final dynamic #t2 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(0));
12+
self::expect(42, let final dynamic #t3 = CheckLibraryIsLoaded(prefix) in let final core::int* #t4 = 0 in let final core::int* #t5 = 42 in let final void #t6 = def::Extension|set#property(#t4, #t5) in #t5);
13+
self::expect(84, let final dynamic #t7 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(42));
14+
self::expect(85, let final dynamic #t8 = CheckLibraryIsLoaded(prefix) in def::Extension|method(43));
15+
self::expect(42, let final dynamic #t9 = CheckLibraryIsLoaded(prefix) in def::Extension|staticProperty);
16+
self::expect(87, let final dynamic #t10 = CheckLibraryIsLoaded(prefix) in def::Extension|staticProperty = 87);
17+
self::expect(87, let final dynamic #t11 = CheckLibraryIsLoaded(prefix) in def::Extension|staticMethod());
18+
}
19+
static method expect(dynamic expected, dynamic actual) → dynamic {
20+
if(!expected.{core::Object::==}(actual))
21+
throw "Expected ${expected}, actual ${actual}";
22+
}
23+
24+
library;
25+
import self as def;
26+
import "dart:core" as core;
27+
28+
extension Extension on core::int* {
29+
static field staticField = def::Extension|staticField;
30+
static get staticProperty = get def::Extension|staticProperty;
31+
static method staticMethod = def::Extension|staticMethod;
32+
get property = def::Extension|get#property;
33+
method method = def::Extension|method;
34+
tearoff method = def::Extension|get#method;
35+
static set staticProperty = set def::Extension|staticProperty;
36+
set property = def::Extension|set#property;
37+
}
38+
static field core::int* Extension|staticField = 0;
39+
static get Extension|staticProperty() → core::int*
40+
return def::Extension|staticField;
41+
static set Extension|staticProperty(core::int* value) → void {
42+
def::Extension|staticField = value;
43+
}
44+
static method Extension|staticMethod() → core::int*
45+
return def::Extension|staticField;
46+
static method Extension|get#property(final core::int* #this) → core::int*
47+
return #this.{core::num::+}(def::Extension|staticField);
48+
static method Extension|set#property(final core::int* #this, core::int* value) → void {
49+
def::Extension|staticField = value;
50+
}
51+
static method Extension|method(final core::int* #this) → core::int*
52+
return #this.{core::num::+}(def::Extension|staticField);
53+
static method Extension|get#method(final core::int* #this) → () →* core::int*
54+
return () → core::int* => def::Extension|method(#this);
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
library;
2+
import self as self;
3+
import "dart:async" as asy;
4+
import "dart:core" as core;
5+
import "deferred_explicit_access_lib.dart" as def;
6+
7+
import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;
8+
9+
static method main() → dynamic /* originally async */ {
10+
final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
11+
asy::FutureOr<dynamic>* :return_value;
12+
dynamic :async_stack_trace;
13+
dynamic :async_op_then;
14+
dynamic :async_op_error;
15+
dynamic :await_jump_var = 0;
16+
dynamic :await_ctx_var;
17+
dynamic :saved_try_context_var0;
18+
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
19+
try {
20+
#L1:
21+
{
22+
[yield] let dynamic #t1 = asy::_awaitHelper(LoadLibrary(prefix), :async_op_then, :async_op_error, :async_op) in null;
23+
:result;
24+
self::expect(0, let final core::Object* #t2 = CheckLibraryIsLoaded(prefix) in def::Extension|staticField);
25+
self::expect(0, let final core::Object* #t3 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(0));
26+
self::expect(42, let final core::Object* #t4 = CheckLibraryIsLoaded(prefix) in let final core::int* #t5 = 0 in let final core::int* #t6 = 42 in let final void #t7 = def::Extension|set#property(#t5, #t6) in #t6);
27+
self::expect(84, let final core::Object* #t8 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(42));
28+
self::expect(85, let final core::Object* #t9 = CheckLibraryIsLoaded(prefix) in def::Extension|method(43));
29+
self::expect(42, let final core::Object* #t10 = CheckLibraryIsLoaded(prefix) in def::Extension|staticProperty);
30+
self::expect(87, let final core::Object* #t11 = CheckLibraryIsLoaded(prefix) in def::Extension|staticProperty = 87);
31+
self::expect(87, let final core::Object* #t12 = CheckLibraryIsLoaded(prefix) in def::Extension|staticMethod());
32+
}
33+
asy::_completeOnAsyncReturn(:async_completer, :return_value);
34+
return;
35+
}
36+
on dynamic catch(dynamic :exception, dynamic :stack_trace) {
37+
:async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
38+
}
39+
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
40+
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
41+
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
42+
:async_completer.start(:async_op);
43+
return :async_completer.{asy::Completer::future};
44+
}
45+
static method expect(dynamic expected, dynamic actual) → dynamic {
46+
if(!expected.{core::Object::==}(actual))
47+
throw "Expected ${expected}, actual ${actual}";
48+
}
49+
50+
library;
51+
import self as def;
52+
import "dart:core" as core;
53+
54+
extension Extension on core::int* {
55+
static field staticField = def::Extension|staticField;
56+
static get staticProperty = get def::Extension|staticProperty;
57+
static method staticMethod = def::Extension|staticMethod;
58+
get property = def::Extension|get#property;
59+
method method = def::Extension|method;
60+
tearoff method = def::Extension|get#method;
61+
static set staticProperty = set def::Extension|staticProperty;
62+
set property = def::Extension|set#property;
63+
}
64+
static field core::int* Extension|staticField = 0;
65+
static get Extension|staticProperty() → core::int*
66+
return def::Extension|staticField;
67+
static set Extension|staticProperty(core::int* value) → void {
68+
def::Extension|staticField = value;
69+
}
70+
static method Extension|staticMethod() → core::int*
71+
return def::Extension|staticField;
72+
static method Extension|get#property(final core::int* #this) → core::int*
73+
return #this.{core::num::+}(def::Extension|staticField);
74+
static method Extension|set#property(final core::int* #this, core::int* value) → void {
75+
def::Extension|staticField = value;
76+
}
77+
static method Extension|method(final core::int* #this) → core::int*
78+
return #this.{core::num::+}(def::Extension|staticField);
79+
static method Extension|get#method(final core::int* #this) → () →* core::int*
80+
return () → core::int* => def::Extension|method(#this);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
extension Extension on int {
6+
static int staticField = 0;
7+
8+
static int get staticProperty => staticField;
9+
10+
static void set staticProperty(int value) {
11+
staticField = value;
12+
}
13+
14+
static int staticMethod() => staticField;
15+
16+
int get property => this + staticField;
17+
18+
void set property(int value) {
19+
staticField = value;
20+
}
21+
22+
int method() => this + staticField;
23+
}

pkg/front_end/testcases/text_serialization.status

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extensions/compounds: TextSerializationFailure
1515
extensions/conflict_with_object: TextSerializationFailure
1616
extensions/conflicts: TextSerializationFailure
1717
extensions/default_values: TextSerializationFailure
18+
extensions/deferred_explicit_access: TextSerializationFailure
1819
extensions/direct_instance_access: TextSerializationFailure
1920
extensions/direct_static_access: TextSerializationFailure
2021
extensions/dynamic_invoke: TextSerializationFailure

0 commit comments

Comments
 (0)