OLD | NEW |
---|---|
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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.interceptor_data; | 5 library js_backend.interceptor_data; |
6 | 6 |
7 import '../common/names.dart' show Identifiers; | 7 import '../common/names.dart' show Identifiers; |
8 import '../common/resolution.dart' show Resolution; | |
8 import '../common_elements.dart' show CommonElements; | 9 import '../common_elements.dart' show CommonElements; |
9 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
10 import '../elements/entities.dart'; | 11 import '../elements/entities.dart'; |
11 import '../elements/types.dart'; | 12 import '../elements/types.dart'; |
12 import '../js/js.dart' as jsAst; | 13 import '../js/js.dart' as jsAst; |
13 import '../types/types.dart' show TypeMask; | 14 import '../types/types.dart' show TypeMask; |
14 import '../universe/selector.dart'; | 15 import '../universe/selector.dart'; |
15 import '../world.dart' show ClosedWorld; | 16 import '../world.dart' show ClosedWorld; |
16 import 'backend_helpers.dart'; | 17 import 'backend_helpers.dart'; |
17 import 'namer.dart'; | 18 import 'namer.dart'; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 ClassEntity classElement = interfaceType.element; | 210 ClassEntity classElement = interfaceType.element; |
210 if (isInterceptedClass(classElement)) return false; | 211 if (isInterceptedClass(classElement)) return false; |
211 return _closedWorld.hasOnlySubclasses(classElement); | 212 return _closedWorld.hasOnlySubclasses(classElement); |
212 } | 213 } |
213 } | 214 } |
214 | 215 |
215 class InterceptorDataBuilderImpl implements InterceptorDataBuilder { | 216 class InterceptorDataBuilderImpl implements InterceptorDataBuilder { |
216 final NativeData _nativeData; | 217 final NativeData _nativeData; |
217 final BackendHelpers _helpers; | 218 final BackendHelpers _helpers; |
218 final CommonElements _commonElements; | 219 final CommonElements _commonElements; |
220 final Resolution _resolution; | |
Siggi Cherem (dart-lang)
2017/03/14 03:35:17
any chance that we are guaranteed that cls argumen
Johnni Winther
2017/03/15 10:10:20
Still investigating. It will be gone soon!
| |
219 | 221 |
220 /// The members of instantiated interceptor classes: maps a member name to the | 222 /// The members of instantiated interceptor classes: maps a member name to the |
221 /// list of members that have that name. This map is used by the codegen to | 223 /// list of members that have that name. This map is used by the codegen to |
222 /// know whether a send must be intercepted or not. | 224 /// know whether a send must be intercepted or not. |
223 final Map<String, Set<Element>> _interceptedElements = | 225 final Map<String, Set<Element>> _interceptedElements = |
224 <String, Set<Element>>{}; | 226 <String, Set<Element>>{}; |
225 | 227 |
226 /// Set of classes whose methods are intercepted. | 228 /// Set of classes whose methods are intercepted. |
227 final Set<ClassElement> _interceptedClasses = new Set<ClassElement>(); | 229 final Set<ClassElement> _interceptedClasses = new Set<ClassElement>(); |
228 | 230 |
229 /// Set of classes used as mixins on intercepted (native and primitive) | 231 /// Set of classes used as mixins on intercepted (native and primitive) |
230 /// classes. Methods on these classes might also be mixed in to regular Dart | 232 /// classes. Methods on these classes might also be mixed in to regular Dart |
231 /// (unintercepted) classes. | 233 /// (unintercepted) classes. |
232 final Set<ClassElement> _classesMixedIntoInterceptedClasses = | 234 final Set<ClassElement> _classesMixedIntoInterceptedClasses = |
233 new Set<ClassElement>(); | 235 new Set<ClassElement>(); |
234 | 236 |
235 InterceptorDataBuilderImpl( | 237 InterceptorDataBuilderImpl( |
236 this._nativeData, this._helpers, this._commonElements); | 238 this._nativeData, this._helpers, this._commonElements, this._resolution); |
237 | 239 |
238 InterceptorData onResolutionComplete(ClosedWorld closedWorld) { | 240 InterceptorData onResolutionComplete(ClosedWorld closedWorld) { |
239 return new InterceptorDataImpl( | 241 return new InterceptorDataImpl( |
240 _nativeData, | 242 _nativeData, |
241 _helpers, | 243 _helpers, |
242 closedWorld, | 244 closedWorld, |
243 _interceptedElements, | 245 _interceptedElements, |
244 _interceptedClasses, | 246 _interceptedClasses, |
245 _classesMixedIntoInterceptedClasses); | 247 _classesMixedIntoInterceptedClasses); |
246 } | 248 } |
247 | 249 |
248 void addInterceptorsForNativeClassMembers(ClassElement cls) { | 250 void addInterceptorsForNativeClassMembers(ClassElement cls) { |
251 cls.ensureResolved(_resolution); | |
249 cls.forEachMember((ClassElement classElement, Element member) { | 252 cls.forEachMember((ClassElement classElement, Element member) { |
250 if (member.name == Identifiers.call) { | 253 if (member.name == Identifiers.call) { |
251 return; | 254 return; |
252 } | 255 } |
253 if (member.isSynthesized) return; | 256 if (member.isSynthesized) return; |
254 // All methods on [Object] are shadowed by [Interceptor]. | 257 // All methods on [Object] are shadowed by [Interceptor]. |
255 if (classElement == _commonElements.objectClass) return; | 258 if (classElement == _commonElements.objectClass) return; |
256 Set<Element> set = _interceptedElements.putIfAbsent( | 259 Set<Element> set = _interceptedElements.putIfAbsent( |
257 member.name, () => new Set<Element>()); | 260 member.name, () => new Set<Element>()); |
258 set.add(member); | 261 set.add(member); |
259 }, includeSuperAndInjectedMembers: true); | 262 }, includeSuperAndInjectedMembers: true); |
260 | 263 |
261 // Walk superclass chain to find mixins. | 264 // Walk superclass chain to find mixins. |
262 for (; cls != null; cls = cls.superclass) { | 265 for (; cls != null; cls = cls.superclass) { |
263 if (cls.isMixinApplication) { | 266 if (cls.isMixinApplication) { |
264 MixinApplicationElement mixinApplication = cls; | 267 MixinApplicationElement mixinApplication = cls; |
265 _classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); | 268 _classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); |
266 } | 269 } |
267 } | 270 } |
268 } | 271 } |
269 | 272 |
270 void addInterceptors(ClassElement cls) { | 273 void addInterceptors(ClassElement cls) { |
271 if (_interceptedClasses.add(cls)) { | 274 if (_interceptedClasses.add(cls)) { |
275 cls.ensureResolved(_resolution); | |
272 cls.forEachMember((ClassElement classElement, Element member) { | 276 cls.forEachMember((ClassElement classElement, Element member) { |
273 // All methods on [Object] are shadowed by [Interceptor]. | 277 // All methods on [Object] are shadowed by [Interceptor]. |
274 if (classElement == _commonElements.objectClass) return; | 278 if (classElement == _commonElements.objectClass) return; |
275 Set<Element> set = _interceptedElements.putIfAbsent( | 279 Set<Element> set = _interceptedElements.putIfAbsent( |
276 member.name, () => new Set<Element>()); | 280 member.name, () => new Set<Element>()); |
277 set.add(member); | 281 set.add(member); |
278 }, includeSuperAndInjectedMembers: true); | 282 }, includeSuperAndInjectedMembers: true); |
279 } | 283 } |
280 _interceptedClasses.add(_helpers.jsInterceptorClass); | 284 _interceptedClasses.add(_helpers.jsInterceptorClass); |
281 } | 285 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 jsAst.Name name = namer.nameForGetInterceptor(classes); | 332 jsAst.Name name = namer.nameForGetInterceptor(classes); |
329 if (classes.contains(_helpers.jsInterceptorClass)) { | 333 if (classes.contains(_helpers.jsInterceptorClass)) { |
330 // We can't use a specialized [getInterceptorMethod], so we make | 334 // We can't use a specialized [getInterceptorMethod], so we make |
331 // sure we emit the one with all checks. | 335 // sure we emit the one with all checks. |
332 _specializedGetInterceptors[name] = _interceptorData.interceptedClasses; | 336 _specializedGetInterceptors[name] = _interceptorData.interceptedClasses; |
333 } else { | 337 } else { |
334 _specializedGetInterceptors[name] = classes; | 338 _specializedGetInterceptors[name] = classes; |
335 } | 339 } |
336 } | 340 } |
337 } | 341 } |
OLD | NEW |