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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE; | 153 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE; |
| 154 bool isField() => kind === ElementKind.FIELD; | 154 bool isField() => kind === ElementKind.FIELD; |
| 155 bool isGetter() => kind === ElementKind.GETTER; | 155 bool isGetter() => kind === ElementKind.GETTER; |
| 156 bool isSetter() => kind === ElementKind.SETTER; | 156 bool isSetter() => kind === ElementKind.SETTER; |
| 157 bool isAccessor() => isGetter() || isSetter(); | 157 bool isAccessor() => isGetter() || isSetter(); |
| 158 bool isForeign() => kind === ElementKind.FOREIGN; | 158 bool isForeign() => kind === ElementKind.FOREIGN; |
| 159 bool isLibrary() => kind === ElementKind.LIBRARY; | 159 bool isLibrary() => kind === ElementKind.LIBRARY; |
| 160 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; | 160 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; |
| 161 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0; | 161 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0; |
| 162 | 162 |
| 163 /** See [ErroneousElement] for documentation. */ | |
| 164 bool isErroneous() => false; | |
| 165 | |
| 163 // TODO(johnniwinther): This breaks for libraries (for which enclosing | 166 // TODO(johnniwinther): This breaks for libraries (for which enclosing |
| 164 // elements are null) and is invalid for top level variable declarations for | 167 // elements are null) and is invalid for top level variable declarations for |
| 165 // which the enclosing element is a VariableDeclarations and not a compilation | 168 // which the enclosing element is a VariableDeclarations and not a compilation |
| 166 // unit. | 169 // unit. |
| 167 bool isTopLevel() { | 170 bool isTopLevel() { |
| 168 return enclosingElement !== null && enclosingElement.isCompilationUnit(); | 171 return enclosingElement !== null && enclosingElement.isCompilationUnit(); |
| 169 } | 172 } |
| 170 | 173 |
| 171 bool isAssignable() { | 174 bool isAssignable() { |
| 172 if (modifiers != null && modifiers.isFinal()) return false; | 175 if (modifiers != null && modifiers.isFinal()) return false; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 bool _isNative = false; | 280 bool _isNative = false; |
| 278 void setNative() { _isNative = true; } | 281 void setNative() { _isNative = true; } |
| 279 bool isNative() => _isNative; | 282 bool isNative() => _isNative; |
| 280 | 283 |
| 281 FunctionElement asFunctionElement() => null; | 284 FunctionElement asFunctionElement() => null; |
| 282 | 285 |
| 283 Element cloneTo(Element enclosing, DiagnosticListener listener) { | 286 Element cloneTo(Element enclosing, DiagnosticListener listener) { |
| 284 listener.cancel("Unimplemented cloneTo", element: this); | 287 listener.cancel("Unimplemented cloneTo", element: this); |
| 285 } | 288 } |
| 286 | 289 |
| 290 | |
| 291 static bool isInvalid(Element e) => e == null || e.isErroneous(); | |
| 292 } | |
| 293 | |
| 294 /** | |
| 295 * Represents an unresolvable element. | |
|
ahe
2012/08/21 12:55:25
I imagine this could also be used for duplicated e
karlklose
2012/08/21 13:05:59
Done.
| |
| 296 * | |
| 297 * [ErroneousElement]s are used instead of [null] to provide additional | |
|
ahe
2012/08/21 12:55:25
Perhaps more elegant:
An [ErroneousElement] is us
karlklose
2012/08/21 13:05:59
Done.
| |
| 298 * information about the error that caused the element to be unresolvable. | |
| 299 * | |
| 300 * Accessing any field or calling any method defined on [Element] except | |
| 301 * [isValid] will currently throw an exception. (This might change when we | |
| 302 * actually want more information on the erroneous element, e.g., the name | |
| 303 * of the element we were trying to resolve.) | |
| 304 * | |
| 305 * Code that does not handle [ErroneousElement]s should use | |
|
ahe
2012/08/21 12:55:25
Perhaps more elegant:
Code that cannot handle an
karlklose
2012/08/21 13:05:59
Done.
| |
| 306 * [: Element.isInvalid(element) :] | |
| 307 * to check for unresolvable elements instead of | |
| 308 * [: element == null :]. | |
| 309 */ | |
| 310 class ErroneousElement extends Element { | |
| 311 final Message errorMessage; | |
| 312 | |
| 313 ErroneousElement(this.errorMessage, Element enclosing) | |
| 314 : super(const SourceString('erroneous element'), null, enclosing); | |
| 315 | |
| 316 isErroneous() => true; | |
| 317 | |
| 318 unsupported() { | |
| 319 throw 'unsupported operation on erroneous element'; | |
| 320 } | |
| 321 | |
| 322 SourceString get name() => unsupported(); | |
| 323 ElementKind get kind() => unsupported(); | |
| 324 Link<Node> get metadata() => unsupported(); | |
| 325 } | |
| 326 | |
| 327 class ErroneousFunctionElement extends ErroneousElement | |
| 328 implements FunctionElement { | |
| 329 ErroneousFunctionElement(errorMessage, Element enclosing) | |
| 330 : super(errorMessage, enclosing); | |
| 331 | |
| 332 get type() => unsupported(); | |
| 333 get cachedNode() => unsupported(); | |
| 334 get functionSignature() => unsupported(); | |
| 335 get patch() => unsupported(); | |
| 336 get defaultImplementation() => unsupported(); | |
| 337 bool get isPatched() => unsupported(); | |
| 338 setPatch(patch) => unsupported(); | |
| 339 computeSignature(compiler) => unsupported(); | |
| 340 requiredParameterCount(compiler) => unsupported(); | |
| 341 optionalParameterCount(compiler) => unsupported(); | |
| 342 parameterCount(copmiler) => unsupported(); | |
| 287 } | 343 } |
| 288 | 344 |
| 289 class ContainerElement extends Element { | 345 class ContainerElement extends Element { |
| 290 Link<Element> localMembers = const EmptyLink<Element>(); | 346 Link<Element> localMembers = const EmptyLink<Element>(); |
| 291 | 347 |
| 292 ContainerElement(name, kind, enclosingElement) | 348 ContainerElement(name, kind, enclosingElement) |
| 293 : super(name, kind, enclosingElement); | 349 : super(name, kind, enclosingElement); |
| 294 | 350 |
| 295 void addMember(Element element, DiagnosticListener listener) { | 351 void addMember(Element element, DiagnosticListener listener) { |
| 296 localMembers = localMembers.prepend(element); | 352 localMembers = localMembers.prepend(element); |
| (...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1310 listener.internalErrorOnElement(this, 'unsupported operation'); | 1366 listener.internalErrorOnElement(this, 'unsupported operation'); |
| 1311 } | 1367 } |
| 1312 | 1368 |
| 1313 Link<Type> get allSupertypesAndSelf() { | 1369 Link<Type> get allSupertypesAndSelf() { |
| 1314 return allSupertypes.prepend(new InterfaceType(this)); | 1370 return allSupertypes.prepend(new InterfaceType(this)); |
| 1315 } | 1371 } |
| 1316 } | 1372 } |
| 1317 | 1373 |
| 1318 class Elements { | 1374 class Elements { |
| 1319 static bool isLocal(Element element) { | 1375 static bool isLocal(Element element) { |
| 1320 return ((element !== null) | 1376 return !Element.isInvalid(element) |
| 1321 && !element.isInstanceMember() | 1377 && !element.isInstanceMember() |
| 1322 && !isStaticOrTopLevelField(element) | 1378 && !isStaticOrTopLevelField(element) |
| 1323 && !isStaticOrTopLevelFunction(element) | 1379 && !isStaticOrTopLevelFunction(element) |
| 1324 && (element.kind === ElementKind.VARIABLE || | 1380 && (element.kind === ElementKind.VARIABLE || |
| 1325 element.kind === ElementKind.PARAMETER || | 1381 element.kind === ElementKind.PARAMETER || |
| 1326 element.kind === ElementKind.FUNCTION)); | 1382 element.kind === ElementKind.FUNCTION); |
| 1327 } | 1383 } |
| 1328 | 1384 |
| 1329 static bool isInstanceField(Element element) { | 1385 static bool isInstanceField(Element element) { |
| 1330 return (element !== null) | 1386 return !Element.isInvalid(element) |
| 1331 && element.isInstanceMember() | 1387 && element.isInstanceMember() |
| 1332 && (element.kind === ElementKind.FIELD | 1388 && (element.kind === ElementKind.FIELD |
| 1333 || element.kind === ElementKind.GETTER | 1389 || element.kind === ElementKind.GETTER |
| 1334 || element.kind === ElementKind.SETTER); | 1390 || element.kind === ElementKind.SETTER); |
| 1335 } | 1391 } |
| 1336 | 1392 |
| 1337 static bool isStaticOrTopLevel(Element element) { | 1393 static bool isStaticOrTopLevel(Element element) { |
| 1338 // TODO(ager): This should not be necessary when patch support has | 1394 // TODO(ager): This should not be necessary when patch support has |
| 1339 // been reworked. | 1395 // been reworked. |
| 1340 if (element != null | 1396 if (!Element.isInvalid(element) |
| 1341 && element.modifiers != null | 1397 && element.modifiers != null |
| 1342 && element.modifiers.isStatic()) { | 1398 && element.modifiers.isStatic()) { |
| 1343 return true; | 1399 return true; |
| 1344 } | 1400 } |
| 1345 return (element != null) | 1401 return !Element.isInvalid(element) |
| 1346 && !element.isInstanceMember() | 1402 && !element.isInstanceMember() |
| 1347 && !element.isPrefix() | 1403 && !element.isPrefix() |
| 1348 && element.enclosingElement !== null | 1404 && element.enclosingElement !== null |
| 1349 && (element.enclosingElement.kind == ElementKind.CLASS || | 1405 && (element.enclosingElement.kind == ElementKind.CLASS || |
| 1350 element.enclosingElement.kind == ElementKind.COMPILATION_UNIT || | 1406 element.enclosingElement.kind == ElementKind.COMPILATION_UNIT || |
| 1351 element.enclosingElement.kind == ElementKind.LIBRARY); | 1407 element.enclosingElement.kind == ElementKind.LIBRARY); |
| 1352 } | 1408 } |
| 1353 | 1409 |
| 1354 static bool isStaticOrTopLevelField(Element element) { | 1410 static bool isStaticOrTopLevelField(Element element) { |
| 1355 return isStaticOrTopLevel(element) | 1411 return isStaticOrTopLevel(element) |
| 1356 && (element.kind === ElementKind.FIELD | 1412 && (element.kind === ElementKind.FIELD |
| 1357 || element.kind === ElementKind.GETTER | 1413 || element.kind === ElementKind.GETTER |
| 1358 || element.kind === ElementKind.SETTER); | 1414 || element.kind === ElementKind.SETTER); |
| 1359 } | 1415 } |
| 1360 | 1416 |
| 1361 static bool isStaticOrTopLevelFunction(Element element) { | 1417 static bool isStaticOrTopLevelFunction(Element element) { |
| 1362 return isStaticOrTopLevel(element) | 1418 return isStaticOrTopLevel(element) |
| 1363 && (element.kind === ElementKind.FUNCTION); | 1419 && (element.kind === ElementKind.FUNCTION); |
| 1364 } | 1420 } |
| 1365 | 1421 |
| 1366 static bool isInstanceMethod(Element element) { | 1422 static bool isInstanceMethod(Element element) { |
| 1367 return (element != null) | 1423 return !Element.isInvalid(element) |
| 1368 && element.isInstanceMember() | 1424 && element.isInstanceMember() |
| 1369 && (element.kind === ElementKind.FUNCTION); | 1425 && (element.kind === ElementKind.FUNCTION); |
| 1370 } | 1426 } |
| 1371 | 1427 |
| 1372 static bool isInstanceSend(Send send, TreeElements elements) { | 1428 static bool isInstanceSend(Send send, TreeElements elements) { |
| 1373 Element element = elements[send]; | 1429 Element element = elements[send]; |
| 1374 if (element === null) return !isClosureSend(send, element); | 1430 if (element === null) return !isClosureSend(send, element); |
| 1375 return isInstanceMethod(element) || isInstanceField(element); | 1431 return isInstanceMethod(element) || isInstanceField(element); |
| 1376 } | 1432 } |
| 1377 | 1433 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1510 Node parseNode(compiler) => cachedNode; | 1566 Node parseNode(compiler) => cachedNode; |
| 1511 | 1567 |
| 1512 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; | 1568 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; |
| 1513 | 1569 |
| 1514 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { | 1570 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { |
| 1515 TypeVariableElement result = | 1571 TypeVariableElement result = |
| 1516 new TypeVariableElement(name, enclosing, cachedNode, type, bound); | 1572 new TypeVariableElement(name, enclosing, cachedNode, type, bound); |
| 1517 return result; | 1573 return result; |
| 1518 } | 1574 } |
| 1519 } | 1575 } |
| OLD | NEW |