| 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 | 197 |
| 198 Element getOutermostEnclosingMemberOrTopLevel() { | 198 Element getOutermostEnclosingMemberOrTopLevel() { |
| 199 for (Element e = this; e !== null; e = e.enclosingElement) { | 199 for (Element e = this; e !== null; e = e.enclosingElement) { |
| 200 if (e.isMember() || e.isTopLevel()) { | 200 if (e.isMember() || e.isTopLevel()) { |
| 201 return e; | 201 return e; |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 return null; | 204 return null; |
| 205 } | 205 } |
| 206 | 206 |
| 207 String toString() { | 207 toString() { |
| 208 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an | 208 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an |
| 209 // invariant for all element types. | 209 // invariant for all element types. |
| 210 if (!isTopLevel()) { | 210 if (!isTopLevel()) { |
| 211 String holderName = enclosingElement.name.slowToString(); | 211 String holderName = enclosingElement.name.slowToString(); |
| 212 return '$kind($holderName#${name.slowToString()})'; | 212 return '$kind($holderName#${name.slowToString()})'; |
| 213 } else { | 213 } else { |
| 214 return '$kind(${name.slowToString()})'; | 214 return '$kind(${name.slowToString()})'; |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 | 217 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 class LibraryElement extends CompilationUnitElement { | 299 class LibraryElement extends CompilationUnitElement { |
| 300 // TODO(ahe): Library element should not be a subclass of | 300 // TODO(ahe): Library element should not be a subclass of |
| 301 // CompilationUnitElement. | 301 // CompilationUnitElement. |
| 302 | 302 |
| 303 Link<CompilationUnitElement> compilationUnits = | 303 Link<CompilationUnitElement> compilationUnits = |
| 304 const EmptyLink<CompilationUnitElement>(); | 304 const EmptyLink<CompilationUnitElement>(); |
| 305 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); | 305 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); |
| 306 ScriptTag libraryTag; | 306 ScriptTag libraryTag; |
| 307 Map<SourceString, Element> elements; | 307 Map<SourceString, Element> elements; |
| 308 bool canUseNative = false; | 308 bool canUseNative = false; |
| 309 LibraryElement patch = null; | |
| 310 | 309 |
| 311 LibraryElement(Script script) | 310 LibraryElement(Script script) |
| 312 : elements = new Map<SourceString, Element>(), | 311 : elements = new Map<SourceString, Element>(), |
| 313 super.library(script); | 312 super.library(script); |
| 314 | 313 |
| 315 bool get isPatched() => patch !== null; | |
| 316 | |
| 317 void addCompilationUnit(CompilationUnitElement element) { | 314 void addCompilationUnit(CompilationUnitElement element) { |
| 318 compilationUnits = compilationUnits.prepend(element); | 315 compilationUnits = compilationUnits.prepend(element); |
| 319 } | 316 } |
| 320 | 317 |
| 321 void addTag(ScriptTag tag, DiagnosticListener listener) { | 318 void addTag(ScriptTag tag, DiagnosticListener listener) { |
| 322 tags = tags.prepend(tag); | 319 tags = tags.prepend(tag); |
| 323 } | 320 } |
| 324 | 321 |
| 325 void addMember(Element element, DiagnosticListener listener) { | 322 void addMember(Element element, DiagnosticListener listener) { |
| 326 topLevelElements = topLevelElements.prepend(element); | 323 topLevelElements = topLevelElements.prepend(element); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 } | 591 } |
| 595 | 592 |
| 596 class FunctionElement extends Element { | 593 class FunctionElement extends Element { |
| 597 FunctionExpression cachedNode; | 594 FunctionExpression cachedNode; |
| 598 Type type; | 595 Type type; |
| 599 final Modifiers modifiers; | 596 final Modifiers modifiers; |
| 600 | 597 |
| 601 FunctionSignature functionSignature; | 598 FunctionSignature functionSignature; |
| 602 | 599 |
| 603 /** | 600 /** |
| 604 * A function declaration that should be parsed instead of the current one. | |
| 605 * The patch should be parsed as if it was in the current scope. Its | |
| 606 * signature must match this function's signature. | |
| 607 */ | |
| 608 // TODO(lrn): Consider using [defaultImplementation] to store the patch. | |
| 609 FunctionElement patch = null; | |
| 610 | |
| 611 /** | |
| 612 * If this is an interface constructor, [defaultImplementation] will | 601 * If this is an interface constructor, [defaultImplementation] will |
| 613 * changed by the resolver to point to the default | 602 * changed by the resolver to point to the default |
| 614 * implementation. Otherwise, [:defaultImplementation === this:]. | 603 * implementation. Otherwise, [:defaultImplementation === this:]. |
| 615 */ | 604 */ |
| 616 FunctionElement defaultImplementation; | 605 FunctionElement defaultImplementation; |
| 617 | 606 |
| 618 FunctionElement(SourceString name, | 607 FunctionElement(SourceString name, |
| 619 ElementKind kind, | 608 ElementKind kind, |
| 620 Modifiers modifiers, | 609 Modifiers modifiers, |
| 621 Element enclosing) | 610 Element enclosing) |
| 622 : this.tooMuchOverloading(name, null, kind, modifiers, enclosing, null); | 611 : this.tooMuchOverloading(name, null, kind, modifiers, enclosing, null); |
| 623 | 612 |
| 624 FunctionElement.node(SourceString name, | 613 FunctionElement.node(SourceString name, |
| 625 FunctionExpression node, | 614 FunctionExpression node, |
| 626 ElementKind kind, | 615 ElementKind kind, |
| 627 Modifiers modifiers, | 616 Modifiers modifiers, |
| 628 Element enclosing) | 617 Element enclosing) |
| 629 : this.tooMuchOverloading(name, node, kind, modifiers, enclosing, null); | 618 : this.tooMuchOverloading(name, node, kind, modifiers, enclosing, null); |
| 630 | 619 |
| 631 FunctionElement.from(SourceString name, | 620 FunctionElement.from(SourceString name, |
| 632 FunctionElement other, | 621 FunctionElement other, |
| 633 Element enclosing) | 622 Element enclosing) |
| 634 : this.tooMuchOverloading(name, other.cachedNode, other.kind, | 623 : this.tooMuchOverloading(name, other.cachedNode, other.kind, |
| 635 other.modifiers, enclosing, | 624 other.modifiers, enclosing, |
| 636 other.functionSignature); | 625 other.functionSignature); |
| 637 | 626 |
| 638 FunctionElement.tooMuchOverloading(SourceString name, | 627 FunctionElement.tooMuchOverloading(SourceString name, |
| 639 FunctionExpression this.cachedNode, | 628 FunctionExpression this.cachedNode, |
| 640 ElementKind kind, | 629 ElementKind kind, |
| 641 Modifiers this.modifiers, | 630 Modifiers this.modifiers, |
| 642 Element enclosing, | 631 Element enclosing, |
| 643 FunctionSignature this.functionSignature) | 632 FunctionSignature this.functionSignature) |
| 644 : super(name, kind, enclosing) { | 633 : super(name, kind, enclosing) |
| 634 { |
| 645 defaultImplementation = this; | 635 defaultImplementation = this; |
| 646 } | 636 } |
| 647 | 637 |
| 648 CompilationUnitElement getCompilationUnit() { | |
| 649 if (patch !== null) return patch.getCompilationUnit(); | |
| 650 return super.getCompilationUnit(); | |
| 651 } | |
| 652 | |
| 653 bool get isPatched() => patch !== null; | |
| 654 | |
| 655 /** | |
| 656 * Applies a patch function to this function. The patch function's body | |
| 657 * is used as replacement when parsing this function's body. | |
| 658 * This method must not be called after the function has been parsed, | |
| 659 * and it must be called at most once. | |
| 660 */ | |
| 661 void setPatch(FunctionElement patchElement) { | |
| 662 // Sanity checks. The caller must check these things before calling. | |
| 663 assert(patch !== null); | |
| 664 assert(cachedNode !== null); | |
| 665 this.patch = patchElement; | |
| 666 cachedNode = patchElement.cachedNode; | |
| 667 } | |
| 668 | |
| 669 bool isInstanceMember() { | 638 bool isInstanceMember() { |
| 670 return isMember() | 639 return isMember() |
| 671 && kind != ElementKind.GENERATIVE_CONSTRUCTOR | 640 && kind != ElementKind.GENERATIVE_CONSTRUCTOR |
| 672 && !modifiers.isFactory() | 641 && !modifiers.isFactory() |
| 673 && !modifiers.isStatic(); | 642 && !modifiers.isStatic(); |
| 674 } | 643 } |
| 675 | 644 |
| 676 FunctionSignature computeSignature(Compiler compiler) { | 645 FunctionSignature computeSignature(Compiler compiler) { |
| 677 if (functionSignature !== null) return functionSignature; | 646 if (functionSignature !== null) return functionSignature; |
| 678 compiler.withCurrentElement(this, () { | 647 compiler.withCurrentElement(this, () { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 692 int parameterCount(Compiler compiler) { | 661 int parameterCount(Compiler compiler) { |
| 693 return computeSignature(compiler).parameterCount; | 662 return computeSignature(compiler).parameterCount; |
| 694 } | 663 } |
| 695 | 664 |
| 696 FunctionType computeType(Compiler compiler) { | 665 FunctionType computeType(Compiler compiler) { |
| 697 if (type != null) return type; | 666 if (type != null) return type; |
| 698 type = compiler.computeFunctionType(this, computeSignature(compiler)); | 667 type = compiler.computeFunctionType(this, computeSignature(compiler)); |
| 699 return type; | 668 return type; |
| 700 } | 669 } |
| 701 | 670 |
| 702 Node parseNode(DiagnosticListener listener) { | 671 Node parseNode(DiagnosticListener listener) => cachedNode; |
| 703 if (cachedNode !== null) return cachedNode; | |
| 704 if (patch !== null) { | |
| 705 cachedNode = patch.parseNode(listener); | |
| 706 } | |
| 707 return cachedNode; | |
| 708 } | |
| 709 | 672 |
| 710 Token position() => cachedNode.getBeginToken(); | 673 Token position() => cachedNode.getBeginToken(); |
| 711 | 674 |
| 712 FunctionElement asFunctionElement() => this; | 675 FunctionElement asFunctionElement() => this; |
| 713 } | 676 } |
| 714 | 677 |
| 715 class ConstructorBodyElement extends FunctionElement { | 678 class ConstructorBodyElement extends FunctionElement { |
| 716 FunctionElement constructor; | 679 FunctionElement constructor; |
| 717 | 680 |
| 718 ConstructorBodyElement(FunctionElement constructor) | 681 ConstructorBodyElement(FunctionElement constructor) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 Map<SourceString, Element> constructors; | 731 Map<SourceString, Element> constructors; |
| 769 Link<Type> interfaces = const EmptyLink<Type>(); | 732 Link<Type> interfaces = const EmptyLink<Type>(); |
| 770 LinkedHashMap<SourceString, TypeVariableElement> typeParameters; | 733 LinkedHashMap<SourceString, TypeVariableElement> typeParameters; |
| 771 bool isResolved = false; | 734 bool isResolved = false; |
| 772 bool isBeingResolved = false; | 735 bool isBeingResolved = false; |
| 773 // backendMembers are members that have been added by the backend to simplify | 736 // backendMembers are members that have been added by the backend to simplify |
| 774 // compilation. They don't have any user-side counter-part. | 737 // compilation. They don't have any user-side counter-part. |
| 775 Link<Element> backendMembers = const EmptyLink<Element>(); | 738 Link<Element> backendMembers = const EmptyLink<Element>(); |
| 776 | 739 |
| 777 Link<Type> allSupertypes; | 740 Link<Type> allSupertypes; |
| 778 ClassElement patch = null; | |
| 779 | 741 |
| 780 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) | 742 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) |
| 781 : localMembers = new Map<SourceString, Element>(), | 743 : localMembers = new Map<SourceString, Element>(), |
| 782 constructors = new Map<SourceString, Element>(), | 744 constructors = new Map<SourceString, Element>(), |
| 783 typeParameters = new LinkedHashMap<SourceString, TypeVariableElement>(), | 745 typeParameters = new LinkedHashMap<SourceString, TypeVariableElement>(), |
| 784 super(name, ElementKind.CLASS, enclosing); | 746 super(name, ElementKind.CLASS, enclosing); |
| 785 | 747 |
| 786 void addMember(Element element, DiagnosticListener listener) { | 748 void addMember(Element element, DiagnosticListener listener) { |
| 787 members = members.prepend(element); | 749 members = members.prepend(element); |
| 788 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || | 750 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 final Node node; | 1091 final Node node; |
| 1130 Type bound; | 1092 Type bound; |
| 1131 Type type; | 1093 Type type; |
| 1132 TypeVariableElement(name, Element enclosing, this.node, this.type, | 1094 TypeVariableElement(name, Element enclosing, this.node, this.type, |
| 1133 [this.bound]) | 1095 [this.bound]) |
| 1134 : super(name, ElementKind.TYPE_VARIABLE, enclosing); | 1096 : super(name, ElementKind.TYPE_VARIABLE, enclosing); |
| 1135 Type computeType(compiler) => type; | 1097 Type computeType(compiler) => type; |
| 1136 Node parseNode(compiler) => node; | 1098 Node parseNode(compiler) => node; |
| 1137 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; | 1099 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; |
| 1138 } | 1100 } |
| OLD | NEW |