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

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

Issue 10917298: [dart2dart] Cut declaration types by default if we check that it is safe to do so. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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 | no next file » | 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 ElementAst { 5 class ElementAst {
6 final Node ast; 6 final Node ast;
7 final TreeElements treeElements; 7 final TreeElements treeElements;
8 8
9 ElementAst(this.ast, this.treeElements); 9 ElementAst(this.ast, this.treeElements);
10 10
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 82
83 class DartBackend extends Backend { 83 class DartBackend extends Backend {
84 final List<CompilerTask> tasks; 84 final List<CompilerTask> tasks;
85 final bool cutDeclarationTypes; 85 final bool cutDeclarationTypes;
86 // TODO(antonm): make available from command-line options. 86 // TODO(antonm): make available from command-line options.
87 final bool outputAst = false; 87 final bool outputAst = false;
88 88
89 Map<Element, TreeElements> get resolvedElements => 89 Map<Element, TreeElements> get resolvedElements =>
90 compiler.enqueuer.resolution.resolvedElements; 90 compiler.enqueuer.resolution.resolvedElements;
91 91
92 /**
93 * Tells whether it is safe to remove type declarations from variables, functi ons
Anton Muhin 2012/09/17 18:45:15 nit: isn't this string too long?
Roman 2012/09/18 10:24:08 Sorry, forgot to check long lines before sending t
94 * parameters. It becomes not safe if:
95 * 1) TypeError is used somewhere in the code,
96 * 2) The code has typedefs in right hand side of IS checks,
97 * 3) The code has classes which extend typedefs, have type arguments typedefs
98 * or type variable bounds typedefs.
99 * These restrictions can be less strict.
100 */
101 bool isSafeToRemoveTypeDeclarations(Map<ClassElement, Set<Element>> classMembe rs) {
Anton Muhin 2012/09/17 18:45:15 generic question: why do you have to parse element
Roman 2012/09/18 10:24:08 Unfortunately, no. When I have: class A extends B<
102 Set<DartType> processedTypes = new Set<DartType>();
103 List<DartType> workQueue = new List<DartType>();
104 workQueue.addAll(classMembers.getKeys().map((classElement) => classElement.t ype));
Anton Muhin 2012/09/17 18:45:15 ditto for this line and all the lines below
105 workQueue.addAll(compiler.resolverWorld.isChecks);
106 DartType typeErrorType = compiler.coreLibrary.find(new SourceString('TypeErr or')).type;
107 if (workQueue.indexOf(typeErrorType) != -1) {
108 return true;
109 }
110
111 void processTypeArguments(Element classElement, NodeList typeArguments) {
112 if (typeArguments == null) return;
113 for (Node typeArgument in typeArguments.nodes.toList()) {
Anton Muhin 2012/09/17 18:45:15 do you need .toList()?
Roman 2012/09/18 10:24:08 Indeed I don't, Link is iterable. Removed.
114 if (typeArgument is TypeVariable) {
115 typeArgument = typeArgument.bound;
116 }
117 if (typeArgument == null) continue;
118 assert(typeArgument is TypeAnnotation);
119 DartType argumentType = compiler.resolveTypeAnnotation(classElement, typ eArgument);
120 assert(argumentType !== null);
121 workQueue.add(argumentType);
Anton Muhin 2012/09/17 18:45:15 shouldn't you check processedTypes before adding a
Roman 2012/09/18 10:24:08 Not necessary, when I pop next work element, I che
Anton Muhin 2012/09/18 10:27:03 Yes, I know, we can just consume less memory. Ove
Roman 2012/09/18 13:12:21 It is possible that we can add processed items sev
122 }
123 }
124
125 while (!workQueue.isEmpty()) {
126 DartType type = workQueue.removeLast();
127 if (processedTypes.contains(type)) continue;
128 processedTypes.add(type);
129 if (type is TypedefType) return true;
130 if (type is InterfaceType) {
131 ClassElement element = type.element;
132 ClassNode node = element.parseNode(compiler);
133 // Check class type args.
134 processTypeArguments(element, node.typeParameters);
135 // Check superclass type args.
136 if (node.superclass !== null) {
137 NodeList typeArguments = node.superclass.typeArguments;
138 processTypeArguments(element, node.superclass.typeArguments);
139 }
140 // Check interfaces type args.
141 for (Node interfaceNode in node.interfaces) {
142 processTypeArguments(element, (interfaceNode as TypeAnnotation).typeAr guments);
143 }
144 // Check all supertypes.
145 if (element.allSupertypes !== null) {
146 workQueue.addAll(element.allSupertypes.toList());
147 }
148 }
149 }
150 return false;
151 }
152
92 DartBackend(Compiler compiler, this.cutDeclarationTypes) 153 DartBackend(Compiler compiler, this.cutDeclarationTypes)
93 : tasks = <CompilerTask>[], 154 : tasks = <CompilerTask>[],
94 super(compiler); 155 super(compiler);
95 156
96 void enqueueHelpers(Enqueuer world) { 157 void enqueueHelpers(Enqueuer world) {
97 // Right now resolver doesn't always resolve interfaces needed 158 // Right now resolver doesn't always resolve interfaces needed
98 // for literals, so force them. TODO(antonm): fix in the resolver. 159 // for literals, so force them. TODO(antonm): fix in the resolver.
99 final LITERAL_TYPE_NAMES = const [ 160 final LITERAL_TYPE_NAMES = const [
100 'Map', 'List', 'num', 'int', 'double', 'bool' 161 'Map', 'List', 'num', 'int', 'double', 'bool'
101 ]; 162 ];
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 // Create all necessary placeholders. 287 // Create all necessary placeholders.
227 PlaceholderCollector collector = 288 PlaceholderCollector collector =
228 new PlaceholderCollector(compiler, fixedMemberNames, elementAsts); 289 new PlaceholderCollector(compiler, fixedMemberNames, elementAsts);
229 makePlaceholders(element) { 290 makePlaceholders(element) {
230 collector.collect(element); 291 collector.collect(element);
231 if (element is ClassElement) { 292 if (element is ClassElement) {
232 classMembers[element].forEach(makePlaceholders); 293 classMembers[element].forEach(makePlaceholders);
233 } 294 }
234 } 295 }
235 topLevelElements.forEach(makePlaceholders); 296 topLevelElements.forEach(makePlaceholders);
236
237 // Create renames. 297 // Create renames.
238 Map<Node, String> renames = new Map<Node, String>(); 298 Map<Node, String> renames = new Map<Node, String>();
239 Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); 299 Map<LibraryElement, String> imports = new Map<LibraryElement, String>();
300 bool shouldCutDeclarationTypes =
301 cutDeclarationTypes || !isSafeToRemoveTypeDeclarations(classMembers);
240 renamePlaceholders( 302 renamePlaceholders(
241 compiler, collector, renames, imports, 303 compiler, collector, renames, imports,
242 fixedMemberNames, cutDeclarationTypes); 304 fixedMemberNames, shouldCutDeclarationTypes));
243 305
244 // Sort elements. 306 // Sort elements.
245 final sortedTopLevels = sortElements(topLevelElements); 307 final sortedTopLevels = sortElements(topLevelElements);
246 final sortedClassMembers = new Map<ClassElement, List<Element>>(); 308 final sortedClassMembers = new Map<ClassElement, List<Element>>();
247 classMembers.forEach((classElement, members) { 309 classMembers.forEach((classElement, members) {
248 sortedClassMembers[classElement] = sortElements(members); 310 sortedClassMembers[classElement] = sortElements(members);
249 }); 311 });
250 312
251 if (outputAst) { 313 if (outputAst) {
252 // TODO(antonm): Ideally XML should be a separate backend. 314 // TODO(antonm): Ideally XML should be a separate backend.
(...skipping 28 matching lines...) Expand all
281 } 343 }
282 344
283 final unparser = new Unparser.withRenamer((Node node) => renames[node]); 345 final unparser = new Unparser.withRenamer((Node node) => renames[node]);
284 emitCode(unparser, imports, topLevelNodes, memberNodes); 346 emitCode(unparser, imports, topLevelNodes, memberNodes);
285 compiler.assembledCode = unparser.result; 347 compiler.assembledCode = unparser.result;
286 } 348 }
287 349
288 log(String message) => compiler.log('[DartBackend] $message'); 350 log(String message) => compiler.log('[DartBackend] $message');
289 } 351 }
290 352
353 /*
Anton Muhin 2012/09/17 18:45:15 commented out code
Roman 2012/09/18 10:24:08 That was my first emotional attempt to write anoth
354 class TypedefRhsChecker extends AbstractVisitor {
355 static bool hasTypedefsRhs(Node node) {
356 TypedefRhsChecker checker = new TypedefRhsChecker();
357 node.accept(checker);
358 }
359
360 visitNode(Node node) { node.visitChildren(this); }
361
362 visitSend(Send node) {
363 if (node.isOperator && node.op)
364 }
365 }
366 */
367
291 /** 368 /**
292 * Some elements are not recorded by resolver now, 369 * Some elements are not recorded by resolver now,
293 * for example, typedefs or classes which are only 370 * for example, typedefs or classes which are only
294 * used in signatures, as/is operators or in super clauses 371 * used in signatures, as/is operators or in super clauses
295 * (just to name a few). Retraverse AST to pick those up. 372 * (just to name a few). Retraverse AST to pick those up.
296 */ 373 */
297 class ReferencedElementCollector extends AbstractVisitor { 374 class ReferencedElementCollector extends AbstractVisitor {
298 final Compiler compiler; 375 final Compiler compiler;
299 final Element rootElement; 376 final Element rootElement;
300 final TreeElements treeElements; 377 final TreeElements treeElements;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 } 424 }
348 425
349 compareElements(e0, e1) { 426 compareElements(e0, e1) {
350 int result = compareBy((e) => e.getLibrary().uri.toString())(e0, e1); 427 int result = compareBy((e) => e.getLibrary().uri.toString())(e0, e1);
351 if (result != 0) return result; 428 if (result != 0) return result;
352 return compareBy((e) => e.position().charOffset)(e0, e1); 429 return compareBy((e) => e.position().charOffset)(e0, e1);
353 } 430 }
354 431
355 List<Element> sortElements(Collection<Element> elements) => 432 List<Element> sortElements(Collection<Element> elements) =>
356 sorted(elements, compareElements); 433 sorted(elements, compareElements);
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698