| 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 toString() { | 207 String toString() { |
| 208 if (!isTopLevel()) { | 208 if (!isTopLevel()) { |
| 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; } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 class LibraryElement extends CompilationUnitElement { | 297 class LibraryElement extends CompilationUnitElement { |
| 298 // TODO(ahe): Library element should not be a subclass of | 298 // TODO(ahe): Library element should not be a subclass of |
| 299 // CompilationUnitElement. | 299 // CompilationUnitElement. |
| 300 | 300 |
| 301 Link<CompilationUnitElement> compilationUnits = | 301 Link<CompilationUnitElement> compilationUnits = |
| 302 const EmptyLink<CompilationUnitElement>(); | 302 const EmptyLink<CompilationUnitElement>(); |
| 303 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); | 303 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); |
| 304 ScriptTag libraryTag; | 304 ScriptTag libraryTag; |
| 305 Map<SourceString, Element> elements; | 305 Map<SourceString, Element> elements; |
| 306 bool canUseNative = false; | 306 bool canUseNative = false; |
| 307 LibraryElement patch = null; |
| 307 | 308 |
| 308 LibraryElement(Script script) | 309 LibraryElement(Script script) |
| 309 : elements = new Map<SourceString, Element>(), | 310 : elements = new Map<SourceString, Element>(), |
| 310 super.library(script); | 311 super.library(script); |
| 311 | 312 |
| 313 bool get isPatched() => patch !== null; |
| 314 |
| 312 void addCompilationUnit(CompilationUnitElement element) { | 315 void addCompilationUnit(CompilationUnitElement element) { |
| 313 compilationUnits = compilationUnits.prepend(element); | 316 compilationUnits = compilationUnits.prepend(element); |
| 314 } | 317 } |
| 315 | 318 |
| 316 void addTag(ScriptTag tag, DiagnosticListener listener) { | 319 void addTag(ScriptTag tag, DiagnosticListener listener) { |
| 317 tags = tags.prepend(tag); | 320 tags = tags.prepend(tag); |
| 318 } | 321 } |
| 319 | 322 |
| 320 void addMember(Element element, DiagnosticListener listener) { | 323 void addMember(Element element, DiagnosticListener listener) { |
| 321 topLevelElements = topLevelElements.prepend(element); | 324 topLevelElements = topLevelElements.prepend(element); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 } | 577 } |
| 575 | 578 |
| 576 class FunctionElement extends Element { | 579 class FunctionElement extends Element { |
| 577 FunctionExpression cachedNode; | 580 FunctionExpression cachedNode; |
| 578 Type type; | 581 Type type; |
| 579 final Modifiers modifiers; | 582 final Modifiers modifiers; |
| 580 | 583 |
| 581 FunctionSignature functionSignature; | 584 FunctionSignature functionSignature; |
| 582 | 585 |
| 583 /** | 586 /** |
| 587 * A function declaration that should be parsed instead of the current one. |
| 588 * The patch should be parsed as if it was in the current scope. Its |
| 589 * signature must match this function's signature. |
| 590 */ |
| 591 // TODO(lrn): Consider using [defaultImplementation] to store the patch. |
| 592 FunctionElement patch = null; |
| 593 |
| 594 /** |
| 584 * If this is an interface constructor, [defaultImplementation] will | 595 * If this is an interface constructor, [defaultImplementation] will |
| 585 * changed by the resolver to point to the default | 596 * changed by the resolver to point to the default |
| 586 * implementation. Otherwise, [:defaultImplementation === this:]. | 597 * implementation. Otherwise, [:defaultImplementation === this:]. |
| 587 */ | 598 */ |
| 588 FunctionElement defaultImplementation; | 599 FunctionElement defaultImplementation; |
| 589 | 600 |
| 590 FunctionElement(SourceString name, | 601 FunctionElement(SourceString name, |
| 591 ElementKind kind, | 602 ElementKind kind, |
| 592 Modifiers modifiers, | 603 Modifiers modifiers, |
| 593 Element enclosing) | 604 Element enclosing) |
| 594 : this.tooMuchOverloading(name, null, kind, modifiers, enclosing, null); | 605 : this.tooMuchOverloading(name, null, kind, modifiers, enclosing, null); |
| 595 | 606 |
| 596 FunctionElement.node(SourceString name, | 607 FunctionElement.node(SourceString name, |
| 597 FunctionExpression node, | 608 FunctionExpression node, |
| 598 ElementKind kind, | 609 ElementKind kind, |
| 599 Modifiers modifiers, | 610 Modifiers modifiers, |
| 600 Element enclosing) | 611 Element enclosing) |
| 601 : this.tooMuchOverloading(name, node, kind, modifiers, enclosing, null); | 612 : this.tooMuchOverloading(name, node, kind, modifiers, enclosing, null); |
| 602 | 613 |
| 603 FunctionElement.from(SourceString name, | 614 FunctionElement.from(SourceString name, |
| 604 FunctionElement other, | 615 FunctionElement other, |
| 605 Element enclosing) | 616 Element enclosing) |
| 606 : this.tooMuchOverloading(name, other.cachedNode, other.kind, | 617 : this.tooMuchOverloading(name, other.cachedNode, other.kind, |
| 607 other.modifiers, enclosing, | 618 other.modifiers, enclosing, |
| 608 other.functionSignature); | 619 other.functionSignature); |
| 609 | 620 |
| 610 FunctionElement.tooMuchOverloading(SourceString name, | 621 FunctionElement.tooMuchOverloading(SourceString name, |
| 611 FunctionExpression this.cachedNode, | 622 FunctionExpression this.cachedNode, |
| 612 ElementKind kind, | 623 ElementKind kind, |
| 613 Modifiers this.modifiers, | 624 Modifiers this.modifiers, |
| 614 Element enclosing, | 625 Element enclosing, |
| 615 FunctionSignature this.functionSignature) | 626 FunctionSignature this.functionSignature) |
| 616 : super(name, kind, enclosing) | 627 : super(name, kind, enclosing) { |
| 617 { | |
| 618 defaultImplementation = this; | 628 defaultImplementation = this; |
| 619 } | 629 } |
| 620 | 630 |
| 631 CompilationUnitElement getCompilationUnit() { |
| 632 if (patch !== null) return patch.getCompilationUnit(); |
| 633 return super.getCompilationUnit(); |
| 634 } |
| 635 |
| 636 bool get isPatched() => patch !== null; |
| 637 |
| 638 /** |
| 639 * Applies a patch function to this function. The patch function's body |
| 640 * is used as replacement when parsing this function's body. |
| 641 * This method must not be called after the function has been parsed, |
| 642 * and it must be called at most once. |
| 643 */ |
| 644 void setPatch(FunctionElement patchElement) { |
| 645 // Sanity checks. The caller must check these things before calling. |
| 646 assert(patch !== null); |
| 647 assert(cachedNode !== null); |
| 648 this.patch = patchElement; |
| 649 cachedNode = patchElement.cachedNode; |
| 650 } |
| 651 |
| 621 bool isInstanceMember() { | 652 bool isInstanceMember() { |
| 622 return isMember() | 653 return isMember() |
| 623 && kind != ElementKind.GENERATIVE_CONSTRUCTOR | 654 && kind != ElementKind.GENERATIVE_CONSTRUCTOR |
| 624 && !modifiers.isFactory() | 655 && !modifiers.isFactory() |
| 625 && !modifiers.isStatic(); | 656 && !modifiers.isStatic(); |
| 626 } | 657 } |
| 627 | 658 |
| 628 FunctionSignature computeSignature(Compiler compiler) { | 659 FunctionSignature computeSignature(Compiler compiler) { |
| 629 if (functionSignature !== null) return functionSignature; | 660 if (functionSignature !== null) return functionSignature; |
| 630 compiler.withCurrentElement(this, () { | 661 compiler.withCurrentElement(this, () { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 644 int parameterCount(Compiler compiler) { | 675 int parameterCount(Compiler compiler) { |
| 645 return computeSignature(compiler).parameterCount; | 676 return computeSignature(compiler).parameterCount; |
| 646 } | 677 } |
| 647 | 678 |
| 648 FunctionType computeType(Compiler compiler) { | 679 FunctionType computeType(Compiler compiler) { |
| 649 if (type != null) return type; | 680 if (type != null) return type; |
| 650 type = compiler.computeFunctionType(this, computeSignature(compiler)); | 681 type = compiler.computeFunctionType(this, computeSignature(compiler)); |
| 651 return type; | 682 return type; |
| 652 } | 683 } |
| 653 | 684 |
| 654 Node parseNode(DiagnosticListener listener) => cachedNode; | 685 Node parseNode(DiagnosticListener listener) { |
| 686 if (cachedNode !== null) return cachedNode; |
| 687 if (patch !== null) { |
| 688 cachedNode = patch.parseNode(listener); |
| 689 } |
| 690 return cachedNode; |
| 691 } |
| 655 | 692 |
| 656 Token position() => cachedNode.getBeginToken(); | 693 Token position() => cachedNode.getBeginToken(); |
| 657 | 694 |
| 658 FunctionElement asFunctionElement() => this; | 695 FunctionElement asFunctionElement() => this; |
| 659 } | 696 } |
| 660 | 697 |
| 661 class ConstructorBodyElement extends FunctionElement { | 698 class ConstructorBodyElement extends FunctionElement { |
| 662 FunctionElement constructor; | 699 FunctionElement constructor; |
| 663 | 700 |
| 664 ConstructorBodyElement(FunctionElement constructor) | 701 ConstructorBodyElement(FunctionElement constructor) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 Map<SourceString, Element> constructors; | 751 Map<SourceString, Element> constructors; |
| 715 Link<Type> interfaces = const EmptyLink<Type>(); | 752 Link<Type> interfaces = const EmptyLink<Type>(); |
| 716 LinkedHashMap<SourceString, TypeVariableElement> typeParameters; | 753 LinkedHashMap<SourceString, TypeVariableElement> typeParameters; |
| 717 bool isResolved = false; | 754 bool isResolved = false; |
| 718 bool isBeingResolved = false; | 755 bool isBeingResolved = false; |
| 719 // backendMembers are members that have been added by the backend to simplify | 756 // backendMembers are members that have been added by the backend to simplify |
| 720 // compilation. They don't have any user-side counter-part. | 757 // compilation. They don't have any user-side counter-part. |
| 721 Link<Element> backendMembers = const EmptyLink<Element>(); | 758 Link<Element> backendMembers = const EmptyLink<Element>(); |
| 722 | 759 |
| 723 Link<Type> allSupertypes; | 760 Link<Type> allSupertypes; |
| 761 ClassElement patch = null; |
| 724 | 762 |
| 725 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) | 763 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) |
| 726 : localMembers = new Map<SourceString, Element>(), | 764 : localMembers = new Map<SourceString, Element>(), |
| 727 constructors = new Map<SourceString, Element>(), | 765 constructors = new Map<SourceString, Element>(), |
| 728 typeParameters = new LinkedHashMap<SourceString, TypeVariableElement>(), | 766 typeParameters = new LinkedHashMap<SourceString, TypeVariableElement>(), |
| 729 super(name, ElementKind.CLASS, enclosing); | 767 super(name, ElementKind.CLASS, enclosing); |
| 730 | 768 |
| 731 void addMember(Element element, DiagnosticListener listener) { | 769 void addMember(Element element, DiagnosticListener listener) { |
| 732 members = members.prepend(element); | 770 members = members.prepend(element); |
| 733 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || | 771 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 final Node node; | 1112 final Node node; |
| 1075 Type bound; | 1113 Type bound; |
| 1076 Type type; | 1114 Type type; |
| 1077 TypeVariableElement(name, Element enclosing, this.node, this.type, | 1115 TypeVariableElement(name, Element enclosing, this.node, this.type, |
| 1078 [this.bound]) | 1116 [this.bound]) |
| 1079 : super(name, ElementKind.TYPE_VARIABLE, enclosing); | 1117 : super(name, ElementKind.TYPE_VARIABLE, enclosing); |
| 1080 Type computeType(compiler) => type; | 1118 Type computeType(compiler) => type; |
| 1081 Node parseNode(compiler) => node; | 1119 Node parseNode(compiler) => node; |
| 1082 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; | 1120 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; |
| 1083 } | 1121 } |
| OLD | NEW |