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

Side by Side Diff: tests/compiler/dart2js/inference/enumerator.dart

Issue 2950493002: Add closure_test (Closed)
Patch Set: Created 3 years, 6 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'package:compiler/src/elements/elements.dart';
6 import 'package:compiler/src/resolution/access_semantics.dart';
7 import 'package:compiler/src/resolution/send_structure.dart';
8 import 'package:compiler/src/resolution/tree_elements.dart';
9 import 'package:compiler/src/tree/nodes.dart' as ast;
10 import 'package:kernel/ast.dart' as ir;
11
12 enum IdKind { element, node }
13
14 /// Id for a code point or element with type inference information.
15 abstract class Id {
16 IdKind get kind;
17 }
18
19 /// Id for an element with type inference information.
20 // TODO(johnniwinther): Support local variables, functions and parameters.
21 class ElementId implements Id {
22 final String className;
23 final String memberName;
24
25 factory ElementId(String text) {
26 int dotPos = text.indexOf('.');
27 if (dotPos != -1) {
28 return new ElementId.internal(
29 text.substring(dotPos + 1), text.substring(0, dotPos));
30 } else {
31 return new ElementId.internal(text);
32 }
33 }
34
35 ElementId.internal(this.memberName, [this.className]);
36
37 int get hashCode => className.hashCode * 13 + memberName.hashCode * 17;
38
39 bool operator ==(other) {
40 if (identical(this, other)) return true;
41 if (other is! ElementId) return false;
42 return className == other.className && memberName == other.memberName;
43 }
44
45 IdKind get kind => IdKind.element;
46
47 String toString() =>
48 className != null ? '$className.$memberName' : memberName;
49 }
50
51 /// Id for a code point with type inference information.
52 // TODO(johnniwinther): Create an [NodeId]-based equivalence with the kernel IR.
53 class NodeId implements Id {
54 final int value;
55
56 const NodeId(this.value);
57
58 int get hashCode => value.hashCode;
59
60 bool operator ==(other) {
61 if (identical(this, other)) return true;
62 if (other is! NodeId) return false;
63 return value == other.value;
64 }
65
66 IdKind get kind => IdKind.node;
67
68 String toString() => value.toString();
69 }
70
71 abstract class AstEnumeratorMixin {
72 TreeElements get elements;
73
74 ElementId computeElementId(AstElement element) {
75 String memberName = element.name;
76 if (element.isSetter) {
77 memberName += '=';
78 }
79 String className = element.enclosingClass?.name;
80 return new ElementId.internal(memberName, className);
81 }
82
83 NodeId computeAccessId(ast.Send node, AccessSemantics access) {
84 switch (access.kind) {
85 case AccessKind.DYNAMIC_PROPERTY:
86 return new NodeId(node.selector.getBeginToken().charOffset);
87 default:
88 return new NodeId(node.getBeginToken().charOffset);
89 }
90 }
91
92 NodeId computeNodeId(ast.Send node) {
93 dynamic sendStructure = elements.getSendStructure(node);
94 if (sendStructure == null) return null;
95 switch (sendStructure.kind) {
96 case SendStructureKind.GET:
97 case SendStructureKind.INVOKE:
98 case SendStructureKind.INCOMPATIBLE_INVOKE:
99 return computeAccessId(node, sendStructure.semantics);
100 default:
101 return new NodeId(node.getBeginToken().charOffset);
102 }
103 }
104 }
105
106 /// Visitor that finds the AST node or element corresponding to an [Id].
107 class AstIdFinder extends ast.Visitor with AstEnumeratorMixin {
108 Id soughtId;
109 var /*AstElement|ast.Node*/ found;
110 final TreeElements elements;
111
112 AstIdFinder(this.elements);
113
114 /// Visits the subtree of [root] returns the [ast.Node] or [AstElement]
115 /// corresponding to [id].
116 /*AstElement|ast.Node*/ find(ast.Node root, Id id) {
117 soughtId = id;
118 root.accept(this);
119 var result = found;
120 found = null;
121 return result;
122 }
123
124 visit(ast.Node node) {
125 if (found == null) {
126 node?.accept(this);
127 }
128 }
129
130 visitNode(ast.Node node) {
131 if (found == null) {
132 node.visitChildren(this);
133 }
134 }
135
136 visitSend(ast.Send node) {
137 if (found == null) {
138 visitNode(node);
139 Id id = computeNodeId(node);
140 if (id == soughtId) {
141 found = node;
142 }
143 }
144 }
145
146 visitVariableDefinitions(ast.VariableDefinitions node) {
147 if (found == null) {
148 for (ast.Node child in node.definitions) {
149 AstElement element = elements[child];
150 if (element != null) {
151 Id id = computeElementId(element);
152 if (id == soughtId) {
153 found = element;
154 return;
155 }
156 }
157 }
158 visitNode(node);
159 }
160 }
161
162 visitFunctionExpression(ast.FunctionExpression node) {
163 if (found == null) {
164 AstElement element = elements.getFunctionDefinition(node);
165 if (element != null) {
166 Id id = computeElementId(element);
167 if (id == soughtId) {
168 found = element;
169 return;
170 }
171 }
172 visitNode(node);
173 }
174 }
175 }
176
177 abstract class IrEnumeratorMixin {
178 Id computeElementId(ir.Member node) {
179 String className;
180 if (node.enclosingClass != null) {
181 className = node.enclosingClass.name;
182 }
183 String memberName = node.name.name;
184 if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) {
185 memberName += '=';
186 }
187 return new ElementId.internal(memberName, className);
188 }
189
190 Id computeNodeId(ir.Node node) {
191 if (node is ir.MethodInvocation) {
192 assert(node.fileOffset != ir.TreeNode.noOffset);
193 return new NodeId(node.fileOffset);
194 } else if (node is ir.PropertyGet) {
195 assert(node.fileOffset != ir.TreeNode.noOffset);
196 return new NodeId(node.fileOffset);
197 }
198 return null;
199 }
200 }
201
202 /// Visitor that finds the IR node corresponding to an [Id].
203 class IrIdFinder extends ir.Visitor with IrEnumeratorMixin {
204 Id soughtId;
205 ir.Node found;
206
207 /// Visits the subtree of [root] returns the [ir.Node] corresponding to [id].
208 ir.Node find(ir.Node root, Id id) {
209 soughtId = id;
210 root.accept(this);
211 var result = found;
212 found = null;
213 return result;
214 }
215
216 defaultNode(ir.Node node) {
217 if (found == null) {
218 Id id = computeNodeId(node);
219 if (id == soughtId) {
220 found = node;
221 return;
222 }
223 node.visitChildren(this);
224 }
225 }
226
227 defaultMember(ir.Member node) {
228 if (found == null) {
229 Id id = computeElementId(node);
230 if (id == soughtId) {
231 found = node;
232 return;
233 }
234 defaultNode(node);
235 }
236 }
237 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/equivalence/id_equivalence_test.dart ('k') | tests/compiler/dart2js/inference/id_equivalence_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698