Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 class SendVisitor extends ResolvedVisitor { | |
| 6 final PlaceholderCollector collector; | |
| 7 | |
| 8 SendVisitor(this.collector, TreeElements elements) : super(elements); | |
| 9 | |
| 10 visitSuperSend(Send node) {} | |
| 11 visitOperatorSend(Send node) {} | |
| 12 visitClosureSend(Send node) {} | |
| 13 visitDynamicSend(Send node) {} | |
| 14 visitForeignSend(Send node) {} | |
| 15 | |
| 16 visitGetterSend(Send node) { | |
| 17 final element = elements[node]; | |
| 18 // element === null means dynamic property access. | |
|
Anton Muhin
2012/08/08 08:27:20
what !isTopLevel() means?
Roman
2012/08/09 05:02:35
added comment that we don't want to rename non-top
| |
| 19 if (element === null || !element.isTopLevel()) return; | |
| 20 // Unqualified <class> in static invocation, why it's not a type annotation? | |
| 21 // Another option would be to process in visitStaticSend, NB: | |
| 22 // those elements are not top-level. | |
| 23 // OR: unqualified top level. | |
| 24 collector.placeholderForElement(node.selector, element); | |
|
Anton Muhin
2012/08/08 08:27:20
nit: placeholderForElement makes me think it shoul
Roman
2012/08/09 05:02:35
Done.
| |
| 25 if (node.receiver !== null) { | |
| 26 // <lib prefix>.<top level>. | |
| 27 collector.placeholderForNull(node.receiver); // Cut library prefix. | |
| 28 } | |
| 29 } | |
| 30 | |
| 31 visitStaticSend(Send node) { | |
| 32 final element = elements[node]; | |
| 33 if (!element.isTopLevel()) return; | |
| 34 // Another ugly case: <lib prefix>.<top level> is represented as | |
| 35 // receiver: lib prefix, selector: top level. | |
| 36 collector.placeholderForMethod(node.selector, element); | |
| 37 if (node.receiver !== null) { | |
| 38 assert(elements[node.receiver].isPrefix()); | |
| 39 // Hack: putting null into map overrides receiver of original node. | |
| 40 collector.placeholderForNull(node.receiver); | |
| 41 } | |
| 42 } | |
| 43 } | |
| 44 | |
| 45 class PlaceholderCollector extends AbstractVisitor { | |
| 46 final Compiler compiler; | |
| 47 final Map<Node, Placeholder> placeholders; | |
| 48 Element currentElement; | |
| 49 TreeElements treeElements; | |
| 50 | |
| 51 PlaceholderCollector(this.compiler) : | |
| 52 placeholders = new Map<Node, Placeholder>(); | |
| 53 | |
| 54 void processFunction(FunctionElement element, Node node) { | |
|
Anton Muhin
2012/08/08 08:27:20
nit: process (here and in the method below) is too
Roman
2012/08/09 05:02:35
Done.
| |
| 55 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { | |
| 56 // Two complicated cases for class/interface renaming: | |
| 57 // 1) class which implements constructors of other interfaces, but not | |
| 58 // implements interfaces themselves: | |
| 59 // 0.dart: class C { I(); } | |
| 60 // 1.dart and 2.dart: interface I default C { I(); } | |
| 61 // now we have to duplicate our I() constructor in C class with | |
| 62 // proper names. | |
| 63 // 2) (even worse for us): | |
| 64 // 0.dart: class C { C(); } | |
| 65 // 1.dart: interface C default p0.C { C(); } | |
| 66 // the second case is just a bug now. | |
| 67 final enclosingClass = element.getEnclosingClass(); | |
| 68 Node nameNode = node.name; | |
| 69 if (nameNode is Send) nameNode = nameNode.receiver; | |
| 70 // For cases like class C implements I { I(); } | |
| 71 if (nameNode.token.slowToString() == enclosingClass.name.slowToString()) { | |
| 72 placeholderForType(nameNode, enclosingClass.type); | |
| 73 } | |
| 74 } else { | |
| 75 placeholderForElement(node.name, element); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 void process(Element element, TreeElements elements) { | |
| 80 if (element.isField()) { | |
| 81 // TODO(smok): In the future make sure we don't process same | |
| 82 // variable list element twice, better merge this with emitter logic. | |
| 83 element = element.variables; | |
| 84 } | |
| 85 currentElement = element; | |
| 86 treeElements = elements; | |
| 87 Node elementNode = element.parseNode(compiler); | |
| 88 if (element is FunctionElement) { | |
| 89 processFunction(element, elementNode); | |
| 90 } | |
| 91 elementNode.accept(this); | |
| 92 } | |
| 93 | |
| 94 Type resolveType(TypeAnnotation typeAnnotation) { | |
| 95 if (treeElements === null) return null; | |
| 96 var result = treeElements.getType(typeAnnotation); | |
| 97 // TODO: Have better type resolution. | |
| 98 if (result === null) { | |
| 99 result = compiler.resolveTypeAnnotation(currentElement, typeAnnotation); | |
| 100 } | |
| 101 return result; | |
| 102 } | |
| 103 | |
| 104 void placeholderForType(Node node, Type type) { | |
| 105 assert(type !== null); | |
| 106 placeholders[node] = new TypePlaceholder(type); | |
| 107 } | |
|
Anton Muhin
2012/08/08 08:27:20
nit: blank lines between methods, please
Roman
2012/08/09 05:02:35
Done.
| |
| 108 void placeholderForMethod(Node node, Element method) { | |
| 109 assert(method !== null); | |
| 110 assert(method is FunctionElement || method is VariableElement); | |
| 111 placeholders[node] = new MethodPlaceholder(method); | |
| 112 } | |
| 113 void placeholderForNull(Node node) { | |
| 114 placeholders[node] = new NullPlaceholder(); | |
| 115 } | |
| 116 void placeholderForElement(Node node, Element element) { | |
| 117 assert(element !== null); | |
| 118 placeholders[node] = new ElementPlaceholder(element); | |
| 119 } | |
| 120 | |
| 121 void internalError(String reason, [Node node]) { | |
| 122 compiler.cancel(reason: reason, node: node); | |
| 123 } | |
| 124 | |
| 125 visit(Node node) => (node === null) ? null : node.accept(this); | |
| 126 visitNode(Node node) { node.visitChildren(this); } // We must go deeper. | |
|
Anton Muhin
2012/08/08 08:27:20
memegen link? :)
| |
| 127 | |
| 128 visitClassNode(ClassNode node) { | |
| 129 internalError('Should never meet ClassNode', node); | |
| 130 } | |
| 131 | |
| 132 visitSend(Send send) { | |
| 133 new SendVisitor(this, treeElements).visitSend(send); | |
| 134 send.visitChildren(this); | |
|
Anton Muhin
2012/08/08 08:27:20
super.visitSend(send)?
Roman
2012/08/09 05:02:35
Done.
| |
| 135 } | |
| 136 | |
| 137 visitTypeAnnotation(TypeAnnotation node) { | |
| 138 final type = compiler.resolveTypeAnnotation(currentElement, node); | |
| 139 if (type is !InterfaceType) return null; | |
| 140 var target = node.typeName; | |
| 141 if (node.typeName is Send) { | |
| 142 final element = treeElements[node]; | |
| 143 if (element !== null) { | |
| 144 final send = node.typeName.asSend(); | |
| 145 final isPrefixed = element.lookupConstructor( | |
|
Anton Muhin
2012/08/08 08:27:20
nit: please, rename isPrefixed -> hasPrefix
Roman
2012/08/09 05:02:35
Done.
| |
| 146 send.receiver.source, send.selector.source) === null; | |
| 147 if (!isPrefixed) target = send.receiver; | |
| 148 } | |
| 149 } | |
| 150 placeholderForType(target, type); | |
| 151 visit(node.typeArguments); | |
|
Anton Muhin
2012/08/08 08:27:20
super.visitTypeAnnotation(node)?
Roman
2012/08/09 05:02:35
Done.
| |
| 152 } | |
| 153 } | |
| OLD | NEW |