| 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 /** | 5 /** |
| 6 * Generates the code for all used classes in the program. Static fields (even | 6 * Generates the code for all used classes in the program. Static fields (even |
| 7 * in classes) are ignored, since they can be treated as non-class elements. | 7 * in classes) are ignored, since they can be treated as non-class elements. |
| 8 * | 8 * |
| 9 * The code for the containing (used) methods must exist in the [:universe:]. | 9 * The code for the containing (used) methods must exist in the [:universe:]. |
| 10 */ | 10 */ |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 count++; | 127 count++; |
| 128 }); | 128 }); |
| 129 buffer.add('${Strings.join(parametersBuffer, ",")}) {\n'); | 129 buffer.add('${Strings.join(parametersBuffer, ",")}) {\n'); |
| 130 String arguments = Strings.join(argumentsBuffer, ","); | 130 String arguments = Strings.join(argumentsBuffer, ","); |
| 131 | 131 |
| 132 if (isNative) { | 132 if (isNative) { |
| 133 nativeEmitter.emitParameterStub( | 133 nativeEmitter.emitParameterStub( |
| 134 member, invocationName, arguments, buffer); | 134 member, invocationName, arguments, buffer); |
| 135 } else { | 135 } else { |
| 136 buffer.add(' return this.${namer.getName(member)}($arguments)'); | 136 buffer.add(' return this.${namer.getName(member)}($arguments)'); |
| 137 } | 137 } |
| 138 buffer.add('\n}\n'); | 138 buffer.add('\n}\n'); |
| 139 } | 139 } |
| 140 | 140 |
| 141 void addParameterStubs(FunctionElement member, | 141 void addParameterStubs(FunctionElement member, |
| 142 String attachTo(String invocationName), | 142 String attachTo(String invocationName), |
| 143 StringBuffer buffer, | 143 StringBuffer buffer, |
| 144 [bool isNative = false]) { | 144 [bool isNative = false]) { |
| 145 Set<Selector> selectors = compiler.universe.invokedNames[member.name]; | 145 Set<Selector> selectors = compiler.universe.invokedNames[member.name]; |
| 146 if (selectors == null) return; | 146 if (selectors == null) return; |
| 147 for (Selector selector in selectors) { | 147 for (Selector selector in selectors) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 if (member.isInstanceMember()) { | 255 if (member.isInstanceMember()) { |
| 256 addInstanceMember(member, prototype, buffer); | 256 addInstanceMember(member, prototype, buffer); |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 for (Element member in classElement.backendMembers) { | 259 for (Element member in classElement.backendMembers) { |
| 260 if (member.isInstanceMember()) { | 260 if (member.isInstanceMember()) { |
| 261 addInstanceMember(member, prototype, buffer); | 261 addInstanceMember(member, prototype, buffer); |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 buffer.add('$prototype.${namer.operatorIs(classElement)} = true;\n'); | 264 buffer.add('$prototype.${namer.operatorIs(classElement)} = true;\n'); |
| 265 for (Type ifc in classElement.interfaces) { | 265 generateInterfacesIsTests(buffer, prototype, classElement); |
| 266 buffer.add('$prototype.${namer.operatorIs(ifc.element)} = true;\n'); | 266 if (superclass === null) { |
| 267 // JS "toString" wrapper. This gives better exceptions. The |
| 268 // function must handle the situation where builtin$toString$0 |
| 269 // is not generated. |
| 270 buffer.add(''' |
| 271 $prototype.toString = function() { |
| 272 try { |
| 273 if (typeof ${namer.CURRENT_ISOLATE}.builtin\$toString\$0\$1 == 'function') { |
| 274 return ${namer.CURRENT_ISOLATE}.builtin\$toString\$0\$1(this); |
| 275 } else { |
| 276 var name = this.constructor.name; |
| 277 if (typeof name != 'string') { |
| 278 name = this.constructor.toString(); |
| 279 name = name.match(/^\s*function\s*(\S*)\s*\(/)[1]; |
| 280 } |
| 281 return "Instance of '" + name +"'"; |
| 267 } | 282 } |
| 268 if (superclass === null) { | 283 } catch (ex) { |
| 269 // JS "toString" wrapper. This gives better exceptions. | 284 return "uncaught exception in toString"; |
| 270 buffer.add('$prototype.toString = function() {\n'); | 285 } |
| 271 buffer.add(' try {'); | 286 }; |
| 272 buffer.add(' return ${namer.CURRENT_ISOLATE}'); | 287 '''); |
| 273 buffer.add('.builtin\$toString\$0\$1(this);'); | |
| 274 buffer.add(' } catch (ex) {'); | |
| 275 buffer.add(' return "uncaught exception in toString";'); | |
| 276 buffer.add(' }'); | |
| 277 buffer.add('};\n'); | |
| 278 | 288 |
| 279 // Emit the noSuchMethods on the Object prototype now, so that | 289 // Emit the noSuchMethods on the Object prototype now, so that |
| 280 // the code in the dynamicMethod can find them. Note that the | 290 // the code in the dynamicMethod can find them. Note that the |
| 281 // code in dynamicMethod is invoked before analyzing the full JS | 291 // code in dynamicMethod is invoked before analyzing the full JS |
| 282 // script. | 292 // script. |
| 283 emitNoSuchMethodCalls(buffer); | 293 emitNoSuchMethodCalls(buffer); |
| 284 } | 294 } |
| 285 } | 295 } |
| 286 | 296 |
| 297 void generateInterfacesIsTests(StringBuffer buffer, String prototype, |
| 298 ClassElement cls) { |
| 299 for (Type ifc in cls.interfaces) { |
| 300 buffer.add('$prototype.${namer.operatorIs(ifc.element)} = true;\n'); |
| 301 generateInterfacesIsTests(buffer, prototype, ifc.element); |
| 302 } |
| 303 } |
| 304 |
| 287 void emitClasses(StringBuffer buffer) { | 305 void emitClasses(StringBuffer buffer) { |
| 288 Set seenClasses = new Set<ClassElement>(); | 306 Set seenClasses = new Set<ClassElement>(); |
| 289 for (ClassElement element in compiler.universe.instantiatedClasses) { | 307 for (ClassElement element in compiler.universe.instantiatedClasses) { |
| 290 generateClass(element, buffer, seenClasses); | 308 generateClass(element, buffer, seenClasses); |
| 291 } | 309 } |
| 292 } | 310 } |
| 293 | 311 |
| 294 void emitStaticFunctionsWithNamer(StringBuffer buffer, | 312 void emitStaticFunctionsWithNamer(StringBuffer buffer, |
| 295 Map<Element, String> generatedCode, | 313 Map<Element, String> generatedCode, |
| 296 String functionNamer(Element element)) { | 314 String functionNamer(Element element)) { |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 if (!member.isInstanceMember()) continue; | 484 if (!member.isInstanceMember()) continue; |
| 467 if (member.kind == ElementKind.GETTER || | 485 if (member.kind == ElementKind.GETTER || |
| 468 member.kind == ElementKind.FIELD) { | 486 member.kind == ElementKind.FIELD) { |
| 469 Set<Selector> selectors = | 487 Set<Selector> selectors = |
| 470 compiler.universe.invokedNames[member.name]; | 488 compiler.universe.invokedNames[member.name]; |
| 471 if (selectors == null || selectors.isEmpty()) continue; | 489 if (selectors == null || selectors.isEmpty()) continue; |
| 472 emitCallStubForGetter(buffer, currentClass, member, selectors); | 490 emitCallStubForGetter(buffer, currentClass, member, selectors); |
| 473 } | 491 } |
| 474 } | 492 } |
| 475 } | 493 } |
| 476 } | 494 } |
| 477 } | 495 } |
| 478 | 496 |
| 479 void emitStaticNonFinalFieldInitializations(StringBuffer buffer) { | 497 void emitStaticNonFinalFieldInitializations(StringBuffer buffer) { |
| 480 // Adds initializations inside the Isolate constructor. | 498 // Adds initializations inside the Isolate constructor. |
| 481 // Example: | 499 // Example: |
| 482 // function Isolate() { | 500 // function Isolate() { |
| 483 // this.staticNonFinal = Isolate.prototype.someVal; | 501 // this.staticNonFinal = Isolate.prototype.someVal; |
| 484 // ... | 502 // ... |
| 485 // } | 503 // } |
| 486 CompileTimeConstantHandler handler = compiler.compileTimeConstantHandler; | 504 CompileTimeConstantHandler handler = compiler.compileTimeConstantHandler; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 emitCompileTimeConstants(buffer); | 609 emitCompileTimeConstants(buffer); |
| 592 emitStaticFinalFieldInitializations(buffer); | 610 emitStaticFinalFieldInitializations(buffer); |
| 593 buffer.add('var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); | 611 buffer.add('var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); |
| 594 Element main = compiler.mainApp.find(Compiler.MAIN); | 612 Element main = compiler.mainApp.find(Compiler.MAIN); |
| 595 buffer.add('${namer.isolateAccess(main)}();\n'); | 613 buffer.add('${namer.isolateAccess(main)}();\n'); |
| 596 compiler.assembledCode = buffer.toString(); | 614 compiler.assembledCode = buffer.toString(); |
| 597 }); | 615 }); |
| 598 return compiler.assembledCode; | 616 return compiler.assembledCode; |
| 599 } | 617 } |
| 600 } | 618 } |
| OLD | NEW |