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 |