| 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 | |
| 426 } | 425 } |
| 427 | 426 |
| 428 jsAst.Node optional(bool condition, jsAst.Node node) { | 427 jsAst.Node optional(bool condition, jsAst.Node node) { |
| 429 return condition ? node : new jsAst.EmptyStatement(); | 428 return condition ? node : new jsAst.EmptyStatement(); |
| 430 } | 429 } |
| 431 | 430 |
| 432 jsAst.FunctionDeclaration buildFinishClass() { | 431 jsAst.FunctionDeclaration buildFinishClass() { |
| 433 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" | 432 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" |
| 434 | 433 |
| 435 return js.statement(''' | 434 return js.statement(''' |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 return [ | 608 return [ |
| 610 js('$finishIsolateConstructorName = #', finishIsolateConstructorFunction) | 609 js('$finishIsolateConstructorName = #', finishIsolateConstructorFunction) |
| 611 ]; | 610 ]; |
| 612 } | 611 } |
| 613 | 612 |
| 614 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { | 613 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { |
| 615 String isolate = namer.isolateName; | 614 String isolate = namer.isolateName; |
| 616 buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N"); | 615 buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N"); |
| 617 } | 616 } |
| 618 | 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 |
| 619 /// Returns the "reflection name" of an [Element] or [Selector]. | 630 /// Returns the "reflection name" of an [Element] or [Selector]. |
| 620 /// The reflection name of a getter 'foo' is 'foo'. | 631 /// The reflection name of a getter 'foo' is 'foo'. |
| 621 /// The reflection name of a setter 'foo' is 'foo='. | 632 /// The reflection name of a setter 'foo' is 'foo='. |
| 622 /// 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 |
| 623 /// 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 |
| 624 /// O is the named arguments. | 635 /// O is the named arguments. |
| 625 /// 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 |
| 626 /// starts with 'new '. | 637 /// starts with 'new '. |
| 627 /// The reflection name of class 'C' is 'C'. | 638 /// The reflection name of class 'C' is 'C'. |
| 628 /// An anonymous mixin application has no reflection name. | 639 /// An anonymous mixin application has no reflection name. |
| 629 /// This is used by js_mirrors.dart. | 640 /// This is used by js_mirrors.dart. |
| 630 String getReflectionName(elementOrSelector, String mangledName) { | 641 String getReflectionName(elementOrSelector, String mangledName) { |
| 631 String name = elementOrSelector.name; | 642 String name = elementOrSelector.name; |
| 632 if (!backend.shouldRetainName(name)) { | 643 if (backend.shouldRetainName(name) || |
| 633 if (name == '' && elementOrSelector is Element) { | 644 elementOrSelector is Element && |
| 634 // Make sure to retain names of unnamed constructors. | 645 // Make sure to retain names of unnamed constructors, and |
| 635 if (!backend.isNeededForReflection(elementOrSelector)) return null; | 646 // for common native types. |
| 636 } else { | 647 (name == '' && backend.isNeededForReflection(elementOrSelector) || |
| 637 return null; | 648 _isNativeTypeNeedingReflectionName(elementOrSelector))) { |
| 638 } | 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); |
| 639 } | 655 } |
| 640 // TODO(ahe): Enable the next line when I can tell the difference between | 656 return null; |
| 641 // an instance method and a global. They may have the same mangled name. | |
| 642 // if (recordedMangledNames.contains(mangledName)) return null; | |
| 643 recordedMangledNames.add(mangledName); | |
| 644 return getReflectionNameInternal(elementOrSelector, mangledName); | |
| 645 } | 657 } |
| 646 | 658 |
| 647 String getReflectionNameInternal(elementOrSelector, String mangledName) { | 659 String getReflectionNameInternal(elementOrSelector, String mangledName) { |
| 648 String name = elementOrSelector.name; | 660 String name = elementOrSelector.name; |
| 649 if (elementOrSelector.isGetter()) return name; | 661 if (elementOrSelector.isGetter()) return name; |
| 650 if (elementOrSelector.isSetter()) { | 662 if (elementOrSelector.isSetter()) { |
| 651 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; | 663 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; |
| 652 String base = mangledName.substring(namer.setterPrefix.length); | 664 String base = mangledName.substring(namer.setterPrefix.length); |
| 653 String getter = '${namer.getterPrefix}$base'; | 665 String getter = '${namer.getterPrefix}$base'; |
| 654 mangledFieldNames[getter] = name; | 666 mangledFieldNames[getter] = name; |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 // neededClasses must only contain classes that have been resolved and | 1148 // neededClasses must only contain classes that have been resolved and |
| 1137 // codegen'd. The rtiNeededClasses may contain additional classes, but | 1149 // codegen'd. The rtiNeededClasses may contain additional classes, but |
| 1138 // these are thought to not have been instantiated, so we neeed to be able | 1150 // these are thought to not have been instantiated, so we neeed to be able |
| 1139 // to identify them later and make sure we only emit "empty shells" without | 1151 // to identify them later and make sure we only emit "empty shells" without |
| 1140 // fields, etc. | 1152 // fields, etc. |
| 1141 typeTestEmitter.computeRtiNeededClasses(); | 1153 typeTestEmitter.computeRtiNeededClasses(); |
| 1142 typeTestEmitter.rtiNeededClasses.removeAll(neededClasses); | 1154 typeTestEmitter.rtiNeededClasses.removeAll(neededClasses); |
| 1143 // rtiNeededClasses now contains only the "empty shells". | 1155 // rtiNeededClasses now contains only the "empty shells". |
| 1144 neededClasses.addAll(typeTestEmitter.rtiNeededClasses); | 1156 neededClasses.addAll(typeTestEmitter.rtiNeededClasses); |
| 1145 | 1157 |
| 1158 // TODO(18175, floitsch): remove once issue 18175 is fixed. |
| 1159 if (neededClasses.contains(backend.jsIntClass)) { |
| 1160 neededClasses.add(compiler.intClass); |
| 1161 } |
| 1162 if (neededClasses.contains(backend.jsDoubleClass)) { |
| 1163 neededClasses.add(compiler.doubleClass); |
| 1164 } |
| 1165 if (neededClasses.contains(backend.jsNumberClass)) { |
| 1166 neededClasses.add(compiler.numClass); |
| 1167 } |
| 1168 if (neededClasses.contains(backend.jsStringClass)) { |
| 1169 neededClasses.add(compiler.stringClass); |
| 1170 } |
| 1171 if (neededClasses.contains(backend.jsBoolClass)) { |
| 1172 neededClasses.add(compiler.boolClass); |
| 1173 } |
| 1174 if (neededClasses.contains(backend.jsArrayClass)) { |
| 1175 neededClasses.add(compiler.listClass); |
| 1176 } |
| 1177 |
| 1146 // 5. Finally, sort the classes. | 1178 // 5. Finally, sort the classes. |
| 1147 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); | 1179 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); |
| 1148 | 1180 |
| 1149 for (ClassElement element in sortedClasses) { | 1181 for (ClassElement element in sortedClasses) { |
| 1150 if (typeTestEmitter.rtiNeededClasses.contains(element)) { | 1182 if (typeTestEmitter.rtiNeededClasses.contains(element)) { |
| 1151 // TODO(sigurdm): We might be able to defer some of these. | 1183 // TODO(sigurdm): We might be able to defer some of these. |
| 1152 outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, | 1184 outputClassLists.putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, |
| 1153 () => new List<ClassElement>()).add(element); | 1185 () => new List<ClassElement>()).add(element); |
| 1154 } else if (Elements.isNativeOrExtendsNative(element)) { | 1186 } else if (Elements.isNativeOrExtendsNative(element)) { |
| 1155 // For now, native classes and related classes cannot be deferred. | 1187 // For now, native classes and related classes cannot be deferred. |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1707 String sourceMap = sourceMapBuilder.build(); | 1739 String sourceMap = sourceMapBuilder.build(); |
| 1708 compiler.outputProvider(name, 'js.map') | 1740 compiler.outputProvider(name, 'js.map') |
| 1709 ..add(sourceMap) | 1741 ..add(sourceMap) |
| 1710 ..close(); | 1742 ..close(); |
| 1711 } | 1743 } |
| 1712 | 1744 |
| 1713 void registerReadTypeVariable(TypeVariableElement element) { | 1745 void registerReadTypeVariable(TypeVariableElement element) { |
| 1714 readTypeVariables.add(element); | 1746 readTypeVariables.add(element); |
| 1715 } | 1747 } |
| 1716 } | 1748 } |
| OLD | NEW |