Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: pkg/compiler/lib/src/js_backend/native_data.dart

Issue 2998543002: Handle js interop members in impact computation. (Closed)
Patch Set: Updated cf. comments. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library js_backend.native_data; 5 library js_backend.native_data;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common_elements.dart' show ElementEnvironment; 8 import '../common_elements.dart' show ElementEnvironment;
9 import '../elements/entities.dart'; 9 import '../elements/entities.dart';
10 import '../native/behavior.dart' show NativeBehavior; 10 import '../native/behavior.dart' show NativeBehavior;
(...skipping 20 matching lines...) Expand all
31 bool isNativeOrExtendsNative(ClassEntity element); 31 bool isNativeOrExtendsNative(ClassEntity element);
32 32
33 /// Returns `true` if js interop features are used. 33 /// Returns `true` if js interop features are used.
34 bool get isJsInteropUsed; 34 bool get isJsInteropUsed;
35 35
36 /// Returns `true` if [element] is a JsInterop library. 36 /// Returns `true` if [element] is a JsInterop library.
37 bool isJsInteropLibrary(LibraryEntity element); 37 bool isJsInteropLibrary(LibraryEntity element);
38 38
39 /// Returns `true` if [element] is a JsInterop class. 39 /// Returns `true` if [element] is a JsInterop class.
40 bool isJsInteropClass(ClassEntity element); 40 bool isJsInteropClass(ClassEntity element);
41
42 /// Returns `true` if [element] is a JsInterop member.
43 bool isJsInteropMember(MemberEntity element);
41 } 44 }
42 45
43 /// Additional element information for native classes and methods and js-interop 46 /// Additional element information for native classes and methods and js-interop
44 /// methods. 47 /// methods.
45 /// 48 ///
46 /// This information is computed during resolution using [NativeDataBuilder]. 49 /// This information is computed during resolution using [NativeDataBuilder].
47 abstract class NativeData extends NativeBasicData { 50 abstract class NativeData extends NativeBasicData {
48 /// Returns `true` if [element] corresponds to a native JavaScript member. 51 /// Returns `true` if [element] corresponds to a native JavaScript member.
49 /// 52 ///
50 /// A member is marked as native either through the native mechanism 53 /// A member is marked as native either through the native mechanism
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 100 }
98 101
99 abstract class NativeBasicDataBuilder { 102 abstract class NativeBasicDataBuilder {
100 /// Sets the native tag info for [cls]. 103 /// Sets the native tag info for [cls].
101 /// 104 ///
102 /// The tag info string contains comma-separated 'words' which are either 105 /// The tag info string contains comma-separated 'words' which are either
103 /// dispatch tags (having JavaScript identifier syntax) and directives that 106 /// dispatch tags (having JavaScript identifier syntax) and directives that
104 /// begin with `!`. 107 /// begin with `!`.
105 void setNativeClassTagInfo(ClassEntity cls, String tagInfo); 108 void setNativeClassTagInfo(ClassEntity cls, String tagInfo);
106 109
107 /// Marks [element] as an explicit part of JsInterop. The js interop name is 110 /// Marks [element] as an explicit part of js interop.
108 /// expected to be computed later. 111 ///
109 void markAsJsInteropLibrary(LibraryEntity element); 112 /// If [name] is provided, it sets the explicit js interop name for the
113 /// library [element], other the js interop name is expected to be computed
114 /// later.
115 void markAsJsInteropLibrary(LibraryEntity element, {String name});
110 116
111 /// Marks [element] as an explicit part of JsInterop. The js interop name is 117 /// Marks [element] as an explicit part of js interop.
112 /// expected to be computed later. 118 ///
113 void markAsJsInteropClass(ClassEntity element); 119 /// If [name] is provided, it sets the explicit js interop name for the
120 /// class [element], other the js interop name is expected to be computed
121 /// later.
122 void markAsJsInteropClass(ClassEntity element,
123 {String name, bool isAnonymous: false});
124
125 /// Marks [element] as an explicit part of js interop and sets the explicit js
126 /// interop [name] for the member [element].
127 void markAsJsInteropMember(MemberEntity element, String name);
114 128
115 /// Creates the [NativeBasicData] object for the data collected in this 129 /// Creates the [NativeBasicData] object for the data collected in this
116 /// builder. 130 /// builder.
117 NativeBasicData close(ElementEnvironment environment); 131 NativeBasicData close(ElementEnvironment environment);
118 } 132 }
119 133
120 abstract class NativeDataBuilder { 134 abstract class NativeDataBuilder {
121 /// Registers the [behavior] for calling the native [method]. 135 /// Registers the [behavior] for calling the native [method].
122 void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior); 136 void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior);
123 137
124 /// Registers the [behavior] for reading from the native [field]. 138 /// Registers the [behavior] for reading from the native [field].
125 void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior); 139 void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior);
126 140
127 /// Registers the [behavior] for writing to the native [field]. 141 /// Registers the [behavior] for writing to the native [field].
128 void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior); 142 void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior);
129 143
130 /// Returns [element] as an explicit part of JsInterop. The js interop name is 144 /// Marks [element] as an explicit part of JsInterop. The js interop name is
131 /// expected to be computed later. 145 /// expected to be computed later.
132 void markAsJsInteropMember(MemberEntity element); 146 void markAsJsInteropMember(MemberEntity element);
133 147
134 /// Sets the native [name] for the member [element]. This name is used for 148 /// Sets the native [name] for the member [element]. This name is used for
135 /// [element] in the generated JavaScript. 149 /// [element] in the generated JavaScript.
136 void setNativeMemberName(MemberEntity element, String name); 150 void setNativeMemberName(MemberEntity element, String name);
137 151
138 /// Sets the explicit js interop [name] for the library [element]. 152 /// Sets the explicit js interop [name] for the library [element].
139 void setJsInteropLibraryName(LibraryEntity element, String name); 153 void setJsInteropLibraryName(LibraryEntity element, String name);
140 154
(...skipping 10 matching lines...) Expand all
151 NativeData close(); 165 NativeData close();
152 } 166 }
153 167
154 class NativeBasicDataBuilderImpl implements NativeBasicDataBuilder { 168 class NativeBasicDataBuilderImpl implements NativeBasicDataBuilder {
155 /// Tag info for native JavaScript classes names. See 169 /// Tag info for native JavaScript classes names. See
156 /// [setNativeClassTagInfo]. 170 /// [setNativeClassTagInfo].
157 Map<ClassEntity, NativeClassTag> nativeClassTagInfo = 171 Map<ClassEntity, NativeClassTag> nativeClassTagInfo =
158 <ClassEntity, NativeClassTag>{}; 172 <ClassEntity, NativeClassTag>{};
159 173
160 /// The JavaScript libraries implemented via typed JavaScript interop. 174 /// The JavaScript libraries implemented via typed JavaScript interop.
161 Set<LibraryEntity> jsInteropLibraries = new Set<LibraryEntity>(); 175 Map<LibraryEntity, String> jsInteropLibraries = <LibraryEntity, String>{};
162 176
163 /// The JavaScript classes implemented via typed JavaScript interop. 177 /// The JavaScript classes implemented via typed JavaScript interop.
164 Set<ClassEntity> jsInteropClasses = new Set<ClassEntity>(); 178 Map<ClassEntity, String> jsInteropClasses = <ClassEntity, String>{};
179
180 /// JavaScript interop classes annotated with `@anonymous`
181 Set<ClassEntity> anonymousJsInteropClasses = new Set<ClassEntity>();
182
183 /// The JavaScript members implemented via typed JavaScript interop.
184 Map<MemberEntity, String> jsInteropMembers = <MemberEntity, String>{};
165 185
166 /// Sets the native tag info for [cls]. 186 /// Sets the native tag info for [cls].
167 /// 187 ///
168 /// The tag info string contains comma-separated 'words' which are either 188 /// The tag info string contains comma-separated 'words' which are either
169 /// dispatch tags (having JavaScript identifier syntax) and directives that 189 /// dispatch tags (having JavaScript identifier syntax) and directives that
170 /// begin with `!`. 190 /// begin with `!`.
171 void setNativeClassTagInfo(ClassEntity cls, String tagText) { 191 void setNativeClassTagInfo(ClassEntity cls, String tagText) {
172 // TODO(johnniwinther): Assert that this is only called once. The memory 192 // TODO(johnniwinther): Assert that this is only called once. The memory
173 // compiler copies pre-processed elements into a new compiler through 193 // compiler copies pre-processed elements into a new compiler through
174 // [Compiler.onLibraryScanned] and thereby causes multiple calls to this 194 // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
175 // method. 195 // method.
176 assert( 196 assert(
177 nativeClassTagInfo[cls] == null || 197 nativeClassTagInfo[cls] == null ||
178 nativeClassTagInfo[cls].text == tagText, 198 nativeClassTagInfo[cls].text == tagText,
179 failedAt( 199 failedAt(
180 cls, 200 cls,
181 "Native tag info set inconsistently on $cls: " 201 "Native tag info set inconsistently on $cls: "
182 "Existing tag info '${nativeClassTagInfo[cls]}', " 202 "Existing tag info '${nativeClassTagInfo[cls]}', "
183 "new tag info '$tagText'.")); 203 "new tag info '$tagText'."));
184 nativeClassTagInfo[cls] = new NativeClassTag(tagText); 204 nativeClassTagInfo[cls] = new NativeClassTag(tagText);
185 } 205 }
186 206
187 @override 207 @override
188 void markAsJsInteropLibrary(LibraryEntity element) { 208 void markAsJsInteropLibrary(LibraryEntity element, {String name}) {
189 jsInteropLibraries.add(element); 209 jsInteropLibraries[element] = name;
190 } 210 }
191 211
192 @override 212 @override
193 void markAsJsInteropClass(ClassEntity element) { 213 void markAsJsInteropClass(ClassEntity element,
194 jsInteropClasses.add(element); 214 {String name, bool isAnonymous: false}) {
215 jsInteropClasses[element] = name;
216 if (isAnonymous) {
217 anonymousJsInteropClasses.add(element);
218 }
219 }
220
221 @override
222 void markAsJsInteropMember(MemberEntity element, String name) {
223 jsInteropMembers[element] = name;
195 } 224 }
196 225
197 NativeBasicData close(ElementEnvironment environment) { 226 NativeBasicData close(ElementEnvironment environment) {
198 return new NativeBasicDataImpl( 227 return new NativeBasicDataImpl(
199 environment, nativeClassTagInfo, jsInteropLibraries, jsInteropClasses); 228 environment,
229 nativeClassTagInfo,
230 jsInteropLibraries,
231 jsInteropClasses,
232 anonymousJsInteropClasses,
233 jsInteropMembers);
200 } 234 }
201 } 235 }
202 236
203 class NativeBasicDataImpl implements NativeBasicData { 237 class NativeBasicDataImpl implements NativeBasicData {
204 final ElementEnvironment _env; 238 final ElementEnvironment _env;
205 239
206 /// Tag info for native JavaScript classes names. See 240 /// Tag info for native JavaScript classes names. See
207 /// [setNativeClassTagInfo]. 241 /// [setNativeClassTagInfo].
208 final Map<ClassEntity, NativeClassTag> nativeClassTagInfo; 242 final Map<ClassEntity, NativeClassTag> nativeClassTagInfo;
209 243
210 /// The JavaScript libraries implemented via typed JavaScript interop. 244 /// The JavaScript libraries implemented via typed JavaScript interop.
211 final Set<LibraryEntity> jsInteropLibraries; 245 final Map<LibraryEntity, String> jsInteropLibraries;
212 246
213 /// The JavaScript classes implemented via typed JavaScript interop. 247 /// The JavaScript classes implemented via typed JavaScript interop.
214 final Set<ClassEntity> jsInteropClasses; 248 final Map<ClassEntity, String> jsInteropClasses;
215 249
216 NativeBasicDataImpl(this._env, this.nativeClassTagInfo, 250 /// JavaScript interop classes annotated with `@anonymous`
217 this.jsInteropLibraries, this.jsInteropClasses); 251 final Set<ClassEntity> anonymousJsInteropClasses;
218 252
219 /// Returns `true` if [cls] is a native class. 253 /// The JavaScript members implemented via typed JavaScript interop.
254 final Map<MemberEntity, String> jsInteropMembers;
255
256 NativeBasicDataImpl(
257 this._env,
258 this.nativeClassTagInfo,
259 this.jsInteropLibraries,
260 this.jsInteropClasses,
261 this.anonymousJsInteropClasses,
262 this.jsInteropMembers);
263
264 @override
220 bool isNativeClass(ClassEntity element) { 265 bool isNativeClass(ClassEntity element) {
221 if (isJsInteropClass(element)) return true; 266 if (isJsInteropClass(element)) return true;
222 return nativeClassTagInfo.containsKey(element); 267 return nativeClassTagInfo.containsKey(element);
223 } 268 }
224 269
225 /// Returns the list of non-directive native tag words for [cls]. 270 @override
226 List<String> getNativeTagsOfClass(ClassEntity cls) { 271 List<String> getNativeTagsOfClass(ClassEntity cls) {
227 return nativeClassTagInfo[cls].names; 272 return nativeClassTagInfo[cls].names;
228 } 273 }
229 274
230 /// Returns `true` if [cls] has a `!nonleaf` tag word. 275 @override
231 bool hasNativeTagsForcedNonLeaf(ClassEntity cls) { 276 bool hasNativeTagsForcedNonLeaf(ClassEntity cls) {
232 return nativeClassTagInfo[cls].isNonLeaf; 277 return nativeClassTagInfo[cls].isNonLeaf;
233 } 278 }
234 279
280 @override
235 bool get isJsInteropUsed => 281 bool get isJsInteropUsed =>
236 jsInteropLibraries.isNotEmpty || jsInteropClasses.isNotEmpty; 282 jsInteropLibraries.isNotEmpty || jsInteropClasses.isNotEmpty;
237 283
238 /// Returns `true` if [element] is explicitly marked as part of JsInterop. 284 @override
239 bool isJsInteropLibrary(LibraryEntity element) { 285 bool isJsInteropLibrary(LibraryEntity element) {
240 return jsInteropLibraries.contains(element); 286 return jsInteropLibraries.containsKey(element);
241 } 287 }
242 288
243 /// Returns `true` if [element] is explicitly marked as part of JsInterop. 289 @override
244 bool isJsInteropClass(ClassEntity element) { 290 bool isJsInteropClass(ClassEntity element) {
245 return jsInteropClasses.contains(element); 291 return jsInteropClasses.containsKey(element);
246 } 292 }
247 293
248 /// Returns `true` if [element] or any of its superclasses is native. 294 @override
295 bool isJsInteropMember(MemberEntity element) {
296 return jsInteropMembers.containsKey(element);
297 }
298
299 @override
249 bool isNativeOrExtendsNative(ClassEntity element) { 300 bool isNativeOrExtendsNative(ClassEntity element) {
250 if (element == null) return false; 301 if (element == null) return false;
251 if (isNativeClass(element) || isJsInteropClass(element)) { 302 if (isNativeClass(element) || isJsInteropClass(element)) {
252 return true; 303 return true;
253 } 304 }
254 return isNativeOrExtendsNative(_env.getSuperClass(element)); 305 return isNativeOrExtendsNative(_env.getSuperClass(element));
255 } 306 }
256 } 307 }
257 308
258 class NativeDataBuilderImpl implements NativeDataBuilder { 309 class NativeDataBuilderImpl implements NativeDataBuilder {
259 final NativeBasicData _nativeBasicData; 310 final NativeBasicDataImpl _nativeBasicData;
260 311
261 /// The JavaScript names for native JavaScript elements implemented. 312 /// The JavaScript names for native JavaScript elements implemented.
262 Map<MemberEntity, String> nativeMemberName = <MemberEntity, String>{}; 313 Map<MemberEntity, String> nativeMemberName = <MemberEntity, String>{};
263 314
264 /// Cache for [NativeBehavior]s for calling native methods. 315 /// Cache for [NativeBehavior]s for calling native methods.
265 Map<FunctionEntity, NativeBehavior> nativeMethodBehavior = 316 Map<FunctionEntity, NativeBehavior> nativeMethodBehavior =
266 <FunctionEntity, NativeBehavior>{}; 317 <FunctionEntity, NativeBehavior>{};
267 318
268 /// Cache for [NativeBehavior]s for reading from native fields. 319 /// Cache for [NativeBehavior]s for reading from native fields.
269 Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = 320 Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior =
270 <FieldEntity, NativeBehavior>{}; 321 <FieldEntity, NativeBehavior>{};
271 322
272 /// Cache for [NativeBehavior]s for writing to native fields. 323 /// Cache for [NativeBehavior]s for writing to native fields.
273 Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior = 324 Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior =
274 <FieldEntity, NativeBehavior>{}; 325 <FieldEntity, NativeBehavior>{};
275 326
276 /// The JavaScript names for libraries implemented via typed JavaScript 327 /// The JavaScript names for libraries implemented via typed JavaScript
277 /// interop. 328 /// interop.
278 Map<LibraryEntity, String> jsInteropLibraryNames = <LibraryEntity, String>{}; 329 final Map<LibraryEntity, String> jsInteropLibraries;
279 330
280 /// JavaScript interop classes annotated with `@anonymous` 331 /// JavaScript interop classes annotated with `@anonymous`
281 Set<ClassEntity> anonymousJsInteropClasses = new Set<ClassEntity>(); 332 final Set<ClassEntity> anonymousJsInteropClasses;
282 333
283 /// The JavaScript names for classes implemented via typed JavaScript 334 /// The JavaScript names for classes implemented via typed JavaScript
284 /// interop. 335 /// interop.
285 Map<ClassEntity, String> jsInteropClassNames = <ClassEntity, String>{}; 336 final Map<ClassEntity, String> jsInteropClasses;
286 337
287 /// The JavaScript names for members implemented via typed JavaScript 338 /// The JavaScript names for members implemented via typed JavaScript
288 /// interop. 339 /// interop.
289 Map<MemberEntity, String> jsInteropMemberNames = <MemberEntity, String>{}; 340 final Map<MemberEntity, String> jsInteropMembers;
290 341
291 NativeDataBuilderImpl(this._nativeBasicData); 342 NativeDataBuilderImpl(this._nativeBasicData)
343 : jsInteropLibraries = _nativeBasicData.jsInteropLibraries,
344 jsInteropClasses = _nativeBasicData.jsInteropClasses,
345 anonymousJsInteropClasses = _nativeBasicData.anonymousJsInteropClasses,
346 jsInteropMembers = _nativeBasicData.jsInteropMembers;
292 347
293 /// Sets the native [name] for the member [element]. This name is used for 348 /// Sets the native [name] for the member [element]. This name is used for
294 /// [element] in the generated JavaScript. 349 /// [element] in the generated JavaScript.
295 void setNativeMemberName(MemberEntity element, String name) { 350 void setNativeMemberName(MemberEntity element, String name) {
296 // TODO(johnniwinther): Avoid setting this more than once. The enqueuer 351 // TODO(johnniwinther): Avoid setting this more than once. The enqueuer
297 // might enqueue [element] several times (before processing it) and computes 352 // might enqueue [element] several times (before processing it) and computes
298 // name on each call to `internalAddToWorkList`. 353 // name on each call to `internalAddToWorkList`.
299 assert( 354 assert(
300 nativeMemberName[element] == null || nativeMemberName[element] == name, 355 nativeMemberName[element] == null || nativeMemberName[element] == name,
301 failedAt( 356 failedAt(
(...skipping 18 matching lines...) Expand all
320 void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior) { 375 void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior) {
321 nativeFieldStoreBehavior[field] = behavior; 376 nativeFieldStoreBehavior[field] = behavior;
322 } 377 }
323 378
324 /// Sets the explicit js interop [name] for the library [element]. 379 /// Sets the explicit js interop [name] for the library [element].
325 void setJsInteropLibraryName(LibraryEntity element, String name) { 380 void setJsInteropLibraryName(LibraryEntity element, String name) {
326 assert( 381 assert(
327 _nativeBasicData.isJsInteropLibrary(element), 382 _nativeBasicData.isJsInteropLibrary(element),
328 failedAt(element, 383 failedAt(element,
329 'Library $element is not js interop but given a js interop name.')); 384 'Library $element is not js interop but given a js interop name.'));
330 jsInteropLibraryNames[element] = name; 385 jsInteropLibraries[element] = name;
331 } 386 }
332 387
333 @override 388 @override
334 void markJsInteropClassAsAnonymous(ClassEntity element) { 389 void markJsInteropClassAsAnonymous(ClassEntity element) {
335 anonymousJsInteropClasses.add(element); 390 anonymousJsInteropClasses.add(element);
336 } 391 }
337 392
338 /// Sets the explicit js interop [name] for the class [element]. 393 /// Sets the explicit js interop [name] for the class [element].
339 void setJsInteropClassName(ClassEntity element, String name) { 394 void setJsInteropClassName(ClassEntity element, String name) {
340 assert( 395 assert(
341 _nativeBasicData.isJsInteropClass(element), 396 _nativeBasicData.isJsInteropClass(element),
342 failedAt(element, 397 failedAt(element,
343 'Class $element is not js interop but given a js interop name.')); 398 'Class $element is not js interop but given a js interop name.'));
344 jsInteropClassNames[element] = name; 399 jsInteropClasses[element] = name;
345 } 400 }
346 401
347 @override 402 @override
348 void markAsJsInteropMember(MemberEntity element) { 403 void markAsJsInteropMember(MemberEntity element) {
349 jsInteropMemberNames[element] = null; 404 jsInteropMembers[element] = null;
350 } 405 }
351 406
352 /// Sets the explicit js interop [name] for the member [element]. 407 /// Sets the explicit js interop [name] for the member [element].
353 void setJsInteropMemberName(MemberEntity element, String name) { 408 void setJsInteropMemberName(MemberEntity element, String name) {
354 assert( 409 assert(
355 jsInteropMemberNames.containsKey(element), 410 jsInteropMembers.containsKey(element),
356 failedAt(element, 411 failedAt(element,
357 'Member $element is not js interop but given a js interop name.')); 412 'Member $element is not js interop but given a js interop name.'));
358 jsInteropMemberNames[element] = name; 413 jsInteropMembers[element] = name;
359 } 414 }
360 415
361 @override 416 @override
362 NativeData close() => new NativeDataImpl( 417 NativeData close() => new NativeDataImpl(
363 _nativeBasicData, 418 _nativeBasicData,
364 nativeMemberName, 419 nativeMemberName,
365 nativeMethodBehavior, 420 nativeMethodBehavior,
366 nativeFieldLoadBehavior, 421 nativeFieldLoadBehavior,
367 nativeFieldStoreBehavior, 422 nativeFieldStoreBehavior,
368 jsInteropLibraryNames, 423 jsInteropLibraries,
369 anonymousJsInteropClasses, 424 anonymousJsInteropClasses,
370 jsInteropClassNames, 425 jsInteropClasses,
371 jsInteropMemberNames); 426 jsInteropMembers);
372 } 427 }
373 428
374 class NativeDataImpl implements NativeData, NativeBasicDataImpl { 429 class NativeDataImpl implements NativeData, NativeBasicDataImpl {
375 /// Prefix used to escape JS names that are not valid Dart names 430 /// Prefix used to escape JS names that are not valid Dart names
376 /// when using JSInterop. 431 /// when using JSInterop.
377 static const String _jsInteropEscapePrefix = r'JS$'; 432 static const String _jsInteropEscapePrefix = r'JS$';
378 433
379 final NativeBasicDataImpl _nativeBasicData; 434 final NativeBasicDataImpl _nativeBasicData;
380 435
381 /// The JavaScript names for native JavaScript elements implemented. 436 /// The JavaScript names for native JavaScript elements implemented.
382 final Map<MemberEntity, String> nativeMemberName; 437 final Map<MemberEntity, String> nativeMemberName;
383 438
384 /// Cache for [NativeBehavior]s for calling native methods. 439 /// Cache for [NativeBehavior]s for calling native methods.
385 final Map<FunctionEntity, NativeBehavior> nativeMethodBehavior; 440 final Map<FunctionEntity, NativeBehavior> nativeMethodBehavior;
386 441
387 /// Cache for [NativeBehavior]s for reading from native fields. 442 /// Cache for [NativeBehavior]s for reading from native fields.
388 final Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior; 443 final Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior;
389 444
390 /// Cache for [NativeBehavior]s for writing to native fields. 445 /// Cache for [NativeBehavior]s for writing to native fields.
391 final Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior; 446 final Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior;
392 447
393 /// The JavaScript names for libraries implemented via typed JavaScript 448 /// The JavaScript names for libraries implemented via typed JavaScript
394 /// interop. 449 /// interop.
395 final Map<LibraryEntity, String> jsInteropLibraryNames; 450 final Map<LibraryEntity, String> jsInteropLibraries;
396 451
397 /// JavaScript interop classes annotated with `@anonymous` 452 /// JavaScript interop classes annotated with `@anonymous`
398 final Set<ClassEntity> anonymousJsInteropClasses; 453 final Set<ClassEntity> anonymousJsInteropClasses;
399 454
400 /// The JavaScript names for classes implemented via typed JavaScript 455 /// The JavaScript names for classes implemented via typed JavaScript
401 /// interop. 456 /// interop.
402 final Map<ClassEntity, String> jsInteropClassNames; 457 final Map<ClassEntity, String> jsInteropClasses;
403 458
404 /// The JavaScript names for members implemented via typed JavaScript 459 /// The JavaScript names for members implemented via typed JavaScript
405 /// interop. 460 /// interop.
406 final Map<MemberEntity, String> jsInteropMemberNames; 461 final Map<MemberEntity, String> jsInteropMembers;
407 462
408 NativeDataImpl( 463 NativeDataImpl(
409 this._nativeBasicData, 464 this._nativeBasicData,
410 this.nativeMemberName, 465 this.nativeMemberName,
411 this.nativeMethodBehavior, 466 this.nativeMethodBehavior,
412 this.nativeFieldLoadBehavior, 467 this.nativeFieldLoadBehavior,
413 this.nativeFieldStoreBehavior, 468 this.nativeFieldStoreBehavior,
414 this.jsInteropLibraryNames, 469 this.jsInteropLibraries,
415 this.anonymousJsInteropClasses, 470 this.anonymousJsInteropClasses,
416 this.jsInteropClassNames, 471 this.jsInteropClasses,
417 this.jsInteropMemberNames); 472 this.jsInteropMembers);
418 473
419 @override 474 @override
420 bool isAnonymousJsInteropClass(ClassEntity element) { 475 bool isAnonymousJsInteropClass(ClassEntity element) {
421 return anonymousJsInteropClasses.contains(element); 476 return anonymousJsInteropClasses.contains(element);
422 } 477 }
423 478
424 /// Returns `true` if [cls] is a native class. 479 /// Returns `true` if [cls] is a native class.
425 bool isNativeClass(ClassEntity element) => 480 bool isNativeClass(ClassEntity element) =>
426 _nativeBasicData.isNativeClass(element); 481 _nativeBasicData.isNativeClass(element);
427 482
(...skipping 14 matching lines...) Expand all
442 /// Returns `true` if [element] is a JsInterop class. 497 /// Returns `true` if [element] is a JsInterop class.
443 bool isJsInteropClass(ClassEntity element) => 498 bool isJsInteropClass(ClassEntity element) =>
444 _nativeBasicData.isJsInteropClass(element); 499 _nativeBasicData.isJsInteropClass(element);
445 500
446 /// Returns `true` if [element] or any of its superclasses is native. 501 /// Returns `true` if [element] or any of its superclasses is native.
447 bool isNativeOrExtendsNative(ClassEntity element) => 502 bool isNativeOrExtendsNative(ClassEntity element) =>
448 _nativeBasicData.isNativeOrExtendsNative(element); 503 _nativeBasicData.isNativeOrExtendsNative(element);
449 504
450 /// Returns the explicit js interop name for library [element]. 505 /// Returns the explicit js interop name for library [element].
451 String getJsInteropLibraryName(LibraryEntity element) { 506 String getJsInteropLibraryName(LibraryEntity element) {
452 return jsInteropLibraryNames[element]; 507 return jsInteropLibraries[element];
453 } 508 }
454 509
455 /// Returns the explicit js interop name for class [element]. 510 /// Returns the explicit js interop name for class [element].
456 String getJsInteropClassName(ClassEntity element) { 511 String getJsInteropClassName(ClassEntity element) {
457 return jsInteropClassNames[element]; 512 return jsInteropClasses[element];
458 } 513 }
459 514
460 /// Returns the explicit js interop name for member [element]. 515 /// Returns the explicit js interop name for member [element].
461 String getJsInteropMemberName(MemberEntity element) { 516 String getJsInteropMemberName(MemberEntity element) {
462 return jsInteropMemberNames[element]; 517 return jsInteropMembers[element];
463 } 518 }
464 519
465 /// Returns `true` if [element] is explicitly marked as part of JsInterop. 520 /// Returns `true` if [element] is explicitly marked as part of JsInterop.
466 bool _isJsInteropMember(MemberEntity element) { 521 bool _isJsInteropMember(MemberEntity element) {
467 return jsInteropMemberNames.containsKey(element); 522 return jsInteropMembers.containsKey(element);
468 } 523 }
469 524
470 /// Returns `true` if [element] is a JsInterop method. 525 /// Returns `true` if [element] is a JsInterop method.
471 bool isJsInteropMember(MemberEntity element) { 526 bool isJsInteropMember(MemberEntity element) {
472 if (element.isFunction || 527 if (element.isFunction ||
473 element.isConstructor || 528 element.isConstructor ||
474 element.isGetter || 529 element.isGetter ||
475 element.isSetter) { 530 element.isSetter) {
476 FunctionEntity function = element; 531 FunctionEntity function = element;
477 if (!function.isExternal) return false; 532 if (!function.isExternal) return false;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 return 'self'; 571 return 'self';
517 } 572 }
518 573
519 String _jsClassNameHelper(ClassEntity element) { 574 String _jsClassNameHelper(ClassEntity element) {
520 String jsInteropName = getJsInteropClassName(element); 575 String jsInteropName = getJsInteropClassName(element);
521 if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName; 576 if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName;
522 return computeUnescapedJSInteropName(element.name); 577 return computeUnescapedJSInteropName(element.name);
523 } 578 }
524 579
525 String _jsMemberNameHelper(MemberEntity element) { 580 String _jsMemberNameHelper(MemberEntity element) {
526 String jsInteropName = jsInteropMemberNames[element]; 581 String jsInteropName = jsInteropMembers[element];
527 assert( 582 assert(
528 !(jsInteropMemberNames.containsKey(element) && jsInteropName == null), 583 !(jsInteropMembers.containsKey(element) && jsInteropName == null),
529 failedAt( 584 failedAt(
530 element, 585 element,
531 'Member $element is js interop but js interop name has not yet ' 586 'Member $element is js interop but js interop name has not yet '
532 'been computed.')); 587 'been computed.'));
533 if (jsInteropName != null && jsInteropName.isNotEmpty) { 588 if (jsInteropName != null && jsInteropName.isNotEmpty) {
534 return jsInteropName; 589 return jsInteropName;
535 } 590 }
536 return computeUnescapedJSInteropName(element.name); 591 return computeUnescapedJSInteropName(element.name);
537 } 592 }
538 593
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 653
599 /// Apply JS$ escaping scheme to convert possible escaped Dart names into 654 /// Apply JS$ escaping scheme to convert possible escaped Dart names into
600 /// JS names. 655 /// JS names.
601 String computeUnescapedJSInteropName(String name) { 656 String computeUnescapedJSInteropName(String name) {
602 return name.startsWith(_jsInteropEscapePrefix) 657 return name.startsWith(_jsInteropEscapePrefix)
603 ? name.substring(_jsInteropEscapePrefix.length) 658 ? name.substring(_jsInteropEscapePrefix.length)
604 : name; 659 : name;
605 } 660 }
606 661
607 @override 662 @override
608 Set<ClassEntity> get jsInteropClasses => _nativeBasicData.jsInteropClasses;
609
610 @override
611 Set<LibraryEntity> get jsInteropLibraries =>
612 _nativeBasicData.jsInteropLibraries;
613
614 @override
615 Map<ClassEntity, NativeClassTag> get nativeClassTagInfo => 663 Map<ClassEntity, NativeClassTag> get nativeClassTagInfo =>
616 _nativeBasicData.nativeClassTagInfo; 664 _nativeBasicData.nativeClassTagInfo;
617 665
618 @override 666 @override
619 ElementEnvironment get _env => _nativeBasicData._env; 667 ElementEnvironment get _env => _nativeBasicData._env;
620 } 668 }
621 669
622 class NativeClassTag { 670 class NativeClassTag {
623 final List<String> names; 671 final List<String> names;
624 final bool isNonLeaf; 672 final bool isNonLeaf;
(...skipping 22 matching lines...) Expand all
647 int get hashCode => Hashing.listHash(names, isNonLeaf.hashCode); 695 int get hashCode => Hashing.listHash(names, isNonLeaf.hashCode);
648 696
649 bool operator ==(other) { 697 bool operator ==(other) {
650 if (identical(this, other)) return true; 698 if (identical(this, other)) return true;
651 if (other is! NativeClassTag) return false; 699 if (other is! NativeClassTag) return false;
652 return equalElements(names, other.names) && isNonLeaf == other.isNonLeaf; 700 return equalElements(names, other.names) && isNonLeaf == other.isNonLeaf;
653 } 701 }
654 702
655 String toString() => text; 703 String toString() => text;
656 } 704 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend_serialization.dart ('k') | pkg/compiler/lib/src/js_model/js_strategy.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698