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

Side by Side Diff: tests/compiler/dart2js/equivalence/id_equivalence.dart

Issue 3001223002: Support unittest of jumps (Closed)
Patch Set: Updated cf. comments Created 3 years, 4 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
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/common.dart';
5 import 'package:compiler/src/elements/elements.dart'; 6 import 'package:compiler/src/elements/elements.dart';
6 import 'package:compiler/src/resolution/access_semantics.dart'; 7 import 'package:compiler/src/resolution/access_semantics.dart';
7 import 'package:compiler/src/resolution/send_structure.dart'; 8 import 'package:compiler/src/resolution/send_structure.dart';
8 import 'package:compiler/src/resolution/tree_elements.dart'; 9 import 'package:compiler/src/resolution/tree_elements.dart';
9 import 'package:compiler/src/tree/nodes.dart' as ast; 10 import 'package:compiler/src/tree/nodes.dart' as ast;
10 import 'package:kernel/ast.dart' as ir; 11 import 'package:kernel/ast.dart' as ir;
11 12
12 enum IdKind { 13 enum IdKind {
13 element, 14 element,
14 node, 15 node,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 if (identical(this, other)) return true; 65 if (identical(this, other)) return true;
65 if (other is! NodeId) return false; 66 if (other is! NodeId) return false;
66 return value == other.value; 67 return value == other.value;
67 } 68 }
68 69
69 IdKind get kind => IdKind.node; 70 IdKind get kind => IdKind.node;
70 71
71 String toString() => '$kind:$value'; 72 String toString() => '$kind:$value';
72 } 73 }
73 74
74 abstract class AstEnumeratorMixin { 75 class ActualData {
75 TreeElements get elements; 76 final Id id;
77 final String value;
78 final SourceSpan sourceSpan;
79 final Object object;
80
81 ActualData(this.id, this.value, this.sourceSpan, this.object);
82 }
83
84 /// Abstract AST visitor for computing data corresponding to a node or element,
85 // and record it with a generic [Id].
86 abstract class AstDataExtractor extends ast.Visitor {
87 final DiagnosticReporter reporter;
88 final Map<Id, ActualData> actualMap;
89 final ResolvedAst resolvedAst;
90
91 AstDataExtractor(this.reporter, this.actualMap, this.resolvedAst);
92
93 /// Implement this to compute the data corresponding to [element].
94 ///
95 /// If `null` is returned, [element] has no associated data.
96 String computeElementValue(AstElement element);
97
98 /// Implement this to compute the data corresponding to [node]. If [node] has
99 /// a corresponding [AstElement] this is provided in [element].
100 ///
101 /// If `null` is returned, [node] has no associated data.
102 String computeNodeValue(ast.Node node, AstElement element);
103
104 TreeElements get elements => resolvedAst.elements;
105
106 void registerValue(
107 SourceSpan sourceSpan, Id id, String value, Object object) {
108 if (value != null) {
109 actualMap[id] = new ActualData(id, value, sourceSpan, object);
110 }
111 }
76 112
77 ElementId computeElementId(AstElement element) { 113 ElementId computeElementId(AstElement element) {
78 String memberName = element.name; 114 String memberName = element.name;
79 if (element.isSetter) { 115 if (element.isSetter) {
80 memberName += '='; 116 memberName += '=';
81 } 117 }
82 String className = element.enclosingClass?.name; 118 String className = element.enclosingClass?.name;
83 return new ElementId.internal(memberName, className); 119 return new ElementId.internal(memberName, className);
84 } 120 }
85 121
86 NodeId computeAccessId(ast.Send node, AccessSemantics access) { 122 NodeId computeAccessId(ast.Send node, AccessSemantics access) {
87 switch (access.kind) { 123 switch (access.kind) {
88 case AccessKind.DYNAMIC_PROPERTY: 124 case AccessKind.DYNAMIC_PROPERTY:
89 return new NodeId(node.selector.getBeginToken().charOffset); 125 case AccessKind.LOCAL_VARIABLE:
126 case AccessKind.FINAL_LOCAL_VARIABLE:
127 case AccessKind.LOCAL_FUNCTION:
128 case AccessKind.PARAMETER:
129 case AccessKind.FINAL_PARAMETER:
130 case AccessKind.EXPRESSION:
131 return computeDefaultNodeId(node.selector);
90 default: 132 default:
91 return null; 133 return null;
92 } 134 }
93 } 135 }
94 136
95 NodeId computeNodeId(ast.Node node, AstElement element) { 137 void computeForElement(AstElement element) {
96 if (element != null && element.isLocal) { 138 ElementId id = computeElementId(element);
97 return new NodeId(node.getBeginToken().charOffset); 139 if (id == null) return;
98 } else if (node is ast.Send) { 140 String value = computeElementValue(element);
99 dynamic sendStructure = elements.getSendStructure(node); 141 registerValue(element.sourcePosition, id, value, element);
100 if (sendStructure == null) return null; 142 }
143
144 void computeForNode(ast.Node node, NodeId id, [AstElement element]) {
145 if (id == null) return;
146 String value = computeNodeValue(node, element);
147 SourceSpan sourceSpan = computeSourceSpan(node);
148 registerValue(sourceSpan, id, value, element ?? node);
149 }
150
151 SourceSpan computeSourceSpan(ast.Node node) {
152 return new SourceSpan(resolvedAst.sourceUri,
153 node.getBeginToken().charOffset, node.getEndToken().charEnd);
154 }
155
156 NodeId computeDefaultNodeId(ast.Node node) {
157 return new NodeId(node.getBeginToken().charOffset);
158 }
159
160 NodeId computeLoopNodeId(ast.Node node) {
161 return new NodeId(node.getBeginToken().charOffset);
162 }
163
164 NodeId computeGotoNodeId(ast.Node node) {
165 return new NodeId(node.getBeginToken().charOffset);
166 }
167
168 void run() {
169 resolvedAst.node.accept(this);
170 }
171
172 visitNode(ast.Node node) {
173 node.visitChildren(this);
174 }
175
176 visitVariableDefinitions(ast.VariableDefinitions node) {
177 for (ast.Node child in node.definitions) {
178 AstElement element = elements[child];
179 if (element == null) {
180 reportHere(reporter, child, 'No element for variable.');
181 } else if (!element.isLocal) {
182 computeForElement(element);
183 } else {
184 computeForNode(child, computeDefaultNodeId(child), element);
185 }
186 }
187 visitNode(node);
188 }
189
190 visitFunctionExpression(ast.FunctionExpression node) {
191 AstElement element = elements.getFunctionDefinition(node);
192 if (!element.isLocal) {
193 computeForElement(element);
194 } else {
195 computeForNode(node, computeDefaultNodeId(node), element);
196 }
197 visitNode(node);
198 }
199
200 visitSend(ast.Send node) {
201 dynamic sendStructure = elements.getSendStructure(node);
202 if (sendStructure != null) {
101 switch (sendStructure.kind) { 203 switch (sendStructure.kind) {
102 case SendStructureKind.GET: 204 case SendStructureKind.GET:
103 case SendStructureKind.INVOKE: 205 case SendStructureKind.INVOKE:
104 return computeAccessId(node, sendStructure.semantics); 206 case SendStructureKind.BINARY:
207 case SendStructureKind.EQUALS:
208 case SendStructureKind.NOT_EQUALS:
209 computeForNode(node, computeAccessId(node, sendStructure.semantics));
210 break;
105 default: 211 default:
106 } 212 }
107 } 213 }
108 return null; 214 visitNode(node);
215 }
216
217 visitLoop(ast.Loop node) {
218 computeForNode(node, computeLoopNodeId(node));
219 visitNode(node);
220 }
221
222 visitGotoStatement(ast.GotoStatement node) {
223 computeForNode(node, computeGotoNodeId(node));
224 visitNode(node);
109 } 225 }
110 } 226 }
111 227
112 /// Visitor that finds the AST node or element corresponding to an [Id]. 228 /// Abstract IR visitor for computing data corresponding to a node or element,
113 class AstIdFinder extends ast.Visitor with AstEnumeratorMixin { 229 /// and record it with a generic [Id]
114 Id soughtId; 230 abstract class IrDataExtractor extends ir.Visitor {
115 var /*AstElement|ast.Node*/ found; 231 final Map<Id, ActualData> actualMap;
116 final TreeElements elements;
117 232
118 AstIdFinder(this.elements); 233 void registerValue(
119 234 SourceSpan sourceSpan, Id id, String value, Object object) {
120 /// Visits the subtree of [root] returns the [ast.Node] or [AstElement] 235 if (value != null) {
121 /// corresponding to [id]. 236 actualMap[id] = new ActualData(id, value, sourceSpan, object);
122 /*AstElement|ast.Node*/ find(ast.Node root, Id id) {
123 soughtId = id;
124 root.accept(this);
125 var result = found;
126 found = null;
127 return result;
128 }
129
130 visit(ast.Node node) {
131 if (found == null) {
132 node?.accept(this);
133 } 237 }
134 } 238 }
135 239
136 visitNode(ast.Node node) { 240 /// Implement this to compute the data corresponding to [member].
137 if (found == null) { 241 ///
138 node.visitChildren(this); 242 /// If `null` is returned, [member] has no associated data.
139 } 243 String computeMemberValue(ir.Member member);
140 }
141 244
142 visitSend(ast.Send node) { 245 /// Implement this to compute the data corresponding to [node].
143 if (found == null) { 246 ///
144 visitNode(node); 247 /// If `null` is returned, [node] has no associated data.
145 Id id = computeNodeId(node, null); 248 String computeNodeValue(ir.TreeNode node);
146 if (id == soughtId) {
147 found = node;
148 }
149 }
150 }
151 249
152 visitVariableDefinitions(ast.VariableDefinitions node) { 250 IrDataExtractor(this.actualMap);
153 if (found == null) {
154 for (ast.Node child in node.definitions) {
155 AstElement element = elements[child];
156 if (element != null) {
157 Id id;
158 if (element is FieldElement) {
159 id = computeElementId(element);
160 } else {
161 id = computeNodeId(child, element);
162 }
163 if (id == soughtId) {
164 found = element;
165 return;
166 }
167 }
168 }
169 visitNode(node);
170 }
171 }
172
173 visitFunctionExpression(ast.FunctionExpression node) {
174 if (found == null) {
175 AstElement element = elements.getFunctionDefinition(node);
176 if (element != null) {
177 Id id;
178 if (element is LocalFunctionElement) {
179 id = computeNodeId(node, element);
180 } else {
181 id = computeElementId(element);
182 }
183 if (id == soughtId) {
184 found = element;
185 return;
186 }
187 }
188 visitNode(node);
189 }
190 }
191 }
192
193 abstract class IrEnumeratorMixin {
194 Id computeElementId(ir.Member node) { 251 Id computeElementId(ir.Member node) {
195 String className; 252 String className;
196 if (node.enclosingClass != null) { 253 if (node.enclosingClass != null) {
197 className = node.enclosingClass.name; 254 className = node.enclosingClass.name;
198 } 255 }
199 String memberName = node.name.name; 256 String memberName = node.name.name;
200 if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) { 257 if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) {
201 memberName += '='; 258 memberName += '=';
202 } 259 }
203 return new ElementId.internal(memberName, className); 260 return new ElementId.internal(memberName, className);
204 } 261 }
205 262
206 Id computeNodeId(ir.TreeNode node) { 263 void computeForMember(ir.Member member) {
207 if (node is ir.MethodInvocation) { 264 ElementId id = computeElementId(member);
208 assert(node.fileOffset != ir.TreeNode.noOffset); 265 if (id == null) return;
209 return new NodeId(node.fileOffset); 266 String value = computeMemberValue(member);
210 } else if (node is ir.PropertyGet) { 267 registerValue(computeSourceSpan(member), id, value, member);
211 assert(node.fileOffset != ir.TreeNode.noOffset);
212 return new NodeId(node.fileOffset);
213 } else if (node is ir.VariableDeclaration) {
214 assert(node.fileOffset != ir.TreeNode.noOffset);
215 return new NodeId(node.fileOffset);
216 } else if (node is ir.FunctionExpression) {
217 assert(node.fileOffset != ir.TreeNode.noOffset);
218 return new NodeId(node.fileOffset);
219 } else if (node is ir.FunctionDeclaration) {
220 assert(node.fileOffset != ir.TreeNode.noOffset);
221 return new NodeId(node.fileOffset);
222 }
223 return null;
224 }
225 }
226
227 /// Visitor that finds the IR node corresponding to an [Id].
228 class IrIdFinder extends ir.Visitor with IrEnumeratorMixin {
229 Id soughtId;
230 ir.Node found;
231
232 /// Visits the subtree of [root] returns the [ir.Node] corresponding to [id].
233 ir.Node find(ir.Node root, Id id) {
234 soughtId = id;
235 root.accept(this);
236 var result = found;
237 found = null;
238 return result;
239 } 268 }
240 269
241 defaultTreeNode(ir.TreeNode node) { 270 void computeForNode(ir.TreeNode node, NodeId id) {
242 if (found == null) { 271 if (id == null) return;
243 Id id = computeNodeId(node); 272 String value = computeNodeValue(node);
244 if (id == soughtId) { 273 registerValue(computeSourceSpan(node), id, value, node);
245 found = node; 274 }
246 return; 275
247 } 276 SourceSpan computeSourceSpan(ir.TreeNode node) {
248 node.visitChildren(this); 277 return new SourceSpan(
249 } 278 Uri.parse(node.location.file), node.fileOffset, node.fileOffset + 1);
279 }
280
281 NodeId computeDefaultNodeId(ir.TreeNode node) {
282 assert(node.fileOffset != ir.TreeNode.noOffset);
283 return new NodeId(node.fileOffset);
284 }
285
286 NodeId computeLoopNodeId(ir.TreeNode node) => computeDefaultNodeId(node);
287 NodeId computeGotoNodeId(ir.TreeNode node) => computeDefaultNodeId(node);
288
289 void run(ir.Node root) {
290 root.accept(this);
291 }
292
293 defaultNode(ir.Node node) {
294 node.visitChildren(this);
250 } 295 }
251 296
252 defaultMember(ir.Member node) { 297 defaultMember(ir.Member node) {
253 if (found == null) { 298 computeForMember(node);
254 Id id = computeElementId(node); 299 super.defaultMember(node);
255 if (id == soughtId) { 300 }
256 found = node; 301
257 return; 302 visitMethodInvocation(ir.MethodInvocation node) {
258 } 303 computeForNode(node, computeDefaultNodeId(node));
259 defaultTreeNode(node); 304 super.visitMethodInvocation(node);
260 } 305 }
306
307 visitPropertyGet(ir.PropertyGet node) {
308 computeForNode(node, computeDefaultNodeId(node));
309 super.visitPropertyGet(node);
310 }
311
312 visitVariableDeclaration(ir.VariableDeclaration node) {
313 computeForNode(node, computeDefaultNodeId(node));
314 super.visitVariableDeclaration(node);
315 }
316
317 visitFunctionDeclaration(ir.FunctionDeclaration node) {
318 computeForNode(node, computeDefaultNodeId(node));
319 super.visitFunctionDeclaration(node);
320 }
321
322 visitFunctionExpression(ir.FunctionExpression node) {
323 computeForNode(node, computeDefaultNodeId(node));
324 super.visitFunctionExpression(node);
325 }
326
327 visitVariableGet(ir.VariableGet node) {
328 computeForNode(node, computeDefaultNodeId(node));
329 super.visitVariableGet(node);
330 }
331
332 visitDoStatement(ir.DoStatement node) {
333 computeForNode(node, computeLoopNodeId(node));
334 super.visitDoStatement(node);
335 }
336
337 visitForStatement(ir.ForStatement node) {
338 computeForNode(node, computeLoopNodeId(node));
339 super.visitForStatement(node);
340 }
341
342 visitForInStatement(ir.ForInStatement node) {
343 computeForNode(node, computeLoopNodeId(node));
344 super.visitForInStatement(node);
345 }
346
347 visitWhileStatement(ir.WhileStatement node) {
348 computeForNode(node, computeLoopNodeId(node));
349 super.visitWhileStatement(node);
350 }
351
352 visitBreakStatement(ir.BreakStatement node) {
353 computeForNode(node, computeGotoNodeId(node));
354 super.visitBreakStatement(node);
261 } 355 }
262 } 356 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/closure/closure_test.dart ('k') | tests/compiler/dart2js/equivalence/id_equivalence_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698