| 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 'common/names.dart' show | 7 import 'common/names.dart' show |
| 8 Identifiers; | 8 Identifiers; |
| 9 import 'common/resolution.dart' show | 9 import 'common/resolution.dart' show |
| 10 Parsing, | 10 Parsing, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } | 71 } |
| 72 assert(closureMappingCache[node] != null); | 72 assert(closureMappingCache[node] != null); |
| 73 return closureMappingCache[node]; | 73 return closureMappingCache[node]; |
| 74 }); | 74 }); |
| 75 } | 75 } |
| 76 | 76 |
| 77 ClosureClassMap getMappingForNestedFunction(FunctionExpression node) { | 77 ClosureClassMap getMappingForNestedFunction(FunctionExpression node) { |
| 78 return measure(() { | 78 return measure(() { |
| 79 ClosureClassMap nestedClosureData = closureMappingCache[node]; | 79 ClosureClassMap nestedClosureData = closureMappingCache[node]; |
| 80 if (nestedClosureData == null) { | 80 if (nestedClosureData == null) { |
| 81 compiler.internalError(node, "No closure cache."); | 81 reporter.internalError(node, "No closure cache."); |
| 82 } | 82 } |
| 83 return nestedClosureData; | 83 return nestedClosureData; |
| 84 }); | 84 }); |
| 85 } | 85 } |
| 86 | 86 |
| 87 void forgetElement(var closure) { | 87 void forgetElement(var closure) { |
| 88 ClosureClassElement cls; | 88 ClosureClassElement cls; |
| 89 if (closure is ClosureFieldElement) { | 89 if (closure is ClosureFieldElement) { |
| 90 cls = closure.closureClass; | 90 cls = closure.closureClass; |
| 91 } else if (closure is SynthesizedCallMethodElementX) { | 91 } else if (closure is SynthesizedCallMethodElementX) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 supertype = superclass.thisType; | 204 supertype = superclass.thisType; |
| 205 interfaces = const Link<DartType>(); | 205 interfaces = const Link<DartType>(); |
| 206 thisType = rawType = new InterfaceType(this); | 206 thisType = rawType = new InterfaceType(this); |
| 207 allSupertypesAndSelf = | 207 allSupertypesAndSelf = |
| 208 superclass.allSupertypesAndSelf.extendClass(thisType); | 208 superclass.allSupertypesAndSelf.extendClass(thisType); |
| 209 callType = methodElement.type; | 209 callType = methodElement.type; |
| 210 } | 210 } |
| 211 | 211 |
| 212 Iterable<ClosureFieldElement> get closureFields => _closureFields; | 212 Iterable<ClosureFieldElement> get closureFields => _closureFields; |
| 213 | 213 |
| 214 void addField(ClosureFieldElement field, DiagnosticListener listener) { | 214 void addField(ClosureFieldElement field, DiagnosticReporter listener) { |
| 215 _closureFields.add(field); | 215 _closureFields.add(field); |
| 216 addMember(field, listener); | 216 addMember(field, listener); |
| 217 } | 217 } |
| 218 | 218 |
| 219 bool get hasNode => true; | 219 bool get hasNode => true; |
| 220 | 220 |
| 221 bool get isClosure => true; | 221 bool get isClosure => true; |
| 222 | 222 |
| 223 Token get position => node.getBeginToken(); | 223 Token get position => node.getBeginToken(); |
| 224 | 224 |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 | 503 |
| 504 // The closureData of the currentFunctionElement. | 504 // The closureData of the currentFunctionElement. |
| 505 ClosureClassMap closureData; | 505 ClosureClassMap closureData; |
| 506 | 506 |
| 507 bool insideClosure = false; | 507 bool insideClosure = false; |
| 508 | 508 |
| 509 ClosureTranslator(this.compiler, | 509 ClosureTranslator(this.compiler, |
| 510 this.elements, | 510 this.elements, |
| 511 this.closureMappingCache); | 511 this.closureMappingCache); |
| 512 | 512 |
| 513 DiagnosticReporter get reporter => compiler.reporter; |
| 514 |
| 513 /// Generate a unique name for the [id]th closure field, with proposed name | 515 /// Generate a unique name for the [id]th closure field, with proposed name |
| 514 /// [name]. | 516 /// [name]. |
| 515 /// | 517 /// |
| 516 /// The result is used as the name of [ClosureFieldElement]s, and must | 518 /// The result is used as the name of [ClosureFieldElement]s, and must |
| 517 /// therefore be unique to avoid breaking an invariant in the element model | 519 /// therefore be unique to avoid breaking an invariant in the element model |
| 518 /// (classes cannot declare multiple fields with the same name). | 520 /// (classes cannot declare multiple fields with the same name). |
| 519 /// | 521 /// |
| 520 /// Also, the names should be distinct from real field names to prevent | 522 /// Also, the names should be distinct from real field names to prevent |
| 521 /// clashes with selectors for those fields. | 523 /// clashes with selectors for those fields. |
| 522 String getClosureVariableName(String name, int id) { | 524 String getClosureVariableName(String name, int id) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 535 String getBoxFieldName(int id) { | 537 String getBoxFieldName(int id) { |
| 536 return "_box_$id"; | 538 return "_box_$id"; |
| 537 } | 539 } |
| 538 | 540 |
| 539 bool isCapturedVariable(Local element) { | 541 bool isCapturedVariable(Local element) { |
| 540 return _capturedVariableMapping.containsKey(element); | 542 return _capturedVariableMapping.containsKey(element); |
| 541 } | 543 } |
| 542 | 544 |
| 543 void addCapturedVariable(Node node, Local variable) { | 545 void addCapturedVariable(Node node, Local variable) { |
| 544 if (_capturedVariableMapping[variable] != null) { | 546 if (_capturedVariableMapping[variable] != null) { |
| 545 compiler.internalError(node, 'In closure analyzer.'); | 547 reporter.internalError(node, 'In closure analyzer.'); |
| 546 } | 548 } |
| 547 _capturedVariableMapping[variable] = null; | 549 _capturedVariableMapping[variable] = null; |
| 548 } | 550 } |
| 549 | 551 |
| 550 void setCapturedVariableBoxField(Local variable, | 552 void setCapturedVariableBoxField(Local variable, |
| 551 BoxFieldElement boxField) { | 553 BoxFieldElement boxField) { |
| 552 assert(isCapturedVariable(variable)); | 554 assert(isCapturedVariable(variable)); |
| 553 _capturedVariableMapping[variable] = boxField; | 555 _capturedVariableMapping[variable] = boxField; |
| 554 } | 556 } |
| 555 | 557 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 boxes.add(boxFieldElement.box); | 607 boxes.add(boxFieldElement.box); |
| 606 } | 608 } |
| 607 }); | 609 }); |
| 608 ClosureClassElement closureClass = data.closureClassElement; | 610 ClosureClassElement closureClass = data.closureClassElement; |
| 609 assert(closureClass != null || | 611 assert(closureClass != null || |
| 610 (fieldCaptures.isEmpty && boxes.isEmpty)); | 612 (fieldCaptures.isEmpty && boxes.isEmpty)); |
| 611 | 613 |
| 612 void addClosureField(Local local, String name) { | 614 void addClosureField(Local local, String name) { |
| 613 ClosureFieldElement closureField = | 615 ClosureFieldElement closureField = |
| 614 new ClosureFieldElement(name, local, closureClass); | 616 new ClosureFieldElement(name, local, closureClass); |
| 615 closureClass.addField(closureField, compiler); | 617 closureClass.addField(closureField, reporter); |
| 616 data.freeVariableMap[local] = closureField; | 618 data.freeVariableMap[local] = closureField; |
| 617 } | 619 } |
| 618 | 620 |
| 619 // Add the box elements first so we get the same ordering. | 621 // Add the box elements first so we get the same ordering. |
| 620 // TODO(sra): What is the canonical order of multiple boxes? | 622 // TODO(sra): What is the canonical order of multiple boxes? |
| 621 for (BoxLocal capturedElement in boxes) { | 623 for (BoxLocal capturedElement in boxes) { |
| 622 addClosureField(capturedElement, capturedElement.name); | 624 addClosureField(capturedElement, capturedElement.name); |
| 623 } | 625 } |
| 624 | 626 |
| 625 /// Comparator for locals. Position boxes before elements. | 627 /// Comparator for locals. Position boxes before elements. |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 ClosureClassElement globalizedElement = new ClosureClassElement( | 997 ClosureClassElement globalizedElement = new ClosureClassElement( |
| 996 node, closureName, compiler, element); | 998 node, closureName, compiler, element); |
| 997 FunctionElement callElement = | 999 FunctionElement callElement = |
| 998 new SynthesizedCallMethodElementX(Identifiers.call, | 1000 new SynthesizedCallMethodElementX(Identifiers.call, |
| 999 element, | 1001 element, |
| 1000 globalizedElement); | 1002 globalizedElement); |
| 1001 backend.maybeMarkClosureAsNeededForReflection( | 1003 backend.maybeMarkClosureAsNeededForReflection( |
| 1002 globalizedElement, callElement, element); | 1004 globalizedElement, callElement, element); |
| 1003 MemberElement enclosing = element.memberContext; | 1005 MemberElement enclosing = element.memberContext; |
| 1004 enclosing.nestedClosures.add(callElement); | 1006 enclosing.nestedClosures.add(callElement); |
| 1005 globalizedElement.addMember(callElement, compiler); | 1007 globalizedElement.addMember(callElement, reporter); |
| 1006 globalizedElement.computeAllClassMembers(compiler); | 1008 globalizedElement.computeAllClassMembers(compiler); |
| 1007 // The nested function's 'this' is the same as the one for the outer | 1009 // The nested function's 'this' is the same as the one for the outer |
| 1008 // function. It could be [null] if we are inside a static method. | 1010 // function. It could be [null] if we are inside a static method. |
| 1009 ThisLocal thisElement = closureData.thisLocal; | 1011 ThisLocal thisElement = closureData.thisLocal; |
| 1010 | 1012 |
| 1011 return new ClosureClassMap(element, globalizedElement, | 1013 return new ClosureClassMap(element, globalizedElement, |
| 1012 callElement, thisElement); | 1014 callElement, thisElement); |
| 1013 } | 1015 } |
| 1014 | 1016 |
| 1015 void visitInvokable(ExecutableElement element, | 1017 void visitInvokable(ExecutableElement element, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1123 | 1125 |
| 1124 String get name => typeVariable.name; | 1126 String get name => typeVariable.name; |
| 1125 | 1127 |
| 1126 int get hashCode => typeVariable.hashCode; | 1128 int get hashCode => typeVariable.hashCode; |
| 1127 | 1129 |
| 1128 bool operator ==(other) { | 1130 bool operator ==(other) { |
| 1129 if (other is! TypeVariableLocal) return false; | 1131 if (other is! TypeVariableLocal) return false; |
| 1130 return typeVariable == other.typeVariable; | 1132 return typeVariable == other.typeVariable; |
| 1131 } | 1133 } |
| 1132 } | 1134 } |
| OLD | NEW |