Chromium Code Reviews| 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 20 matching lines...) Expand all Loading... | |
| 31 | 31 |
| 32 static final int ALIAS = 32; | 32 static final int ALIAS = 32; |
| 33 | 33 |
| 34 static final int SUPER = 64; | 34 static final int SUPER = 64; |
| 35 | 35 |
| 36 /** Type variable */ | 36 /** Type variable */ |
| 37 static final int TYPE_VARIABLE = 128; | 37 static final int TYPE_VARIABLE = 128; |
| 38 | 38 |
| 39 static final int IMPLIES_TYPE = CLASS | ALIAS | TYPE_VARIABLE; | 39 static final int IMPLIES_TYPE = CLASS | ALIAS | TYPE_VARIABLE; |
| 40 | 40 |
| 41 static final int IS_EXTENDABLE = CLASS | ALIAS; | 41 static final int IS_EXTENDABLE = CLASS; |
| 42 } | 42 } |
| 43 | 43 |
| 44 class ElementKind { | 44 class ElementKind { |
| 45 final String id; | 45 final String id; |
| 46 final int category; | 46 final int category; |
| 47 | 47 |
| 48 const ElementKind(String this.id, this.category); | 48 const ElementKind(String this.id, this.category); |
| 49 | 49 |
| 50 static final ElementKind VARIABLE = | 50 static final ElementKind VARIABLE = |
| 51 const ElementKind('variable', ElementCategory.VARIABLE); | 51 const ElementKind('variable', ElementCategory.VARIABLE); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 | 207 |
| 208 Element getOutermostEnclosingMemberOrTopLevel() { | 208 Element getOutermostEnclosingMemberOrTopLevel() { |
| 209 for (Element e = this; e !== null; e = e.enclosingElement) { | 209 for (Element e = this; e !== null; e = e.enclosingElement) { |
| 210 if (e.isMember() || e.isTopLevel()) { | 210 if (e.isMember() || e.isTopLevel()) { |
| 211 return e; | 211 return e; |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 return null; | 214 return null; |
| 215 } | 215 } |
| 216 | 216 |
| 217 /** | |
| 218 * Creates the scope for this element. The scope of the | |
| 219 * enclosing element will be the parent scope. | |
| 220 */ | |
| 221 Scope buildScope() => buildEnclosingScope(); | |
| 222 | |
| 223 /** | |
| 224 * Creates the scope for the enclosing element. The scope of the | |
| 225 * enclosing element will be the parent scope. | |
|
ahe
2012/08/02 06:43:14
Could you explain what the difference between thes
| |
| 226 */ | |
| 227 Scope buildEnclosingScope() => enclosingElement.buildScope(); | |
| 228 | |
| 217 String toString() { | 229 String toString() { |
| 218 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an | 230 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an |
| 219 // invariant for all element types? | 231 // invariant for all element types? |
| 220 var nameText = name !== null ? name.slowToString() : '?'; | 232 var nameText = name !== null ? name.slowToString() : '?'; |
| 221 if (enclosingElement !== null && !isTopLevel()) { | 233 if (enclosingElement !== null && !isTopLevel()) { |
| 222 String holderName = enclosingElement.name !== null | 234 String holderName = enclosingElement.name !== null |
| 223 ? enclosingElement.name.slowToString() | 235 ? enclosingElement.name.slowToString() |
| 224 : '${enclosingElement.kind}?'; | 236 : '${enclosingElement.kind}?'; |
| 225 return '$kind($holderName#${nameText})'; | 237 return '$kind($holderName#${nameText})'; |
| 226 } else { | 238 } else { |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 */ | 399 */ |
| 388 String getLibraryOrScriptName() { | 400 String getLibraryOrScriptName() { |
| 389 if (libraryTag !== null) { | 401 if (libraryTag !== null) { |
| 390 return libraryTag.argument.dartString.slowToString(); | 402 return libraryTag.argument.dartString.slowToString(); |
| 391 } else { | 403 } else { |
| 392 // Use the file name as script name. | 404 // Use the file name as script name. |
| 393 var path = script.uri.path; | 405 var path = script.uri.path; |
| 394 return path.substring(path.lastIndexOf('/') + 1); | 406 return path.substring(path.lastIndexOf('/') + 1); |
| 395 } | 407 } |
| 396 } | 408 } |
| 409 | |
| 410 Scope buildEnclosingScope() => new TopScope(this); | |
| 397 } | 411 } |
| 398 | 412 |
| 399 class PrefixElement extends Element { | 413 class PrefixElement extends Element { |
| 400 Map<SourceString, Element> imported; | 414 Map<SourceString, Element> imported; |
| 401 Token firstPosition; | 415 Token firstPosition; |
| 402 final CompilationUnitElement patchSource; | 416 final CompilationUnitElement patchSource; |
| 403 | 417 |
| 404 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition, | 418 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition, |
| 405 [this.patchSource]) | 419 [this.patchSource]) |
| 406 : imported = new Map<SourceString, Element>(), | 420 : imported = new Map<SourceString, Element>(), |
| 407 super(prefix, ElementKind.PREFIX, enclosing); | 421 super(prefix, ElementKind.PREFIX, enclosing); |
| 408 | 422 |
| 409 CompilationUnitElement getCompilationUnit() { | 423 CompilationUnitElement getCompilationUnit() { |
| 410 if (patchSource !== null) return patchSource; | 424 if (patchSource !== null) return patchSource; |
| 411 return super.getCompilationUnit(); | 425 return super.getCompilationUnit(); |
| 412 } | 426 } |
| 413 | 427 |
| 414 lookupLocalMember(SourceString memberName) => imported[memberName]; | 428 lookupLocalMember(SourceString memberName) => imported[memberName]; |
| 415 | 429 |
| 416 Type computeType(Compiler compiler) => compiler.types.dynamicType; | 430 Type computeType(Compiler compiler) => compiler.types.dynamicType; |
| 417 | 431 |
| 418 Token position() => firstPosition; | 432 Token position() => firstPosition; |
| 419 } | 433 } |
| 420 | 434 |
| 421 class TypedefElement extends Element { | 435 class TypedefElement extends Element implements TypeDeclarationElement { |
| 422 Type cachedType; | 436 TypedefElement(SourceString name, Element enclosing) |
| 437 : super(name, ElementKind.TYPEDEF, enclosing); | |
| 438 | |
| 439 TypedefType cachedType; | |
| 440 Type alias; | |
| 423 Typedef cachedNode; | 441 Typedef cachedNode; |
| 424 | 442 |
| 425 TypedefElement(SourceString name, Element enclosing) | 443 /** |
| 426 : super(name, ElementKind.TYPEDEF, enclosing); | 444 * Function signature for a typedef of a function type. The signature is |
| 445 * kept to provide full information about parameter names through the mirror | |
| 446 * system. | |
| 447 * | |
| 448 * The [functionSignature] is not available until the typedef element has been | |
| 449 * resolved. | |
| 450 */ | |
| 451 FunctionSignature functionSignature; | |
| 427 | 452 |
| 428 Type computeType(Compiler compiler) { | 453 TypedefType computeType(Compiler compiler) { |
| 429 if (cachedType !== null) return cachedType; | 454 if (cachedType == null) { |
| 430 cachedType = compiler.computeFunctionType( | 455 Typedef node = parseNode(compiler); |
| 431 this, compiler.resolveTypedef(this)); | 456 Link<TypeVariableType> parameters = |
| 457 createTypeVariables(this, node.typeParameters); | |
|
ahe
2012/08/02 06:43:14
How about adding:
assert(cachedType === null);
| |
| 458 cachedType = new TypedefType(this, parameters); | |
| 459 } | |
| 432 return cachedType; | 460 return cachedType; |
| 433 } | 461 } |
| 462 | |
| 463 | |
| 464 Link<TypeVariableType> get typeVariables() => cachedType.typeArguments; | |
| 465 | |
| 466 Scope buildScope() => | |
| 467 new TypeDeclarationScope(enclosingElement.buildScope(), this); | |
| 434 } | 468 } |
| 435 | 469 |
| 436 class VariableElement extends Element { | 470 class VariableElement extends Element { |
| 437 final VariableListElement variables; | 471 final VariableListElement variables; |
| 438 Expression cachedNode; // The send or the identifier in the variables list. | 472 Expression cachedNode; // The send or the identifier in the variables list. |
| 439 | 473 |
| 440 Modifiers get modifiers() => variables.modifiers; | 474 Modifiers get modifiers() => variables.modifiers; |
| 441 | 475 |
| 442 VariableElement(SourceString name, | 476 VariableElement(SourceString name, |
| 443 VariableListElement this.variables, | 477 VariableListElement this.variables, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 // It contains the node, and the type. A [VariableElement] always | 532 // It contains the node, and the type. A [VariableElement] always |
| 499 // references its [VariableListElement]. It forwards its | 533 // references its [VariableListElement]. It forwards its |
| 500 // [computeType] and [parseNode] methods to this element. | 534 // [computeType] and [parseNode] methods to this element. |
| 501 class VariableListElement extends Element { | 535 class VariableListElement extends Element { |
| 502 VariableDefinitions cachedNode; | 536 VariableDefinitions cachedNode; |
| 503 Type type; | 537 Type type; |
| 504 final Modifiers modifiers; | 538 final Modifiers modifiers; |
| 505 | 539 |
| 506 /** | 540 /** |
| 507 * Function signature for a variable with a function type. The signature is | 541 * Function signature for a variable with a function type. The signature is |
| 508 * kept to provide full information about parameter names through the the | 542 * kept to provide full information about parameter names through the mirror |
| 509 * mirror system. | 543 * system. |
| 510 */ | 544 */ |
| 511 FunctionSignature functionSignature; | 545 FunctionSignature functionSignature; |
| 512 | 546 |
| 513 VariableListElement(ElementKind kind, | 547 VariableListElement(ElementKind kind, |
| 514 Modifiers this.modifiers, | 548 Modifiers this.modifiers, |
| 515 Element enclosing) | 549 Element enclosing) |
| 516 : super(null, kind, enclosing); | 550 : super(null, kind, enclosing); |
| 517 | 551 |
| 518 VariableListElement.node(VariableDefinitions node, | 552 VariableListElement.node(VariableDefinitions node, |
| 519 ElementKind kind, | 553 ElementKind kind, |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 getter.modifiers.nodes, | 640 getter.modifiers.nodes, |
| 607 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 641 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 608 } else { | 642 } else { |
| 609 return new Modifiers.withFlags( | 643 return new Modifiers.withFlags( |
| 610 setter.modifiers.nodes, | 644 setter.modifiers.nodes, |
| 611 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); | 645 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); |
| 612 } | 646 } |
| 613 } | 647 } |
| 614 } | 648 } |
| 615 | 649 |
| 650 // TODO(johnniwinther): [FunctionSignature] should be merged with | |
| 651 // [FunctionType]. | |
| 616 class FunctionSignature { | 652 class FunctionSignature { |
| 617 Link<Element> requiredParameters; | 653 Link<Element> requiredParameters; |
| 618 Link<Element> optionalParameters; | 654 Link<Element> optionalParameters; |
| 619 Type returnType; | 655 Type returnType; |
| 620 int requiredParameterCount; | 656 int requiredParameterCount; |
| 621 int optionalParameterCount; | 657 int optionalParameterCount; |
| 622 FunctionSignature(this.requiredParameters, | 658 FunctionSignature(this.requiredParameters, |
| 623 this.optionalParameters, | 659 this.optionalParameters, |
| 624 this.requiredParameterCount, | 660 this.requiredParameterCount, |
| 625 this.optionalParameterCount, | 661 this.optionalParameterCount, |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 class VoidElement extends Element { | 840 class VoidElement extends Element { |
| 805 VoidElement(Element enclosing) | 841 VoidElement(Element enclosing) |
| 806 : super(const SourceString('void'), ElementKind.VOID, enclosing); | 842 : super(const SourceString('void'), ElementKind.VOID, enclosing); |
| 807 Type computeType(compiler) => compiler.types.voidType; | 843 Type computeType(compiler) => compiler.types.voidType; |
| 808 Node parseNode(_) { | 844 Node parseNode(_) { |
| 809 throw 'internal error: parseNode on void'; | 845 throw 'internal error: parseNode on void'; |
| 810 } | 846 } |
| 811 bool impliesType() => true; | 847 bool impliesType() => true; |
| 812 } | 848 } |
| 813 | 849 |
| 814 class ClassElement extends ContainerElement { | 850 /** |
| 851 * [TypeDeclarationElement] defines the common interface for class/interface | |
| 852 * declarations and typedefs. | |
| 853 */ | |
| 854 interface TypeDeclarationElement extends Element { | |
| 855 /** | |
| 856 * The type variables declared on this declaration. The type variables are not | |
| 857 * available until the type of the element has been computed through | |
| 858 * [computeType]. | |
| 859 */ | |
| 860 // TODO(johnniwinther): Find a (better) way to decouple [typeVariables] from | |
| 861 // [Compiler]. | |
| 862 final Link<TypeVariableType> typeVariables; | |
| 863 } | |
| 864 | |
| 865 /** | |
| 866 * Creates the type variables, their type and corresponding element, for the | |
| 867 * type variables declared in [parameter] on [element]. The bounds of the type | |
| 868 * variables are not set until [element] has been resolved. | |
| 869 */ | |
| 870 Link<TypeVariableType> createTypeVariables(TypeDeclarationElement element, | |
| 871 NodeList parameters) { | |
| 872 if (parameters === null) return const EmptyLink<TypeVariableType>(); | |
| 873 | |
| 874 // Create types and elements for type variable. | |
| 875 var arguments = new LinkBuilder<TypeVariableType>(); | |
| 876 for (Link<Node> link = parameters.nodes; !link.isEmpty(); link = link.tail) { | |
| 877 TypeVariable typeNode = link.head; | |
| 878 SourceString variableName = typeNode.name.source; | |
| 879 TypeVariableType variableType = new TypeVariableType(variableName); | |
| 880 arguments.addLast(variableType); | |
| 881 TypeVariableElement variableElement = | |
| 882 new TypeVariableElement(variableName, element, typeNode, variableType); | |
| 883 variableType.element = variableElement; | |
| 884 } | |
| 885 return arguments.toLink(); | |
| 886 } | |
| 887 | |
| 888 /** | |
| 889 * Looks up [name] within the type variables declared in [element]. | |
| 890 */ | |
| 891 Element lookupTypeVariable(TypeDeclarationElement element, | |
| 892 SourceString name) { | |
| 893 Link<TypeVariableType> typeVariableLink = element.typeVariables; | |
| 894 while (!typeVariableLink.isEmpty()) { | |
| 895 TypeVariableType typeVariable = typeVariableLink.head; | |
| 896 if (typeVariable.name == name) { | |
| 897 return typeVariable.element; | |
| 898 } | |
| 899 typeVariableLink = typeVariableLink.tail; | |
| 900 } | |
| 901 return null; | |
| 902 } | |
| 903 | |
|
ahe
2012/08/02 06:43:14
Extra line.
| |
| 904 | |
| 905 class ClassElement extends ContainerElement | |
| 906 implements TypeDeclarationElement { | |
| 815 final int id; | 907 final int id; |
| 816 Type type; | 908 InterfaceType type; |
| 817 Type supertype; | 909 InterfaceType supertype; |
|
ahe
2012/08/02 06:43:14
Eventually an interface may extend a typedef. So I
| |
| 818 Type defaultClass; | 910 InterfaceType defaultClass; |
| 819 Link<Element> members = const EmptyLink<Element>(); | 911 Link<Element> members = const EmptyLink<Element>(); |
| 820 Map<SourceString, Element> localMembers; | 912 Map<SourceString, Element> localMembers; |
| 821 Map<SourceString, Element> constructors; | 913 Map<SourceString, Element> constructors; |
| 822 Link<Type> interfaces = const EmptyLink<Type>(); | 914 Link<InterfaceType> interfaces = const EmptyLink<InterfaceType>(); |
| 823 LinkedHashMap<SourceString, TypeVariableElement> typeParameters; | |
| 824 bool isResolved = false; | 915 bool isResolved = false; |
| 825 bool isBeingResolved = false; | 916 bool isBeingResolved = false; |
| 826 // backendMembers are members that have been added by the backend to simplify | 917 // backendMembers are members that have been added by the backend to simplify |
| 827 // compilation. They don't have any user-side counter-part. | 918 // compilation. They don't have any user-side counter-part. |
| 828 Link<Element> backendMembers = const EmptyLink<Element>(); | 919 Link<Element> backendMembers = const EmptyLink<Element>(); |
| 829 | 920 |
| 830 Link<Type> allSupertypes; | 921 Link<InterfaceType> allSupertypes; |
| 831 ClassElement patch = null; | 922 ClassElement patch = null; |
| 832 Node defaultClause; // Only for interfaces. | 923 Node defaultClause; // Only for interfaces. |
| 833 | 924 |
| 834 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) | 925 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) |
| 835 : localMembers = new Map<SourceString, Element>(), | 926 : localMembers = new Map<SourceString, Element>(), |
| 836 constructors = new Map<SourceString, Element>(), | 927 constructors = new Map<SourceString, Element>(), |
| 837 typeParameters = new LinkedHashMap<SourceString, TypeVariableElement>(), | |
| 838 super(name, ElementKind.CLASS, enclosing); | 928 super(name, ElementKind.CLASS, enclosing); |
| 839 | 929 |
| 840 void addMember(Element element, DiagnosticListener listener) { | 930 void addMember(Element element, DiagnosticListener listener) { |
| 841 members = members.prepend(element); | 931 members = members.prepend(element); |
| 842 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || | 932 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || |
| 843 element.modifiers.isFactory()) { | 933 element.modifiers.isFactory()) { |
| 844 constructors[element.name] = element; | 934 constructors[element.name] = element; |
| 845 } else if (element.kind == ElementKind.GETTER | 935 } else if (element.kind == ElementKind.GETTER |
| 846 || element.kind == ElementKind.SETTER) { | 936 || element.kind == ElementKind.SETTER) { |
| 847 addGetterOrSetter(element, localMembers[element.name], listener); | 937 addGetterOrSetter(element, localMembers[element.name], listener); |
| 848 } else { | 938 } else { |
| 849 localMembers[element.name] = element; | 939 localMembers[element.name] = element; |
| 850 } | 940 } |
| 851 } | 941 } |
| 852 | 942 |
| 853 Type computeType(compiler) { | 943 InterfaceType computeType(compiler) { |
| 854 if (type === null) { | 944 if (type == null) { |
| 855 type = new InterfaceType(this); | 945 ClassNode node = parseNode(compiler); |
| 946 Link<TypeVariableType> parameters = | |
| 947 createTypeVariables(this, node.typeParameters); | |
| 948 type = new InterfaceType(this, parameters); | |
| 856 } | 949 } |
| 857 return type; | 950 return type; |
| 858 } | 951 } |
| 859 | 952 |
| 953 Link<TypeVariableType> get typeVariables() => type.typeArguments; | |
|
ahe
2012/08/02 06:43:14
Same applies here, so I would prefer Link<Type>.
| |
| 954 | |
| 860 ClassElement ensureResolved(Compiler compiler) { | 955 ClassElement ensureResolved(Compiler compiler) { |
| 861 compiler.resolveClass(this); | 956 compiler.resolveClass(this); |
| 862 return this; | 957 return this; |
| 863 } | 958 } |
| 864 | 959 |
| 865 Element lookupTypeParameter(SourceString parameterName) { | |
| 866 Element result = typeParameters[parameterName]; | |
| 867 return result; | |
| 868 } | |
| 869 | |
| 870 Element lookupLocalMember(SourceString memberName) { | 960 Element lookupLocalMember(SourceString memberName) { |
| 871 return localMembers[memberName]; | 961 return localMembers[memberName]; |
| 872 } | 962 } |
| 873 | 963 |
| 874 Element lookupSuperMember(SourceString memberName) { | 964 Element lookupSuperMember(SourceString memberName) { |
| 875 for (ClassElement s = superclass; s != null; s = s.superclass) { | 965 for (ClassElement s = superclass; s != null; s = s.superclass) { |
| 876 Element e = s.lookupLocalMember(memberName); | 966 Element e = s.lookupLocalMember(memberName); |
| 877 if (e === null) continue; | 967 if (e === null) continue; |
| 878 // Private members from a different library are not visible. | 968 // Private members from a different library are not visible. |
| 879 if (memberName.isPrivate() && getLibrary() !== e.getLibrary()) continue; | 969 if (memberName.isPrivate() && getLibrary() !== e.getLibrary()) continue; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 995 for (ClassElement s = this; s != null; s = s.superclass) { | 1085 for (ClassElement s = this; s != null; s = s.superclass) { |
| 996 if (s === cls) return true; | 1086 if (s === cls) return true; |
| 997 } | 1087 } |
| 998 return false; | 1088 return false; |
| 999 } | 1089 } |
| 1000 | 1090 |
| 1001 bool isInterface() => false; | 1091 bool isInterface() => false; |
| 1002 bool isNative() => nativeName != null; | 1092 bool isNative() => nativeName != null; |
| 1003 SourceString nativeName; | 1093 SourceString nativeName; |
| 1004 int hashCode() => id; | 1094 int hashCode() => id; |
| 1095 | |
| 1096 Scope buildScope() => | |
| 1097 new ClassScope(enclosingElement.buildScope(), this); | |
| 1005 } | 1098 } |
| 1006 | 1099 |
| 1007 class Elements { | 1100 class Elements { |
| 1008 static bool isLocal(Element element) { | 1101 static bool isLocal(Element element) { |
| 1009 return ((element !== null) | 1102 return ((element !== null) |
| 1010 && !element.isInstanceMember() | 1103 && !element.isInstanceMember() |
| 1011 && !isStaticOrTopLevelField(element) | 1104 && !isStaticOrTopLevelField(element) |
| 1012 && !isStaticOrTopLevelFunction(element) | 1105 && !isStaticOrTopLevelFunction(element) |
| 1013 && (element.kind === ElementKind.VARIABLE || | 1106 && (element.kind === ElementKind.VARIABLE || |
| 1014 element.kind === ElementKind.PARAMETER || | 1107 element.kind === ElementKind.PARAMETER || |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1173 | 1266 |
| 1174 Node parseNode(DiagnosticListener l) => statement; | 1267 Node parseNode(DiagnosticListener l) => statement; |
| 1175 | 1268 |
| 1176 bool get isSwitch() => statement is SwitchStatement; | 1269 bool get isSwitch() => statement is SwitchStatement; |
| 1177 | 1270 |
| 1178 Token position() => statement.getBeginToken(); | 1271 Token position() => statement.getBeginToken(); |
| 1179 String toString() => statement.toString(); | 1272 String toString() => statement.toString(); |
| 1180 } | 1273 } |
| 1181 | 1274 |
| 1182 class TypeVariableElement extends Element { | 1275 class TypeVariableElement extends Element { |
| 1183 final Node node; | 1276 final Node cachedNode; |
| 1184 Type bound; | 1277 Type bound; |
| 1185 Type type; | 1278 TypeVariableType type; |
| 1186 TypeVariableElement(name, Element enclosing, this.node, this.type, | 1279 |
| 1280 TypeVariableElement(name, Element enclosing, this.cachedNode, this.type, | |
| 1187 [this.bound]) | 1281 [this.bound]) |
| 1188 : super(name, ElementKind.TYPE_VARIABLE, enclosing); | 1282 : super(name, ElementKind.TYPE_VARIABLE, enclosing); |
| 1189 Type computeType(compiler) => type; | 1283 |
| 1190 Node parseNode(compiler) => node; | 1284 TypeVariableType computeType(compiler) => type; |
| 1191 toString() => "${enclosingElement.toString()}.${name.slowToString()}"; | 1285 |
| 1286 Node parseNode(compiler) => cachedNode; | |
| 1287 | |
| 1288 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; | |
|
ahe
2012/08/02 06:43:14
This change is fine, but am I the only one thinkin
| |
| 1192 } | 1289 } |
| OLD | NEW |