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

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

Issue 12334088: Stop creating selectors in the SSA builder that were already created by the resolver. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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 | sdk/lib/_internal/compiler/implementation/ssa/builder.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 operator[](Node node); 8 Element operator[](Node node);
9 Selector getSelector(Send send); 9 Selector getSelector(Send send);
10 Selector getGetterSelectorInComplexSendSet(SendSet node);
11 Selector getOperatorSelectorInComplexSendSet(SendSet node);
12 Selector getIteratorSelector(ForIn node);
13 Selector getMoveNextSelector(ForIn node);
14 Selector getCurrentSelector(ForIn node);
10 DartType getType(Node node); 15 DartType getType(Node node);
11 bool isParameterChecked(Element element); 16 bool isParameterChecked(Element element);
12 Set<Node> get superUses; 17 Set<Node> get superUses;
13 } 18 }
14 19
15 class TreeElementMapping implements TreeElements { 20 class TreeElementMapping implements TreeElements {
16 final Element currentElement; 21 final Element currentElement;
17 final Map<Node, Selector> selectors = new LinkedHashMap<Node, Selector>(); 22 final Map<Spannable, Selector> selectors =
23 new LinkedHashMap<Spannable, Selector>();
18 final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>(); 24 final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>();
19 final Set<Element> checkedParameters = new Set<Element>(); 25 final Set<Element> checkedParameters = new Set<Element>();
20 final Set<Node> superUses = new Set<Node>(); 26 final Set<Node> superUses = new Set<Node>();
21 27
22 TreeElementMapping(this.currentElement); 28 TreeElementMapping(this.currentElement);
23 29
24 operator []=(Node node, Element element) { 30 operator []=(Node node, Element element) {
25 assert(invariant(node, () { 31 assert(invariant(node, () {
26 if (node is FunctionExpression) { 32 if (node is FunctionExpression) {
27 return !node.modifiers.isExternal(); 33 return !node.modifiers.isExternal();
(...skipping 26 matching lines...) Expand all
54 void setType(Node node, DartType type) { 60 void setType(Node node, DartType type) {
55 types[node] = type; 61 types[node] = type;
56 } 62 }
57 63
58 DartType getType(Node node) => types[node]; 64 DartType getType(Node node) => types[node];
59 65
60 void setSelector(Node node, Selector selector) { 66 void setSelector(Node node, Selector selector) {
61 selectors[node] = selector; 67 selectors[node] = selector;
62 } 68 }
63 69
64 Selector getSelector(Node node) => selectors[node]; 70 Selector getSelector(Node node) {
71 return selectors[node];
72 }
73
74 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
75 selectors[node.selector] = selector;
76 }
77
78 Selector getGetterSelectorInComplexSendSet(SendSet node) {
79 return selectors[node.selector];
80 }
81
82 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
83 selectors[node.assignmentOperator] = selector;
84 }
85
86 Selector getOperatorSelectorInComplexSendSet(SendSet node) {
87 return selectors[node.assignmentOperator];
88 }
89
90 // The following methods set selectors on the "for in" node. Since
91 // we're using three selectors, we need to use children of the node,
92 // and we arbritraly choose which ones.
kasperl 2013/02/27 10:11:28 arbitrarily
ngeoffray 2013/02/27 12:23:59 Done.
93
94 Selector setIteratorSelector(ForIn node, Selector selector) {
95 selectors[node] = selector;
96 }
97
98 Selector getIteratorSelector(ForIn node) {
99 return selectors[node];
100 }
101
102 Selector setMoveNextSelector(ForIn node, Selector selector) {
103 selectors[node.forToken] = selector;
104 }
105
106 Selector getMoveNextSelector(ForIn node) {
107 return selectors[node.forToken];
108 }
109
110 Selector setCurrentSelector(ForIn node, Selector selector) {
111 selectors[node.inToken] = selector;
112 }
113
114 Selector getCurrentSelector(ForIn node) {
115 return selectors[node.inToken];
116 }
65 117
66 bool isParameterChecked(Element element) { 118 bool isParameterChecked(Element element) {
67 return checkedParameters.contains(element); 119 return checkedParameters.contains(element);
68 } 120 }
69 } 121 }
70 122
71 class ResolverTask extends CompilerTask { 123 class ResolverTask extends CompilerTask {
72 ResolverTask(Compiler compiler) : super(compiler); 124 ResolverTask(Compiler compiler) : super(compiler);
73 125
74 String get name => 'Resolver'; 126 String get name => 'Resolver';
(...skipping 1873 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 // for a real error message. 2000 // for a real error message.
1949 error(node.receiver, MessageKind.GENERIC, 2001 error(node.receiver, MessageKind.GENERIC,
1950 {'text': "Object has no superclass"}); 2002 {'text': "Object has no superclass"});
1951 } 2003 }
1952 // TODO(johnniwinther): Ensure correct behavior if currentClass is a 2004 // TODO(johnniwinther): Ensure correct behavior if currentClass is a
1953 // patch. 2005 // patch.
1954 target = currentClass.lookupSuperMember(name); 2006 target = currentClass.lookupSuperMember(name);
1955 // [target] may be null which means invoking noSuchMethod on 2007 // [target] may be null which means invoking noSuchMethod on
1956 // super. 2008 // super.
1957 if (target == null) { 2009 if (target == null) {
2010 target = warnAndCreateErroneousElement(
2011 node, name, MessageKind.NO_SUCH_SUPER_MEMBER,
2012 {'className': currentClass, 'memberName': name});
2013 // We still need to register the invocation, because we might
2014 // call [:super.noSuchMethod:] that does a
2015 // [:InvocationMirror.invokeOn:].
2016 world.registerDynamicInvocation(selector.name, selector);
1958 compiler.backend.registerSuperNoSuchMethod(); 2017 compiler.backend.registerSuperNoSuchMethod();
1959 } 2018 }
1960 } else if (Elements.isUnresolved(resolvedReceiver)) { 2019 } else if (Elements.isUnresolved(resolvedReceiver)) {
1961 return null; 2020 return null;
1962 } else if (resolvedReceiver.isClass()) { 2021 } else if (resolvedReceiver.isClass()) {
1963 ClassElement receiverClass = resolvedReceiver; 2022 ClassElement receiverClass = resolvedReceiver;
1964 receiverClass.ensureResolved(compiler); 2023 receiverClass.ensureResolved(compiler);
1965 if (node.isOperator) { 2024 if (node.isOperator) {
1966 // When the resolved receiver is a class, we can have two cases: 2025 // When the resolved receiver is a class, we can have two cases:
1967 // 1) a static send: C.foo, or 2026 // 1) a static send: C.foo, or
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 MessageKind.CANNOT_RESOLVE_GETTER); 2286 MessageKind.CANNOT_RESOLVE_GETTER);
2228 compiler.backend.registerThrowNoSuchMethod(); 2287 compiler.backend.registerThrowNoSuchMethod();
2229 } 2288 }
2230 } else if (target.impliesType()) { 2289 } else if (target.impliesType()) {
2231 compiler.backend.registerThrowNoSuchMethod(); 2290 compiler.backend.registerThrowNoSuchMethod();
2232 } else if (target.modifiers.isFinal() || target.modifiers.isConst()) { 2291 } else if (target.modifiers.isFinal() || target.modifiers.isConst()) {
2233 setter = 2292 setter =
2234 warnAndCreateErroneousElement(node.selector, target.name, 2293 warnAndCreateErroneousElement(node.selector, target.name,
2235 MessageKind.CANNOT_RESOLVE_SETTER); 2294 MessageKind.CANNOT_RESOLVE_SETTER);
2236 compiler.backend.registerThrowNoSuchMethod(); 2295 compiler.backend.registerThrowNoSuchMethod();
2296 } else if (isComplex && target.name == const SourceString('[]=')) {
2297 getter =
2298 setter.getEnclosingClass().lookupMember(const SourceString('[]'));
kasperl 2013/02/27 10:11:28 Seems more logical to use the enclosing class of t
ngeoffray 2013/02/27 12:23:59 Yes, it's the same. Replaced to use target.
2299 if (getter == null) {
2300 getter =
2301 warnAndCreateErroneousElement(node, setter.name,
kasperl 2013/02/27 10:11:28 Move the warnAnd...( part to the previous line (li
ngeoffray 2013/02/27 12:23:59 Done.
2302 MessageKind.CANNOT_RESOLVE_INDEX);
2303 compiler.backend.registerThrowNoSuchMethod();
2304 }
2237 } 2305 }
2238 } 2306 }
2239 2307
2240 visit(node.argumentsNode); 2308 visit(node.argumentsNode);
2241 2309
2242 // TODO(ngeoffray): Check if the target can be assigned. 2310 // TODO(ngeoffray): Check if the target can be assigned.
2243 // TODO(ngeoffray): Warn if target is null and the send is 2311 // TODO(ngeoffray): Warn if target is null and the send is
2244 // unqualified. 2312 // unqualified.
2245 2313
2246 Selector selector = mapping.getSelector(node); 2314 Selector selector = mapping.getSelector(node);
2247 if (isComplex) { 2315 if (isComplex) {
2316 Selector getterSelector;
2248 if (selector.isSetter()) { 2317 if (selector.isSetter()) {
2249 // TODO(kasperl): We're registering the getter selector for 2318 getterSelector = new Selector.getterFrom(selector);
2250 // compound assignments on the AST selector node. In the code
2251 // generator, we then fetch it from there when generating the
2252 // getter for a SendSet node.
2253 Selector getterSelector = new Selector.getterFrom(selector);
2254 registerSend(getterSelector, getter);
2255 mapping.setSelector(node.selector, getterSelector);
2256 useElement(node.selector, getter);
2257 } else { 2319 } else {
2258 // TODO(kasperl): If [getter] is resolved, it will actually
2259 // refer to the []= operator which isn't the one we want to
2260 // register here. We should consider using some notion of
2261 // abstract indexable element that we can resolve to so we can
2262 // distinguish the two.
2263 assert(selector.isIndexSet()); 2320 assert(selector.isIndexSet());
2264 registerSend(new Selector.index(), null); 2321 getterSelector = new Selector.index();
2265 } 2322 }
2323 registerSend(getterSelector, getter);
2324 mapping.setGetterSelectorInComplexSendSet(node, getterSelector);
2325 useElement(node.selector, getter);
2266 2326
2267 // Make sure we include the + and - operators if we are using 2327 // Make sure we include the + and - operators if we are using
2268 // the ++ and -- ones. Also, if op= form is used, include op itself. 2328 // the ++ and -- ones. Also, if op= form is used, include op itself.
2269 void registerBinaryOperator(SourceString name) { 2329 void registerBinaryOperator(SourceString name) {
2270 Selector binop = new Selector.binaryOperator(name); 2330 Selector binop = new Selector.binaryOperator(name);
2271 world.registerDynamicInvocation(binop.name, binop); 2331 world.registerDynamicInvocation(binop.name, binop);
2332 mapping.setOperatorSelectorInComplexSendSet(node, binop);
2272 } 2333 }
2273 if (identical(source, '++')) registerBinaryOperator(const SourceString('+' )); 2334 if (identical(source, '++')) {
2274 if (identical(source, '--')) registerBinaryOperator(const SourceString('-' )); 2335 registerBinaryOperator(const SourceString('+'));
2275 if (source.endsWith('=')) { 2336 } else if (identical(source, '--')) {
2337 registerBinaryOperator(const SourceString('-'));
2338 } else if (source.endsWith('=')) {
2276 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); 2339 registerBinaryOperator(Elements.mapToUserOperator(operatorName));
2277 } 2340 }
2278 } 2341 }
2279 2342
2280 registerSend(selector, setter); 2343 registerSend(selector, setter);
2281 return useElement(node, setter); 2344 return useElement(node, setter);
2282 } 2345 }
2283 2346
2284 void registerSend(Selector selector, Element target) { 2347 void registerSend(Selector selector, Element target) {
2285 if (target == null || target.isInstanceMember()) { 2348 if (target == null || target.isInstanceMember()) {
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 mapping[node.target] = label; 2687 mapping[node.target] = label;
2625 } 2688 }
2626 mapping[node] = target; 2689 mapping[node] = target;
2627 } 2690 }
2628 2691
2629 registerImplicitInvocation(SourceString name, int arity) { 2692 registerImplicitInvocation(SourceString name, int arity) {
2630 Selector selector = new Selector.call(name, null, arity); 2693 Selector selector = new Selector.call(name, null, arity);
2631 world.registerDynamicInvocation(name, selector); 2694 world.registerDynamicInvocation(name, selector);
2632 } 2695 }
2633 2696
2634 registerImplicitFieldGet(SourceString name) { 2697 visitForIn(ForIn node) {
2635 Selector selector = new Selector.getter(name, null); 2698 LibraryElement library = enclosingElement.getLibrary();
2636 world.registerDynamicGetter(name, selector); 2699 Selector iteratorSelector =
2637 } 2700 new Selector.getter(const SourceString('iterator'), library);
2701 world.registerDynamicGetter(iteratorSelector.name, iteratorSelector);
2702 mapping.setIteratorSelector(node, iteratorSelector);
2638 2703
2639 visitForIn(ForIn node) { 2704 Selector currentSelector =
2640 for (final name in const [ 2705 new Selector.getter(const SourceString('current'), library);
2641 const SourceString('iterator'), 2706 world.registerDynamicGetter(currentSelector.name, currentSelector);
2642 const SourceString('current')]) { 2707 mapping.setCurrentSelector(node, currentSelector);
2643 registerImplicitFieldGet(name); 2708
2644 } 2709 Selector moveNextSelector =
2645 registerImplicitInvocation(const SourceString('moveNext'), 0); 2710 new Selector.call(const SourceString('moveNext'), library, 0);
2711 world.registerDynamicInvocation(moveNextSelector.name, moveNextSelector);
2712 mapping.setMoveNextSelector(node, moveNextSelector);
2713
2646 visit(node.expression); 2714 visit(node.expression);
2647 Scope blockScope = new BlockScope(scope); 2715 Scope blockScope = new BlockScope(scope);
2648 Node declaration = node.declaredIdentifier; 2716 Node declaration = node.declaredIdentifier;
2649 visitIn(declaration, blockScope); 2717 visitIn(declaration, blockScope);
2650 visitLoopBodyIn(node, node.body, blockScope); 2718 visitLoopBodyIn(node, node.body, blockScope);
2651 2719
2652 // TODO(lrn): Also allow a single identifier. 2720 // TODO(lrn): Also allow a single identifier.
2653 if ((declaration is !Send || declaration.asSend().selector is !Identifier 2721 if ((declaration is !Send || declaration.asSend().selector is !Identifier
2654 || declaration.asSend().receiver != null) 2722 || declaration.asSend().receiver != null)
2655 && (declaration is !VariableDefinitions || 2723 && (declaration is !VariableDefinitions ||
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after
3739 return e; 3807 return e;
3740 } 3808 }
3741 3809
3742 /// Assumed to be called by [resolveRedirectingFactory]. 3810 /// Assumed to be called by [resolveRedirectingFactory].
3743 Element visitReturn(Return node) { 3811 Element visitReturn(Return node) {
3744 Node expression = node.expression; 3812 Node expression = node.expression;
3745 return finishConstructorReference(visit(expression), 3813 return finishConstructorReference(visit(expression),
3746 expression, expression); 3814 expression, expression);
3747 } 3815 }
3748 } 3816 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698