Skip to content

Commit b12bed3

Browse files
a-sivacommit-bot@chromium.org
authored andcommitted
[VM] Implement isExtensionMember in MethodMirror and VariableMirror
Added ability to recognize a MethodMirror to be a mirror of an extension member Added ability to recognize a VariableMirror to be a mirror of a static extension field. Change-Id: I56715a491bba0d8cafb2796ebb755bd339e147c6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/120760 Reviewed-by: Siva Annamalai <asiva@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Siva Annamalai <asiva@google.com>
1 parent 5092b8e commit b12bed3

File tree

8 files changed

+173
-8
lines changed

8 files changed

+173
-8
lines changed

runtime/lib/mirrors.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ static RawInstance* CreateMethodMirror(const Function& func,
274274
(static_cast<intptr_t>(func.is_external()) << Mirrors::kExternal);
275275
bool is_synthetic = func.is_no_such_method_forwarder();
276276
kind_flags |= (static_cast<intptr_t>(is_synthetic) << Mirrors::kSynthetic);
277+
kind_flags |= (static_cast<intptr_t>(func.is_extension_member())
278+
<< Mirrors::kExtensionMember);
277279
args.SetAt(5, Smi::Handle(Smi::New(kind_flags)));
278280

279281
return CreateMirror(Symbols::_MethodMirror(), args);
@@ -286,14 +288,15 @@ static RawInstance* CreateVariableMirror(const Field& field,
286288

287289
const String& name = String::Handle(field.name());
288290

289-
const Array& args = Array::Handle(Array::New(7));
291+
const Array& args = Array::Handle(Array::New(8));
290292
args.SetAt(0, field_ref);
291293
args.SetAt(1, name);
292294
args.SetAt(2, owner_mirror);
293295
args.SetAt(3, Object::null_instance()); // Null for type.
294296
args.SetAt(4, Bool::Get(field.is_static()));
295297
args.SetAt(5, Bool::Get(field.is_final()));
296298
args.SetAt(6, Bool::Get(field.is_const()));
299+
args.SetAt(7, Bool::Get(field.is_extension_member()));
297300

298301
return CreateMirror(Symbols::_VariableMirror(), args);
299302
}
@@ -1320,12 +1323,16 @@ DEFINE_NATIVE_ENTRY(ClosureMirror_function, 0, 1) {
13201323
Function& function = Function::Handle();
13211324
bool callable = closure.IsCallable(&function);
13221325
if (callable) {
1323-
if (function.IsImplicitClosureFunction()) {
1326+
const Function& parent = Function::Handle(function.parent_function());
1327+
if (function.IsImplicitClosureFunction() || parent.is_extension_member()) {
13241328
// The VM uses separate Functions for tear-offs, but the mirrors consider
13251329
// the tear-offs to be the same as the torn-off methods. Avoid handing out
13261330
// a reference to the tear-off here to avoid a special case in the
13271331
// the equality test.
1328-
function = function.parent_function();
1332+
// In the case of extension methods also we avoid handing out a reference
1333+
// to the tear-off and instead get the parent function of the
1334+
// anonymous closure.
1335+
function = parent.raw();
13291336
}
13301337

13311338
Type& instantiator = Type::Handle();

runtime/lib/mirrors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class Mirrors : public AllStatic {
2121
V(kRedirectingCtor) \
2222
V(kFactoryCtor) \
2323
V(kExternal) \
24-
V(kSynthetic)
24+
V(kSynthetic) \
25+
V(kExtensionMember)
2526

2627
// These offsets much be kept in sync with those in mirrors_impl.dart.
2728
enum KindShifts {

sdk/lib/_internal/vm/lib/mirrors_impl.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class _SyntheticAccessor implements MethodMirror {
157157
bool get isExternal => false;
158158
bool get isRedirectingConstructor => false;
159159
bool get isAbstract => false;
160+
bool get isExtensionMember => false;
160161

161162
bool get isSetter => !isGetter;
162163
bool get isPrivate => _n(simpleName).startsWith('_');
@@ -193,6 +194,7 @@ class _SyntheticSetterParameter implements ParameterMirror {
193194
bool get isConst => false;
194195
bool get isFinal => true;
195196
bool get isPrivate => false;
197+
bool get isExtensionMember => false;
196198
bool get hasDefaultValue => false;
197199
InstanceMirror get defaultValue => null;
198200
SourceLocation get location => null;
@@ -1168,6 +1170,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror {
11681170
static const kFactoryCtor = 7;
11691171
static const kExternal = 8;
11701172
static const kSynthetic = 9;
1173+
static const kExtensionMember = 10;
11711174

11721175
// These offsets much be kept in sync with those in mirrors.h.
11731176
bool get isAbstract => 0 != (_kindFlags & (1 << kAbstract));
@@ -1182,6 +1185,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror {
11821185
bool get isFactoryConstructor => 0 != (_kindFlags & (1 << kFactoryCtor));
11831186
bool get isExternal => 0 != (_kindFlags & (1 << kExternal));
11841187
bool get isSynthetic => 0 != (_kindFlags & (1 << kSynthetic));
1188+
bool get isExtensionMember => 0 != (_kindFlags & (1 << kExtensionMember));
11851189

11861190
static const _operators = const [
11871191
"%", "&", "*", "+", "-", "/", "<", "<<", //
@@ -1281,9 +1285,10 @@ class _VariableMirror extends _DeclarationMirror implements VariableMirror {
12811285
final bool isStatic;
12821286
final bool isFinal;
12831287
final bool isConst;
1288+
final bool isExtensionMember;
12841289

12851290
_VariableMirror._(reflectee, String simpleName, this.owner, this._type,
1286-
this.isStatic, this.isFinal, this.isConst)
1291+
this.isStatic, this.isFinal, this.isConst, this.isExtensionMember)
12871292
: super._(reflectee, _s(simpleName));
12881293

12891294
bool get isTopLevel => owner is LibraryMirror;
@@ -1339,7 +1344,8 @@ class _ParameterMirror extends _VariableMirror implements ParameterMirror {
13391344
null, // We override the type.
13401345
false, // isStatic does not apply.
13411346
isFinal,
1342-
false // Not const.
1347+
false, // Not const.
1348+
false // Not extension member.
13431349
);
13441350

13451351
Object _defaultValueReflectee;

sdk/lib/mirrors/mirrors.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,11 @@ abstract class MethodMirror implements DeclarationMirror {
10701070
*/
10711071
bool get isFactoryConstructor;
10721072

1073+
/**
1074+
* Is the reflectee an extension method?
1075+
*/
1076+
bool get isExtensionMember;
1077+
10731078
/**
10741079
* Whether this mirror is equal to [other].
10751080
*
@@ -1111,6 +1116,11 @@ abstract class VariableMirror implements DeclarationMirror {
11111116
*/
11121117
bool get isConst;
11131118

1119+
/**
1120+
* Is the reflectee an extension member?
1121+
*/
1122+
bool get isExtensionMember;
1123+
11141124
/**
11151125
* Whether this mirror is equal to [other].
11161126
*

sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class _SyntheticAccessor implements MethodMirror {
159159
bool get isExternal => false;
160160
bool get isRedirectingConstructor => false;
161161
bool get isAbstract => false;
162+
bool get isExtensionMember => false;
162163

163164
bool get isSetter => !isGetter;
164165
bool get isPrivate => _n(simpleName).startsWith('_');
@@ -195,6 +196,7 @@ class _SyntheticSetterParameter implements ParameterMirror {
195196
bool get isConst => false;
196197
bool get isFinal => true;
197198
bool get isPrivate => false;
199+
bool get isExtensionMember => false;
198200
bool get hasDefaultValue => false;
199201
InstanceMirror get defaultValue => null;
200202
SourceLocation get location => null;
@@ -1170,6 +1172,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror {
11701172
static const kFactoryCtor = 7;
11711173
static const kExternal = 8;
11721174
static const kSynthetic = 9;
1175+
static const kExtensionMember = 10;
11731176

11741177
// These offsets much be kept in sync with those in mirrors.h.
11751178
bool get isAbstract => 0 != (_kindFlags & (1 << kAbstract));
@@ -1184,6 +1187,7 @@ class _MethodMirror extends _DeclarationMirror implements MethodMirror {
11841187
bool get isFactoryConstructor => 0 != (_kindFlags & (1 << kFactoryCtor));
11851188
bool get isExternal => 0 != (_kindFlags & (1 << kExternal));
11861189
bool get isSynthetic => 0 != (_kindFlags & (1 << kSynthetic));
1190+
bool get isExtensionMember => 0 != (_kindFlags & (1 << kExtensionMember));
11871191

11881192
static const _operators = const [
11891193
"%", "&", "*", "+", "-", "/", "<", "<<", //
@@ -1283,9 +1287,10 @@ class _VariableMirror extends _DeclarationMirror implements VariableMirror {
12831287
final bool isStatic;
12841288
final bool isFinal;
12851289
final bool isConst;
1290+
final bool isExtensionMember;
12861291

12871292
_VariableMirror._(reflectee, String simpleName, this.owner, this._type,
1288-
this.isStatic, this.isFinal, this.isConst)
1293+
this.isStatic, this.isFinal, this.isConst, this.isExtensionMember)
12891294
: super._(reflectee, _s(simpleName));
12901295

12911296
bool get isTopLevel => owner is LibraryMirror;
@@ -1341,7 +1346,8 @@ class _ParameterMirror extends _VariableMirror implements ParameterMirror {
13411346
null, // We override the type.
13421347
false, // isStatic does not apply.
13431348
isFinal,
1344-
false // Not const.
1349+
false, // Not const.
1350+
false // Not extension member.
13451351
);
13461352

13471353
Object _defaultValueReflectee;

sdk_nnbd/lib/mirrors/mirrors.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,11 @@ abstract class MethodMirror implements DeclarationMirror {
10721072
*/
10731073
bool get isFactoryConstructor;
10741074

1075+
/**
1076+
* Is the reflectee an extension method?
1077+
*/
1078+
bool get isExtensionMember;
1079+
10751080
/**
10761081
* Whether this mirror is equal to [other].
10771082
*
@@ -1113,6 +1118,11 @@ abstract class VariableMirror implements DeclarationMirror {
11131118
*/
11141119
bool get isConst;
11151120

1121+
/**
1122+
* Is the reflectee an extension member?
1123+
*/
1124+
bool get isExtensionMember;
1125+
11161126
/**
11171127
* Whether this mirror is equal to [other].
11181128
*
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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+
// SharedOptions=--enable-experiment=extension-methods
6+
7+
library lib;
8+
9+
import "dart:mirrors";
10+
11+
import "package:expect/expect.dart";
12+
13+
class C<T> {
14+
static int tracefunc() {
15+
try {
16+
throw "producing a stack trace";
17+
} catch (e, s) {
18+
print(s);
19+
}
20+
return 10;
21+
}
22+
}
23+
24+
extension ext<T> on C<T> {
25+
func() {
26+
try {
27+
throw "producing a stack trace";
28+
} catch (e, s) {
29+
print(s);
30+
}
31+
}
32+
33+
get prop {
34+
try {
35+
throw "producing a stack trace";
36+
} catch (e, s) {
37+
print(s);
38+
}
39+
}
40+
41+
set prop(value) {
42+
try {
43+
throw "producing a stack trace";
44+
} catch (e, s) {
45+
print(s);
46+
}
47+
}
48+
49+
operator +(val) {
50+
try {
51+
throw "producing a stack trace";
52+
} catch (e, s) {
53+
print(s);
54+
}
55+
}
56+
57+
operator -(val) {
58+
try {
59+
throw "producing a stack trace";
60+
} catch (e, s) {
61+
print(s);
62+
}
63+
}
64+
65+
static int sfld = C.tracefunc();
66+
static sfunc() {
67+
try {
68+
throw "producing a stack trace";
69+
} catch (e, s) {
70+
print(s);
71+
}
72+
}
73+
74+
static get sprop {
75+
try {
76+
throw "producing a stack trace";
77+
} catch (e, s) {
78+
print(s);
79+
}
80+
}
81+
82+
static set sprop(value) {
83+
try {
84+
throw "producing a stack trace";
85+
} catch (e, s) {
86+
print(s);
87+
}
88+
}
89+
}
90+
91+
checkExtensionKind(closure, kind) {
92+
var closureMirror = reflect(closure) as ClosureMirror;
93+
var methodMirror = closureMirror.function;
94+
Expect.equals(kind, methodMirror.isExtensionMember, "isExtension");
95+
}
96+
97+
void testExtension(sym, mirror) {
98+
if (mirror is MethodMirror) {
99+
var methodMirror = mirror as MethodMirror;
100+
if (MirrorSystem.getName(sym).startsWith('ext', 0)) {
101+
Expect.equals(true, methodMirror.isExtensionMember, "isExtension");
102+
} else {
103+
Expect.equals(false, methodMirror.isExtensionMember, "isExtension");
104+
}
105+
} else if (mirror is VariableMirror) {
106+
var variableMirror = mirror as VariableMirror;
107+
if (MirrorSystem.getName(sym).startsWith('ext', 0)) {
108+
Expect.equals(true, variableMirror.isExtensionMember, "isExtension");
109+
} else {
110+
Expect.equals(false, variableMirror.isExtensionMember, "isExtension");
111+
}
112+
}
113+
}
114+
115+
main() {
116+
checkExtensionKind(C.tracefunc, false);
117+
118+
C c = new C();
119+
checkExtensionKind(c.func, true);
120+
checkExtensionKind(ext.sfunc, true);
121+
122+
var libraryMirror = reflectClass(C).owner as LibraryMirror;
123+
libraryMirror.declarations.forEach(testExtension);
124+
}

tests/lib_2/mirrors/method_mirror_properties_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ checkKinds(method, kinds) {
4343
Expect.equals(kinds[2], method.isGetter, "isGetter");
4444
Expect.equals(kinds[3], method.isSetter, "isSetter");
4545
Expect.equals(kinds[4], method.isConstructor, "isConstructor");
46+
Expect.equals(false, method.isExtensionMember, "isExtension");
4647
}
4748

4849
main() {

0 commit comments

Comments
 (0)