OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'package:compiler/src/elements/elements.dart'; | 5 import 'package:compiler/src/elements/elements.dart'; |
6 import 'package:compiler/src/resolution/access_semantics.dart'; | 6 import 'package:compiler/src/resolution/access_semantics.dart'; |
7 import 'package:compiler/src/resolution/send_structure.dart'; | 7 import 'package:compiler/src/resolution/send_structure.dart'; |
8 import 'package:compiler/src/resolution/tree_elements.dart'; | 8 import 'package:compiler/src/resolution/tree_elements.dart'; |
9 import 'package:compiler/src/tree/nodes.dart' as ast; | 9 import 'package:compiler/src/tree/nodes.dart' as ast; |
10 import 'package:kernel/ast.dart' as ir; | 10 import 'package:kernel/ast.dart' as ir; |
11 | 11 |
12 enum IdKind { element, node } | 12 enum IdKind { element, node, local_variable, local_function } |
13 | 13 |
14 /// Id for a code point or element with type inference information. | 14 /// Id for a code point or element with type inference information. |
15 abstract class Id { | 15 abstract class Id { |
16 IdKind get kind; | 16 IdKind get kind; |
17 } | 17 } |
18 | 18 |
19 /// Id for an element with type inference information. | 19 /// Id for an element with type inference information. |
20 // TODO(johnniwinther): Support local variables, functions and parameters. | 20 // TODO(johnniwinther): Support local variables, functions and parameters. |
21 class ElementId implements Id { | 21 class ElementId implements Id { |
22 final String className; | 22 final String className; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 int get hashCode => value.hashCode; | 58 int get hashCode => value.hashCode; |
59 | 59 |
60 bool operator ==(other) { | 60 bool operator ==(other) { |
61 if (identical(this, other)) return true; | 61 if (identical(this, other)) return true; |
62 if (other is! NodeId) return false; | 62 if (other is! NodeId) return false; |
63 return value == other.value; | 63 return value == other.value; |
64 } | 64 } |
65 | 65 |
66 IdKind get kind => IdKind.node; | 66 IdKind get kind => IdKind.node; |
67 | 67 |
68 String toString() => value.toString(); | 68 String toString() => '$kind:$value'; |
69 } | 69 } |
70 | 70 |
71 abstract class AstEnumeratorMixin { | 71 abstract class AstEnumeratorMixin { |
72 TreeElements get elements; | 72 TreeElements get elements; |
73 | 73 |
74 ElementId computeElementId(AstElement element) { | 74 ElementId computeElementId(AstElement element) { |
75 String memberName = element.name; | 75 String memberName = element.name; |
76 if (element.isSetter) { | 76 if (element.isSetter) { |
77 memberName += '='; | 77 memberName += '='; |
78 } | 78 } |
79 String className = element.enclosingClass?.name; | 79 String className = element.enclosingClass?.name; |
80 return new ElementId.internal(memberName, className); | 80 return new ElementId.internal(memberName, className); |
81 } | 81 } |
82 | 82 |
83 NodeId computeAccessId(ast.Send node, AccessSemantics access) { | 83 NodeId computeAccessId(ast.Send node, AccessSemantics access) { |
84 switch (access.kind) { | 84 switch (access.kind) { |
85 case AccessKind.DYNAMIC_PROPERTY: | 85 case AccessKind.DYNAMIC_PROPERTY: |
86 return new NodeId(node.selector.getBeginToken().charOffset); | 86 return new NodeId(node.selector.getBeginToken().charOffset); |
87 default: | 87 default: |
88 return new NodeId(node.getBeginToken().charOffset); | 88 return new NodeId(node.getBeginToken().charOffset); |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 NodeId computeNodeId(ast.Send node) { | 92 NodeId computeNodeId(ast.Node node, AstElement element) { |
93 dynamic sendStructure = elements.getSendStructure(node); | 93 if (element != null && element.isLocal) { |
94 if (sendStructure == null) return null; | 94 return new NodeId(node.getBeginToken().charOffset); |
95 switch (sendStructure.kind) { | 95 } else if (node is ast.Send) { |
96 case SendStructureKind.GET: | 96 dynamic sendStructure = elements.getSendStructure(node); |
97 case SendStructureKind.INVOKE: | 97 if (sendStructure == null) return null; |
98 case SendStructureKind.INCOMPATIBLE_INVOKE: | 98 switch (sendStructure.kind) { |
99 return computeAccessId(node, sendStructure.semantics); | 99 case SendStructureKind.GET: |
100 default: | 100 case SendStructureKind.INVOKE: |
101 return new NodeId(node.getBeginToken().charOffset); | 101 case SendStructureKind.INCOMPATIBLE_INVOKE: |
| 102 return computeAccessId(node, sendStructure.semantics); |
| 103 default: |
| 104 return new NodeId(node.getBeginToken().charOffset); |
| 105 } |
102 } | 106 } |
| 107 return new NodeId(node.getBeginToken().charOffset); |
103 } | 108 } |
104 } | 109 } |
105 | 110 |
106 /// Visitor that finds the AST node or element corresponding to an [Id]. | 111 /// Visitor that finds the AST node or element corresponding to an [Id]. |
107 class AstIdFinder extends ast.Visitor with AstEnumeratorMixin { | 112 class AstIdFinder extends ast.Visitor with AstEnumeratorMixin { |
108 Id soughtId; | 113 Id soughtId; |
109 var /*AstElement|ast.Node*/ found; | 114 var /*AstElement|ast.Node*/ found; |
110 final TreeElements elements; | 115 final TreeElements elements; |
111 | 116 |
112 AstIdFinder(this.elements); | 117 AstIdFinder(this.elements); |
(...skipping 16 matching lines...) Expand all Loading... |
129 | 134 |
130 visitNode(ast.Node node) { | 135 visitNode(ast.Node node) { |
131 if (found == null) { | 136 if (found == null) { |
132 node.visitChildren(this); | 137 node.visitChildren(this); |
133 } | 138 } |
134 } | 139 } |
135 | 140 |
136 visitSend(ast.Send node) { | 141 visitSend(ast.Send node) { |
137 if (found == null) { | 142 if (found == null) { |
138 visitNode(node); | 143 visitNode(node); |
139 Id id = computeNodeId(node); | 144 Id id = computeNodeId(node, null); |
140 if (id == soughtId) { | 145 if (id == soughtId) { |
141 found = node; | 146 found = node; |
142 } | 147 } |
143 } | 148 } |
144 } | 149 } |
145 | 150 |
146 visitVariableDefinitions(ast.VariableDefinitions node) { | 151 visitVariableDefinitions(ast.VariableDefinitions node) { |
147 if (found == null) { | 152 if (found == null) { |
148 for (ast.Node child in node.definitions) { | 153 for (ast.Node child in node.definitions) { |
149 AstElement element = elements[child]; | 154 AstElement element = elements[child]; |
150 if (element != null) { | 155 if (element != null) { |
151 Id id = computeElementId(element); | 156 Id id; |
| 157 if (element is FieldElement) { |
| 158 id = computeElementId(element); |
| 159 } else { |
| 160 id = computeNodeId(child, element); |
| 161 } |
152 if (id == soughtId) { | 162 if (id == soughtId) { |
153 found = element; | 163 found = element; |
154 return; | 164 return; |
155 } | 165 } |
156 } | 166 } |
157 } | 167 } |
158 visitNode(node); | 168 visitNode(node); |
159 } | 169 } |
160 } | 170 } |
161 | 171 |
162 visitFunctionExpression(ast.FunctionExpression node) { | 172 visitFunctionExpression(ast.FunctionExpression node) { |
163 if (found == null) { | 173 if (found == null) { |
164 AstElement element = elements.getFunctionDefinition(node); | 174 AstElement element = elements.getFunctionDefinition(node); |
165 if (element != null) { | 175 if (element != null) { |
166 Id id = computeElementId(element); | 176 Id id; |
| 177 if (element is LocalFunctionElement) { |
| 178 id = computeNodeId(node, element); |
| 179 } else { |
| 180 id = computeElementId(element); |
| 181 } |
167 if (id == soughtId) { | 182 if (id == soughtId) { |
168 found = element; | 183 found = element; |
169 return; | 184 return; |
170 } | 185 } |
171 } | 186 } |
172 visitNode(node); | 187 visitNode(node); |
173 } | 188 } |
174 } | 189 } |
175 } | 190 } |
176 | 191 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 if (found == null) { | 243 if (found == null) { |
229 Id id = computeElementId(node); | 244 Id id = computeElementId(node); |
230 if (id == soughtId) { | 245 if (id == soughtId) { |
231 found = node; | 246 found = node; |
232 return; | 247 return; |
233 } | 248 } |
234 defaultNode(node); | 249 defaultNode(node); |
235 } | 250 } |
236 } | 251 } |
237 } | 252 } |
OLD | NEW |