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 part of dart_backend; | 5 part of dart_backend; |
6 | 6 |
7 // TODO(ahe): This class is simply wrong. This backend should use | 7 // TODO(ahe): This class is simply wrong. This backend should use |
8 // elements when it can, not AST nodes. Perhaps a [Map<Element, | 8 // elements when it can, not AST nodes. Perhaps a [Map<Element, |
9 // TreeElements>] is what is needed. | 9 // TreeElements>] is what is needed. |
10 class ElementAst { | 10 class ElementAst { |
(...skipping 27 matching lines...) Expand all Loading... |
38 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary | 38 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary |
39 /// field is set. | 39 /// field is set. |
40 FunctionElement mirrorHelperGetNameFunction; | 40 FunctionElement mirrorHelperGetNameFunction; |
41 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary | 41 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary |
42 /// field is set. | 42 /// field is set. |
43 Element mirrorHelperSymbolsMap; | 43 Element mirrorHelperSymbolsMap; |
44 | 44 |
45 Map<Element, TreeElements> get resolvedElements => | 45 Map<Element, TreeElements> get resolvedElements => |
46 compiler.enqueuer.resolution.resolvedElements; | 46 compiler.enqueuer.resolution.resolvedElements; |
47 | 47 |
| 48 final Set<ClassElement> usedTypeLiterals = new Set<ClassElement>(); |
| 49 |
48 /** | 50 /** |
49 * Tells whether it is safe to remove type declarations from variables, | 51 * Tells whether it is safe to remove type declarations from variables, |
50 * functions parameters. It becomes not safe if: | 52 * functions parameters. It becomes not safe if: |
51 * 1) TypeError is used somewhere in the code, | 53 * 1) TypeError is used somewhere in the code, |
52 * 2) The code has typedefs in right hand side of IS checks, | 54 * 2) The code has typedefs in right hand side of IS checks, |
53 * 3) The code has classes which extend typedefs, have type arguments typedefs | 55 * 3) The code has classes which extend typedefs, have type arguments typedefs |
54 * or type variable bounds typedefs. | 56 * or type variable bounds typedefs. |
55 * These restrictions can be less strict. | 57 * These restrictions can be less strict. |
56 */ | 58 */ |
57 bool isSafeToRemoveTypeDeclarations( | 59 bool isSafeToRemoveTypeDeclarations( |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 assert(shouldOutput(enclosingClass)); | 292 assert(shouldOutput(enclosingClass)); |
291 addClass(enclosingClass); | 293 addClass(enclosingClass); |
292 classMembers[enclosingClass].add(element); | 294 classMembers[enclosingClass].add(element); |
293 processElement(element, elementAst); | 295 processElement(element, elementAst); |
294 } else { | 296 } else { |
295 if (element.isTopLevel()) { | 297 if (element.isTopLevel()) { |
296 addTopLevel(element, elementAst); | 298 addTopLevel(element, elementAst); |
297 } | 299 } |
298 } | 300 } |
299 }); | 301 }); |
| 302 Set<ClassElement> emitNoMembersFor = new Set<ClassElement>(); |
| 303 usedTypeLiterals.forEach((ClassElement element) { |
| 304 if (shouldOutput(element)) { |
| 305 if (!topLevelElements.contains(element)) { |
| 306 // The class is only referenced by type literals. |
| 307 emitNoMembersFor.add(element); |
| 308 } |
| 309 addClass(element); |
| 310 } |
| 311 }); |
300 | 312 |
301 // Add synthesized constructors to classes with no resolved constructors, | 313 // Add synthesized constructors to classes with no resolved constructors, |
302 // but which originally had any constructor. That should prevent | 314 // but which originally had any constructor. That should prevent |
303 // those classes from being instantiable with default constructor. | 315 // those classes from being instantiable with default constructor. |
304 Identifier synthesizedIdentifier = new Identifier( | 316 Identifier synthesizedIdentifier = new Identifier( |
305 new StringToken.fromString(IDENTIFIER_INFO, '', -1)); | 317 new StringToken.fromString(IDENTIFIER_INFO, '', -1)); |
306 | 318 |
307 NextClassElement: | 319 NextClassElement: |
308 for (ClassElement classElement in classMembers.keys) { | 320 for (ClassElement classElement in classMembers.keys) { |
| 321 if (emitNoMembersFor.contains(classElement)) continue; |
309 for (Element member in classMembers[classElement]) { | 322 for (Element member in classMembers[classElement]) { |
310 if (member.isConstructor()) continue NextClassElement; | 323 if (member.isConstructor()) continue NextClassElement; |
311 } | 324 } |
312 if (classElement.constructors.isEmpty) continue NextClassElement; | 325 if (classElement.constructors.isEmpty) continue NextClassElement; |
313 | 326 |
314 // TODO(antonm): check with AAR team if there is better approach. | 327 // TODO(antonm): check with AAR team if there is better approach. |
315 // As an idea: provide template as a Dart code---class C { C.name(); }--- | 328 // As an idea: provide template as a Dart code---class C { C.name(); }--- |
316 // and then overwrite necessary parts. | 329 // and then overwrite necessary parts. |
317 var classNode = classElement.parseNode(compiler); | 330 var classNode = classElement.parseNode(compiler); |
318 SynthesizedConstructorElementX constructor = | 331 SynthesizedConstructorElementX constructor = |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 if (outputAst) { | 387 if (outputAst) { |
375 // TODO(antonm): Ideally XML should be a separate backend. | 388 // TODO(antonm): Ideally XML should be a separate backend. |
376 // TODO(antonm): obey renames and minification, at least as an option. | 389 // TODO(antonm): obey renames and minification, at least as an option. |
377 StringBuffer sb = new StringBuffer(); | 390 StringBuffer sb = new StringBuffer(); |
378 outputElement(element) { | 391 outputElement(element) { |
379 sb.write(element.parseNode(compiler).toDebugString()); | 392 sb.write(element.parseNode(compiler).toDebugString()); |
380 } | 393 } |
381 | 394 |
382 // Emit XML for AST instead of the program. | 395 // Emit XML for AST instead of the program. |
383 for (final topLevel in sortedTopLevels) { | 396 for (final topLevel in sortedTopLevels) { |
384 if (topLevel.isClass()) { | 397 if (topLevel.isClass() && !emitNoMembersFor.contains(topLevel)) { |
385 // TODO(antonm): add some class info. | 398 // TODO(antonm): add some class info. |
386 sortedClassMembers[topLevel].forEach(outputElement); | 399 sortedClassMembers[topLevel].forEach(outputElement); |
387 } else { | 400 } else { |
388 outputElement(topLevel); | 401 outputElement(topLevel); |
389 } | 402 } |
390 } | 403 } |
391 compiler.assembledCode = '<Program>\n$sb</Program>\n'; | 404 compiler.assembledCode = '<Program>\n$sb</Program>\n'; |
392 return; | 405 return; |
393 } | 406 } |
394 | 407 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 mirrorHelperLibrary = element; | 459 mirrorHelperLibrary = element; |
447 mirrorHelperGetNameFunction = mirrorHelperLibrary.find( | 460 mirrorHelperGetNameFunction = mirrorHelperLibrary.find( |
448 MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION); | 461 MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION); |
449 mirrorHelperSymbolsMap = mirrorHelperLibrary.find( | 462 mirrorHelperSymbolsMap = mirrorHelperLibrary.find( |
450 MirrorRenamer.MIRROR_HELPER_SYMBOLS_MAP_NAME); | 463 MirrorRenamer.MIRROR_HELPER_SYMBOLS_MAP_NAME); |
451 }); | 464 }); |
452 } | 465 } |
453 return new Future.value(); | 466 return new Future.value(); |
454 } | 467 } |
455 | 468 |
| 469 void registerTypeLiteral(Element element, |
| 470 Enqueuer enqueuer, |
| 471 TreeElements elements) { |
| 472 if (element.isClass()) { |
| 473 usedTypeLiterals.add(element); |
| 474 } |
| 475 } |
| 476 |
456 void registerStaticSend(Element element, Node node) { | 477 void registerStaticSend(Element element, Node node) { |
457 if (useMirrorHelperLibrary) { | 478 if (useMirrorHelperLibrary) { |
458 mirrorRenamer.registerStaticSend(element, node); | 479 mirrorRenamer.registerStaticSend(element, node); |
459 } | 480 } |
460 } | 481 } |
461 | 482 |
462 void registerMirrorHelperElement(Element element, Node node) { | 483 void registerMirrorHelperElement(Element element, Node node) { |
463 if (mirrorHelperLibrary != null | 484 if (mirrorHelperLibrary != null |
464 && element.getLibrary() == mirrorHelperLibrary) { | 485 && element.getLibrary() == mirrorHelperLibrary) { |
465 mirrorRenamer.registerHelperElement(element, node); | 486 mirrorRenamer.registerHelperElement(element, node); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 } | 574 } |
554 | 575 |
555 compareElements(e0, e1) { | 576 compareElements(e0, e1) { |
556 int result = compareBy((e) => e.getLibrary().canonicalUri.toString())(e0, e1); | 577 int result = compareBy((e) => e.getLibrary().canonicalUri.toString())(e0, e1); |
557 if (result != 0) return result; | 578 if (result != 0) return result; |
558 return compareBy((e) => e.position().charOffset)(e0, e1); | 579 return compareBy((e) => e.position().charOffset)(e0, e1); |
559 } | 580 } |
560 | 581 |
561 List<Element> sortElements(Iterable<Element> elements) => | 582 List<Element> sortElements(Iterable<Element> elements) => |
562 sorted(elements, compareElements); | 583 sorted(elements, compareElements); |
OLD | NEW |