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('dart:uri'); | 7 #import('dart:uri'); |
| 8 | 8 |
| 9 #import('../tree/tree.dart'); | 9 #import('../tree/tree.dart'); |
| 10 #import('../scanner/scannerlib.dart'); | 10 #import('../scanner/scannerlib.dart'); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 static const ElementKind STATEMENT = | 100 static const ElementKind STATEMENT = |
| 101 const ElementKind('statement', ElementCategory.NONE); | 101 const ElementKind('statement', ElementCategory.NONE); |
| 102 static const ElementKind LABEL = | 102 static const ElementKind LABEL = |
| 103 const ElementKind('label', ElementCategory.NONE); | 103 const ElementKind('label', ElementCategory.NONE); |
| 104 static const ElementKind VOID = | 104 static const ElementKind VOID = |
| 105 const ElementKind('void', ElementCategory.NONE); | 105 const ElementKind('void', ElementCategory.NONE); |
| 106 | 106 |
| 107 toString() => id; | 107 toString() => id; |
| 108 } | 108 } |
| 109 | 109 |
| 110 class Element implements Hashable { | 110 class Element implements Hashable, Spanable { |
|
ahe
2012/09/20 11:12:07
It's "spanned" and "spanning", so shouldn't it be
Johnni Winther
2012/09/21 09:18:25
Probably :)
| |
| 111 final SourceString name; | 111 final SourceString name; |
| 112 final ElementKind kind; | 112 final ElementKind kind; |
| 113 final Element enclosingElement; | 113 final Element enclosingElement; |
| 114 Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>(); | 114 Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>(); |
| 115 | 115 |
| 116 Element(this.name, this.kind, this.enclosingElement) { | 116 Element(this.name, this.kind, this.enclosingElement) { |
| 117 assert(getLibrary() !== null); | 117 assert(getLibrary() !== null); |
| 118 } | 118 } |
| 119 | 119 |
| 120 Modifiers get modifiers => null; | 120 Modifiers get modifiers => null; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 bool isSetter() => kind === ElementKind.SETTER; | 164 bool isSetter() => kind === ElementKind.SETTER; |
| 165 bool isAccessor() => isGetter() || isSetter(); | 165 bool isAccessor() => isGetter() || isSetter(); |
| 166 bool isForeign() => kind === ElementKind.FOREIGN; | 166 bool isForeign() => kind === ElementKind.FOREIGN; |
| 167 bool isLibrary() => kind === ElementKind.LIBRARY; | 167 bool isLibrary() => kind === ElementKind.LIBRARY; |
| 168 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; | 168 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; |
| 169 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0; | 169 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0; |
| 170 | 170 |
| 171 /** See [ErroneousElement] for documentation. */ | 171 /** See [ErroneousElement] for documentation. */ |
| 172 bool isErroneous() => false; | 172 bool isErroneous() => false; |
| 173 | 173 |
| 174 //---------------------------------------------------------------------------- | |
|
ahe
2012/09/20 11:12:07
Can you remove this comment now?
Johnni Winther
2012/09/21 09:18:25
Done.
| |
| 175 // Patch related getters. See [:patch_parser.dart:] for a description of the | |
| 176 // terminology. | |
| 177 //---------------------------------------------------------------------------- | |
| 178 | |
| 179 /** | |
| 180 * Is [:true:] iff this element has a corresponding patch. | |
|
ahe
2012/09/20 11:12:07
Don't use "iff" or "if and only if" in documentati
Johnni Winther
2012/09/21 09:18:25
Done.
| |
| 181 * | |
| 182 * If [:true:] this element has a non-null [patch] field. | |
| 183 * | |
| 184 * See [:patch_parser.dart:] for a description of the terminology. | |
| 185 */ | |
| 186 bool get isPatched => false; | |
| 187 | |
| 188 /** | |
| 189 * Is [:true:] iff this element is a patch. | |
| 190 * | |
| 191 * If [:true:] this element has a non-null [origin] field. | |
| 192 * | |
| 193 * See [:patch_parser.dart:] for a description of the terminology. | |
| 194 */ | |
| 195 bool get isPatch => false; | |
| 196 | |
| 197 | |
| 198 /** | |
| 199 * Is [:true:] iff this element defines the implementation for the entity of | |
| 200 * this element. | |
| 201 * | |
| 202 * See [:patch_parser.dart:] for a description of the terminology. | |
| 203 */ | |
| 204 bool get isImplementation => implementation === this; | |
| 205 | |
| 206 /** | |
| 207 * Is [:true:] iff this element introduces the entity of this element. | |
| 208 * | |
| 209 * See [:patch_parser.dart:] for a description of the terminology. | |
| 210 */ | |
| 211 bool get isDeclaration => declaration === this; | |
| 212 | |
| 213 /** | |
| 214 * Returns the element which defines the implementation for the entity of this | |
| 215 * element. | |
| 216 * | |
| 217 * See [:patch_parser.dart:] for a description of the terminology. | |
| 218 */ | |
| 219 Element get implementation => this; | |
| 220 | |
| 221 /** | |
| 222 * Returns the element which introduces the entity of this element. | |
| 223 * | |
| 224 * See [:patch_parser.dart:] for a description of the terminology. | |
| 225 */ | |
| 226 Element get declaration => this; | |
| 227 | |
| 174 // TODO(johnniwinther): This breaks for libraries (for which enclosing | 228 // TODO(johnniwinther): This breaks for libraries (for which enclosing |
| 175 // elements are null) and is invalid for top level variable declarations for | 229 // elements are null) and is invalid for top level variable declarations for |
| 176 // which the enclosing element is a VariableDeclarations and not a compilation | 230 // which the enclosing element is a VariableDeclarations and not a compilation |
| 177 // unit. | 231 // unit. |
| 178 bool isTopLevel() { | 232 bool isTopLevel() { |
| 179 return enclosingElement !== null && enclosingElement.isCompilationUnit(); | 233 return enclosingElement !== null && enclosingElement.isCompilationUnit(); |
| 180 } | 234 } |
| 181 | 235 |
| 182 bool isAssignable() { | 236 bool isAssignable() { |
| 183 if (modifiers != null && modifiers.isFinalOrConst()) return false; | 237 if (modifiers != null && modifiers.isFinalOrConst()) return false; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 } | 276 } |
| 223 | 277 |
| 224 LibraryElement getLibrary() { | 278 LibraryElement getLibrary() { |
| 225 Element element = this; | 279 Element element = this; |
| 226 while (element.kind !== ElementKind.LIBRARY) { | 280 while (element.kind !== ElementKind.LIBRARY) { |
| 227 element = element.enclosingElement; | 281 element = element.enclosingElement; |
| 228 } | 282 } |
| 229 return element; | 283 return element; |
| 230 } | 284 } |
| 231 | 285 |
| 286 LibraryElement getImplementationLibrary() => getLibrary(); | |
| 287 | |
| 232 ClassElement getEnclosingClass() { | 288 ClassElement getEnclosingClass() { |
| 233 for (Element e = this; e !== null; e = e.enclosingElement) { | 289 for (Element e = this; e !== null; e = e.enclosingElement) { |
| 234 if (e.isClass()) return e; | 290 if (e.isClass()) return e; |
| 235 } | 291 } |
| 236 return null; | 292 return null; |
| 237 } | 293 } |
| 238 | 294 |
| 239 Element getEnclosingClassOrCompilationUnit() { | 295 Element getEnclosingClassOrCompilationUnit() { |
| 240 for (Element e = this; e !== null; e = e.enclosingElement) { | 296 for (Element e = this; e !== null; e = e.enclosingElement) { |
| 241 if (e.isClass() || e.isCompilationUnit()) return e; | 297 if (e.isClass() || e.isCompilationUnit()) return e; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 | 343 |
| 288 bool _isNative = false; | 344 bool _isNative = false; |
| 289 void setNative() { _isNative = true; } | 345 void setNative() { _isNative = true; } |
| 290 bool isNative() => _isNative; | 346 bool isNative() => _isNative; |
| 291 | 347 |
| 292 FunctionElement asFunctionElement() => null; | 348 FunctionElement asFunctionElement() => null; |
| 293 | 349 |
| 294 Element cloneTo(Element enclosing, DiagnosticListener listener) { | 350 Element cloneTo(Element enclosing, DiagnosticListener listener) { |
| 295 listener.cancel("Unimplemented cloneTo", element: this); | 351 listener.cancel("Unimplemented cloneTo", element: this); |
| 296 } | 352 } |
| 297 | |
| 298 bool get isPatched => false; | |
| 299 } | 353 } |
| 300 | 354 |
| 301 /** | 355 /** |
| 302 * Represents an unresolvable or duplicated element. | 356 * Represents an unresolvable or duplicated element. |
| 303 * | 357 * |
| 304 * An [ErroneousElement] is used instead of [null] to provide additional | 358 * An [ErroneousElement] is used instead of [null] to provide additional |
| 305 * information about the error that caused the element to be unresolvable | 359 * information about the error that caused the element to be unresolvable |
| 306 * or otherwise invalid. | 360 * or otherwise invalid. |
| 307 * | 361 * |
| 308 * Accessing any field or calling any method defined on [ErroneousElement] | 362 * Accessing any field or calling any method defined on [ErroneousElement] |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 338 class ErroneousFunctionElement extends ErroneousElement | 392 class ErroneousFunctionElement extends ErroneousElement |
| 339 implements FunctionElement { | 393 implements FunctionElement { |
| 340 ErroneousFunctionElement(Message errorMessage, SourceString targetName, | 394 ErroneousFunctionElement(Message errorMessage, SourceString targetName, |
| 341 Element enclosing) | 395 Element enclosing) |
| 342 : super(errorMessage, targetName, enclosing); | 396 : super(errorMessage, targetName, enclosing); |
| 343 | 397 |
| 344 get type => unsupported(); | 398 get type => unsupported(); |
| 345 get cachedNode => unsupported(); | 399 get cachedNode => unsupported(); |
| 346 get functionSignature => unsupported(); | 400 get functionSignature => unsupported(); |
| 347 get patch => unsupported(); | 401 get patch => unsupported(); |
| 402 get origin => unsupported(); | |
| 348 get defaultImplementation => unsupported(); | 403 get defaultImplementation => unsupported(); |
| 349 bool get isPatched => unsupported(); | 404 bool get isPatched => unsupported(); |
| 405 bool get isPatch => unsupported(); | |
| 350 setPatch(patch) => unsupported(); | 406 setPatch(patch) => unsupported(); |
| 351 computeSignature(compiler) => unsupported(); | 407 computeSignature(compiler) => unsupported(); |
| 352 requiredParameterCount(compiler) => unsupported(); | 408 requiredParameterCount(compiler) => unsupported(); |
| 353 optionalParameterCount(compiler) => unsupported(); | 409 optionalParameterCount(compiler) => unsupported(); |
| 354 parameterCount(copmiler) => unsupported(); | 410 parameterCount(copmiler) => unsupported(); |
| 355 } | 411 } |
| 356 | 412 |
| 357 class ContainerElement extends Element { | 413 class ContainerElement extends Element { |
| 358 Link<Element> localMembers = const EmptyLink<Element>(); | 414 Link<Element> localMembers = const EmptyLink<Element>(); |
| 359 | 415 |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 973 int optionalParameterCount(Compiler compiler) { | 1029 int optionalParameterCount(Compiler compiler) { |
| 974 return computeSignature(compiler).optionalParameterCount; | 1030 return computeSignature(compiler).optionalParameterCount; |
| 975 } | 1031 } |
| 976 | 1032 |
| 977 int parameterCount(Compiler compiler) { | 1033 int parameterCount(Compiler compiler) { |
| 978 return computeSignature(compiler).parameterCount; | 1034 return computeSignature(compiler).parameterCount; |
| 979 } | 1035 } |
| 980 | 1036 |
| 981 FunctionType computeType(Compiler compiler) { | 1037 FunctionType computeType(Compiler compiler) { |
| 982 if (type != null) return type; | 1038 if (type != null) return type; |
| 983 type = compiler.computeFunctionType(this, computeSignature(compiler)); | 1039 type = compiler.computeFunctionType(declaration, |
| 1040 computeSignature(compiler)); | |
| 984 return type; | 1041 return type; |
| 985 } | 1042 } |
| 986 | 1043 |
| 987 Node parseNode(DiagnosticListener listener) { | 1044 Node parseNode(DiagnosticListener listener) { |
|
ahe
2012/09/20 11:12:07
I think this method is fishy. It concerns me great
Johnni Winther
2012/09/21 09:18:25
Bad merge. These should not have been removed unti
| |
| 988 if (cachedNode !== null) return cachedNode; | |
| 989 if (patch === null) { | 1045 if (patch === null) { |
| 990 if (modifiers.isExternal()) { | 1046 if (modifiers != null && modifiers.isExternal()) { |
| 991 listener.cancel("Compiling external function with no implementation.", | 1047 listener.cancel("Compiling external function with no implementation.", |
| 992 element: this); | 1048 element: this); |
| 993 } | 1049 } |
| 994 return null; | |
| 995 } | 1050 } |
| 996 cachedNode = patch.parseNode(listener); | |
| 997 return cachedNode; | 1051 return cachedNode; |
| 998 } | 1052 } |
| 999 | 1053 |
| 1000 Token position() => cachedNode.getBeginToken(); | 1054 Token position() => cachedNode.getBeginToken(); |
| 1001 | 1055 |
| 1002 FunctionElement asFunctionElement() => this; | 1056 FunctionElement asFunctionElement() => this; |
| 1003 | 1057 |
| 1004 FunctionElement cloneTo(Element enclosing, DiagnosticListener listener) { | 1058 String toString() { |
| 1005 FunctionElement result = new FunctionElement.tooMuchOverloading( | 1059 if (isPatch) { |
| 1006 name, cachedNode, kind, modifiers, enclosing, functionSignature); | 1060 return 'patch ${super.toString()}'; |
| 1007 result.defaultImplementation = defaultImplementation; | 1061 } else if (isPatched) { |
| 1008 result.type = type; | 1062 return 'origin ${super.toString()}'; |
| 1009 return result; | 1063 } else { |
| 1064 return super.toString(); | |
| 1065 } | |
| 1010 } | 1066 } |
| 1011 | 1067 |
| 1012 Scope buildScope() { | 1068 Scope buildScope() { |
| 1013 Scope result = new MethodScope(enclosingElement.buildScope(), this); | 1069 Scope result = |
| 1070 new MethodScope(enclosingElement.buildScope(), this); | |
| 1014 if (enclosingElement.isClass()) { | 1071 if (enclosingElement.isClass()) { |
| 1015 ClassScope clsScope = result.parent; | 1072 Scope clsScope = result.parent; |
| 1016 clsScope.inStaticContext = !isInstanceMember() && !isConstructor(); | 1073 clsScope.inStaticContext = !isInstanceMember() && !isConstructor(); |
| 1017 } | 1074 } |
| 1018 return result; | 1075 return result; |
| 1019 } | 1076 } |
| 1020 } | 1077 } |
| 1021 | 1078 |
| 1022 | |
| 1023 class ConstructorBodyElement extends FunctionElement { | 1079 class ConstructorBodyElement extends FunctionElement { |
| 1024 FunctionElement constructor; | 1080 FunctionElement constructor; |
| 1025 | 1081 |
| 1026 ConstructorBodyElement(FunctionElement constructor) | 1082 ConstructorBodyElement(FunctionElement constructor) |
| 1027 : this.constructor = constructor, | 1083 : this.constructor = constructor, |
| 1028 super(constructor.name, | 1084 super(constructor.name, |
| 1029 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, | 1085 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, |
| 1030 null, | 1086 null, |
| 1031 constructor.enclosingElement) { | 1087 constructor.enclosingElement) { |
| 1032 functionSignature = constructor.functionSignature; | 1088 functionSignature = constructor.functionSignature; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1148 ClassNode node = parseNode(compiler); | 1204 ClassNode node = parseNode(compiler); |
| 1149 Link<DartType> parameters = | 1205 Link<DartType> parameters = |
| 1150 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); | 1206 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); |
| 1151 type = new InterfaceType(this, parameters); | 1207 type = new InterfaceType(this, parameters); |
| 1152 } | 1208 } |
| 1153 return type; | 1209 return type; |
| 1154 } | 1210 } |
| 1155 | 1211 |
| 1156 bool get isPatched => patch != null; | 1212 bool get isPatched => patch != null; |
| 1157 | 1213 |
| 1214 /** | |
| 1215 * Return [:true:] if this element is the [:Object:] class for the [compiler]. | |
|
ahe
2012/09/20 11:12:07
This is not using "iff" and is perfectly clear.
| |
| 1216 */ | |
| 1217 bool isObject(Compiler compiler) => | |
| 1218 declaration === compiler.objectClass; | |
| 1219 | |
| 1158 Link<DartType> get typeVariables => type.arguments; | 1220 Link<DartType> get typeVariables => type.arguments; |
| 1159 | 1221 |
| 1160 ClassElement ensureResolved(Compiler compiler) { | 1222 ClassElement ensureResolved(Compiler compiler) { |
| 1161 if (resolutionState == STATE_NOT_STARTED) { | 1223 if (resolutionState == STATE_NOT_STARTED) { |
| 1162 compiler.resolver.resolveClass(this); | 1224 compiler.resolver.resolveClass(this); |
| 1163 } | 1225 } |
| 1164 return this; | 1226 return this; |
| 1165 } | 1227 } |
| 1166 | 1228 |
| 1167 /** | 1229 /** |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1691 | 1753 |
| 1692 MetadataAnnotation ensureResolved(Compiler compiler) { | 1754 MetadataAnnotation ensureResolved(Compiler compiler) { |
| 1693 if (resolutionState == STATE_NOT_STARTED) { | 1755 if (resolutionState == STATE_NOT_STARTED) { |
| 1694 compiler.resolver.resolveMetadataAnnotation(this); | 1756 compiler.resolver.resolveMetadataAnnotation(this); |
| 1695 } | 1757 } |
| 1696 return this; | 1758 return this; |
| 1697 } | 1759 } |
| 1698 | 1760 |
| 1699 String toString() => 'MetadataAnnotation($value, $resolutionState)'; | 1761 String toString() => 'MetadataAnnotation($value, $resolutionState)'; |
| 1700 } | 1762 } |
| OLD | NEW |