| 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 BailoutException { | 5 class BailoutException { |
| 6 final String reason; | 6 final String reason; |
| 7 | 7 |
| 8 const BailoutException(this.reason); | 8 const BailoutException(this.reason); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 * collections. | 39 * collections. |
| 40 */ | 40 */ |
| 41 void addMemberToClass(Element element, ClassElement classElement) { | 41 void addMemberToClass(Element element, ClassElement classElement) { |
| 42 // ${element} should have ${classElement} as enclosing. | 42 // ${element} should have ${classElement} as enclosing. |
| 43 assert(element.enclosingElement == classElement); | 43 assert(element.enclosingElement == classElement); |
| 44 Set<Element> resolvedElementsInClass = resolvedClassMembers.putIfAbsent( | 44 Set<Element> resolvedElementsInClass = resolvedClassMembers.putIfAbsent( |
| 45 classElement, () => new Set<Element>()); | 45 classElement, () => new Set<Element>()); |
| 46 resolvedElementsInClass.add(element); | 46 resolvedElementsInClass.add(element); |
| 47 } | 47 } |
| 48 | 48 |
| 49 /** | |
| 50 * Outputs given class element with given inner elements to a string buffer. | |
| 51 */ | |
| 52 void outputClass(ClassElement classElement, Set<Element> innerElements, | |
| 53 StringBuffer sb) { | |
| 54 // TODO(smok): Very soon properly print out correct class declaration with | |
| 55 // extends, implements, etc. | |
| 56 sb.add('class '); | |
| 57 sb.add(classElement.name.slowToString()); | |
| 58 sb.add('{'); | |
| 59 innerElements.forEach((element) { | |
| 60 // TODO(smok): Filter out default constructors here. | |
| 61 outputElement(element, sb); | |
| 62 }); | |
| 63 sb.add('}'); | |
| 64 } | |
| 65 | |
| 66 void outputElement(Element element, StringBuffer sb) { | |
| 67 // TODO(smok): Figure out why AbstractFieldElement appears here, | |
| 68 // we have used getters/setters resolved instead of it. | |
| 69 if (element is SynthesizedConstructorElement | |
| 70 || element is AbstractFieldElement) return; | |
| 71 if (element.isField()) { | |
| 72 // Add modifiers first. | |
| 73 sb.add(element.modifiers.toString()); | |
| 74 sb.add(' '); | |
| 75 // Figure out type. | |
| 76 if (element is VariableElement) { | |
| 77 VariableListElement variables = element.variables; | |
| 78 if (variables.type !== null) { | |
| 79 sb.add(variables.type); | |
| 80 sb.add(' '); | |
| 81 } | |
| 82 } | |
| 83 // TODO(smok): Maybe not rely on node unparsing, | |
| 84 // but unparse initializer manually. | |
| 85 sb.add(element.parseNode(compiler).unparse()); | |
| 86 sb.add(';'); | |
| 87 } else { | |
| 88 if (element.isSetter()) { | |
| 89 sb.add('set '); | |
| 90 } else if (element.isGetter()) { | |
| 91 sb.add('get '); | |
| 92 } | |
| 93 sb.add(element.parseNode(compiler).unparse()); | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 void assembleProgram() { | 49 void assembleProgram() { |
| 98 resolvedElements.forEach((element, treeElements) { | 50 resolvedElements.forEach((element, treeElements) { |
| 99 unparseValidator.check(element); | 51 unparseValidator.check(element); |
| 100 }); | 52 }); |
| 101 | 53 |
| 102 // TODO(antonm): Eventually bailouts will be proper errors. | 54 // TODO(antonm): Eventually bailouts will be proper errors. |
| 103 void bailout(String reason) { | 55 void bailout(String reason) { |
| 104 throw new BailoutException(reason); | 56 throw new BailoutException(reason); |
| 105 } | 57 } |
| 106 | 58 |
| 107 /** | 59 /** |
| 108 * Tells whether we should output given element. Corelib classes like | 60 * Tells whether we should output given element. Corelib classes like |
| 109 * Object should not be in the resulting code. | 61 * Object should not be in the resulting code. |
| 110 */ | 62 */ |
| 111 bool shouldOutput(Element element) { | 63 bool shouldOutput(Element element) { |
| 112 return element.kind !== ElementKind.VOID | 64 return element.kind !== ElementKind.VOID |
| 113 && element.getLibrary() !== compiler.coreLibrary; | 65 && element.getLibrary() !== compiler.coreLibrary; |
| 114 } | 66 } |
| 115 | 67 |
| 116 try { | 68 try { |
| 117 StringBuffer sb = new StringBuffer(); | 69 Emitter emitter = new Emitter(compiler); |
| 118 resolvedElements.forEach((element, treeElements) { | 70 resolvedElements.forEach((element, treeElements) { |
| 119 if (!shouldOutput(element)) return; | 71 if (!shouldOutput(element)) return; |
| 120 if (element.isMember()) { | 72 if (element.isMember()) { |
| 121 var enclosingClass = element.enclosingElement; | 73 var enclosingClass = element.enclosingElement; |
| 122 assert(enclosingClass.isClass()); | 74 assert(enclosingClass.isClass()); |
| 123 assert(enclosingClass.isTopLevel()); | 75 assert(enclosingClass.isTopLevel()); |
| 124 addMemberToClass(element, enclosingClass); | 76 addMemberToClass(element, enclosingClass); |
| 125 return; | 77 return; |
| 126 } | 78 } |
| 127 if (!element.isTopLevel()) { | 79 if (!element.isTopLevel()) { |
| 128 bailout('Cannot process non top-level $element'); | 80 bailout('Cannot process non top-level $element'); |
| 129 } | 81 } |
| 130 | 82 |
| 131 outputElement(element, sb); | 83 emitter.outputElement(element); |
| 132 }); | 84 }); |
| 133 | 85 |
| 134 // Now output resolved classes with inner elements we met before. | 86 // Now output resolved classes with inner elements we met before. |
| 135 resolvedClassMembers.forEach((classElement, resolvedElements) { | 87 resolvedClassMembers.forEach(emitter.outputClass); |
| 136 outputClass(classElement, resolvedElements, sb); | 88 compiler.assembledCode = emitter.toString(); |
| 137 }); | |
| 138 compiler.assembledCode = sb.toString(); | |
| 139 } catch (BailoutException e) { | 89 } catch (BailoutException e) { |
| 140 compiler.assembledCode = ''' | 90 compiler.assembledCode = ''' |
| 141 main() { | 91 main() { |
| 142 final bailout_reason = "${e.reason}"; | 92 final bailout_reason = "${e.reason}"; |
| 143 } | 93 } |
| 144 '''; | 94 '''; |
| 145 } | 95 } |
| 146 } | 96 } |
| 147 | 97 |
| 148 log(String message) => compiler.log('[DartBackend] $message'); | 98 log(String message) => compiler.log('[DartBackend] $message'); |
| 149 } | 99 } |
| OLD | NEW |