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 library closureToClassMapper; | 5 library closureToClassMapper; |
6 | 6 |
7 import "elements/elements.dart"; | 7 import "elements/elements.dart"; |
8 import "dart2jslib.dart"; | 8 import "dart2jslib.dart"; |
9 import "dart_types.dart"; | 9 import "dart_types.dart"; |
10 import "scanner/scannerlib.dart" show Token; | 10 import "scanner/scannerlib.dart" show Token; |
(...skipping 25 matching lines...) Expand all Loading... |
36 if (cached != null) return cached; | 36 if (cached != null) return cached; |
37 | 37 |
38 ClosureTranslator translator = | 38 ClosureTranslator translator = |
39 new ClosureTranslator(compiler, elements, closureMappingCache, namer); | 39 new ClosureTranslator(compiler, elements, closureMappingCache, namer); |
40 | 40 |
41 // The translator will store the computed closure-mappings inside the | 41 // The translator will store the computed closure-mappings inside the |
42 // cache. One for given node and one for each nested closure. | 42 // cache. One for given node and one for each nested closure. |
43 if (node is FunctionExpression) { | 43 if (node is FunctionExpression) { |
44 translator.translateFunction(element, node); | 44 translator.translateFunction(element, node); |
45 } else if (element.isSynthesized) { | 45 } else if (element.isSynthesized) { |
46 return new ClosureClassMap(null, null, null, | 46 return new ClosureClassMap(null, null, null, new ThisElement(element)); |
47 new ThisElement(element, compiler.types.dynamicType)); | |
48 } else { | 47 } else { |
49 assert(element.isField); | 48 assert(element.isField); |
50 VariableElement field = element; | 49 VariableElement field = element; |
51 if (field.initializer != null) { | 50 if (field.initializer != null) { |
52 // The lazy initializer of a static. | 51 // The lazy initializer of a static. |
53 translator.translateLazyInitializer(element, node, field.initializer); | 52 translator.translateLazyInitializer(element, node, field.initializer); |
54 } else { | 53 } else { |
55 assert(element.isInstanceMember); | 54 assert(element.isInstanceMember); |
56 closureMappingCache[node] = | 55 closureMappingCache[node] = |
57 new ClosureClassMap(null, null, null, | 56 new ClosureClassMap(null, null, null, new ThisElement(element)); |
58 new ThisElement(element, compiler.types.dynamicType)); | |
59 } | 57 } |
60 } | 58 } |
61 assert(closureMappingCache[node] != null); | 59 assert(closureMappingCache[node] != null); |
62 return closureMappingCache[node]; | 60 return closureMappingCache[node]; |
63 }); | 61 }); |
64 } | 62 } |
65 | 63 |
66 ClosureClassMap getMappingForNestedFunction(FunctionExpression node) { | 64 ClosureClassMap getMappingForNestedFunction(FunctionExpression node) { |
67 return measure(() { | 65 return measure(() { |
68 ClosureClassMap nestedClosureData = closureMappingCache[node]; | 66 ClosureClassMap nestedClosureData = closureMappingCache[node]; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 162 |
165 get enclosingElement => methodElement; | 163 get enclosingElement => methodElement; |
166 | 164 |
167 accept(ElementVisitor visitor) => visitor.visitClosureClassElement(this); | 165 accept(ElementVisitor visitor) => visitor.visitClosureClassElement(this); |
168 } | 166 } |
169 | 167 |
170 // TODO(ahe): These classes continuously cause problems. We need to | 168 // TODO(ahe): These classes continuously cause problems. We need to |
171 // move these classes to elements/modelx.dart or see if we can find a | 169 // move these classes to elements/modelx.dart or see if we can find a |
172 // more general solution. | 170 // more general solution. |
173 class BoxElement extends ElementX implements TypedElement { | 171 class BoxElement extends ElementX implements TypedElement { |
174 final DartType type; | 172 BoxElement(String name, Element enclosingElement) |
175 | |
176 BoxElement(String name, Element enclosingElement, this.type) | |
177 : super(name, ElementKind.VARIABLE_LIST, enclosingElement); | 173 : super(name, ElementKind.VARIABLE_LIST, enclosingElement); |
178 | 174 |
179 DartType computeType(Compiler compiler) => type; | 175 DartType computeType(Compiler compiler) => type; |
180 | 176 |
| 177 DartType get type => const DynamicType(); |
| 178 |
181 accept(ElementVisitor visitor) => visitor.visitBoxElement(this); | 179 accept(ElementVisitor visitor) => visitor.visitBoxElement(this); |
182 } | 180 } |
183 | 181 |
184 // TODO(ngeoffray, ahe): These classes continuously cause problems. We need to | 182 // TODO(ngeoffray, ahe): These classes continuously cause problems. We need to |
185 // move these classes to elements/modelx.dart or see if we can find a | 183 // move these classes to elements/modelx.dart or see if we can find a |
186 // more general solution. | 184 // more general solution. |
187 class BoxFieldElement extends ElementX implements TypedElement { | 185 class BoxFieldElement extends ElementX implements TypedElement { |
188 BoxFieldElement(String name, | 186 BoxFieldElement(String name, |
189 this.variableElement, | 187 this.variableElement, |
190 BoxElement enclosingBox) | 188 BoxElement enclosingBox) |
191 : super(name, ElementKind.FIELD, enclosingBox); | 189 : super(name, ElementKind.FIELD, enclosingBox); |
192 | 190 |
193 DartType computeType(Compiler compiler) => type; | 191 DartType computeType(Compiler compiler) => type; |
194 | 192 |
195 DartType get type => variableElement.type; | 193 DartType get type => variableElement.type; |
196 | 194 |
197 final VariableElement variableElement; | 195 final VariableElement variableElement; |
198 | 196 |
199 accept(ElementVisitor visitor) => visitor.visitBoxFieldElement(this); | 197 accept(ElementVisitor visitor) => visitor.visitBoxFieldElement(this); |
200 } | 198 } |
201 | 199 |
202 // TODO(ahe): These classes continuously cause problems. We need to | 200 // TODO(ahe): These classes continuously cause problems. We need to |
203 // move these classes to elements/modelx.dart or see if we can find a | 201 // move these classes to elements/modelx.dart or see if we can find a |
204 // more general solution. | 202 // more general solution. |
205 class ThisElement extends ElementX implements TypedElement { | 203 class ThisElement extends ElementX implements TypedElement { |
206 final DartType type; | 204 ThisElement(Element enclosing) |
207 | |
208 ThisElement(Element enclosing, this.type) | |
209 : super('this', ElementKind.PARAMETER, enclosing); | 205 : super('this', ElementKind.PARAMETER, enclosing); |
210 | 206 |
211 bool get isAssignable => false; | 207 bool get isAssignable => false; |
212 | 208 |
213 DartType computeType(Compiler compiler) => compiler.types.dynamicType; | 209 DartType computeType(Compiler compiler) => type; |
| 210 |
| 211 DartType get type => const DynamicType(); |
214 | 212 |
215 // Since there is no declaration corresponding to 'this', use the position of | 213 // Since there is no declaration corresponding to 'this', use the position of |
216 // the enclosing method. | 214 // the enclosing method. |
217 Token get position => enclosingElement.position; | 215 Token get position => enclosingElement.position; |
218 | 216 |
219 accept(ElementVisitor visitor) => visitor.visitThisElement(this); | 217 accept(ElementVisitor visitor) => visitor.visitThisElement(this); |
220 } | 218 } |
221 | 219 |
222 /// Call method of a closure class. | 220 /// Call method of a closure class. |
223 class SynthesizedCallMethodElementX extends FunctionElementX { | 221 class SynthesizedCallMethodElementX extends FunctionElementX { |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 for (Element element in scopeVariables) { | 628 for (Element element in scopeVariables) { |
631 // No need to box non-assignable elements. | 629 // No need to box non-assignable elements. |
632 if (!element.isAssignable) continue; | 630 if (!element.isAssignable) continue; |
633 if (!mutatedVariables.contains(element)) continue; | 631 if (!mutatedVariables.contains(element)) continue; |
634 if (capturedVariableMapping.containsKey(element)) { | 632 if (capturedVariableMapping.containsKey(element)) { |
635 if (box == null) { | 633 if (box == null) { |
636 // TODO(floitsch): construct better box names. | 634 // TODO(floitsch): construct better box names. |
637 String boxName = | 635 String boxName = |
638 namer.getClosureVariableName('box', closureFieldCounter++); | 636 namer.getClosureVariableName('box', closureFieldCounter++); |
639 box = new BoxElement( | 637 box = new BoxElement( |
640 boxName, currentElement, compiler.types.dynamicType); | 638 boxName, currentElement); |
641 } | 639 } |
642 String elementName = element.name; | 640 String elementName = element.name; |
643 String boxedName = | 641 String boxedName = |
644 namer.getClosureVariableName(elementName, boxedFieldCounter++); | 642 namer.getClosureVariableName(elementName, boxedFieldCounter++); |
645 // TODO(kasperl): Should this be a FieldElement instead? | 643 // TODO(kasperl): Should this be a FieldElement instead? |
646 Element boxed = new BoxFieldElement(boxedName, element, box); | 644 Element boxed = new BoxFieldElement(boxedName, element, box); |
647 // No need to rename the fields of a box, so we give them a native name | 645 // No need to rename the fields of a box, so we give them a native name |
648 // right now. | 646 // right now. |
649 boxed.setFixedBackendName(boxedName); | 647 boxed.setFixedBackendName(boxedName); |
650 scopeMapping[element] = boxed; | 648 scopeMapping[element] = boxed; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 | 757 |
760 insideClosure = outermostElement != null; | 758 insideClosure = outermostElement != null; |
761 currentElement = element; | 759 currentElement = element; |
762 if (insideClosure) { | 760 if (insideClosure) { |
763 closures.add(node); | 761 closures.add(node); |
764 closureData = globalizeClosure(node, element); | 762 closureData = globalizeClosure(node, element); |
765 } else { | 763 } else { |
766 outermostElement = element; | 764 outermostElement = element; |
767 Element thisElement = null; | 765 Element thisElement = null; |
768 if (element.isInstanceMember || element.isGenerativeConstructor) { | 766 if (element.isInstanceMember || element.isGenerativeConstructor) { |
769 thisElement = new ThisElement(element, compiler.types.dynamicType); | 767 thisElement = new ThisElement(element); |
770 } | 768 } |
771 closureData = new ClosureClassMap(null, null, null, thisElement); | 769 closureData = new ClosureClassMap(null, null, null, thisElement); |
772 } | 770 } |
773 closureMappingCache[node] = closureData; | 771 closureMappingCache[node] = closureData; |
774 | 772 |
775 inNewScope(node, () { | 773 inNewScope(node, () { |
776 // We have to declare the implicit 'this' parameter. | 774 // We have to declare the implicit 'this' parameter. |
777 if (!insideClosure && closureData.thisElement != null) { | 775 if (!insideClosure && closureData.thisElement != null) { |
778 declareLocal(closureData.thisElement); | 776 declareLocal(closureData.thisElement); |
779 } | 777 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 } | 852 } |
855 | 853 |
856 visitTryStatement(TryStatement node) { | 854 visitTryStatement(TryStatement node) { |
857 // TODO(ngeoffray): implement finer grain state. | 855 // TODO(ngeoffray): implement finer grain state. |
858 bool oldInTryStatement = inTryStatement; | 856 bool oldInTryStatement = inTryStatement; |
859 inTryStatement = true; | 857 inTryStatement = true; |
860 node.visitChildren(this); | 858 node.visitChildren(this); |
861 inTryStatement = oldInTryStatement; | 859 inTryStatement = oldInTryStatement; |
862 } | 860 } |
863 } | 861 } |
OLD | NEW |