| 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 part of resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 AnalyzableElement get analyzedElement; | 8 AnalyzableElement get analyzedElement; |
| 9 Iterable<Node> get superUses; | 9 Iterable<Node> get superUses; |
| 10 | 10 |
| (...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 // TODO(johnniwinther): Register the relation between the annotation | 1325 // TODO(johnniwinther): Register the relation between the annotation |
| 1326 // and the annotated element instead. This will allow the backend to | 1326 // and the annotated element instead. This will allow the backend to |
| 1327 // retrieve the backend constant and only register metadata on the | 1327 // retrieve the backend constant and only register metadata on the |
| 1328 // elements for which it is needed. (Issue 17732). | 1328 // elements for which it is needed. (Issue 17732). |
| 1329 registry.registerMetadataConstant(annotation, annotatedElement); | 1329 registry.registerMetadataConstant(annotation, annotatedElement); |
| 1330 annotation.resolutionState = STATE_DONE; | 1330 annotation.resolutionState = STATE_DONE; |
| 1331 })); | 1331 })); |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 error(Spannable node, MessageKind kind, [arguments = const {}]) { | 1334 error(Spannable node, MessageKind kind, [arguments = const {}]) { |
| 1335 // TODO(ahe): Make non-fatal. | 1335 compiler.reportError(node, kind, arguments); |
| 1336 compiler.reportFatalError(node, kind, arguments); | |
| 1337 } | 1336 } |
| 1338 | 1337 |
| 1339 Link<MetadataAnnotation> resolveMetadata(Element element, | 1338 Link<MetadataAnnotation> resolveMetadata(Element element, |
| 1340 VariableDefinitions node) { | 1339 VariableDefinitions node) { |
| 1341 LinkBuilder<MetadataAnnotation> metadata = | 1340 LinkBuilder<MetadataAnnotation> metadata = |
| 1342 new LinkBuilder<MetadataAnnotation>(); | 1341 new LinkBuilder<MetadataAnnotation>(); |
| 1343 for (Metadata annotation in node.metadata.nodes) { | 1342 for (Metadata annotation in node.metadata.nodes) { |
| 1344 ParameterMetadataAnnotation metadataAnnotation = | 1343 ParameterMetadataAnnotation metadataAnnotation = |
| 1345 new ParameterMetadataAnnotation(annotation); | 1344 new ParameterMetadataAnnotation(annotation); |
| 1346 metadataAnnotation.annotatedElement = element; | 1345 metadataAnnotation.annotatedElement = element; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 final Node selector = init.selector; | 1405 final Node selector = init.selector; |
| 1407 final String name = selector.asIdentifier().source; | 1406 final String name = selector.asIdentifier().source; |
| 1408 // Lookup target field. | 1407 // Lookup target field. |
| 1409 Element target; | 1408 Element target; |
| 1410 if (isFieldInitializer(init)) { | 1409 if (isFieldInitializer(init)) { |
| 1411 target = constructor.enclosingClass.lookupLocalMember(name); | 1410 target = constructor.enclosingClass.lookupLocalMember(name); |
| 1412 if (target == null) { | 1411 if (target == null) { |
| 1413 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name}); | 1412 error(selector, MessageKind.CANNOT_RESOLVE, {'name': name}); |
| 1414 } else if (target.kind != ElementKind.FIELD) { | 1413 } else if (target.kind != ElementKind.FIELD) { |
| 1415 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name}); | 1414 error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name}); |
| 1415 // TODO(ahe): Don't throw, recover from error. |
| 1416 throw new CompilerCancelledException(null); |
| 1416 } else if (!target.isInstanceMember) { | 1417 } else if (!target.isInstanceMember) { |
| 1417 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name}); | 1418 error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name}); |
| 1418 } | 1419 } |
| 1419 } else { | 1420 } else { |
| 1420 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); | 1421 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); |
| 1421 } | 1422 } |
| 1422 registry.useElement(init, target); | 1423 registry.useElement(init, target); |
| 1423 registry.registerStaticUse(target); | 1424 registry.registerStaticUse(target); |
| 1424 checkForDuplicateInitializers(target, init); | 1425 checkForDuplicateInitializers(target, init); |
| 1425 // Resolve initializing value. | 1426 // Resolve initializing value. |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1632 'internal error: Unhandled node: ${node.getObjectDescription()}'); | 1633 'internal error: Unhandled node: ${node.getObjectDescription()}'); |
| 1633 return null; | 1634 return null; |
| 1634 } | 1635 } |
| 1635 | 1636 |
| 1636 R visitEmptyStatement(Node node) => null; | 1637 R visitEmptyStatement(Node node) => null; |
| 1637 | 1638 |
| 1638 /** Convenience method for visiting nodes that may be null. */ | 1639 /** Convenience method for visiting nodes that may be null. */ |
| 1639 R visit(Node node) => (node == null) ? null : node.accept(this); | 1640 R visit(Node node) => (node == null) ? null : node.accept(this); |
| 1640 | 1641 |
| 1641 void error(Spannable node, MessageKind kind, [Map arguments = const {}]) { | 1642 void error(Spannable node, MessageKind kind, [Map arguments = const {}]) { |
| 1642 compiler.reportFatalError(node, kind, arguments); | 1643 compiler.reportError(node, kind, arguments); |
| 1643 } | 1644 } |
| 1644 | 1645 |
| 1645 void warning(Spannable node, MessageKind kind, [Map arguments = const {}]) { | 1646 void warning(Spannable node, MessageKind kind, [Map arguments = const {}]) { |
| 1646 compiler.reportWarning(node, kind, arguments); | 1647 compiler.reportWarning(node, kind, arguments); |
| 1647 } | 1648 } |
| 1648 | 1649 |
| 1649 void internalError(Spannable node, message) { | 1650 void internalError(Spannable node, message) { |
| 1650 compiler.internalError(node, message); | 1651 compiler.internalError(node, message); |
| 1651 } | 1652 } |
| 1652 | 1653 |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2230 MessageKind kind, | 2231 MessageKind kind, |
| 2231 [Map arguments = const {}]) { | 2232 [Map arguments = const {}]) { |
| 2232 compiler.reportWarning(node, kind, arguments); | 2233 compiler.reportWarning(node, kind, arguments); |
| 2233 return new ErroneousElementX(kind, arguments, name, enclosingElement); | 2234 return new ErroneousElementX(kind, arguments, name, enclosingElement); |
| 2234 } | 2235 } |
| 2235 | 2236 |
| 2236 ResolutionResult visitIdentifier(Identifier node) { | 2237 ResolutionResult visitIdentifier(Identifier node) { |
| 2237 if (node.isThis()) { | 2238 if (node.isThis()) { |
| 2238 if (!inInstanceContext) { | 2239 if (!inInstanceContext) { |
| 2239 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); | 2240 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
| 2241 // TODO(ahe): Don't throw, recover from error. |
| 2242 throw new CompilerCancelledException(null); |
| 2240 } | 2243 } |
| 2241 return null; | 2244 return null; |
| 2242 } else if (node.isSuper()) { | 2245 } else if (node.isSuper()) { |
| 2243 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); | 2246 if (!inInstanceContext) { |
| 2247 error(node, MessageKind.NO_SUPER_IN_STATIC); |
| 2248 // TODO(ahe): Don't throw, recover from error. |
| 2249 throw new CompilerCancelledException(null); |
| 2250 } |
| 2244 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 2251 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
| 2245 error(node, MessageKind.INVALID_USE_OF_SUPER); | 2252 error(node, MessageKind.INVALID_USE_OF_SUPER); |
| 2246 } | 2253 } |
| 2247 return null; | 2254 return null; |
| 2248 } else { | 2255 } else { |
| 2249 String name = node.source; | 2256 String name = node.source; |
| 2250 Element element = lookupInScope(compiler, node, scope, name); | 2257 Element element = lookupInScope(compiler, node, scope, name); |
| 2251 if (Elements.isUnresolved(element) && name == 'dynamic') { | 2258 if (Elements.isUnresolved(element) && name == 'dynamic') { |
| 2252 // TODO(johnniwinther): Remove this hack when we can return more complex | 2259 // TODO(johnniwinther): Remove this hack when we can return more complex |
| 2253 // objects than [Element] from this method. | 2260 // objects than [Element] from this method. |
| 2254 element = compiler.typeClass; | 2261 element = compiler.typeClass; |
| 2255 // Set the type to be `dynamic` to mark that this is a type literal. | 2262 // Set the type to be `dynamic` to mark that this is a type literal. |
| 2256 registry.setType(node, const DynamicType()); | 2263 registry.setType(node, const DynamicType()); |
| 2257 } | 2264 } |
| 2258 element = reportLookupErrorIfAny(element, node, node.source); | 2265 element = reportLookupErrorIfAny(element, node, node.source); |
| 2259 if (element == null) { | 2266 if (element == null) { |
| 2260 if (!inInstanceContext) { | 2267 if (!inInstanceContext) { |
| 2261 element = warnAndCreateErroneousElement( | 2268 element = warnAndCreateErroneousElement( |
| 2262 node, node.source, MessageKind.CANNOT_RESOLVE, | 2269 node, node.source, MessageKind.CANNOT_RESOLVE, |
| 2263 {'name': node}); | 2270 {'name': node}); |
| 2264 registry.registerThrowNoSuchMethod(); | 2271 registry.registerThrowNoSuchMethod(); |
| 2265 } | 2272 } |
| 2266 } else if (element.isErroneous) { | 2273 } else if (element.isErroneous) { |
| 2267 // Use the erroneous element. | 2274 // Use the erroneous element. |
| 2268 } else { | 2275 } else { |
| 2269 if ((element.kind.category & allowedCategory) == 0) { | 2276 if ((element.kind.category & allowedCategory) == 0) { |
| 2270 // TODO(ahe): Improve error message. Need UX input. | 2277 // TODO(ahe): Improve error message. Need UX input. |
| 2271 error(node, MessageKind.GENERIC, | 2278 error(node, MessageKind.GENERIC, |
| 2272 {'text': "is not an expression $element"}); | 2279 {'text': "is not an expression $element"}); |
| 2280 // TODO(ahe): Don't throw, recover from error. |
| 2281 throw new CompilerCancelledException(null); |
| 2273 } | 2282 } |
| 2274 } | 2283 } |
| 2275 if (!Elements.isUnresolved(element) && element.isClass) { | 2284 if (!Elements.isUnresolved(element) && element.isClass) { |
| 2276 ClassElement classElement = element; | 2285 ClassElement classElement = element; |
| 2277 classElement.ensureResolved(compiler); | 2286 classElement.ensureResolved(compiler); |
| 2278 } | 2287 } |
| 2279 return new ElementResult(registry.useElement(node, element)); | 2288 return new ElementResult(registry.useElement(node, element)); |
| 2280 } | 2289 } |
| 2281 } | 2290 } |
| 2282 | 2291 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2519 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; | 2528 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; |
| 2520 ResolutionResult resolvedReceiver = visit(node.receiver); | 2529 ResolutionResult resolvedReceiver = visit(node.receiver); |
| 2521 allowedCategory = oldCategory; | 2530 allowedCategory = oldCategory; |
| 2522 | 2531 |
| 2523 Element target; | 2532 Element target; |
| 2524 String name = node.selector.asIdentifier().source; | 2533 String name = node.selector.asIdentifier().source; |
| 2525 if (identical(name, 'this')) { | 2534 if (identical(name, 'this')) { |
| 2526 // TODO(ahe): Why is this using GENERIC? | 2535 // TODO(ahe): Why is this using GENERIC? |
| 2527 error(node.selector, MessageKind.GENERIC, | 2536 error(node.selector, MessageKind.GENERIC, |
| 2528 {'text': "expected an identifier"}); | 2537 {'text': "expected an identifier"}); |
| 2538 return null; |
| 2529 } else if (node.isSuperCall) { | 2539 } else if (node.isSuperCall) { |
| 2530 if (node.isOperator) { | 2540 if (node.isOperator) { |
| 2531 if (isUserDefinableOperator(name)) { | 2541 if (isUserDefinableOperator(name)) { |
| 2532 name = selector.name; | 2542 name = selector.name; |
| 2533 } else { | 2543 } else { |
| 2534 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); | 2544 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); |
| 2545 return null; |
| 2535 } | 2546 } |
| 2536 } | 2547 } |
| 2537 if (!inInstanceContext) { | 2548 if (!inInstanceContext) { |
| 2538 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 2549 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
| 2539 return null; | 2550 return null; |
| 2540 } | 2551 } |
| 2541 if (currentClass.supertype == null) { | 2552 if (currentClass.supertype == null) { |
| 2542 // This is just to guard against internal errors, so no need | 2553 // This is just to guard against internal errors, so no need |
| 2543 // for a real error message. | 2554 // for a real error message. |
| 2544 error(node.receiver, MessageKind.GENERIC, | 2555 error(node.receiver, MessageKind.GENERIC, |
| 2545 {'text': "Object has no superclass"}); | 2556 {'text': "Object has no superclass"}); |
| 2557 return null; |
| 2546 } | 2558 } |
| 2547 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 2559 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
| 2548 // patch. | 2560 // patch. |
| 2549 target = currentClass.lookupSuperSelector(selector); | 2561 target = currentClass.lookupSuperSelector(selector); |
| 2550 // [target] may be null which means invoking noSuchMethod on | 2562 // [target] may be null which means invoking noSuchMethod on |
| 2551 // super. | 2563 // super. |
| 2552 if (target == null) { | 2564 if (target == null) { |
| 2553 target = warnAndCreateErroneousElement( | 2565 target = warnAndCreateErroneousElement( |
| 2554 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, | 2566 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, |
| 2555 {'className': currentClass, 'memberName': name}); | 2567 {'className': currentClass, 'memberName': name}); |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3335 {'type': keyType}); | 3347 {'type': keyType}); |
| 3336 } | 3348 } |
| 3337 } | 3349 } |
| 3338 } | 3350 } |
| 3339 | 3351 |
| 3340 void analyzeConstant(Node node) { | 3352 void analyzeConstant(Node node) { |
| 3341 ConstantExpression constant = | 3353 ConstantExpression constant = |
| 3342 compiler.resolver.constantCompiler.compileNode( | 3354 compiler.resolver.constantCompiler.compileNode( |
| 3343 node, registry.mapping); | 3355 node, registry.mapping); |
| 3344 | 3356 |
| 3357 if (constant == null) { |
| 3358 assert(invariant(node, compiler.compilationFailed)); |
| 3359 return; |
| 3360 } |
| 3361 |
| 3345 ConstantValue value = constant.value; | 3362 ConstantValue value = constant.value; |
| 3346 if (value.isMap) { | 3363 if (value.isMap) { |
| 3347 checkConstMapKeysDontOverrideEquals(node, value); | 3364 checkConstMapKeysDontOverrideEquals(node, value); |
| 3348 } | 3365 } |
| 3349 | 3366 |
| 3350 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names | 3367 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names |
| 3351 // a class that will be instantiated outside the program by attaching a | 3368 // a class that will be instantiated outside the program by attaching a |
| 3352 // native class dispatch record referencing the interceptor. | 3369 // native class dispatch record referencing the interceptor. |
| 3353 if (argumentsToJsInterceptorConstant != null && | 3370 if (argumentsToJsInterceptorConstant != null && |
| 3354 argumentsToJsInterceptorConstant.contains(node)) { | 3371 argumentsToJsInterceptorConstant.contains(node)) { |
| (...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4903 MessageKind.CANNOT_RESOLVE, | 4920 MessageKind.CANNOT_RESOLVE, |
| 4904 {'name': name}); | 4921 {'name': name}); |
| 4905 } else if (element.isErroneous) { | 4922 } else if (element.isErroneous) { |
| 4906 return element; | 4923 return element; |
| 4907 } else if (element.isTypedef) { | 4924 } else if (element.isTypedef) { |
| 4908 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, | 4925 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, |
| 4909 {'typedefName': name}); | 4926 {'typedefName': name}); |
| 4910 } else if (element.isTypeVariable) { | 4927 } else if (element.isTypeVariable) { |
| 4911 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, | 4928 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, |
| 4912 {'typeVariableName': name}); | 4929 {'typeVariableName': name}); |
| 4930 // TODO(ahe): Don't throw, recover from error. |
| 4931 throw new CompilerCancelledException(null); |
| 4913 } else if (!element.isClass && !element.isPrefix) { | 4932 } else if (!element.isClass && !element.isPrefix) { |
| 4914 error(node, MessageKind.NOT_A_TYPE, {'node': name}); | 4933 error(node, MessageKind.NOT_A_TYPE, {'node': name}); |
| 4934 // TODO(ahe): Don't throw, recover from error. |
| 4935 throw new CompilerCancelledException(null); |
| 4915 } | 4936 } |
| 4916 return element; | 4937 return element; |
| 4917 } | 4938 } |
| 4918 | 4939 |
| 4919 /// Assumed to be called by [resolveRedirectingFactory]. | 4940 /// Assumed to be called by [resolveRedirectingFactory]. |
| 4920 Element visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 4941 Element visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
| 4921 Node constructorReference = node.constructorReference; | 4942 Node constructorReference = node.constructorReference; |
| 4922 return finishConstructorReference(visit(constructorReference), | 4943 return finishConstructorReference(visit(constructorReference), |
| 4923 constructorReference, node); | 4944 constructorReference, node); |
| 4924 } | 4945 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4987 } | 5008 } |
| 4988 | 5009 |
| 4989 /// The result for the resolution of the `assert` method. | 5010 /// The result for the resolution of the `assert` method. |
| 4990 class AssertResult implements ResolutionResult { | 5011 class AssertResult implements ResolutionResult { |
| 4991 const AssertResult(); | 5012 const AssertResult(); |
| 4992 | 5013 |
| 4993 Element get element => null; | 5014 Element get element => null; |
| 4994 | 5015 |
| 4995 String toString() => 'AssertResult()'; | 5016 String toString() => 'AssertResult()'; |
| 4996 } | 5017 } |
| OLD | NEW |