Chromium Code Reviews| 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 |