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 |