OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 typedef bool IsSafeToRemoveTypeDeclarations( | 7 typedef bool IsSafeToRemoveTypeDeclarations( |
8 Map<ClassElement, Iterable<Element>> classMembers); | 8 Map<ClassElement, Iterable<Element>> classMembers); |
9 typedef void ElementCallback<E>(E element); | 9 typedef void ElementCallback<E>(E element); |
10 typedef void ElementPostProcessFunction( | 10 typedef void ElementPostProcessFunction( |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 | 89 |
90 if (sortElements == null) { | 90 if (sortElements == null) { |
91 // Ensure deterministic output order. | 91 // Ensure deterministic output order. |
92 sortElements = (Iterable<Element> elements) { | 92 sortElements = (Iterable<Element> elements) { |
93 List<Element> list = elements.toList(); | 93 List<Element> list = elements.toList(); |
94 list.sort((Element a, Element b) => a.name.compareTo(b.name)); | 94 list.sort((Element a, Element b) => a.name.compareTo(b.name)); |
95 return list; | 95 return list; |
96 }; | 96 }; |
97 } | 97 } |
98 | 98 |
99 libraryInfo = LibraryInfo.processLibraries(libraries, resolvedElements); | 99 libraryInfo = LibraryInfo.processLibraries( |
| 100 listener, libraries, resolvedElements); |
100 | 101 |
101 elementInfo = ElementInfoProcessor.createElementInfo( | 102 elementInfo = ElementInfoProcessor.createElementInfo( |
102 instantiatedClasses, | 103 instantiatedClasses, |
103 resolvedElements, | 104 resolvedElements, |
104 usedTypeLiterals, | 105 usedTypeLiterals, |
105 postProcessElementAst: postProcessElementAst, | 106 postProcessElementAst: postProcessElementAst, |
106 parseElementAst: computeElementAst, | 107 parseElementAst: computeElementAst, |
107 shouldOutput: shouldOutput, | 108 shouldOutput: shouldOutput, |
108 sortElements: sortElements); | 109 sortElements: sortElements); |
109 | 110 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 PlaceholderCollector collector = new PlaceholderCollector( | 156 PlaceholderCollector collector = new PlaceholderCollector( |
156 listener, | 157 listener, |
157 mirrorRenamer, | 158 mirrorRenamer, |
158 libraryInfo.fixedDynamicNames, | 159 libraryInfo.fixedDynamicNames, |
159 elementInfo.elementAsts, | 160 elementInfo.elementAsts, |
160 mainFunction); | 161 mainFunction); |
161 | 162 |
162 makePlaceholders(element) { | 163 makePlaceholders(element) { |
163 collector.collect(element); | 164 collector.collect(element); |
164 | 165 |
165 if (element.isClass) { | 166 if (element.isClass && !element.isEnumClass) { |
166 elementInfo.classMembers[element].forEach(makePlaceholders); | 167 elementInfo.classMembers[element].forEach(makePlaceholders); |
167 } | 168 } |
168 } | 169 } |
169 elementInfo.topLevelElements.forEach(makePlaceholders); | 170 elementInfo.topLevelElements.forEach(makePlaceholders); |
170 return collector; | 171 return collector; |
171 } | 172 } |
172 | 173 |
173 static PlaceholderRenamer createRenamer( | 174 static PlaceholderRenamer createRenamer( |
174 PlaceholderCollector collector, | 175 PlaceholderCollector collector, |
175 LibraryInfo libraryInfo, | 176 LibraryInfo libraryInfo, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 final Set<String> fixedDynamicNames; | 222 final Set<String> fixedDynamicNames; |
222 final Map<Element, LibraryElement> reexportingLibraries; | 223 final Map<Element, LibraryElement> reexportingLibraries; |
223 final List<LibraryElement> userLibraries; | 224 final List<LibraryElement> userLibraries; |
224 | 225 |
225 LibraryInfo(this.fixedStaticNames, | 226 LibraryInfo(this.fixedStaticNames, |
226 this.fixedDynamicNames, | 227 this.fixedDynamicNames, |
227 this.reexportingLibraries, | 228 this.reexportingLibraries, |
228 this.userLibraries); | 229 this.userLibraries); |
229 | 230 |
230 static LibraryInfo processLibraries( | 231 static LibraryInfo processLibraries( |
| 232 DiagnosticListener listener, |
231 Iterable<LibraryElement> libraries, | 233 Iterable<LibraryElement> libraries, |
232 Iterable<AstElement> resolvedElements) { | 234 Iterable<AstElement> resolvedElements) { |
233 Set<String> fixedStaticNames = new Set<String>(); | 235 Set<String> fixedStaticNames = new Set<String>(); |
234 Set<String> fixedDynamicNames = new Set<String>(); | 236 Set<String> fixedDynamicNames = new Set<String>(); |
235 Map<Element, LibraryElement> reexportingLibraries = | 237 Map<Element, LibraryElement> reexportingLibraries = |
236 <Element, LibraryElement>{}; | 238 <Element, LibraryElement>{}; |
237 List<LibraryElement> userLibraries = <LibraryElement>[]; | 239 List<LibraryElement> userLibraries = <LibraryElement>[]; |
238 // Conservatively traverse all platform libraries and collect member names. | 240 // Conservatively traverse all platform libraries and collect member names. |
239 // TODO(antonm): ideally we should only collect names of used members, | 241 // TODO(antonm): ideally we should only collect names of used members, |
240 // however as of today there are problems with names of some core library | 242 // however as of today there are problems with names of some core library |
(...skipping 28 matching lines...) Expand all Loading... |
269 if (!library.isInternalLibrary && | 271 if (!library.isInternalLibrary && |
270 export.library.isInternalLibrary) { | 272 export.library.isInternalLibrary) { |
271 // If an element of an internal library is reexported by a platform | 273 // If an element of an internal library is reexported by a platform |
272 // library, we have to import the reexporting library instead of the | 274 // library, we have to import the reexporting library instead of the |
273 // internal library, because the internal library is an | 275 // internal library, because the internal library is an |
274 // implementation detail of dart2js. | 276 // implementation detail of dart2js. |
275 reexportingLibraries[export] = library; | 277 reexportingLibraries[export] = library; |
276 } | 278 } |
277 } | 279 } |
278 } | 280 } |
| 281 |
| 282 // Map to keep track of names of enum classes. Since these cannot be renamed |
| 283 // we ensure that they are unique. |
| 284 Map<String, ClassElement> enumClassMap = <String, ClassElement>{}; |
| 285 |
279 // As of now names of named optionals are not renamed. Therefore add all | 286 // As of now names of named optionals are not renamed. Therefore add all |
280 // field names used as named optionals into [fixedMemberNames]. | 287 // field names used as named optionals into [fixedMemberNames]. |
281 for (final element in resolvedElements) { | 288 for (final element in resolvedElements) { |
282 if (!element.isConstructor) continue; | 289 if (!element.isConstructor) continue; |
283 Link<Element> optionalParameters = | 290 Link<Element> optionalParameters = |
284 element.functionSignature.optionalParameters; | 291 element.functionSignature.optionalParameters; |
285 for (final optional in optionalParameters) { | 292 for (final optional in optionalParameters) { |
286 if (!optional.isInitializingFormal) continue; | 293 if (!optional.isInitializingFormal) continue; |
287 fixedDynamicNames.add(optional.name); | 294 fixedDynamicNames.add(optional.name); |
288 } | 295 } |
| 296 ClassElement cls = element.enclosingClass; |
| 297 if (cls != null && cls.isEnumClass) { |
| 298 fixedDynamicNames.add('index'); |
| 299 |
| 300 ClassElement existingEnumClass = |
| 301 enumClassMap.putIfAbsent(cls.name, () => cls); |
| 302 if (existingEnumClass != cls) { |
| 303 listener.reportError(cls, MessageKind.GENERIC, |
| 304 {'text': "Duplicate enum names are not supported in dart2dart."}); |
| 305 listener.reportInfo(existingEnumClass, MessageKind.GENERIC, |
| 306 {'text': "This is the other declaration of '${cls.name}'."}); |
| 307 } |
| 308 } |
289 } | 309 } |
| 310 |
| 311 fixedStaticNames.addAll(enumClassMap.keys); |
| 312 |
290 // The VM will automatically invoke the call method of objects | 313 // The VM will automatically invoke the call method of objects |
291 // that are invoked as functions. Make sure to not rename that. | 314 // that are invoked as functions. Make sure to not rename that. |
292 fixedDynamicNames.add('call'); | 315 fixedDynamicNames.add('call'); |
293 | 316 |
294 return new LibraryInfo( | 317 return new LibraryInfo( |
295 fixedStaticNames, fixedDynamicNames, | 318 fixedStaticNames, fixedDynamicNames, |
296 reexportingLibraries, userLibraries); | 319 reexportingLibraries, userLibraries); |
297 } | 320 } |
298 } | 321 } |
299 | 322 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 Node node = treePrinter.makeTypedef(element); | 425 Node node = treePrinter.makeTypedef(element); |
403 addTopLevel(element, new ElementAst(node, treeElements)); | 426 addTopLevel(element, new ElementAst(node, treeElements)); |
404 } | 427 } |
405 | 428 |
406 void newClassElementCallback(ClassElement classElement) { | 429 void newClassElementCallback(ClassElement classElement) { |
407 if (!shouldOutput(classElement)) return; | 430 if (!shouldOutput(classElement)) return; |
408 addClass(classElement); | 431 addClass(classElement); |
409 } | 432 } |
410 | 433 |
411 void addMember(element) { | 434 void addMember(element) { |
412 ElementAst elementAst = parseElementAst(element); | |
413 if (element.isClassMember) { | 435 if (element.isClassMember) { |
414 ClassElement enclosingClass = element.enclosingClass; | 436 ClassElement enclosingClass = element.enclosingClass; |
415 assert(enclosingClass.isClass); | 437 assert(enclosingClass.isClass); |
416 assert(enclosingClass.isTopLevel); | 438 assert(enclosingClass.isTopLevel); |
417 assert(shouldOutput(enclosingClass)); | 439 assert(shouldOutput(enclosingClass)); |
418 addClass(enclosingClass); | 440 addClass(enclosingClass); |
419 classMembers[enclosingClass].add(element); | 441 classMembers[enclosingClass].add(element); |
420 processElement(element, elementAst); | 442 if (enclosingClass.isEnumClass) return; |
| 443 processElement(element, parseElementAst(element)); |
421 } else { | 444 } else { |
422 if (element.isTopLevel) { | 445 if (element.isTopLevel) { |
423 addTopLevel(element, elementAst); | 446 addTopLevel(element, parseElementAst(element)); |
424 } | 447 } |
425 } | 448 } |
426 } | 449 } |
427 } | 450 } |
428 | 451 |
429 /// Main output generator for [DartOutputter] that emits dart code through a | 452 /// Main output generator for [DartOutputter] that emits dart code through a |
430 /// [CompilerOutputProvider]. | 453 /// [CompilerOutputProvider]. |
431 class MainOutputGenerator { | 454 class MainOutputGenerator { |
432 final Map<ClassNode, List<Node>> memberNodes = | 455 final Map<ClassNode, List<Node>> memberNodes = |
433 new Map<ClassNode, List<Node>>(); | 456 new Map<ClassNode, List<Node>>(); |
434 final List<Node> topLevelNodes = <Node>[]; | 457 final List<Node> topLevelNodes = <Node>[]; |
435 | 458 |
436 /// Generates the code and returns the total size. | 459 /// Generates the code and returns the total size. |
437 int generateCode( | 460 int generateCode( |
438 LibraryInfo libraryInfo, | 461 LibraryInfo libraryInfo, |
439 ElementInfo elementInfo, | 462 ElementInfo elementInfo, |
440 PlaceholderCollector collector, | 463 PlaceholderCollector collector, |
441 PlaceholderRenamer placeholderRenamer, | 464 PlaceholderRenamer placeholderRenamer, |
442 FunctionElement mainFunction, | 465 FunctionElement mainFunction, |
443 Uri outputUri, | 466 Uri outputUri, |
444 CompilerOutputProvider outputProvider, | 467 CompilerOutputProvider outputProvider, |
445 MirrorRenamer mirrorRenamer, | 468 MirrorRenamer mirrorRenamer, |
446 {bool multiFile: false, | 469 {bool multiFile: false, |
447 bool forceStripTypes: false, | 470 bool forceStripTypes: false, |
448 bool enableMinification: false}) { | 471 bool enableMinification: false}) { |
449 for (Element element in elementInfo.topLevelElements) { | 472 for (Element element in elementInfo.topLevelElements) { |
450 topLevelNodes.add(elementInfo.elementAsts[element].ast); | 473 topLevelNodes.add(elementInfo.elementAsts[element].ast); |
451 if (element.isClass && !element.isMixinApplication) { | 474 if (element.isClass) { |
| 475 ClassElement cls = element; |
| 476 if (cls.isMixinApplication || cls.isEnumClass) { |
| 477 continue; |
| 478 } |
452 final members = <Node>[]; | 479 final members = <Node>[]; |
453 for (Element member in elementInfo.classMembers[element]) { | 480 for (Element member in elementInfo.classMembers[cls]) { |
454 members.add(elementInfo.elementAsts[member].ast); | 481 members.add(elementInfo.elementAsts[member].ast); |
455 } | 482 } |
456 memberNodes[elementInfo.elementAsts[element].ast] = members; | 483 memberNodes[elementInfo.elementAsts[cls].ast] = members; |
457 } | 484 } |
458 } | 485 } |
459 | 486 |
460 mirrorRenamer.addRenames(placeholderRenamer.renames, | 487 mirrorRenamer.addRenames(placeholderRenamer.renames, |
461 topLevelNodes, collector); | 488 topLevelNodes, collector); |
462 | 489 |
463 Map<LibraryElement, String> outputPaths = new Map<LibraryElement, String>(); | 490 Map<LibraryElement, String> outputPaths = new Map<LibraryElement, String>(); |
464 Map<LibraryElement, EmitterUnparser> unparsers = | 491 Map<LibraryElement, EmitterUnparser> unparsers = |
465 new Map<LibraryElement, EmitterUnparser>(); | 492 new Map<LibraryElement, EmitterUnparser>(); |
466 | 493 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 outputProvider("", "dart") | 591 outputProvider("", "dart") |
565 ..add(code) | 592 ..add(code) |
566 ..close(); | 593 ..close(); |
567 | 594 |
568 totalSize = code.length; | 595 totalSize = code.length; |
569 } | 596 } |
570 | 597 |
571 return totalSize; | 598 return totalSize; |
572 } | 599 } |
573 } | 600 } |
OLD | NEW |