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('elements'); | 5 #library('elements'); |
6 | 6 |
7 #import('../tree/tree.dart'); | 7 #import('../tree/tree.dart'); |
8 #import('../scanner/scannerlib.dart'); | 8 #import('../scanner/scannerlib.dart'); |
9 #import('../leg.dart'); // TODO(karlklose): we only need type. | 9 #import('../leg.dart'); // TODO(karlklose): we only need type. |
10 #import('../util/util.dart'); | 10 #import('../util/util.dart'); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 String holderName = enclosingElement.name.slowToString(); | 209 String holderName = enclosingElement.name.slowToString(); |
210 return '$kind($holderName#${name.slowToString()})'; | 210 return '$kind($holderName#${name.slowToString()})'; |
211 } else { | 211 } else { |
212 return '$kind(${name.slowToString()})'; | 212 return '$kind(${name.slowToString()})'; |
213 } | 213 } |
214 } | 214 } |
215 | 215 |
216 bool _isNative = false; | 216 bool _isNative = false; |
217 void setNative() { _isNative = true; } | 217 void setNative() { _isNative = true; } |
218 bool isNative() => _isNative; | 218 bool isNative() => _isNative; |
| 219 |
| 220 FunctionElement asFunctionElement() => null; |
219 } | 221 } |
220 | 222 |
221 class ContainerElement extends Element { | 223 class ContainerElement extends Element { |
222 ContainerElement(name, kind, enclosingElement) : | 224 ContainerElement(name, kind, enclosingElement) : |
223 super(name, kind, enclosingElement); | 225 super(name, kind, enclosingElement); |
224 | 226 |
225 abstract void addMember(Element element, DiagnosticListener listener); | 227 abstract void addMember(Element element, DiagnosticListener listener); |
226 | 228 |
227 void addGetterOrSetter(Element element, | 229 void addGetterOrSetter(Element element, |
228 Element existing, | 230 Element existing, |
(...skipping 16 matching lines...) Expand all Loading... |
245 field.getter = element; | 247 field.getter = element; |
246 } else { | 248 } else { |
247 if (field.setter != null && field.setter != element) { | 249 if (field.setter != null && field.setter != element) { |
248 reportError(field.setter); | 250 reportError(field.setter); |
249 } | 251 } |
250 field.setter = element; | 252 field.setter = element; |
251 } | 253 } |
252 } | 254 } |
253 } else { | 255 } else { |
254 AbstractFieldElement field = new AbstractFieldElement(element.name, this); | 256 AbstractFieldElement field = new AbstractFieldElement(element.name, this); |
255 addMember(field, listener); | |
256 if (element.kind == ElementKind.GETTER) { | 257 if (element.kind == ElementKind.GETTER) { |
257 field.getter = element; | 258 field.getter = element; |
258 } else { | 259 } else { |
259 field.setter = element; | 260 field.setter = element; |
260 } | 261 } |
| 262 addMember(field, listener); |
261 } | 263 } |
262 } | 264 } |
263 } | 265 } |
264 | 266 |
265 class CompilationUnitElement extends ContainerElement { | 267 class CompilationUnitElement extends ContainerElement { |
266 final Script script; | 268 final Script script; |
267 Link<Element> topLevelElements = const EmptyLink<Element>(); | 269 Link<Element> topLevelElements = const EmptyLink<Element>(); |
268 | 270 |
269 CompilationUnitElement(Script script, Element enclosing) | 271 CompilationUnitElement(Script script, Element enclosing) |
270 : this.script = script, | 272 : this.script = script, |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 } | 497 } |
496 | 498 |
497 parseNode(DiagnosticListener listener) { | 499 parseNode(DiagnosticListener listener) { |
498 throw "internal error: ForeignElement has no node"; | 500 throw "internal error: ForeignElement has no node"; |
499 } | 501 } |
500 } | 502 } |
501 | 503 |
502 class AbstractFieldElement extends Element { | 504 class AbstractFieldElement extends Element { |
503 FunctionElement getter; | 505 FunctionElement getter; |
504 FunctionElement setter; | 506 FunctionElement setter; |
505 Modifiers modifiers; | |
506 | 507 |
507 AbstractFieldElement(SourceString name, Element enclosing) | 508 AbstractFieldElement(SourceString name, Element enclosing) |
508 : super(name, ElementKind.ABSTRACT_FIELD, enclosing), | 509 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); |
509 modifiers = new Modifiers.empty(); | |
510 | 510 |
511 Type computeType(Compiler compiler) { | 511 Type computeType(Compiler compiler) { |
512 throw "internal error: AbstractFieldElement has no type"; | 512 throw "internal error: AbstractFieldElement has no type"; |
513 } | 513 } |
514 | 514 |
515 Node parseNode(DiagnosticListener listener) { | 515 Node parseNode(DiagnosticListener listener) { |
516 throw "internal error: AbstractFieldElement has no node"; | 516 throw "internal error: AbstractFieldElement has no node"; |
517 } | 517 } |
518 | 518 |
519 position() { | 519 position() { |
520 // The getter and setter may be defined in two different | 520 // The getter and setter may be defined in two different |
521 // compilation units. However, we know that one of them is | 521 // compilation units. However, we know that one of them is |
522 // non-null and defined in the same compilation unit as the | 522 // non-null and defined in the same compilation unit as the |
523 // abstract element. | 523 // abstract element. |
524 // | 524 // |
525 // We need to make sure that the position returned is relative to | 525 // We need to make sure that the position returned is relative to |
526 // the compilation unit of the abstract element. | 526 // the compilation unit of the abstract element. |
527 if (getter !== null && getter.enclosingElement === enclosingElement) { | 527 if (getter !== null && getter.enclosingElement === enclosingElement) { |
528 return getter.position(); | 528 return getter.position(); |
529 } else if (setter != null) { | 529 } else { |
530 // TODO(ahe): checking for null should not be necessary. | |
531 return setter.position(); | 530 return setter.position(); |
532 } | 531 } |
533 } | 532 } |
| 533 |
| 534 Modifiers get modifiers() { |
| 535 // The resolver ensures that the flags match (ignoring abstract). |
| 536 if (getter !== null) { |
| 537 return new Modifiers.withFlags( |
| 538 getter.modifiers.nodes, |
| 539 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 540 } else { |
| 541 return new Modifiers.withFlags( |
| 542 setter.modifiers.nodes, |
| 543 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 544 } |
| 545 } |
534 } | 546 } |
535 | 547 |
536 class FunctionSignature { | 548 class FunctionSignature { |
537 Link<Element> requiredParameters; | 549 Link<Element> requiredParameters; |
538 Link<Element> optionalParameters; | 550 Link<Element> optionalParameters; |
539 Type returnType; | 551 Type returnType; |
540 int requiredParameterCount; | 552 int requiredParameterCount; |
541 int optionalParameterCount; | 553 int optionalParameterCount; |
542 FunctionSignature(this.requiredParameters, | 554 FunctionSignature(this.requiredParameters, |
543 this.optionalParameters, | 555 this.optionalParameters, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 | 647 |
636 FunctionType computeType(Compiler compiler) { | 648 FunctionType computeType(Compiler compiler) { |
637 if (type != null) return type; | 649 if (type != null) return type; |
638 type = compiler.computeFunctionType(this, computeSignature(compiler)); | 650 type = compiler.computeFunctionType(this, computeSignature(compiler)); |
639 return type; | 651 return type; |
640 } | 652 } |
641 | 653 |
642 Node parseNode(DiagnosticListener listener) => cachedNode; | 654 Node parseNode(DiagnosticListener listener) => cachedNode; |
643 | 655 |
644 Token position() => cachedNode.getBeginToken(); | 656 Token position() => cachedNode.getBeginToken(); |
| 657 |
| 658 FunctionElement asFunctionElement() => this; |
645 } | 659 } |
646 | 660 |
647 class ConstructorBodyElement extends FunctionElement { | 661 class ConstructorBodyElement extends FunctionElement { |
648 FunctionElement constructor; | 662 FunctionElement constructor; |
649 | 663 |
650 ConstructorBodyElement(FunctionElement constructor) | 664 ConstructorBodyElement(FunctionElement constructor) |
651 : this.constructor = constructor, | 665 : this.constructor = constructor, |
652 super(constructor.name, | 666 super(constructor.name, |
653 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, | 667 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
654 null, | 668 null, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 } | 742 } |
729 | 743 |
730 Type computeType(compiler) { | 744 Type computeType(compiler) { |
731 if (type === null) { | 745 if (type === null) { |
732 type = new InterfaceType(this); | 746 type = new InterfaceType(this); |
733 } | 747 } |
734 return type; | 748 return type; |
735 } | 749 } |
736 | 750 |
737 ClassElement ensureResolved(Compiler compiler) { | 751 ClassElement ensureResolved(Compiler compiler) { |
738 if (!isResolved && !isBeingResolved) { | 752 compiler.resolveClass(this); |
739 isBeingResolved = true; | |
740 compiler.resolveClass(this); | |
741 isBeingResolved = false; | |
742 isResolved = true; | |
743 } | |
744 return this; | 753 return this; |
745 } | 754 } |
746 | 755 |
747 Element lookupTypeParameter(SourceString parameterName) { | 756 Element lookupTypeParameter(SourceString parameterName) { |
748 Element result = typeParameters[parameterName]; | 757 Element result = typeParameters[parameterName]; |
749 return result; | 758 return result; |
750 } | 759 } |
751 | 760 |
752 Element lookupLocalMember(SourceString memberName) { | 761 Element lookupLocalMember(SourceString memberName) { |
753 return localMembers[memberName]; | 762 return localMembers[memberName]; |
754 } | 763 } |
755 | 764 |
756 Element lookupSuperMember(SourceString memberName) { | 765 Element lookupSuperMember(SourceString memberName) { |
757 for (ClassElement s = superclass; s != null; s = s.superclass) { | 766 for (ClassElement s = superclass; s != null; s = s.superclass) { |
758 Element e = s.lookupLocalMember(memberName); | 767 Element e = s.lookupLocalMember(memberName); |
759 if (e !== null) { | 768 if (e === null) continue; |
760 if (!memberName.isPrivate() || getLibrary() === e.getLibrary()) { | 769 // Private members from a different library are not visible. |
761 return e; | 770 if (memberName.isPrivate() && getLibrary() !== e.getLibrary()) continue; |
762 } | 771 // Static members are not inherited. |
763 } | 772 if (e.modifiers.isStatic()) continue; |
| 773 return e; |
764 } | 774 } |
765 return null; | 775 return null; |
766 } | 776 } |
767 | 777 |
768 /** | 778 /** |
769 * Find the first member in the class chain with the given | 779 * Find the first member in the class chain with the given |
770 * [memberName]. This method is NOT to be used for resolving | 780 * [memberName]. This method is NOT to be used for resolving |
771 * unqualified sends because it does not implement the scoping | 781 * unqualified sends because it does not implement the scoping |
772 * rules, where library scope comes before superclass scope. | 782 * rules, where library scope comes before superclass scope. |
773 */ | 783 */ |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 final Node node; | 1074 final Node node; |
1065 Type bound; | 1075 Type bound; |
1066 Type type; | 1076 Type type; |
1067 TypeVariableElement(name, Element enclosing, this.node, this.type, | 1077 TypeVariableElement(name, Element enclosing, this.node, this.type, |
1068 [this.bound]) | 1078 [this.bound]) |
1069 : super(name, ElementKind.TYPE_VARIABLE, enclosing); | 1079 : super(name, ElementKind.TYPE_VARIABLE, enclosing); |
1070 Type computeType(compiler) => type; | 1080 Type computeType(compiler) => type; |
1071 Node parseNode(compiler) => node; | 1081 Node parseNode(compiler) => node; |
1072 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; | 1082 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; |
1073 } | 1083 } |
OLD | NEW |