Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(816)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 365043002: Add ResolutionResult as intermediate value in ResolutionVisitor and use it to mark assert. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/compiler/dart2js/resolver_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 Element get currentElement; 8 Element get currentElement;
9 Setlet<Node> get superUses; 9 Setlet<Node> get superUses;
10 10
(...skipping 1935 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 MessageKind.EXISTING_DEFINITION, {'name': name}); 1946 MessageKind.EXISTING_DEFINITION, {'name': name});
1947 } 1947 }
1948 } 1948 }
1949 1949
1950 /** 1950 /**
1951 * Core implementation of resolution. 1951 * Core implementation of resolution.
1952 * 1952 *
1953 * Do not subclass or instantiate this class outside this library 1953 * Do not subclass or instantiate this class outside this library
1954 * except for testing. 1954 * except for testing.
1955 */ 1955 */
1956 class ResolverVisitor extends MappingVisitor<Element> { 1956 class ResolverVisitor extends MappingVisitor<ResolutionResult> {
1957 /** 1957 /**
1958 * The current enclosing element for the visited AST nodes. 1958 * The current enclosing element for the visited AST nodes.
1959 * 1959 *
1960 * This field is updated when nested closures are visited. 1960 * This field is updated when nested closures are visited.
1961 */ 1961 */
1962 Element enclosingElement; 1962 Element enclosingElement;
1963 bool inInstanceContext; 1963 bool inInstanceContext;
1964 bool inCheckContext; 1964 bool inCheckContext;
1965 bool inCatchBlock; 1965 bool inCatchBlock;
1966 Scope scope; 1966 Scope scope;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
2102 } 2102 }
2103 2103
2104 ErroneousElement warnAndCreateErroneousElement(Node node, 2104 ErroneousElement warnAndCreateErroneousElement(Node node,
2105 String name, 2105 String name,
2106 MessageKind kind, 2106 MessageKind kind,
2107 [Map arguments = const {}]) { 2107 [Map arguments = const {}]) {
2108 compiler.reportWarning(node, kind, arguments); 2108 compiler.reportWarning(node, kind, arguments);
2109 return new ErroneousElementX(kind, arguments, name, enclosingElement); 2109 return new ErroneousElementX(kind, arguments, name, enclosingElement);
2110 } 2110 }
2111 2111
2112 Element visitIdentifier(Identifier node) { 2112 ResolutionResult visitIdentifier(Identifier node) {
2113 if (node.isThis()) { 2113 if (node.isThis()) {
2114 if (!inInstanceContext) { 2114 if (!inInstanceContext) {
2115 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); 2115 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node});
2116 } 2116 }
2117 return null; 2117 return null;
2118 } else if (node.isSuper()) { 2118 } else if (node.isSuper()) {
2119 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); 2119 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC);
2120 if ((ElementCategory.SUPER & allowedCategory) == 0) { 2120 if ((ElementCategory.SUPER & allowedCategory) == 0) {
2121 error(node, MessageKind.INVALID_USE_OF_SUPER); 2121 error(node, MessageKind.INVALID_USE_OF_SUPER);
2122 } 2122 }
(...skipping 22 matching lines...) Expand all
2145 if ((element.kind.category & allowedCategory) == 0) { 2145 if ((element.kind.category & allowedCategory) == 0) {
2146 // TODO(ahe): Improve error message. Need UX input. 2146 // TODO(ahe): Improve error message. Need UX input.
2147 error(node, MessageKind.GENERIC, 2147 error(node, MessageKind.GENERIC,
2148 {'text': "is not an expression $element"}); 2148 {'text': "is not an expression $element"});
2149 } 2149 }
2150 } 2150 }
2151 if (!Elements.isUnresolved(element) && element.isClass) { 2151 if (!Elements.isUnresolved(element) && element.isClass) {
2152 ClassElement classElement = element; 2152 ClassElement classElement = element;
2153 classElement.ensureResolved(compiler); 2153 classElement.ensureResolved(compiler);
2154 } 2154 }
2155 return registry.useElement(node, element); 2155 return new ElementResult(registry.useElement(node, element));
2156 } 2156 }
2157 } 2157 }
2158 2158
2159 Element visitTypeAnnotation(TypeAnnotation node) { 2159 ResolutionResult visitTypeAnnotation(TypeAnnotation node) {
2160 DartType type = resolveTypeAnnotation(node); 2160 DartType type = resolveTypeAnnotation(node);
2161 if (type != null) { 2161 if (inCheckContext) {
2162 if (inCheckContext) { 2162 registry.registerIsCheck(type);
2163 registry.registerIsCheck(type);
2164 }
2165 return type.element;
2166 } 2163 }
2167 return null; 2164 return new TypeResult(type);
2168 } 2165 }
2169 2166
2170 bool isNamedConstructor(Send node) => node.receiver != null; 2167 bool isNamedConstructor(Send node) => node.receiver != null;
2171 2168
2172 Selector getRedirectingThisOrSuperConstructorSelector(Send node) { 2169 Selector getRedirectingThisOrSuperConstructorSelector(Send node) {
2173 if (isNamedConstructor(node)) { 2170 if (isNamedConstructor(node)) {
2174 String constructorName = node.selector.asIdentifier().source; 2171 String constructorName = node.selector.asIdentifier().source;
2175 return new Selector.callConstructor( 2172 return new Selector.callConstructor(
2176 constructorName, 2173 constructorName,
2177 enclosingElement.library); 2174 enclosingElement.library);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2247 visit(node.expression); 2244 visit(node.expression);
2248 } 2245 }
2249 2246
2250 visitClassNode(ClassNode node) { 2247 visitClassNode(ClassNode node) {
2251 internalError(node, "shouldn't be called"); 2248 internalError(node, "shouldn't be called");
2252 } 2249 }
2253 2250
2254 visitIn(Node node, Scope nestedScope) { 2251 visitIn(Node node, Scope nestedScope) {
2255 Scope oldScope = scope; 2252 Scope oldScope = scope;
2256 scope = nestedScope; 2253 scope = nestedScope;
2257 Element element = visit(node); 2254 ResolutionResult result = visit(node);
2258 scope = oldScope; 2255 scope = oldScope;
2259 return element; 2256 return result;
2260 } 2257 }
2261 2258
2262 /** 2259 /**
2263 * Introduces new default targets for break and continue 2260 * Introduces new default targets for break and continue
2264 * before visiting the body of the loop 2261 * before visiting the body of the loop
2265 */ 2262 */
2266 visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) { 2263 visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) {
2267 TargetElement element = getOrDefineTarget(loop); 2264 TargetElement element = getOrDefineTarget(loop);
2268 statementScope.enterLoop(element); 2265 statementScope.enterLoop(element);
2269 visitIn(body, bodyScope); 2266 visitIn(body, bodyScope);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2341 registry.registerInstantiatedClass(compiler.functionClass); 2338 registry.registerInstantiatedClass(compiler.functionClass);
2342 } 2339 }
2343 2340
2344 visitIf(If node) { 2341 visitIf(If node) {
2345 doInPromotionScope(node.condition.expression, () => visit(node.condition)); 2342 doInPromotionScope(node.condition.expression, () => visit(node.condition));
2346 doInPromotionScope(node.thenPart, 2343 doInPromotionScope(node.thenPart,
2347 () => visitIn(node.thenPart, new BlockScope(scope))); 2344 () => visitIn(node.thenPart, new BlockScope(scope)));
2348 visitIn(node.elsePart, new BlockScope(scope)); 2345 visitIn(node.elsePart, new BlockScope(scope));
2349 } 2346 }
2350 2347
2351 Element resolveSend(Send node) { 2348 ResolutionResult resolveSend(Send node) {
2352 Selector selector = resolveSelector(node, null); 2349 Selector selector = resolveSelector(node, null);
2353 if (node.isSuperCall) registry.registerSuperUse(node); 2350 if (node.isSuperCall) registry.registerSuperUse(node);
2354 2351
2355 if (node.receiver == null) { 2352 if (node.receiver == null) {
2356 // If this send is of the form "assert(expr);", then 2353 // If this send is of the form "assert(expr);", then
2357 // this is an assertion. 2354 // this is an assertion.
2358 if (selector.isAssert) { 2355 if (selector.isAssert) {
2359 if (selector.argumentCount != 1) { 2356 if (selector.argumentCount != 1) {
2360 error(node.selector, 2357 error(node.selector,
2361 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, 2358 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
2362 {'argumentCount': selector.argumentCount}); 2359 {'argumentCount': selector.argumentCount});
2363 } else if (selector.namedArgumentCount != 0) { 2360 } else if (selector.namedArgumentCount != 0) {
2364 error(node.selector, 2361 error(node.selector,
2365 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, 2362 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
2366 {'argumentCount': selector.namedArgumentCount}); 2363 {'argumentCount': selector.namedArgumentCount});
2367 } 2364 }
2368 registry.registerAssert(node); 2365 registry.registerAssert(node);
2369 // TODO(johnniwinther): Return a marker to indicated that this is 2366 return const AssertResult();
2370 // a call to assert.
2371 return null;
2372 } 2367 }
2373 2368
2374 return node.selector.accept(this); 2369 return node.selector.accept(this);
2375 } 2370 }
2376 2371
2377 var oldCategory = allowedCategory; 2372 var oldCategory = allowedCategory;
2378 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; 2373 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
2379 Element resolvedReceiver = visit(node.receiver); 2374 ResolutionResult resolvedReceiver = visit(node.receiver);
2380 allowedCategory = oldCategory; 2375 allowedCategory = oldCategory;
2381 2376
2382 Element target; 2377 Element target;
karlklose 2014/07/03 08:36:04 Target could be a ResolutionResult.
Johnni Winther 2014/07/03 12:11:35 Not as easy as it looks. Will do it in a later CL.
2383 String name = node.selector.asIdentifier().source; 2378 String name = node.selector.asIdentifier().source;
2384 if (identical(name, 'this')) { 2379 if (identical(name, 'this')) {
2385 // TODO(ahe): Why is this using GENERIC? 2380 // TODO(ahe): Why is this using GENERIC?
2386 error(node.selector, MessageKind.GENERIC, 2381 error(node.selector, MessageKind.GENERIC,
2387 {'text': "expected an identifier"}); 2382 {'text': "expected an identifier"});
2388 } else if (node.isSuperCall) { 2383 } else if (node.isSuperCall) {
2389 if (node.isOperator) { 2384 if (node.isOperator) {
2390 if (isUserDefinableOperator(name)) { 2385 if (isUserDefinableOperator(name)) {
2391 name = selector.name; 2386 name = selector.name;
2392 } else { 2387 } else {
(...skipping 18 matching lines...) Expand all
2411 if (target == null) { 2406 if (target == null) {
2412 target = warnAndCreateErroneousElement( 2407 target = warnAndCreateErroneousElement(
2413 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, 2408 node, name, MessageKind.NO_SUCH_SUPER_MEMBER,
2414 {'className': currentClass, 'memberName': name}); 2409 {'className': currentClass, 'memberName': name});
2415 // We still need to register the invocation, because we might 2410 // We still need to register the invocation, because we might
2416 // call [:super.noSuchMethod:] which calls 2411 // call [:super.noSuchMethod:] which calls
2417 // [JSInvocationMirror._invokeOn]. 2412 // [JSInvocationMirror._invokeOn].
2418 registry.registerDynamicInvocation(selector); 2413 registry.registerDynamicInvocation(selector);
2419 registry.registerSuperNoSuchMethod(); 2414 registry.registerSuperNoSuchMethod();
2420 } 2415 }
2421 } else if (Elements.isUnresolved(resolvedReceiver)) { 2416 } else if (resolvedReceiver == null ||
2417 Elements.isUnresolved(resolvedReceiver.element)) {
2422 return null; 2418 return null;
2423 } else if (resolvedReceiver.isClass) { 2419 } else if (resolvedReceiver.element.isClass) {
2424 ClassElement receiverClass = resolvedReceiver; 2420 ClassElement receiverClass = resolvedReceiver.element;
2425 receiverClass.ensureResolved(compiler); 2421 receiverClass.ensureResolved(compiler);
2426 if (node.isOperator) { 2422 if (node.isOperator) {
2427 // When the resolved receiver is a class, we can have two cases: 2423 // When the resolved receiver is a class, we can have two cases:
2428 // 1) a static send: C.foo, or 2424 // 1) a static send: C.foo, or
2429 // 2) an operator send, where the receiver is a class literal: 'C + 1'. 2425 // 2) an operator send, where the receiver is a class literal: 'C + 1'.
2430 // The following code that looks up the selector on the resolved 2426 // The following code that looks up the selector on the resolved
2431 // receiver will treat the second as the invocation of a static operator 2427 // receiver will treat the second as the invocation of a static operator
2432 // if the resolved receiver is not null. 2428 // if the resolved receiver is not null.
2433 return null; 2429 return null;
2434 } 2430 }
2435 MembersCreator.computeClassMembersByName( 2431 MembersCreator.computeClassMembersByName(
2436 compiler, receiverClass.declaration, name); 2432 compiler, receiverClass.declaration, name);
2437 target = receiverClass.lookupLocalMember(name); 2433 target = receiverClass.lookupLocalMember(name);
2438 if (target == null || target.isInstanceMember) { 2434 if (target == null || target.isInstanceMember) {
2439 registry.registerThrowNoSuchMethod(); 2435 registry.registerThrowNoSuchMethod();
2440 // TODO(johnniwinther): With the simplified [TreeElements] invariant, 2436 // TODO(johnniwinther): With the simplified [TreeElements] invariant,
2441 // try to resolve injected elements if [currentClass] is in the patch 2437 // try to resolve injected elements if [currentClass] is in the patch
2442 // library of [receiverClass]. 2438 // library of [receiverClass].
2443 2439
2444 // TODO(karlklose): this should be reported by the caller of 2440 // TODO(karlklose): this should be reported by the caller of
2445 // [resolveSend] to select better warning messages for getters and 2441 // [resolveSend] to select better warning messages for getters and
2446 // setters. 2442 // setters.
2447 MessageKind kind = (target == null) 2443 MessageKind kind = (target == null)
2448 ? MessageKind.MEMBER_NOT_FOUND 2444 ? MessageKind.MEMBER_NOT_FOUND
2449 : MessageKind.MEMBER_NOT_STATIC; 2445 : MessageKind.MEMBER_NOT_STATIC;
2450 return warnAndCreateErroneousElement(node, name, kind, 2446 return new ElementResult(warnAndCreateErroneousElement(
karlklose 2014/07/03 08:36:04 Change warnAndCreateErroneousElement to return the
Johnni Winther 2014/07/03 12:11:35 Not as easy as it looks. Will do it in a later CL.
2451 {'className': receiverClass.name, 2447 node, name, kind,
2452 'memberName': name}); 2448 {'className': receiverClass.name, 'memberName': name}));
2453 } 2449 }
2454 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { 2450 } else if (resolvedReceiver.element.isPrefix) {
2455 PrefixElement prefix = resolvedReceiver; 2451 PrefixElement prefix = resolvedReceiver.element;
2456 target = prefix.lookupLocalMember(name); 2452 target = prefix.lookupLocalMember(name);
2457 if (Elements.isUnresolved(target)) { 2453 if (Elements.isUnresolved(target)) {
2458 registry.registerThrowNoSuchMethod(); 2454 registry.registerThrowNoSuchMethod();
2459 return warnAndCreateErroneousElement( 2455 return new ElementResult(warnAndCreateErroneousElement(
2460 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, 2456 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER,
2461 {'libraryName': prefix.name, 'memberName': name}); 2457 {'libraryName': prefix.name, 'memberName': name}));
2462 } else if (target.isAmbiguous) { 2458 } else if (target.isAmbiguous) {
2463 registry.registerThrowNoSuchMethod(); 2459 registry.registerThrowNoSuchMethod();
2464 AmbiguousElement ambiguous = target; 2460 AmbiguousElement ambiguous = target;
2465 target = warnAndCreateErroneousElement(node, name, 2461 target = warnAndCreateErroneousElement(node, name,
2466 ambiguous.messageKind, 2462 ambiguous.messageKind,
2467 ambiguous.messageArguments); 2463 ambiguous.messageArguments);
2468 ambiguous.diagnose(enclosingElement, compiler); 2464 ambiguous.diagnose(enclosingElement, compiler);
2469 return target; 2465 return new ElementResult(target);
2470 } else if (target.kind == ElementKind.CLASS) { 2466 } else if (target.kind == ElementKind.CLASS) {
2471 ClassElement classElement = target; 2467 ClassElement classElement = target;
2472 classElement.ensureResolved(compiler); 2468 classElement.ensureResolved(compiler);
2473 } 2469 }
2474 } 2470 }
2475 return target; 2471 return new ElementResult(target);
2476 } 2472 }
2477 2473
2478 static Selector computeSendSelector(Send node, 2474 static Selector computeSendSelector(Send node,
2479 LibraryElement library, 2475 LibraryElement library,
2480 Element element) { 2476 Element element) {
2481 // First determine if this is part of an assignment. 2477 // First determine if this is part of an assignment.
2482 bool isSet = node.asSendSet() != null; 2478 bool isSet = node.asSendSet() != null;
2483 2479
2484 if (node.isIndex) { 2480 if (node.isIndex) {
2485 return isSet ? new Selector.indexSet() : new Selector.index(); 2481 return isSet ? new Selector.indexSet() : new Selector.index();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 } else { 2564 } else {
2569 seenNamedArguments[source] = namedArgument; 2565 seenNamedArguments[source] = namedArgument;
2570 } 2566 }
2571 } else if (!seenNamedArguments.isEmpty) { 2567 } else if (!seenNamedArguments.isEmpty) {
2572 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); 2568 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED);
2573 } 2569 }
2574 } 2570 }
2575 sendIsMemberAccess = oldSendIsMemberAccess; 2571 sendIsMemberAccess = oldSendIsMemberAccess;
2576 } 2572 }
2577 2573
2578 visitSend(Send node) { 2574 ResolutionResult visitSend(Send node) {
2579 bool oldSendIsMemberAccess = sendIsMemberAccess; 2575 bool oldSendIsMemberAccess = sendIsMemberAccess;
2580 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 2576 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
2581 Element target; 2577 ResolutionResult result;
2582 if (node.isLogicalAnd) { 2578 if (node.isLogicalAnd) {
2583 target = doInPromotionScope(node.receiver, () => resolveSend(node)); 2579 result = doInPromotionScope(node.receiver, () => resolveSend(node));
2584 } else { 2580 } else {
2585 target = resolveSend(node); 2581 result = resolveSend(node);
2586 } 2582 }
2587 sendIsMemberAccess = oldSendIsMemberAccess; 2583 sendIsMemberAccess = oldSendIsMemberAccess;
2588 2584
2585 Element target = result != null ? result.element : null;
2586
2589 if (target != null 2587 if (target != null
2590 && target == compiler.mirrorSystemGetNameFunction 2588 && target == compiler.mirrorSystemGetNameFunction
2591 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { 2589 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
2592 compiler.reportHint( 2590 compiler.reportHint(
2593 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, 2591 node.selector, MessageKind.STATIC_FUNCTION_BLOAT,
2594 {'class': compiler.mirrorSystemClass.name, 2592 {'class': compiler.mirrorSystemClass.name,
2595 'name': compiler.mirrorSystemGetNameFunction.name}); 2593 'name': compiler.mirrorSystemGetNameFunction.name});
2596 } 2594 }
2597 2595
2598 if (!Elements.isUnresolved(target)) { 2596 if (!Elements.isUnresolved(target)) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2720 } 2718 }
2721 } 2719 }
2722 } 2720 }
2723 } 2721 }
2724 2722
2725 registry.useElement(node, target); 2723 registry.useElement(node, target);
2726 registerSend(selector, target); 2724 registerSend(selector, target);
2727 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { 2725 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) {
2728 registry.registerGetOfStaticFunction(target.declaration); 2726 registry.registerGetOfStaticFunction(target.declaration);
2729 } 2727 }
2730 return node.isPropertyAccess ? target : null; 2728 return node.isPropertyAccess ? new ElementResult(target) : null;
2731 } 2729 }
2732 2730
2733 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. 2731 /// Callback for native enqueuer to parse a type. Returns [:null:] on error.
2734 DartType resolveTypeFromString(Node node, String typeName) { 2732 DartType resolveTypeFromString(Node node, String typeName) {
2735 Element element = lookupInScope(compiler, node, 2733 Element element = lookupInScope(compiler, node,
2736 scope, typeName); 2734 scope, typeName);
2737 if (element == null) return null; 2735 if (element == null) return null;
2738 if (element is! ClassElement) return null; 2736 if (element is! ClassElement) return null;
2739 ClassElement cls = element; 2737 ClassElement cls = element;
2740 cls.ensureResolved(compiler); 2738 cls.ensureResolved(compiler);
2741 return cls.computeType(compiler); 2739 return cls.computeType(compiler);
2742 } 2740 }
2743 2741
2744 visitSendSet(SendSet node) { 2742 ResolutionResult visitSendSet(SendSet node) {
2745 bool oldSendIsMemberAccess = sendIsMemberAccess; 2743 bool oldSendIsMemberAccess = sendIsMemberAccess;
2746 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 2744 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
2747 Element target = resolveSend(node); 2745 ResolutionResult result = resolveSend(node);
2748 sendIsMemberAccess = oldSendIsMemberAccess; 2746 sendIsMemberAccess = oldSendIsMemberAccess;
2747 Element target = result != null ? result.element : null;
2749 Element setter = target; 2748 Element setter = target;
2750 Element getter = target; 2749 Element getter = target;
2751 String operatorName = node.assignmentOperator.source; 2750 String operatorName = node.assignmentOperator.source;
2752 String source = operatorName; 2751 String source = operatorName;
2753 bool isComplex = !identical(source, '='); 2752 bool isComplex = !identical(source, '=');
2754 if (!(registry.isAssert(node) || Elements.isUnresolved(target))) { 2753 if (!(result is AssertResult || Elements.isUnresolved(target))) {
2755 if (target.isAbstractField) { 2754 if (target.isAbstractField) {
2756 AbstractFieldElement field = target; 2755 AbstractFieldElement field = target;
2757 setter = field.setter; 2756 setter = field.setter;
2758 getter = field.getter; 2757 getter = field.getter;
2759 if (setter == null && !inInstanceContext) { 2758 if (setter == null && !inInstanceContext) {
2760 setter = warnAndCreateErroneousElement( 2759 setter = warnAndCreateErroneousElement(
2761 node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER); 2760 node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER);
2762 registry.registerThrowNoSuchMethod(); 2761 registry.registerThrowNoSuchMethod();
2763 } 2762 }
2764 if (isComplex && getter == null && !inInstanceContext) { 2763 if (isComplex && getter == null && !inInstanceContext) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 registry.registerInstantiatedClass(compiler.intClass); 2830 registry.registerInstantiatedClass(compiler.intClass);
2832 } else if (identical(source, '--')) { 2831 } else if (identical(source, '--')) {
2833 registerBinaryOperator('-'); 2832 registerBinaryOperator('-');
2834 registry.registerInstantiatedClass(compiler.intClass); 2833 registry.registerInstantiatedClass(compiler.intClass);
2835 } else if (source.endsWith('=')) { 2834 } else if (source.endsWith('=')) {
2836 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); 2835 registerBinaryOperator(Elements.mapToUserOperator(operatorName));
2837 } 2836 }
2838 } 2837 }
2839 2838
2840 registerSend(selector, setter); 2839 registerSend(selector, setter);
2841 return registry.useElement(node, setter); 2840 return new ElementResult(registry.useElement(node, setter));
2842 } 2841 }
2843 2842
2844 void registerSend(Selector selector, Element target) { 2843 void registerSend(Selector selector, Element target) {
2845 if (target == null || target.isInstanceMember) { 2844 if (target == null || target.isInstanceMember) {
2846 if (selector.isGetter) { 2845 if (selector.isGetter) {
2847 registry.registerDynamicGetter(selector); 2846 registry.registerDynamicGetter(selector);
2848 } else if (selector.isSetter) { 2847 } else if (selector.isSetter) {
2849 registry.registerDynamicSetter(selector); 2848 registry.registerDynamicSetter(selector);
2850 } else { 2849 } else {
2851 registry.registerDynamicInvocation(selector); 2850 registry.registerDynamicInvocation(selector);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
3052 visitLoopBodyIn(node, node.body, new BlockScope(scope)); 3051 visitLoopBodyIn(node, node.body, new BlockScope(scope));
3053 } 3052 }
3054 3053
3055 visitParenthesizedExpression(ParenthesizedExpression node) { 3054 visitParenthesizedExpression(ParenthesizedExpression node) {
3056 bool oldSendIsMemberAccess = sendIsMemberAccess; 3055 bool oldSendIsMemberAccess = sendIsMemberAccess;
3057 sendIsMemberAccess = false; 3056 sendIsMemberAccess = false;
3058 visit(node.expression); 3057 visit(node.expression);
3059 sendIsMemberAccess = oldSendIsMemberAccess; 3058 sendIsMemberAccess = oldSendIsMemberAccess;
3060 } 3059 }
3061 3060
3062 visitNewExpression(NewExpression node) { 3061 ResolutionResult visitNewExpression(NewExpression node) {
3063 Node selector = node.send.selector; 3062 Node selector = node.send.selector;
3064 FunctionElement constructor = resolveConstructor(node); 3063 FunctionElement constructor = resolveConstructor(node);
3065 final bool isSymbolConstructor = constructor == compiler.symbolConstructor; 3064 final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
3066 final bool isMirrorsUsedConstant = 3065 final bool isMirrorsUsedConstant =
3067 node.isConst && (constructor == compiler.mirrorsUsedConstructor); 3066 node.isConst && (constructor == compiler.mirrorsUsedConstructor);
3068 Selector callSelector = resolveSelector(node.send, constructor); 3067 Selector callSelector = resolveSelector(node.send, constructor);
3069 resolveArguments(node.send.argumentsNode); 3068 resolveArguments(node.send.argumentsNode);
3070 registry.useElement(node.send, constructor); 3069 registry.useElement(node.send, constructor);
3071 if (Elements.isUnresolved(constructor)) return constructor; 3070 if (Elements.isUnresolved(constructor)) {
3071 return new ElementResult(constructor);
3072 }
3072 if (!callSelector.applies(constructor, compiler)) { 3073 if (!callSelector.applies(constructor, compiler)) {
3073 registry.registerThrowNoSuchMethod(); 3074 registry.registerThrowNoSuchMethod();
3074 } 3075 }
3075 3076
3076 // [constructor] might be the implementation element 3077 // [constructor] might be the implementation element
3077 // and only declaration elements may be registered. 3078 // and only declaration elements may be registered.
3078 registry.registerStaticUse(constructor.declaration); 3079 registry.registerStaticUse(constructor.declaration);
3079 ClassElement cls = constructor.enclosingClass; 3080 ClassElement cls = constructor.enclosingClass;
3080 InterfaceType type = registry.getType(node); 3081 InterfaceType type = registry.getType(node);
3081 if (node.isConst && type.containsTypeVariables) { 3082 if (node.isConst && type.containsTypeVariables) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
3195 /** 3196 /**
3196 * Try to resolve the constructor that is referred to by [node]. 3197 * Try to resolve the constructor that is referred to by [node].
3197 * Note: this function may return an ErroneousFunctionElement instead of 3198 * Note: this function may return an ErroneousFunctionElement instead of
3198 * [:null:], if there is no corresponding constructor, class or library. 3199 * [:null:], if there is no corresponding constructor, class or library.
3199 */ 3200 */
3200 ConstructorElement resolveConstructor(NewExpression node) { 3201 ConstructorElement resolveConstructor(NewExpression node) {
3201 return node.accept(new ConstructorResolver(compiler, this)); 3202 return node.accept(new ConstructorResolver(compiler, this));
3202 } 3203 }
3203 3204
3204 ConstructorElement resolveRedirectingFactory(Return node, 3205 ConstructorElement resolveRedirectingFactory(Return node,
3205 {bool inConstContext: false}) { 3206 {bool inConstContext: false}) {
3206 return node.accept(new ConstructorResolver(compiler, this, 3207 return node.accept(new ConstructorResolver(compiler, this,
3207 inConstContext: inConstContext)); 3208 inConstContext: inConstContext));
3208 } 3209 }
3209 3210
3210 DartType resolveTypeAnnotation(TypeAnnotation node, 3211 DartType resolveTypeAnnotation(TypeAnnotation node,
3211 {bool malformedIsError: false, 3212 {bool malformedIsError: false,
3212 bool deferredIsMalformed: true}) { 3213 bool deferredIsMalformed: true}) {
3213 DartType type = typeResolver.resolveTypeAnnotation( 3214 DartType type = typeResolver.resolveTypeAnnotation(
3214 this, node, malformedIsError: malformedIsError, 3215 this, node, malformedIsError: malformedIsError,
3215 deferredIsMalformed: deferredIsMalformed); 3216 deferredIsMalformed: deferredIsMalformed);
3216 if (type == null) return null;
3217 if (inCheckContext) { 3217 if (inCheckContext) {
3218 registry.registerIsCheck(type); 3218 registry.registerIsCheck(type);
3219 registry.registerRequiredType(type, enclosingElement); 3219 registry.registerRequiredType(type, enclosingElement);
3220 } 3220 }
3221 return type; 3221 return type;
3222 } 3222 }
3223 3223
3224 visitModifiers(Modifiers node) { 3224 visitModifiers(Modifiers node) {
3225 internalError(node, 'modifiers'); 3225 internalError(node, 'modifiers');
3226 } 3226 }
(...skipping 1473 matching lines...) Expand 10 before | Expand all | Expand 10 after
4700 TreeElements _treeElements; 4700 TreeElements _treeElements;
4701 4701
4702 bool get hasTreeElements => _treeElements != null; 4702 bool get hasTreeElements => _treeElements != null;
4703 4703
4704 TreeElements get treeElements { 4704 TreeElements get treeElements {
4705 assert(invariant(this, _treeElements !=null, 4705 assert(invariant(this, _treeElements !=null,
4706 message: "TreeElements have not been computed for $this.")); 4706 message: "TreeElements have not been computed for $this."));
4707 return _treeElements; 4707 return _treeElements;
4708 } 4708 }
4709 } 4709 }
4710
4711 /// The result of resolving a node.
4712 abstract class ResolutionResult {
4713 Element get element;
4714 }
4715
4716 /// The result for the resolution of a node that points to an [Element].
4717 class ElementResult implements ResolutionResult {
4718 final Element element;
4719
4720 // TODO(johnniwinther): Remove this factory constructor when `null` is never
4721 // passed as an element result.
4722 factory ElementResult(Element element) {
4723 return element != null ? new ElementResult.internal(element) : null;
4724 }
4725
4726 ElementResult.internal(this.element);
4727
4728 String toString() => 'ElementResult($element)';
4729 }
4730
4731 /// The result for the resolution of a node that points to an [DartType].
4732 class TypeResult implements ResolutionResult {
4733 final DartType type;
4734
4735 TypeResult(this.type) {
4736 assert(type != null);
4737 }
4738
4739 Element get element => type.element;
4740
4741 String toString() => 'TypeResult($type)';
4742 }
4743
4744 /// The result for the resolution of the `assert` method.
4745 class AssertResult implements ResolutionResult {
4746 const AssertResult();
4747
4748 Element get element => null;
4749
4750 String toString() => 'AssertResult()';
4751 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698