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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart

Issue 266913017: Convert property methods into getters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
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 js_backend; 5 part of js_backend;
6 6
7 class NativeEmitter { 7 class NativeEmitter {
8 8
9 CodeEmitterTask emitter; 9 CodeEmitterTask emitter;
10 CodeBuffer nativeBuffer; 10 CodeBuffer nativeBuffer;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 walk(element.superclass); 84 walk(element.superclass);
85 preOrder.add(element); 85 preOrder.add(element);
86 } 86 }
87 classes.forEach(walk); 87 classes.forEach(walk);
88 88
89 // Generate code for each native class into [ClassBuilder]s. 89 // Generate code for each native class into [ClassBuilder]s.
90 90
91 Map<ClassElement, ClassBuilder> builders = 91 Map<ClassElement, ClassBuilder> builders =
92 new Map<ClassElement, ClassBuilder>(); 92 new Map<ClassElement, ClassBuilder>();
93 for (ClassElement classElement in classes) { 93 for (ClassElement classElement in classes) {
94 if (classElement.isNative()) { 94 if (classElement.isNative) {
95 ClassBuilder builder = generateNativeClass(classElement); 95 ClassBuilder builder = generateNativeClass(classElement);
96 builders[classElement] = builder; 96 builders[classElement] = builder;
97 } 97 }
98 } 98 }
99 99
100 // Find which classes are needed and which are non-leaf classes. Any class 100 // Find which classes are needed and which are non-leaf classes. Any class
101 // that is not needed can be treated as a leaf class equivalent to some 101 // that is not needed can be treated as a leaf class equivalent to some
102 // needed class. 102 // needed class.
103 103
104 Set<ClassElement> neededClasses = new Set<ClassElement>(); 104 Set<ClassElement> neededClasses = new Set<ClassElement>();
(...skipping 24 matching lines...) Expand all
129 needed = true; 129 needed = true;
130 } else if (neededByConstant.contains(classElement)) { 130 } else if (neededByConstant.contains(classElement)) {
131 needed = true; 131 needed = true;
132 } else if (modifiedClasses.contains(classElement)) { 132 } else if (modifiedClasses.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(classElement)) { 136 } else if (extensionPoints.containsKey(classElement)) {
137 needed = true; 137 needed = true;
138 } 138 }
139 if (classElement.isNative() && 139 if (classElement.isNative &&
140 native.nativeTagsForcedNonLeaf(classElement)) { 140 native.nativeTagsForcedNonLeaf(classElement)) {
141 needed = true; 141 needed = true;
142 nonleafClasses.add(classElement); 142 nonleafClasses.add(classElement);
143 } 143 }
144 144
145 if (needed || neededClasses.contains(classElement)) { 145 if (needed || neededClasses.contains(classElement)) {
146 neededClasses.add(classElement); 146 neededClasses.add(classElement);
147 neededClasses.add(classElement.superclass); 147 neededClasses.add(classElement.superclass);
148 nonleafClasses.add(classElement.superclass); 148 nonleafClasses.add(classElement.superclass);
149 } 149 }
150 } 150 }
151 151
152 // Collect all the tags that map to each native class. 152 // Collect all the tags that map to each native class.
153 153
154 Map<ClassElement, Set<String>> leafTags = 154 Map<ClassElement, Set<String>> leafTags =
155 new Map<ClassElement, Set<String>>(); 155 new Map<ClassElement, Set<String>>();
156 Map<ClassElement, Set<String>> nonleafTags = 156 Map<ClassElement, Set<String>> nonleafTags =
157 new Map<ClassElement, Set<String>>(); 157 new Map<ClassElement, Set<String>>();
158 158
159 for (ClassElement classElement in classes) { 159 for (ClassElement classElement in classes) {
160 if (!classElement.isNative()) continue; 160 if (!classElement.isNative) continue;
161 List<String> nativeTags = native.nativeTagsOfClass(classElement); 161 List<String> nativeTags = native.nativeTagsOfClass(classElement);
162 162
163 if (nonleafClasses.contains(classElement) || 163 if (nonleafClasses.contains(classElement) ||
164 extensionPoints.containsKey(classElement)) { 164 extensionPoints.containsKey(classElement)) {
165 nonleafTags 165 nonleafTags
166 .putIfAbsent(classElement, () => new Set<String>()) 166 .putIfAbsent(classElement, () => new Set<String>())
167 .addAll(nativeTags); 167 .addAll(nativeTags);
168 } else { 168 } else {
169 ClassElement sufficingInterceptor = classElement; 169 ClassElement sufficingInterceptor = classElement;
170 while (!neededClasses.contains(sufficingInterceptor)) { 170 while (!neededClasses.contains(sufficingInterceptor)) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 } 227 }
228 } 228 }
229 generateClassInfo(backend.jsInterceptorClass); 229 generateClassInfo(backend.jsInterceptorClass);
230 for (ClassElement classElement in classes) { 230 for (ClassElement classElement in classes) {
231 generateClassInfo(classElement); 231 generateClassInfo(classElement);
232 } 232 }
233 } 233 }
234 234
235 // Emit the native class interceptors that were actually used. 235 // Emit the native class interceptors that were actually used.
236 for (ClassElement classElement in classes) { 236 for (ClassElement classElement in classes) {
237 if (!classElement.isNative()) continue; 237 if (!classElement.isNative) continue;
238 if (neededClasses.contains(classElement)) { 238 if (neededClasses.contains(classElement)) {
239 // Define interceptor class for [classElement]. 239 // Define interceptor class for [classElement].
240 emitter.classEmitter.emitClassBuilderWithReflectionData( 240 emitter.classEmitter.emitClassBuilderWithReflectionData(
241 backend.namer.getNameOfClass(classElement), 241 backend.namer.getNameOfClass(classElement),
242 classElement, builders[classElement], 242 classElement, builders[classElement],
243 emitter.getElementDecriptor(classElement)); 243 emitter.getElementDecriptor(classElement));
244 emitter.needsDefineClass = true; 244 emitter.needsDefineClass = true;
245 } 245 }
246 } 246 }
247 } 247 }
248 248
249 /** 249 /**
250 * Computes the native classes that are extended (subclassed) by non-native 250 * Computes the native classes that are extended (subclassed) by non-native
251 * classes and the set non-mative classes that extend them. (A List is used 251 * classes and the set non-mative classes that extend them. (A List is used
252 * instead of a Set for out stability). 252 * instead of a Set for out stability).
253 */ 253 */
254 Map<ClassElement, List<ClassElement>> computeExtensionPoints( 254 Map<ClassElement, List<ClassElement>> computeExtensionPoints(
255 List<ClassElement> classes) { 255 List<ClassElement> classes) {
256 ClassElement nativeSuperclassOf(ClassElement element) { 256 ClassElement nativeSuperclassOf(ClassElement element) {
257 if (element == null) return null; 257 if (element == null) return null;
258 if (element.isNative()) return element; 258 if (element.isNative) return element;
259 return nativeSuperclassOf(element.superclass); 259 return nativeSuperclassOf(element.superclass);
260 } 260 }
261 261
262 ClassElement nativeAncestorOf(ClassElement element) { 262 ClassElement nativeAncestorOf(ClassElement element) {
263 return nativeSuperclassOf(element.superclass); 263 return nativeSuperclassOf(element.superclass);
264 } 264 }
265 265
266 Map<ClassElement, List<ClassElement>> map = 266 Map<ClassElement, List<ClassElement>> map =
267 new Map<ClassElement, List<ClassElement>>(); 267 new Map<ClassElement, List<ClassElement>>();
268 268
269 for (ClassElement classElement in classes) { 269 for (ClassElement classElement in classes) {
270 if (classElement.isNative()) continue; 270 if (classElement.isNative) continue;
271 ClassElement nativeAncestor = nativeAncestorOf(classElement); 271 ClassElement nativeAncestor = nativeAncestorOf(classElement);
272 if (nativeAncestor != null) { 272 if (nativeAncestor != null) {
273 map 273 map
274 .putIfAbsent(nativeAncestor, () => <ClassElement>[]) 274 .putIfAbsent(nativeAncestor, () => <ClassElement>[])
275 .add(classElement); 275 .add(classElement);
276 } 276 }
277 } 277 }
278 return map; 278 return map;
279 } 279 }
280 280
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 List<jsAst.Statement> statements = <jsAst.Statement>[]; 369 List<jsAst.Statement> statements = <jsAst.Statement>[];
370 potentiallyConvertDartClosuresToJs(statements, member, stubParameters); 370 potentiallyConvertDartClosuresToJs(statements, member, stubParameters);
371 371
372 String target; 372 String target;
373 jsAst.Expression receiver; 373 jsAst.Expression receiver;
374 List<jsAst.Expression> arguments; 374 List<jsAst.Expression> arguments;
375 375
376 assert(invariant(member, nativeMethods.contains(member))); 376 assert(invariant(member, nativeMethods.contains(member)));
377 // When calling a JS method, we call it with the native name, and only the 377 // When calling a JS method, we call it with the native name, and only the
378 // arguments up until the last one provided. 378 // arguments up until the last one provided.
379 target = member.fixedBackendName(); 379 target = member.fixedBackendName;
380 380
381 if (isInterceptedMethod) { 381 if (isInterceptedMethod) {
382 receiver = argumentsBuffer[0]; 382 receiver = argumentsBuffer[0];
383 arguments = argumentsBuffer.sublist(1, 383 arguments = argumentsBuffer.sublist(1,
384 indexOfLastOptionalArgumentInParameters + 1); 384 indexOfLastOptionalArgumentInParameters + 1);
385 } else { 385 } else {
386 receiver = js('this'); 386 receiver = js('this');
387 arguments = argumentsBuffer.sublist(0, 387 arguments = argumentsBuffer.sublist(0,
388 indexOfLastOptionalArgumentInParameters + 1); 388 indexOfLastOptionalArgumentInParameters + 1);
389 } 389 }
390 statements.add( 390 statements.add(
391 js.statement('return #.#(#)', [receiver, target, arguments])); 391 js.statement('return #.#(#)', [receiver, target, arguments]));
392 392
393 return statements; 393 return statements;
394 } 394 }
395 395
396 bool isSupertypeOfNativeClass(Element element) { 396 bool isSupertypeOfNativeClass(Element element) {
397 if (element.isTypeVariable()) { 397 if (element.isTypeVariable) {
398 compiler.internalError(element, "Is check for type variable."); 398 compiler.internalError(element, "Is check for type variable.");
399 return false; 399 return false;
400 } 400 }
401 if (element.computeType(compiler).unalias(compiler) is FunctionType) { 401 if (element.computeType(compiler).unalias(compiler) is FunctionType) {
402 // The element type is a function type either directly or through 402 // The element type is a function type either directly or through
403 // typedef(s). 403 // typedef(s).
404 return false; 404 return false;
405 } 405 }
406 406
407 if (!element.isClass()) { 407 if (!element.isClass) {
408 compiler.internalError(element, "Is check does not handle element."); 408 compiler.internalError(element, "Is check does not handle element.");
409 return false; 409 return false;
410 } 410 }
411 411
412 if (backend.classesMixedIntoInterceptedClasses.contains(element)) { 412 if (backend.classesMixedIntoInterceptedClasses.contains(element)) {
413 return true; 413 return true;
414 } 414 }
415 415
416 return subtypes[element] != null; 416 return subtypes[element] != null;
417 } 417 }
418 418
419 bool requiresNativeIsCheck(Element element) { 419 bool requiresNativeIsCheck(Element element) {
420 // TODO(sra): Remove this function. It determines if a native type may 420 // TODO(sra): Remove this function. It determines if a native type may
421 // satisfy a check against [element], in which case an interceptor must be 421 // satisfy a check against [element], in which case an interceptor must be
422 // used. We should also use an interceptor if the check can't be satisfied 422 // used. We should also use an interceptor if the check can't be satisfied
423 // by a native class in case we get a native instance that tries to spoof 423 // by a native class in case we get a native instance that tries to spoof
424 // the type info. i.e the criteria for whether or not to use an interceptor 424 // the type info. i.e the criteria for whether or not to use an interceptor
425 // is whether the receiver can be native, not the type of the test. 425 // is whether the receiver can be native, not the type of the test.
426 if (!element.isClass()) return false; 426 if (!element.isClass) return false;
427 ClassElement cls = element; 427 ClassElement cls = element;
428 if (Elements.isNativeOrExtendsNative(cls)) return true; 428 if (Elements.isNativeOrExtendsNative(cls)) return true;
429 return isSupertypeOfNativeClass(element); 429 return isSupertypeOfNativeClass(element);
430 } 430 }
431 431
432 void assembleCode(CodeBuffer targetBuffer) { 432 void assembleCode(CodeBuffer targetBuffer) {
433 List<jsAst.Property> objectProperties = <jsAst.Property>[]; 433 List<jsAst.Property> objectProperties = <jsAst.Property>[];
434 434
435 void addProperty(String name, jsAst.Expression value) { 435 void addProperty(String name, jsAst.Expression value) {
436 objectProperties.add(new jsAst.Property(js.string(name), value)); 436 objectProperties.add(new jsAst.Property(js.string(name), value));
(...skipping 21 matching lines...) Expand all
458 if (emitter.compiler.enableMinification) targetBuffer.add(';'); 458 if (emitter.compiler.enableMinification) targetBuffer.add(';');
459 targetBuffer.add(jsAst.prettyPrint( 459 targetBuffer.add(jsAst.prettyPrint(
460 new jsAst.ExpressionStatement(init), compiler)); 460 new jsAst.ExpressionStatement(init), compiler));
461 targetBuffer.add('\n'); 461 targetBuffer.add('\n');
462 } 462 }
463 463
464 targetBuffer.add(nativeBuffer); 464 targetBuffer.add(nativeBuffer);
465 targetBuffer.add('\n'); 465 targetBuffer.add('\n');
466 } 466 }
467 } 467 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698