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

Side by Side Diff: lib/compiler/implementation/dart_backend/backend.dart

Issue 10855199: Refactor program traversing logic. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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
« no previous file with comments | « no previous file | tests/compiler/dart2js/unparser_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/unparser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698