| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class NativeEmitter { | 7 class NativeEmitter { |
| 8 | 8 |
| 9 // TODO(floitsch): the native-emitter should not know about ClassBuilders. | 9 // TODO(floitsch): the native-emitter should not know about ClassBuilders. |
| 10 final Map<Element, full_js_emitter.ClassBuilder> cachedBuilders; | 10 final Map<Element, full_js_emitter.ClassBuilder> cachedBuilders; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 } else if (classesModifiedByEmitRTISupport.contains(classElement)) { | 132 } else if (classesModifiedByEmitRTISupport.contains(classElement)) { |
| 133 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer | 133 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer |
| 134 // adds information to a class prototype or constructor. | 134 // adds information to a class prototype or constructor. |
| 135 needed = true; | 135 needed = true; |
| 136 } else if (extensionPoints.containsKey(cls)) { | 136 } else if (extensionPoints.containsKey(cls)) { |
| 137 needed = true; | 137 needed = true; |
| 138 } | 138 } |
| 139 if (backend.isJsInterop(classElement)) { | 139 if (backend.isJsInterop(classElement)) { |
| 140 needed = true; // TODO(jacobr): we don't need all interop classes. | 140 needed = true; // TODO(jacobr): we don't need all interop classes. |
| 141 } else if (cls.isNative && | 141 } else if (cls.isNative && |
| 142 backend.hasNativeTagsForcedNonLeaf(classElement)) { | 142 backend.nativeData.hasNativeTagsForcedNonLeaf(classElement)) { |
| 143 needed = true; | 143 needed = true; |
| 144 nonLeafClasses.add(cls); | 144 nonLeafClasses.add(cls); |
| 145 } | 145 } |
| 146 | 146 |
| 147 if (needed || neededClasses.contains(cls)) { | 147 if (needed || neededClasses.contains(cls)) { |
| 148 neededClasses.add(cls); | 148 neededClasses.add(cls); |
| 149 neededClasses.add(cls.superclass); | 149 neededClasses.add(cls.superclass); |
| 150 nonLeafClasses.add(cls.superclass); | 150 nonLeafClasses.add(cls.superclass); |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 | 153 |
| 154 // Collect all the tags that map to each native class. | 154 // Collect all the tags that map to each native class. |
| 155 | 155 |
| 156 Map<Class, Set<String>> leafTags = new Map<Class, Set<String>>(); | 156 Map<Class, Set<String>> leafTags = new Map<Class, Set<String>>(); |
| 157 Map<Class, Set<String>> nonleafTags = new Map<Class, Set<String>>(); | 157 Map<Class, Set<String>> nonleafTags = new Map<Class, Set<String>>(); |
| 158 | 158 |
| 159 for (Class cls in classes) { | 159 for (Class cls in classes) { |
| 160 if (!cls.isNative) continue; | 160 if (!cls.isNative) continue; |
| 161 if (backend.isJsInterop(cls.element)) continue; | 161 if (backend.isJsInterop(cls.element)) continue; |
| 162 List<String> nativeTags = backend.getNativeTagsOfClass(cls.element); | 162 List<String> nativeTags = |
| 163 backend.nativeData.getNativeTagsOfClass(cls.element); |
| 163 | 164 |
| 164 if (nonLeafClasses.contains(cls) || | 165 if (nonLeafClasses.contains(cls) || |
| 165 extensionPoints.containsKey(cls)) { | 166 extensionPoints.containsKey(cls)) { |
| 166 nonleafTags | 167 nonleafTags |
| 167 .putIfAbsent(cls, () => new Set<String>()) | 168 .putIfAbsent(cls, () => new Set<String>()) |
| 168 .addAll(nativeTags); | 169 .addAll(nativeTags); |
| 169 } else { | 170 } else { |
| 170 Class sufficingInterceptor = cls; | 171 Class sufficingInterceptor = cls; |
| 171 while (!neededClasses.contains(sufficingInterceptor)) { | 172 while (!neededClasses.contains(sufficingInterceptor)) { |
| 172 sufficingInterceptor = sufficingInterceptor.superclass; | 173 sufficingInterceptor = sufficingInterceptor.superclass; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 List<jsAst.Statement> statements = <jsAst.Statement>[]; | 309 List<jsAst.Statement> statements = <jsAst.Statement>[]; |
| 309 potentiallyConvertDartClosuresToJs(statements, member, stubParameters); | 310 potentiallyConvertDartClosuresToJs(statements, member, stubParameters); |
| 310 | 311 |
| 311 String target; | 312 String target; |
| 312 jsAst.Expression receiver; | 313 jsAst.Expression receiver; |
| 313 List<jsAst.Expression> arguments; | 314 List<jsAst.Expression> arguments; |
| 314 | 315 |
| 315 assert(invariant(member, nativeMethods.contains(member))); | 316 assert(invariant(member, nativeMethods.contains(member))); |
| 316 // When calling a JS method, we call it with the native name, and only the | 317 // When calling a JS method, we call it with the native name, and only the |
| 317 // arguments up until the last one provided. | 318 // arguments up until the last one provided. |
| 318 target = backend.getFixedBackendName(member); | 319 target = backend.nativeData.getFixedBackendName(member); |
| 319 | 320 |
| 320 if (isInterceptedMethod) { | 321 if (isInterceptedMethod) { |
| 321 receiver = argumentsBuffer[0]; | 322 receiver = argumentsBuffer[0]; |
| 322 arguments = argumentsBuffer.sublist(1, | 323 arguments = argumentsBuffer.sublist(1, |
| 323 indexOfLastOptionalArgumentInParameters + 1); | 324 indexOfLastOptionalArgumentInParameters + 1); |
| 324 } else { | 325 } else { |
| 325 // Native methods that are not intercepted must be static. | 326 // Native methods that are not intercepted must be static. |
| 326 assert(invariant(member, member.isStatic)); | 327 assert(invariant(member, member.isStatic)); |
| 327 arguments = argumentsBuffer.sublist(0, | 328 arguments = argumentsBuffer.sublist(0, |
| 328 indexOfLastOptionalArgumentInParameters + 1); | 329 indexOfLastOptionalArgumentInParameters + 1); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 359 // used. We should also use an interceptor if the check can't be satisfied | 360 // used. We should also use an interceptor if the check can't be satisfied |
| 360 // by a native class in case we get a native instance that tries to spoof | 361 // by a native class in case we get a native instance that tries to spoof |
| 361 // the type info. i.e the criteria for whether or not to use an interceptor | 362 // the type info. i.e the criteria for whether or not to use an interceptor |
| 362 // is whether the receiver can be native, not the type of the test. | 363 // is whether the receiver can be native, not the type of the test. |
| 363 if (element == null || !element.isClass) return false; | 364 if (element == null || !element.isClass) return false; |
| 364 ClassElement cls = element; | 365 ClassElement cls = element; |
| 365 if (backend.isNativeOrExtendsNative(cls)) return true; | 366 if (backend.isNativeOrExtendsNative(cls)) return true; |
| 366 return isSupertypeOfNativeClass(element); | 367 return isSupertypeOfNativeClass(element); |
| 367 } | 368 } |
| 368 } | 369 } |
| OLD | NEW |