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 class DartBackend extends Backend { | 5 class DartBackend extends Backend { |
| 6 final List<CompilerTask> tasks; | 6 final List<CompilerTask> tasks; |
| 7 final UnparseValidator unparseValidator; | 7 final UnparseValidator unparseValidator; |
| 8 | 8 |
| 9 Map<Element, TreeElements> get resolvedElements() => | 9 Map<Element, TreeElements> get resolvedElements() => |
| 10 compiler.enqueuer.resolution.resolvedElements; | 10 compiler.enqueuer.resolution.resolvedElements; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 final LIBS_TO_IGNORE = [ | 38 final LIBS_TO_IGNORE = [ |
| 39 compiler.jsHelperLibrary, | 39 compiler.jsHelperLibrary, |
| 40 compiler.interceptorsLibrary, | 40 compiler.interceptorsLibrary, |
| 41 ]; | 41 ]; |
| 42 bool shouldOutput(Element element) => | 42 bool shouldOutput(Element element) => |
| 43 element.kind !== ElementKind.VOID && | 43 element.kind !== ElementKind.VOID && |
| 44 LIBS_TO_IGNORE.indexOf(element.getLibrary()) == -1 && | 44 LIBS_TO_IGNORE.indexOf(element.getLibrary()) == -1 && |
| 45 !isDartCoreLib(compiler, element.getLibrary()) && | 45 !isDartCoreLib(compiler, element.getLibrary()) && |
| 46 element is !AbstractFieldElement; | 46 element is !AbstractFieldElement; |
| 47 | 47 |
| 48 // TODO(smok): Refactor this traverse/collect mess. | 48 final emptyTreeElements = new TreeElementMapping(); |
|
Roman
2012/08/16 13:53:26
maybe remove this? it is used only twice, it would
Anton Muhin
2012/08/16 14:06:42
I don't want to create a lot of garbage.
On 2012/
Roman
2012/08/16 14:23:54
Why not?
Anton Muhin
2012/08/16 14:30:44
Why stress GC unnecessarily?
On 2012/08/16 14:23:
| |
| 49 Set<TypedefElement> typedefs = new Set<TypedefElement>(); | 49 |
| 50 Set<ClassElement> classes = new Set<ClassElement>(); | 50 Set<Element> topLevelElements = new Set<Element>(); |
| 51 Set<Element> elements = new Set<Element>(); | 51 Map<ClassElement, Set<Element>> classes = |
| 52 Map<ClassElement, Set<Element>> resolvedClassMembers = | |
| 53 new Map<ClassElement, Set<Element>>(); | 52 new Map<ClassElement, Set<Element>>(); |
| 53 | |
| 54 PlaceholderCollector collector = new PlaceholderCollector(compiler); | 54 PlaceholderCollector collector = new PlaceholderCollector(compiler); |
| 55 var newTypedefElementCallback, newClassElementCallback; | |
| 56 collectReferencedElements(element, treeElements) { | |
|
Roman
2012/08/16 13:53:26
Inline this method? It is used only once. And if y
Anton Muhin
2012/08/16 14:06:42
Alas, variables hacks are a must as Dart requires
| |
| 57 new ReferencedElementCollector( | |
| 58 compiler, | |
| 59 element, treeElements, | |
| 60 newTypedefElementCallback, newClassElementCallback).collect(); | |
| 61 } | |
| 62 processElement(element, treeElements) { | |
| 63 collector.collect(element, treeElements); | |
| 64 collectReferencedElements(element, treeElements); | |
| 65 } | |
| 66 | |
| 67 addTopLevel(element, treeElements) { | |
| 68 if (topLevelElements.contains(element)) return; | |
| 69 topLevelElements.add(element); | |
| 70 processElement(element, treeElements); | |
| 71 } | |
| 72 addClass(classElement) { | |
| 73 if (classes.containsKey(classElement)) return; | |
| 74 classes[classElement] = new Set<Element>(); | |
| 75 processElement(classElement, emptyTreeElements); | |
| 76 } | |
| 77 | |
| 78 newTypedefElementCallback = (TypedefElement element) { | |
| 79 if (!shouldOutput(element)) return; | |
| 80 addTopLevel(element, emptyTreeElements); | |
| 81 }; | |
| 82 newClassElementCallback = (ClassElement classElement) { | |
| 83 if (!shouldOutput(classElement)) return; | |
| 84 addClass(classElement); | |
| 85 }; | |
| 86 | |
| 55 resolvedElements.forEach((element, treeElements) { | 87 resolvedElements.forEach((element, treeElements) { |
| 56 if (!shouldOutput(element)) return; | 88 if (!shouldOutput(element)) return; |
| 89 | |
| 57 if (element.isMember()) { | 90 if (element.isMember()) { |
| 58 ClassElement enclosingClass = element.getEnclosingClass(); | 91 ClassElement enclosingClass = element.getEnclosingClass(); |
| 59 assert(enclosingClass.isClass()); | 92 assert(enclosingClass.isClass()); |
| 60 assert(enclosingClass.isTopLevel()); | 93 assert(enclosingClass.isTopLevel()); |
| 61 resolvedClassMembers | 94 assert(shouldOutput(enclosingClass)); |
| 62 .putIfAbsent(enclosingClass, () => new Set<Element>()) | 95 addClass(enclosingClass); |
| 63 .add(element); | 96 classes[enclosingClass].add(element); |
| 64 return; | 97 processElement(element, treeElements); |
| 98 } else { | |
| 99 if (!element.isTopLevel()) { | |
| 100 compiler.cancel(reason: 'Cannot process $element', element: element); | |
| 101 } | |
| 102 addTopLevel(element, treeElements); | |
| 65 } | 103 } |
| 66 if (!element.isTopLevel()) { | |
| 67 compiler.cancel(reason: 'Cannot process $element', element: element); | |
| 68 } | |
| 69 | |
| 70 elements.add(element); | |
| 71 }); | 104 }); |
| 72 resolvedElements.forEach((element, treeElements) { | |
| 73 if (!shouldOutput(element)) return; | |
| 74 collector.collect(element, treeElements); | |
| 75 new ReferencedElementCollector( | |
| 76 compiler, element, treeElements, typedefs, classes) | |
| 77 .collect(); | |
| 78 }); | |
| 79 | |
| 80 final emptyTreeElements = new TreeElementMapping(); | |
| 81 collectElement(element) { collector.collect(element, emptyTreeElements); } | |
| 82 typedefs.forEach(collectElement); | |
| 83 classes.forEach(collectElement); | |
| 84 resolvedClassMembers.getKeys().forEach(collectElement); | |
| 85 | 105 |
| 86 Map<Node, String> renames = new Map<Node, String>(); | 106 Map<Node, String> renames = new Map<Node, String>(); |
| 87 Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); | 107 Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); |
| 88 renamePlaceholders(compiler, collector, renames, imports); | 108 renamePlaceholders(compiler, collector, renames, imports); |
| 89 | 109 |
| 90 Emitter emitter = new Emitter(compiler, renames); | 110 Emitter emitter = new Emitter(compiler, renames); |
| 91 emitter.outputImports(imports); | 111 emitter.outputImports(imports); |
| 92 elements.forEach(emitter.outputElement); | 112 topLevelElements.forEach(emitter.outputElement); |
| 93 typedefs.forEach(emitter.outputElement); | 113 classes.forEach(emitter.outputClass); |
| 94 final emptySet = new Set<Element>(); | |
| 95 classes.forEach((classElement) { | |
| 96 if (!shouldOutput(classElement)) return; | |
| 97 if (resolvedClassMembers.containsKey(classElement)) return; | |
| 98 emitter.outputClass(classElement, emptySet); | |
| 99 }); | |
| 100 | 114 |
| 101 // Now output resolved classes with inner elements we met before. | |
| 102 resolvedClassMembers.forEach(emitter.outputClass); | |
| 103 compiler.assembledCode = emitter.toString(); | 115 compiler.assembledCode = emitter.toString(); |
| 104 } | 116 } |
| 105 | 117 |
| 106 log(String message) => compiler.log('[DartBackend] $message'); | 118 log(String message) => compiler.log('[DartBackend] $message'); |
| 107 } | 119 } |
| 108 | 120 |
| 109 /** | 121 /** |
| 110 * Checks if [:libraryElement:] is a core lib, that is a library | 122 * Checks if [:libraryElement:] is a core lib, that is a library |
| 111 * provided by the implementation like dart:core, dart:coreimpl, etc. | 123 * provided by the implementation like dart:core, dart:coreimpl, etc. |
| 112 */ | 124 */ |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 123 /** | 135 /** |
| 124 * Some elements are not recorded by resolver now, | 136 * Some elements are not recorded by resolver now, |
| 125 * for example, typedefs or classes which are only | 137 * for example, typedefs or classes which are only |
| 126 * used in signatures, as/is operators or in super clauses | 138 * used in signatures, as/is operators or in super clauses |
| 127 * (just to name a few). Retraverse AST to pick those up. | 139 * (just to name a few). Retraverse AST to pick those up. |
| 128 */ | 140 */ |
| 129 class ReferencedElementCollector extends AbstractVisitor { | 141 class ReferencedElementCollector extends AbstractVisitor { |
| 130 final Compiler compiler; | 142 final Compiler compiler; |
| 131 final Element rootElement; | 143 final Element rootElement; |
| 132 final TreeElements treeElements; | 144 final TreeElements treeElements; |
| 133 final Set<TypedefElement> typedefs; | 145 final newTypedefElementCallback; |
| 134 final Set<ClassElement> classes; | 146 final newClassElementCallback; |
| 135 | 147 |
| 136 ReferencedElementCollector( | 148 ReferencedElementCollector( |
| 137 this.compiler, | 149 this.compiler, |
| 138 this.rootElement, this.treeElements, | 150 this.rootElement, this.treeElements, |
| 139 this.typedefs, this.classes); | 151 this.newTypedefElementCallback, this.newClassElementCallback); |
| 140 | |
| 141 void collectElement(Element element) { | |
| 142 new ReferencedElementCollector( | |
| 143 compiler, element, new TreeElementMapping(), typedefs, classes) | |
| 144 .collect(); | |
| 145 } | |
| 146 | 152 |
| 147 visitClassNode(ClassNode node) { | 153 visitClassNode(ClassNode node) { |
| 148 super.visitClassNode(node); | 154 super.visitClassNode(node); |
| 149 // Temporary hack which should go away once interfaces | 155 // Temporary hack which should go away once interfaces |
| 150 // and default clauses are out. | 156 // and default clauses are out. |
| 151 if (node.defaultClause !== null) { | 157 if (node.defaultClause !== null) { |
| 152 // Resolver cannot resolve parameterized default clauses. | 158 // Resolver cannot resolve parameterized default clauses. |
| 153 TypeAnnotation evilCousine = new TypeAnnotation( | 159 TypeAnnotation evilCousine = new TypeAnnotation( |
| 154 node.defaultClause.typeName, null); | 160 node.defaultClause.typeName, null); |
| 155 evilCousine.accept(this); | 161 evilCousine.accept(this); |
| 156 } | 162 } |
| 157 } | 163 } |
| 158 | 164 |
| 159 visitNode(Node node) { node.visitChildren(this); } | 165 visitNode(Node node) { node.visitChildren(this); } |
| 160 | 166 |
| 161 visitTypeAnnotation(TypeAnnotation typeAnnotation) { | 167 visitTypeAnnotation(TypeAnnotation typeAnnotation) { |
| 162 final type = compiler.resolveTypeAnnotation(rootElement, typeAnnotation); | 168 final type = compiler.resolveTypeAnnotation(rootElement, typeAnnotation); |
| 163 Element typeElement = type.element; | 169 Element typeElement = type.element; |
| 164 if (typeElement.isTypedef() && !typedefs.contains(typeElement)) { | 170 if (typeElement.isTypedef()) newTypedefElementCallback(typeElement); |
| 165 typedefs.add(typeElement); | 171 if (typeElement.isClass()) newClassElementCallback(typeElement); |
| 166 collectElement(typeElement); | |
| 167 } | |
| 168 if (typeElement.isClass() && !classes.contains(typeElement)) { | |
| 169 classes.add(typeElement); | |
| 170 collectElement(typeElement); | |
| 171 } | |
| 172 typeAnnotation.visitChildren(this); | 172 typeAnnotation.visitChildren(this); |
| 173 } | 173 } |
| 174 | 174 |
| 175 void collect() { | 175 void collect() { |
| 176 compiler.withCurrentElement(rootElement, () { | 176 compiler.withCurrentElement(rootElement, () { |
| 177 rootElement.parseNode(compiler).accept(this); | 177 rootElement.parseNode(compiler).accept(this); |
| 178 }); | 178 }); |
| 179 } | 179 } |
| 180 } | 180 } |
| OLD | NEW |