Chromium Code Reviews| 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 /** | 7 /** |
| 8 * Generates the code for all used classes in the program. Static fields (even | 8 * Generates the code for all used classes in the program. Static fields (even |
| 9 * in classes) are ignored, since they can be treated as non-class elements. | 9 * in classes) are ignored, since they can be treated as non-class elements. |
| 10 * | 10 * |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 var finishedClasses = {}; | 409 var finishedClasses = {}; |
| 410 init.interceptorsByTag = Object.create(null); | 410 init.interceptorsByTag = Object.create(null); |
| 411 init.leafTags = {}; | 411 init.leafTags = {}; |
| 412 | 412 |
| 413 #; // buildFinishClass(), | 413 #; // buildFinishClass(), |
| 414 | 414 |
| 415 #; // buildTrivialNsmHandlers() | 415 #; // buildTrivialNsmHandlers() |
| 416 | 416 |
| 417 for (var cls in pendingClasses) finishClass(cls); | 417 for (var cls in pendingClasses) finishClass(cls); |
| 418 }''', [ | 418 }''', [ |
| 419 DEBUG_FAST_OBJECTS, | 419 DEBUG_FAST_OBJECTS, |
| 420 backend.hasRetainedMetadata, | 420 backend.hasRetainedMetadata, |
| 421 needsMixinSupport, | 421 needsMixinSupport, |
| 422 backend.isTreeShakingDisabled, | 422 backend.isTreeShakingDisabled, |
| 423 buildFinishClass(), | 423 buildFinishClass(), |
| 424 nsmEmitter.buildTrivialNsmHandlers()]); | 424 nsmEmitter.buildTrivialNsmHandlers()]); |
| 425 | 425 |
|
karlklose
2014/04/28 14:04:25
Delete line?
floitsch
2014/04/30 19:04:38
Done.
| |
| 426 } | 426 } |
| 427 | 427 |
| 428 jsAst.Node optional(bool condition, jsAst.Node node) { | 428 jsAst.Node optional(bool condition, jsAst.Node node) { |
| 429 return condition ? node : new jsAst.EmptyStatement(); | 429 return condition ? node : new jsAst.EmptyStatement(); |
| 430 } | 430 } |
| 431 | 431 |
| 432 jsAst.FunctionDeclaration buildFinishClass() { | 432 jsAst.FunctionDeclaration buildFinishClass() { |
| 433 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" | 433 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" |
| 434 | 434 |
| 435 return js.statement(''' | 435 return js.statement(''' |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 return [ | 608 return [ |
| 609 js('$finishIsolateConstructorName = #', finishIsolateConstructorFunction) | 609 js('$finishIsolateConstructorName = #', finishIsolateConstructorFunction) |
| 610 ]; | 610 ]; |
| 611 } | 611 } |
| 612 | 612 |
| 613 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { | 613 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { |
| 614 String isolate = namer.isolateName; | 614 String isolate = namer.isolateName; |
| 615 buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N"); | 615 buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N"); |
| 616 } | 616 } |
| 617 | 617 |
| 618 /// In minified mode we want to keep the name for the most common core types. | |
| 619 bool _isNativeTypeNeedingReflectionName(Element element) { | |
| 620 if (!element.isClass()) return false; | |
| 621 return (element == compiler.intClass || | |
| 622 element == compiler.doubleClass || | |
| 623 element == compiler.numClass || | |
| 624 element == compiler.stringClass || | |
| 625 element == compiler.boolClass || | |
| 626 element == compiler.nullClass || | |
| 627 element == compiler.listClass); | |
| 628 } | |
| 629 | |
| 618 /// Returns the "reflection name" of an [Element] or [Selector]. | 630 /// Returns the "reflection name" of an [Element] or [Selector]. |
| 619 /// The reflection name of a getter 'foo' is 'foo'. | 631 /// The reflection name of a getter 'foo' is 'foo'. |
| 620 /// The reflection name of a setter 'foo' is 'foo='. | 632 /// The reflection name of a setter 'foo' is 'foo='. |
| 621 /// The reflection name of a method 'foo' is 'foo:N:M:O', where N is the | 633 /// The reflection name of a method 'foo' is 'foo:N:M:O', where N is the |
| 622 /// number of required arguments, M is the number of optional arguments, and | 634 /// number of required arguments, M is the number of optional arguments, and |
| 623 /// O is the named arguments. | 635 /// O is the named arguments. |
| 624 /// The reflection name of a constructor is similar to a regular method but | 636 /// The reflection name of a constructor is similar to a regular method but |
| 625 /// starts with 'new '. | 637 /// starts with 'new '. |
| 626 /// The reflection name of class 'C' is 'C'. | 638 /// The reflection name of class 'C' is 'C'. |
| 627 /// An anonymous mixin application has no reflection name. | 639 /// An anonymous mixin application has no reflection name. |
| 628 /// This is used by js_mirrors.dart. | 640 /// This is used by js_mirrors.dart. |
| 629 String getReflectionName(elementOrSelector, String mangledName) { | 641 String getReflectionName(elementOrSelector, String mangledName) { |
| 630 String name = elementOrSelector.name; | 642 String name = elementOrSelector.name; |
| 631 if (!backend.shouldRetainName(name)) { | 643 if (backend.shouldRetainName(name) || |
| 632 if (name == '' && elementOrSelector is Element) { | 644 elementOrSelector is Element && |
| 633 // Make sure to retain names of unnamed constructors. | 645 // Make sure to retain names of unnamed constructors, and |
| 634 if (!backend.isNeededForReflection(elementOrSelector)) return null; | 646 // for common native types. |
| 635 } else { | 647 (name == '' && backend.isNeededForReflection(elementOrSelector) || |
| 636 return null; | 648 _isNativeTypeNeedingReflectionName(elementOrSelector))) { |
| 637 } | 649 |
| 650 // TODO(ahe): Enable the next line when I can tell the difference between | |
| 651 // an instance method and a global. They may have the same mangled name. | |
| 652 // if (recordedMangledNames.contains(mangledName)) return null; | |
| 653 recordedMangledNames.add(mangledName); | |
| 654 return getReflectionNameInternal(elementOrSelector, mangledName); | |
| 638 } | 655 } |
| 639 // TODO(ahe): Enable the next line when I can tell the difference between | 656 return null; |
| 640 // an instance method and a global. They may have the same mangled name. | |
| 641 // if (recordedMangledNames.contains(mangledName)) return null; | |
| 642 recordedMangledNames.add(mangledName); | |
| 643 return getReflectionNameInternal(elementOrSelector, mangledName); | |
| 644 } | 657 } |
| 645 | 658 |
| 646 String getReflectionNameInternal(elementOrSelector, String mangledName) { | 659 String getReflectionNameInternal(elementOrSelector, String mangledName) { |
| 647 String name = elementOrSelector.name; | 660 String name = elementOrSelector.name; |
| 648 if (elementOrSelector.isGetter()) return name; | 661 if (elementOrSelector.isGetter()) return name; |
| 649 if (elementOrSelector.isSetter()) { | 662 if (elementOrSelector.isSetter()) { |
| 650 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; | 663 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; |
| 651 String base = mangledName.substring(namer.setterPrefix.length); | 664 String base = mangledName.substring(namer.setterPrefix.length); |
| 652 String getter = '${namer.getterPrefix}$base'; | 665 String getter = '${namer.getterPrefix}$base'; |
| 653 mangledFieldNames[getter] = name; | 666 mangledFieldNames[getter] = name; |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1131 // neededClasses must only contain classes that have been resolved and | 1144 // neededClasses must only contain classes that have been resolved and |
| 1132 // codegen'd. The rtiNeededClasses may contain additional classes, but | 1145 // codegen'd. The rtiNeededClasses may contain additional classes, but |
| 1133 // these are thought to not have been instantiated, so we neeed to be able | 1146 // these are thought to not have been instantiated, so we neeed to be able |
| 1134 // to identify them later and make sure we only emit "empty shells" without | 1147 // to identify them later and make sure we only emit "empty shells" without |
| 1135 // fields, etc. | 1148 // fields, etc. |
| 1136 typeTestEmitter.computeRtiNeededClasses(); | 1149 typeTestEmitter.computeRtiNeededClasses(); |
| 1137 typeTestEmitter.rtiNeededClasses.removeAll(neededClasses); | 1150 typeTestEmitter.rtiNeededClasses.removeAll(neededClasses); |
| 1138 // rtiNeededClasses now contains only the "empty shells". | 1151 // rtiNeededClasses now contains only the "empty shells". |
| 1139 neededClasses.addAll(typeTestEmitter.rtiNeededClasses); | 1152 neededClasses.addAll(typeTestEmitter.rtiNeededClasses); |
| 1140 | 1153 |
| 1154 // TODO(18175, floitsch): remove once issue 18175 is fixed. | |
| 1155 if (neededClasses.contains(backend.jsIntClass)) { | |
| 1156 neededClasses.add(compiler.intClass); | |
| 1157 } | |
| 1158 if (neededClasses.contains(backend.jsDoubleClass)) { | |
| 1159 neededClasses.add(compiler.doubleClass); | |
| 1160 } | |
| 1161 if (neededClasses.contains(backend.jsNumberClass)) { | |
| 1162 neededClasses.add(compiler.numClass); | |
| 1163 } | |
| 1164 if (neededClasses.contains(backend.jsStringClass)) { | |
| 1165 neededClasses.add(compiler.stringClass); | |
| 1166 } | |
| 1167 if (neededClasses.contains(backend.jsBoolClass)) { | |
| 1168 neededClasses.add(compiler.boolClass); | |
| 1169 } | |
| 1170 if (neededClasses.contains(backend.jsArrayClass)) { | |
| 1171 neededClasses.add(compiler.listClass); | |
| 1172 } | |
| 1173 | |
| 1141 // 5. Finally, sort the classes. | 1174 // 5. Finally, sort the classes. |
| 1142 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); | 1175 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); |
| 1143 | 1176 |
| 1144 for (ClassElement element in sortedClasses) { | 1177 for (ClassElement element in sortedClasses) { |
| 1145 if (typeTestEmitter.rtiNeededClasses.contains(element)) { | 1178 if (typeTestEmitter.rtiNeededClasses.contains(element)) { |
| 1146 // TODO(sigurdm): We might be able to defer some of these. | 1179 // TODO(sigurdm): We might be able to defer some of these. |
| 1147 outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, | 1180 outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, |
| 1148 () => new List<ClassElement>()).add(element); | 1181 () => new List<ClassElement>()).add(element); |
| 1149 } else if (Elements.isNativeOrExtendsNative(element)) { | 1182 } else if (Elements.isNativeOrExtendsNative(element)) { |
| 1150 // For now, native classes and related classes cannot be deferred. | 1183 // For now, native classes and related classes cannot be deferred. |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1700 String sourceMap = sourceMapBuilder.build(); | 1733 String sourceMap = sourceMapBuilder.build(); |
| 1701 compiler.outputProvider(name, 'js.map') | 1734 compiler.outputProvider(name, 'js.map') |
| 1702 ..add(sourceMap) | 1735 ..add(sourceMap) |
| 1703 ..close(); | 1736 ..close(); |
| 1704 } | 1737 } |
| 1705 | 1738 |
| 1706 void registerReadTypeVariable(TypeVariableElement element) { | 1739 void registerReadTypeVariable(TypeVariableElement element) { |
| 1707 readTypeVariables.add(element); | 1740 readTypeVariables.add(element); |
| 1708 } | 1741 } |
| 1709 } | 1742 } |
| OLD | NEW |