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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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); |
| OLD | NEW |