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

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();
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
57 processElement(element, treeElements) {
Roman 2012/08/16 14:23:54 How about refactoring all this stuff to a separate
Anton Muhin 2012/08/16 14:30:44 That sounds really interesting, thanks a lot, let
58 collector.collect(element, treeElements);
59 new ReferencedElementCollector(
60 compiler,
61 element, treeElements,
62 newTypedefElementCallback, newClassElementCallback).collect();
63 }
64
65 addTopLevel(element, treeElements) {
66 if (topLevelElements.contains(element)) return;
67 topLevelElements.add(element);
68 processElement(element, treeElements);
69 }
70 addClass(classElement) {
71 if (classes.containsKey(classElement)) return;
72 classes[classElement] = new Set<Element>();
73 processElement(classElement, emptyTreeElements);
74 }
75
76 newTypedefElementCallback = (TypedefElement element) {
77 if (!shouldOutput(element)) return;
78 addTopLevel(element, emptyTreeElements);
79 };
80 newClassElementCallback = (ClassElement classElement) {
81 if (!shouldOutput(classElement)) return;
82 addClass(classElement);
83 };
84
55 resolvedElements.forEach((element, treeElements) { 85 resolvedElements.forEach((element, treeElements) {
56 if (!shouldOutput(element)) return; 86 if (!shouldOutput(element)) return;
87
57 if (element.isMember()) { 88 if (element.isMember()) {
58 ClassElement enclosingClass = element.getEnclosingClass(); 89 ClassElement enclosingClass = element.getEnclosingClass();
59 assert(enclosingClass.isClass()); 90 assert(enclosingClass.isClass());
60 assert(enclosingClass.isTopLevel()); 91 assert(enclosingClass.isTopLevel());
61 resolvedClassMembers 92 assert(shouldOutput(enclosingClass));
62 .putIfAbsent(enclosingClass, () => new Set<Element>()) 93 addClass(enclosingClass);
63 .add(element); 94 classes[enclosingClass].add(element);
64 return; 95 processElement(element, treeElements);
96 } else {
97 if (!element.isTopLevel()) {
98 compiler.cancel(reason: 'Cannot process $element', element: element);
99 }
100 addTopLevel(element, treeElements);
65 } 101 }
66 if (!element.isTopLevel()) {
67 compiler.cancel(reason: 'Cannot process $element', element: element);
68 }
69
70 elements.add(element);
71 }); 102 });
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 103
86 Map<Node, String> renames = new Map<Node, String>(); 104 Map<Node, String> renames = new Map<Node, String>();
87 Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); 105 Map<LibraryElement, String> imports = new Map<LibraryElement, String>();
88 renamePlaceholders(compiler, collector, renames, imports); 106 renamePlaceholders(compiler, collector, renames, imports);
89 107
90 Emitter emitter = new Emitter(compiler, renames); 108 Emitter emitter = new Emitter(compiler, renames);
91 emitter.outputImports(imports); 109 emitter.outputImports(imports);
92 elements.forEach(emitter.outputElement); 110 topLevelElements.forEach(emitter.outputElement);
93 typedefs.forEach(emitter.outputElement); 111 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 112
101 // Now output resolved classes with inner elements we met before.
102 resolvedClassMembers.forEach(emitter.outputClass);
103 compiler.assembledCode = emitter.toString(); 113 compiler.assembledCode = emitter.toString();
104 } 114 }
105 115
106 log(String message) => compiler.log('[DartBackend] $message'); 116 log(String message) => compiler.log('[DartBackend] $message');
107 } 117 }
108 118
109 /** 119 /**
110 * Checks if [:libraryElement:] is a core lib, that is a library 120 * Checks if [:libraryElement:] is a core lib, that is a library
111 * provided by the implementation like dart:core, dart:coreimpl, etc. 121 * provided by the implementation like dart:core, dart:coreimpl, etc.
112 */ 122 */
(...skipping 10 matching lines...) Expand all
123 /** 133 /**
124 * Some elements are not recorded by resolver now, 134 * Some elements are not recorded by resolver now,
125 * for example, typedefs or classes which are only 135 * for example, typedefs or classes which are only
126 * used in signatures, as/is operators or in super clauses 136 * used in signatures, as/is operators or in super clauses
127 * (just to name a few). Retraverse AST to pick those up. 137 * (just to name a few). Retraverse AST to pick those up.
128 */ 138 */
129 class ReferencedElementCollector extends AbstractVisitor { 139 class ReferencedElementCollector extends AbstractVisitor {
130 final Compiler compiler; 140 final Compiler compiler;
131 final Element rootElement; 141 final Element rootElement;
132 final TreeElements treeElements; 142 final TreeElements treeElements;
133 final Set<TypedefElement> typedefs; 143 final newTypedefElementCallback;
134 final Set<ClassElement> classes; 144 final newClassElementCallback;
135 145
136 ReferencedElementCollector( 146 ReferencedElementCollector(
137 this.compiler, 147 this.compiler,
138 this.rootElement, this.treeElements, 148 this.rootElement, this.treeElements,
139 this.typedefs, this.classes); 149 this.newTypedefElementCallback, this.newClassElementCallback);
140
141 void collectElement(Element element) {
142 new ReferencedElementCollector(
143 compiler, element, new TreeElementMapping(), typedefs, classes)
144 .collect();
145 }
146 150
147 visitClassNode(ClassNode node) { 151 visitClassNode(ClassNode node) {
148 super.visitClassNode(node); 152 super.visitClassNode(node);
149 // Temporary hack which should go away once interfaces 153 // Temporary hack which should go away once interfaces
150 // and default clauses are out. 154 // and default clauses are out.
151 if (node.defaultClause !== null) { 155 if (node.defaultClause !== null) {
152 // Resolver cannot resolve parameterized default clauses. 156 // Resolver cannot resolve parameterized default clauses.
153 TypeAnnotation evilCousine = new TypeAnnotation( 157 TypeAnnotation evilCousine = new TypeAnnotation(
154 node.defaultClause.typeName, null); 158 node.defaultClause.typeName, null);
155 evilCousine.accept(this); 159 evilCousine.accept(this);
156 } 160 }
157 } 161 }
158 162
159 visitNode(Node node) { node.visitChildren(this); } 163 visitNode(Node node) { node.visitChildren(this); }
160 164
161 visitTypeAnnotation(TypeAnnotation typeAnnotation) { 165 visitTypeAnnotation(TypeAnnotation typeAnnotation) {
162 final type = compiler.resolveTypeAnnotation(rootElement, typeAnnotation); 166 final type = compiler.resolveTypeAnnotation(rootElement, typeAnnotation);
163 Element typeElement = type.element; 167 Element typeElement = type.element;
164 if (typeElement.isTypedef() && !typedefs.contains(typeElement)) { 168 if (typeElement.isTypedef()) newTypedefElementCallback(typeElement);
165 typedefs.add(typeElement); 169 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); 170 typeAnnotation.visitChildren(this);
173 } 171 }
174 172
175 void collect() { 173 void collect() {
176 compiler.withCurrentElement(rootElement, () { 174 compiler.withCurrentElement(rootElement, () {
177 rootElement.parseNode(compiler).accept(this); 175 rootElement.parseNode(compiler).accept(this);
178 }); 176 });
179 } 177 }
180 } 178 }
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