| 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 static final ElementKind VOID = | 95 static final ElementKind VOID = |
| 96 const ElementKind('void', ElementCategory.NONE); | 96 const ElementKind('void', ElementCategory.NONE); |
| 97 | 97 |
| 98 toString() => id; | 98 toString() => id; |
| 99 } | 99 } |
| 100 | 100 |
| 101 class Element implements Hashable { | 101 class Element implements Hashable { |
| 102 final SourceString name; | 102 final SourceString name; |
| 103 final ElementKind kind; | 103 final ElementKind kind; |
| 104 final Element enclosingElement; | 104 final Element enclosingElement; |
| 105 Script scriptOverride = null; | |
| 106 Link<Node> metadata = const EmptyLink<Node>(); | 105 Link<Node> metadata = const EmptyLink<Node>(); |
| 107 Modifiers get modifiers() => null; | 106 Modifiers get modifiers() => null; |
| 108 | 107 |
| 109 Node parseNode(DiagnosticListener listener) { | 108 Node parseNode(DiagnosticListener listener) { |
| 110 listener.cancel("Internal Error: $this.parseNode", token: position()); | 109 listener.cancel("Internal Error: $this.parseNode", token: position()); |
| 111 } | 110 } |
| 112 | 111 |
| 113 Type computeType(Compiler compiler) { | 112 Type computeType(Compiler compiler) { |
| 114 compiler.internalError("$this.computeType.", token: position()); | 113 compiler.internalError("$this.computeType.", token: position()); |
| 115 } | 114 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 | 168 |
| 170 Element(this.name, this.kind, this.enclosingElement) { | 169 Element(this.name, this.kind, this.enclosingElement) { |
| 171 assert(getLibrary() !== null); | 170 assert(getLibrary() !== null); |
| 172 } | 171 } |
| 173 | 172 |
| 174 // TODO(kasperl): This is a very bad hash code for the element and | 173 // TODO(kasperl): This is a very bad hash code for the element and |
| 175 // there's no reason why two elements with the same name should have | 174 // there's no reason why two elements with the same name should have |
| 176 // the same hash code. Replace this with a simple id in the element? | 175 // the same hash code. Replace this with a simple id in the element? |
| 177 int hashCode() => name.hashCode(); | 176 int hashCode() => name.hashCode(); |
| 178 | 177 |
| 179 Script getScript() { | |
| 180 if (scriptOverride !== null) return scriptOverride; | |
| 181 return getCompilationUnit().script; | |
| 182 } | |
| 183 | |
| 184 CompilationUnitElement getCompilationUnit() { | 178 CompilationUnitElement getCompilationUnit() { |
| 185 Element element = this; | 179 Element element = this; |
| 186 while (element !== null && !element.isCompilationUnit()) { | 180 while (element !== null && !element.isCompilationUnit()) { |
| 187 element = element.enclosingElement; | 181 element = element.enclosingElement; |
| 188 } | 182 } |
| 189 return element; | 183 return element; |
| 190 } | 184 } |
| 191 | 185 |
| 192 LibraryElement getLibrary() { | 186 LibraryElement getLibrary() { |
| 193 Element element = this; | 187 Element element = this; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 } else { | 223 } else { |
| 230 return '$kind(${name.slowToString()})'; | 224 return '$kind(${name.slowToString()})'; |
| 231 } | 225 } |
| 232 } | 226 } |
| 233 | 227 |
| 234 bool _isNative = false; | 228 bool _isNative = false; |
| 235 void setNative() { _isNative = true; } | 229 void setNative() { _isNative = true; } |
| 236 bool isNative() => _isNative; | 230 bool isNative() => _isNative; |
| 237 | 231 |
| 238 FunctionElement asFunctionElement() => null; | 232 FunctionElement asFunctionElement() => null; |
| 239 | |
| 240 Element cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 241 listener.cancel("Unimplemented cloneTo", element: this); | |
| 242 } | |
| 243 } | 233 } |
| 244 | 234 |
| 245 class ContainerElement extends Element { | 235 class ContainerElement extends Element { |
| 246 ContainerElement(name, kind, enclosingElement) : | 236 ContainerElement(name, kind, enclosingElement) : |
| 247 super(name, kind, enclosingElement); | 237 super(name, kind, enclosingElement); |
| 248 | 238 |
| 249 abstract void addMember(Element element, DiagnosticListener listener); | 239 abstract void addMember(Element element, DiagnosticListener listener); |
| 250 | 240 |
| 251 void addGetterOrSetter(Element element, | 241 void addGetterOrSetter(Element element, |
| 252 Element existing, | 242 Element existing, |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 // Use the file name as script name. | 389 // Use the file name as script name. |
| 400 var path = script.uri.path; | 390 var path = script.uri.path; |
| 401 return path.substring(path.lastIndexOf('/') + 1); | 391 return path.substring(path.lastIndexOf('/') + 1); |
| 402 } | 392 } |
| 403 } | 393 } |
| 404 } | 394 } |
| 405 | 395 |
| 406 class PrefixElement extends Element { | 396 class PrefixElement extends Element { |
| 407 Map<SourceString, Element> imported; | 397 Map<SourceString, Element> imported; |
| 408 Token firstPosition; | 398 Token firstPosition; |
| 399 final CompilationUnitElement patchSource; |
| 409 | 400 |
| 410 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition) | 401 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition, |
| 411 : imported = new Map<SourceString, Element>(), | 402 [this.patchSource]) |
| 412 super(prefix, ElementKind.PREFIX, enclosing); | 403 : imported = new Map<SourceString, Element>(), |
| 404 super(prefix, ElementKind.PREFIX, enclosing); |
| 405 |
| 406 CompilationUnitElement getCompilationUnit() { |
| 407 if (patchSource !== null) return patchSource; |
| 408 return super.getCompilationUnit(); |
| 409 } |
| 413 | 410 |
| 414 lookupLocalMember(SourceString memberName) => imported[memberName]; | 411 lookupLocalMember(SourceString memberName) => imported[memberName]; |
| 415 | 412 |
| 416 Type computeType(Compiler compiler) => compiler.types.dynamicType; | 413 Type computeType(Compiler compiler) => compiler.types.dynamicType; |
| 417 | 414 |
| 418 Token position() => firstPosition; | 415 Token position() => firstPosition; |
| 419 | |
| 420 PrefixElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 421 PrefixElement result = new PrefixElement(name, enclosing, firstPosition); | |
| 422 result.scriptOverride = getScript(); | |
| 423 return result; | |
| 424 } | |
| 425 } | 416 } |
| 426 | 417 |
| 427 class TypedefElement extends Element { | 418 class TypedefElement extends Element { |
| 428 Type cachedType; | 419 Type cachedType; |
| 429 Typedef cachedNode; | 420 Typedef cachedNode; |
| 430 | 421 |
| 431 TypedefElement(SourceString name, Element enclosing) | 422 TypedefElement(SourceString name, Element enclosing) |
| 432 : super(name, ElementKind.TYPEDEF, enclosing); | 423 : super(name, ElementKind.TYPEDEF, enclosing); |
| 433 | 424 |
| 434 Type computeType(Compiler compiler) { | 425 Type computeType(Compiler compiler) { |
| 435 if (cachedType !== null) return cachedType; | 426 if (cachedType !== null) return cachedType; |
| 436 cachedType = compiler.computeFunctionType( | 427 cachedType = compiler.computeFunctionType( |
| 437 this, compiler.resolveTypedef(this)); | 428 this, compiler.resolveTypedef(this)); |
| 438 return cachedType; | 429 return cachedType; |
| 439 } | 430 } |
| 440 | |
| 441 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 442 TypedefElement result = new TypedefElement(name, enclosing); | |
| 443 result.scriptOverride = getScript(); | |
| 444 return result; | |
| 445 } | |
| 446 } | 431 } |
| 447 | 432 |
| 448 class VariableElement extends Element { | 433 class VariableElement extends Element { |
| 449 final VariableListElement variables; | 434 final VariableListElement variables; |
| 450 Expression cachedNode; // The send or the identifier in the variables list. | 435 Expression cachedNode; // The send or the identifier in the variables list. |
| 451 | 436 |
| 452 Modifiers get modifiers() => variables.modifiers; | 437 Modifiers get modifiers() => variables.modifiers; |
| 453 | 438 |
| 454 VariableElement(SourceString name, | 439 VariableElement(SourceString name, |
| 455 VariableListElement this.variables, | 440 VariableListElement this.variables, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 482 | 467 |
| 483 Type get type() => variables.type; | 468 Type get type() => variables.type; |
| 484 | 469 |
| 485 bool isInstanceMember() { | 470 bool isInstanceMember() { |
| 486 return isMember() && !modifiers.isStatic(); | 471 return isMember() && !modifiers.isStatic(); |
| 487 } | 472 } |
| 488 | 473 |
| 489 // Note: cachedNode.getBeginToken() will not be correct in all | 474 // Note: cachedNode.getBeginToken() will not be correct in all |
| 490 // cases, for example, for function typed parameters. | 475 // cases, for example, for function typed parameters. |
| 491 Token position() => findMyName(variables.position()); | 476 Token position() => findMyName(variables.position()); |
| 492 | |
| 493 VariableElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 494 VariableListElement clonedVariables = | |
| 495 variables.cloneTo(enclosing, listener); | |
| 496 VariableElement result = new VariableElement( | |
| 497 name, clonedVariables, kind, enclosing, cachedNode); | |
| 498 result.scriptOverride = getScript(); | |
| 499 return result; | |
| 500 } | |
| 501 } | 477 } |
| 502 | 478 |
| 503 /** | 479 /** |
| 504 * Parameters in constructors that directly initialize fields. For example: | 480 * Parameters in constructors that directly initialize fields. For example: |
| 505 * [:A(this.field):]. | 481 * [:A(this.field):]. |
| 506 */ | 482 */ |
| 507 class FieldParameterElement extends VariableElement { | 483 class FieldParameterElement extends VariableElement { |
| 508 VariableElement fieldElement; | 484 VariableElement fieldElement; |
| 509 | 485 |
| 510 FieldParameterElement(SourceString name, | 486 FieldParameterElement(SourceString name, |
| 511 this.fieldElement, | 487 this.fieldElement, |
| 512 VariableListElement variables, | 488 VariableListElement variables, |
| 513 Element enclosing, | 489 Element enclosing, |
| 514 Node node) | 490 Node node) |
| 515 : super(name, variables, ElementKind.FIELD_PARAMETER, enclosing, node); | 491 : super(name, variables, ElementKind.FIELD_PARAMETER, enclosing, node); |
| 516 | |
| 517 FieldParameterElement cloneTo(Element enclosing, | |
| 518 DiagnosticListener listener) { | |
| 519 FieldParameterElement result = | |
| 520 new FieldParameterElement(name, fieldElement, | |
| 521 variables.cloneTo(enclosing, listener), | |
| 522 enclosing, cachedNode); | |
| 523 result.scriptOverride = getScript(); | |
| 524 return result; | |
| 525 } | |
| 526 } | 492 } |
| 527 | 493 |
| 528 // This element represents a list of variable or field declaration. | 494 // This element represents a list of variable or field declaration. |
| 529 // It contains the node, and the type. A [VariableElement] always | 495 // It contains the node, and the type. A [VariableElement] always |
| 530 // references its [VariableListElement]. It forwards its | 496 // references its [VariableListElement]. It forwards its |
| 531 // [computeType] and [parseNode] methods to this element. | 497 // [computeType] and [parseNode] methods to this element. |
| 532 class VariableListElement extends Element { | 498 class VariableListElement extends Element { |
| 533 VariableDefinitions cachedNode; | 499 VariableDefinitions cachedNode; |
| 534 Type type; | 500 Type type; |
| 535 final Modifiers modifiers; | 501 final Modifiers modifiers; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 550 return cachedNode; | 516 return cachedNode; |
| 551 } | 517 } |
| 552 | 518 |
| 553 Type computeType(Compiler compiler) { | 519 Type computeType(Compiler compiler) { |
| 554 if (type != null) return type; | 520 if (type != null) return type; |
| 555 type = compiler.resolveTypeAnnotation(this, parseNode(compiler).type); | 521 type = compiler.resolveTypeAnnotation(this, parseNode(compiler).type); |
| 556 return type; | 522 return type; |
| 557 } | 523 } |
| 558 | 524 |
| 559 Token position() => cachedNode.getBeginToken(); | 525 Token position() => cachedNode.getBeginToken(); |
| 560 | |
| 561 VariableListElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 562 VariableListElement result; | |
| 563 if (cachedNode !== null) { | |
| 564 result = new VariableListElement(cachedNode, kind, enclosing); | |
| 565 } else { | |
| 566 result = new VariableListElement(kind, modifiers, enclosing); | |
| 567 } | |
| 568 result.scriptOverride = getScript(); | |
| 569 return result; | |
| 570 } | |
| 571 } | 526 } |
| 572 | 527 |
| 573 class ForeignElement extends Element { | 528 class ForeignElement extends Element { |
| 574 ForeignElement(SourceString name, ContainerElement enclosingElement) | 529 ForeignElement(SourceString name, ContainerElement enclosingElement) |
| 575 : super(name, ElementKind.FOREIGN, enclosingElement); | 530 : super(name, ElementKind.FOREIGN, enclosingElement); |
| 576 | 531 |
| 577 Type computeType(Compiler compiler) { | 532 Type computeType(Compiler compiler) { |
| 578 return compiler.types.dynamicType; | 533 return compiler.types.dynamicType; |
| 579 } | 534 } |
| 580 | 535 |
| 581 parseNode(DiagnosticListener listener) { | 536 parseNode(DiagnosticListener listener) { |
| 582 throw "internal error: ForeignElement has no node"; | 537 throw "internal error: ForeignElement has no node"; |
| 583 } | 538 } |
| 584 | |
| 585 ForeignElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 586 ForeignElement result = new ForeignElement(name, kind, enclosing); | |
| 587 result.scriptOverride = getScript(); | |
| 588 return result; | |
| 589 } | |
| 590 } | 539 } |
| 591 | 540 |
| 592 class AbstractFieldElement extends Element { | 541 class AbstractFieldElement extends Element { |
| 593 FunctionElement getter; | 542 FunctionElement getter; |
| 594 FunctionElement setter; | 543 FunctionElement setter; |
| 595 | 544 |
| 596 AbstractFieldElement(SourceString name, Element enclosing) | 545 AbstractFieldElement(SourceString name, Element enclosing) |
| 597 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); | 546 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); |
| 598 | 547 |
| 599 Type computeType(Compiler compiler) { | 548 Type computeType(Compiler compiler) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 624 if (getter !== null) { | 573 if (getter !== null) { |
| 625 return new Modifiers.withFlags( | 574 return new Modifiers.withFlags( |
| 626 getter.modifiers.nodes, | 575 getter.modifiers.nodes, |
| 627 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 576 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 628 } else { | 577 } else { |
| 629 return new Modifiers.withFlags( | 578 return new Modifiers.withFlags( |
| 630 setter.modifiers.nodes, | 579 setter.modifiers.nodes, |
| 631 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 580 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 632 } | 581 } |
| 633 } | 582 } |
| 634 | |
| 635 AbstractFieldElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 636 listener.cancel("Cannot clone synthetic AbstractFieldElement", | |
| 637 element: this); | |
| 638 } | |
| 639 } | 583 } |
| 640 | 584 |
| 641 class FunctionSignature { | 585 class FunctionSignature { |
| 642 Link<Element> requiredParameters; | 586 Link<Element> requiredParameters; |
| 643 Link<Element> optionalParameters; | 587 Link<Element> optionalParameters; |
| 644 Type returnType; | 588 Type returnType; |
| 645 int requiredParameterCount; | 589 int requiredParameterCount; |
| 646 int optionalParameterCount; | 590 int optionalParameterCount; |
| 647 FunctionSignature(this.requiredParameters, | 591 FunctionSignature(this.requiredParameters, |
| 648 this.optionalParameters, | 592 this.optionalParameters, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 FunctionElement.tooMuchOverloading(SourceString name, | 655 FunctionElement.tooMuchOverloading(SourceString name, |
| 712 FunctionExpression this.cachedNode, | 656 FunctionExpression this.cachedNode, |
| 713 ElementKind kind, | 657 ElementKind kind, |
| 714 Modifiers this.modifiers, | 658 Modifiers this.modifiers, |
| 715 Element enclosing, | 659 Element enclosing, |
| 716 FunctionSignature this.functionSignature) | 660 FunctionSignature this.functionSignature) |
| 717 : super(name, kind, enclosing) { | 661 : super(name, kind, enclosing) { |
| 718 defaultImplementation = this; | 662 defaultImplementation = this; |
| 719 } | 663 } |
| 720 | 664 |
| 721 Script getScript() { | 665 CompilationUnitElement getCompilationUnit() { |
| 722 if (patch !== null) return patch.getScript(); | 666 if (patch !== null) return patch.getCompilationUnit(); |
| 723 return super.getScript(); | 667 return super.getCompilationUnit(); |
| 724 } | 668 } |
| 725 | 669 |
| 726 bool get isPatched() => patch !== null; | 670 bool get isPatched() => patch !== null; |
| 727 | 671 |
| 728 /** | 672 /** |
| 729 * Applies a patch function to this function. The patch function's body | 673 * Applies a patch function to this function. The patch function's body |
| 730 * is used as replacement when parsing this function's body. | 674 * is used as replacement when parsing this function's body. |
| 731 * This method must not be called after the function has been parsed, | 675 * This method must not be called after the function has been parsed, |
| 732 * and it must be called at most once. | 676 * and it must be called at most once. |
| 733 */ | 677 */ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 } | 725 } |
| 782 return null; | 726 return null; |
| 783 } | 727 } |
| 784 cachedNode = patch.parseNode(listener); | 728 cachedNode = patch.parseNode(listener); |
| 785 return cachedNode; | 729 return cachedNode; |
| 786 } | 730 } |
| 787 | 731 |
| 788 Token position() => cachedNode.getBeginToken(); | 732 Token position() => cachedNode.getBeginToken(); |
| 789 | 733 |
| 790 FunctionElement asFunctionElement() => this; | 734 FunctionElement asFunctionElement() => this; |
| 791 | |
| 792 FunctionElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 793 FunctionElement result = new FunctionElement.tooMuchOverloading( | |
| 794 name, cachedNode, kind, modifiers, enclosing, functionSignature); | |
| 795 result.defaultImplementation = defaultImplementation; | |
| 796 result.type = type; | |
| 797 result.scriptOverride = getScript(); | |
| 798 return result; | |
| 799 } | |
| 800 } | 735 } |
| 801 | 736 |
| 802 | |
| 803 class ConstructorBodyElement extends FunctionElement { | 737 class ConstructorBodyElement extends FunctionElement { |
| 804 FunctionElement constructor; | 738 FunctionElement constructor; |
| 805 | 739 |
| 806 ConstructorBodyElement(FunctionElement constructor) | 740 ConstructorBodyElement(FunctionElement constructor) |
| 807 : this.constructor = constructor, | 741 : this.constructor = constructor, |
| 808 super(constructor.name, | 742 super(constructor.name, |
| 809 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, | 743 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
| 810 null, | 744 null, |
| 811 constructor.enclosingElement) { | 745 constructor.enclosingElement) { |
| 812 functionSignature = constructor.functionSignature; | 746 functionSignature = constructor.functionSignature; |
| 813 } | 747 } |
| 814 | 748 |
| 815 bool isInstanceMember() => true; | 749 bool isInstanceMember() => true; |
| 816 | 750 |
| 817 FunctionType computeType(Compiler compiler) { | 751 FunctionType computeType(Compiler compiler) { |
| 818 compiler.reportFatalError('Internal error: $this.computeType', this); | 752 compiler.reportFatalError('Internal error: $this.computeType', this); |
| 819 } | 753 } |
| 820 | 754 |
| 821 Node parseNode(DiagnosticListener listener) { | 755 Node parseNode(DiagnosticListener listener) { |
| 822 if (cachedNode !== null) return cachedNode; | 756 if (cachedNode !== null) return cachedNode; |
| 823 cachedNode = constructor.parseNode(listener); | 757 cachedNode = constructor.parseNode(listener); |
| 824 assert(cachedNode !== null); | 758 assert(cachedNode !== null); |
| 825 return cachedNode; | 759 return cachedNode; |
| 826 } | 760 } |
| 827 | 761 |
| 828 Token position() => constructor.position(); | 762 Token position() => constructor.position(); |
| 829 | |
| 830 ConstructorBodyElement cloneTo(Element enclosing, | |
| 831 DiagnosticListener listener) { | |
| 832 ConstructorBodyElement result = | |
| 833 new ConstructorBodyElement(constructor.cloneTo(enclosing, listener)); | |
| 834 result.scriptOverride = getScript(); | |
| 835 return result; | |
| 836 } | |
| 837 } | 763 } |
| 838 | 764 |
| 839 class SynthesizedConstructorElement extends FunctionElement { | 765 class SynthesizedConstructorElement extends FunctionElement { |
| 840 SynthesizedConstructorElement(Element enclosing) | 766 SynthesizedConstructorElement(Element enclosing) |
| 841 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, | 767 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, |
| 842 null, enclosing); | 768 null, enclosing); |
| 843 | 769 |
| 844 Token position() => enclosingElement.position(); | 770 Token position() => enclosingElement.position(); |
| 845 | |
| 846 SynthesizedConstructorElement cloneTo(Element enclosing, | |
| 847 DiagnosticListener listener) { | |
| 848 return new SynthesizedConstructorElement(enclosing); | |
| 849 } | |
| 850 } | 771 } |
| 851 | 772 |
| 852 class VoidElement extends Element { | 773 class VoidElement extends Element { |
| 853 VoidElement(Element enclosing) | 774 VoidElement(Element enclosing) |
| 854 : super(const SourceString('void'), ElementKind.VOID, enclosing); | 775 : super(const SourceString('void'), ElementKind.VOID, enclosing); |
| 855 Type computeType(compiler) => compiler.types.voidType; | 776 Type computeType(compiler) => compiler.types.voidType; |
| 856 Node parseNode(_) { | 777 Node parseNode(_) { |
| 857 throw 'internal error: parseNode on void'; | 778 throw 'internal error: parseNode on void'; |
| 858 } | 779 } |
| 859 bool impliesType() => true; | 780 bool impliesType() => true; |
| 860 } | 781 } |
| 861 | 782 |
| 862 class ClassElement extends ContainerElement { | 783 class ClassElement extends ContainerElement { |
| 863 final int id; | 784 final int id; |
| 864 Type type; | 785 Type type; |
| 865 Type supertype; | 786 Type supertype; |
| 866 Type defaultClass; | 787 Type defaultClass; |
| 867 Link<Element> members = const EmptyLink<Element>(); | 788 Link<Element> members = const EmptyLink<Element>(); |
| 868 Map<SourceString, Element> localMembers; | 789 Map<SourceString, Element> localMembers; |
| 869 Map<SourceString, Element> constructors; | 790 Map<SourceString, Element> constructors; |
| 870 Link<Type> interfaces = const EmptyLink<Type>(); | 791 Link<Type> interfaces = const EmptyLink<Type>(); |
| 871 LinkedHashMap<SourceString, TypeVariableElement> typeParameters; | 792 LinkedHashMap<SourceString, TypeVariableElement> typeParameters; |
| 872 SourceString nativeName; | |
| 873 bool isResolved = false; | 793 bool isResolved = false; |
| 874 bool isBeingResolved = false; | 794 bool isBeingResolved = false; |
| 875 // backendMembers are members that have been added by the backend to simplify | 795 // backendMembers are members that have been added by the backend to simplify |
| 876 // compilation. They don't have any user-side counter-part. | 796 // compilation. They don't have any user-side counter-part. |
| 877 Link<Element> backendMembers = const EmptyLink<Element>(); | 797 Link<Element> backendMembers = const EmptyLink<Element>(); |
| 878 | 798 |
| 879 Link<Type> allSupertypes; | 799 Link<Type> allSupertypes; |
| 800 ClassElement patch = null; |
| 880 | 801 |
| 881 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) | 802 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) |
| 882 : localMembers = new Map<SourceString, Element>(), | 803 : localMembers = new Map<SourceString, Element>(), |
| 883 constructors = new Map<SourceString, Element>(), | 804 constructors = new Map<SourceString, Element>(), |
| 884 typeParameters = new LinkedHashMap<SourceString, TypeVariableElement>(), | 805 typeParameters = new LinkedHashMap<SourceString, TypeVariableElement>(), |
| 885 super(name, ElementKind.CLASS, enclosing); | 806 super(name, ElementKind.CLASS, enclosing); |
| 886 | 807 |
| 887 void addMember(Element element, DiagnosticListener listener) { | 808 void addMember(Element element, DiagnosticListener listener) { |
| 888 members = members.prepend(element); | 809 members = members.prepend(element); |
| 889 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || | 810 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 */ | 961 */ |
| 1041 bool isSubclassOf(ClassElement cls) { | 962 bool isSubclassOf(ClassElement cls) { |
| 1042 for (ClassElement s = this; s != null; s = s.superclass) { | 963 for (ClassElement s = this; s != null; s = s.superclass) { |
| 1043 if (s === cls) return true; | 964 if (s === cls) return true; |
| 1044 } | 965 } |
| 1045 return false; | 966 return false; |
| 1046 } | 967 } |
| 1047 | 968 |
| 1048 bool isInterface() => false; | 969 bool isInterface() => false; |
| 1049 bool isNative() => nativeName != null; | 970 bool isNative() => nativeName != null; |
| 971 SourceString nativeName; |
| 1050 int hashCode() => id; | 972 int hashCode() => id; |
| 1051 | |
| 1052 void cloneMembersTo(Element target, DiagnosticListener listener) { | |
| 1053 target.type = type; | |
| 1054 target.supertype = supertype; | |
| 1055 target.defaultClass = defaultClass; | |
| 1056 target.interfaces = interfaces; | |
| 1057 target.typeParameters = | |
| 1058 new LinkedHashMap<SourceString, TypeVariableElement>(); | |
| 1059 typeParameters.forEach((SourceString name, TypeVariableElement type) { | |
| 1060 target.typeParameters[name] = type.cloneTo(target, listener); | |
| 1061 }); | |
| 1062 target.nativeName = nativeName; | |
| 1063 target.isResolved = isResolved; | |
| 1064 target.isBeingResolved = isBeingResolved; | |
| 1065 target.allSupertypes = allSupertypes; | |
| 1066 if (!backendMembers.isEmpty()) { | |
| 1067 listener.cancel("Cloning backend-modified class.", element: this); | |
| 1068 } | |
| 1069 | |
| 1070 Link<Element> elementList = this.members; | |
| 1071 while (!elementList.isEmpty()) { | |
| 1072 target.addMember(elementList.head.cloneTo(target, listener), listener); | |
| 1073 elementList = elementList.tail; | |
| 1074 } | |
| 1075 } | |
| 1076 | |
| 1077 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 1078 // TODO(lrn): Is copying id acceptable? | |
| 1079 ClassElement result = new ClassElement(name, enclosing, id); | |
| 1080 cloneMembersTo(result, listener); | |
| 1081 result.scriptOverride = getScript(); | |
| 1082 return result; | |
| 1083 } | |
| 1084 } | 973 } |
| 1085 | 974 |
| 1086 class Elements { | 975 class Elements { |
| 1087 static bool isLocal(Element element) { | 976 static bool isLocal(Element element) { |
| 1088 return ((element !== null) | 977 return ((element !== null) |
| 1089 && !element.isInstanceMember() | 978 && !element.isInstanceMember() |
| 1090 && !isStaticOrTopLevelField(element) | 979 && !isStaticOrTopLevelField(element) |
| 1091 && !isStaticOrTopLevelFunction(element) | 980 && !isStaticOrTopLevelFunction(element) |
| 1092 && (element.kind === ElementKind.VARIABLE || | 981 && (element.kind === ElementKind.VARIABLE || |
| 1093 element.kind === ElementKind.PARAMETER || | 982 element.kind === ElementKind.PARAMETER || |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 || (element == coreLibrary.find(const SourceString('Pattern'))); | 1083 || (element == coreLibrary.find(const SourceString('Pattern'))); |
| 1195 } | 1084 } |
| 1196 | 1085 |
| 1197 static bool isListSupertype(Element element, Compiler compiler) { | 1086 static bool isListSupertype(Element element, Compiler compiler) { |
| 1198 LibraryElement coreLibrary = compiler.coreLibrary; | 1087 LibraryElement coreLibrary = compiler.coreLibrary; |
| 1199 return (element == coreLibrary.find(const SourceString('Collection'))) | 1088 return (element == coreLibrary.find(const SourceString('Collection'))) |
| 1200 || (element == coreLibrary.find(const SourceString('Iterable'))); | 1089 || (element == coreLibrary.find(const SourceString('Iterable'))); |
| 1201 } | 1090 } |
| 1202 } | 1091 } |
| 1203 | 1092 |
| 1093 |
| 1204 class LabelElement extends Element { | 1094 class LabelElement extends Element { |
| 1205 // We store the original label here so it can be returned by [parseNode]. | 1095 // We store the original label here so it can be returned by [parseNode]. |
| 1206 final Label label; | 1096 final Label label; |
| 1207 final String labelName; | 1097 final String labelName; |
| 1208 final TargetElement target; | 1098 final TargetElement target; |
| 1209 bool isBreakTarget = false; | 1099 bool isBreakTarget = false; |
| 1210 bool isContinueTarget = false; | 1100 bool isContinueTarget = false; |
| 1211 LabelElement(Label label, this.labelName, this.target, | 1101 LabelElement(Label label, this.labelName, this.target, |
| 1212 Element enclosingElement) | 1102 Element enclosingElement) |
| 1213 : this.label = label, | 1103 : this.label = label, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 class TypeVariableElement extends Element { | 1150 class TypeVariableElement extends Element { |
| 1261 final Node node; | 1151 final Node node; |
| 1262 Type bound; | 1152 Type bound; |
| 1263 Type type; | 1153 Type type; |
| 1264 TypeVariableElement(name, Element enclosing, this.node, this.type, | 1154 TypeVariableElement(name, Element enclosing, this.node, this.type, |
| 1265 [this.bound]) | 1155 [this.bound]) |
| 1266 : super(name, ElementKind.TYPE_VARIABLE, enclosing); | 1156 : super(name, ElementKind.TYPE_VARIABLE, enclosing); |
| 1267 Type computeType(compiler) => type; | 1157 Type computeType(compiler) => type; |
| 1268 Node parseNode(compiler) => node; | 1158 Node parseNode(compiler) => node; |
| 1269 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; | 1159 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; |
| 1270 | |
| 1271 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { | |
| 1272 TypeVariableElement result = | |
| 1273 new TypeVariableElement(name, enclosing, node, type, bound); | |
| 1274 result.scriptOverride = getScript(); | |
| 1275 return result; | |
| 1276 } | |
| 1277 } | 1160 } |
| OLD | NEW |