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/equivalence/id_equivalence.dart

Issue 3001223002: Support unittest of jumps (Closed)
Patch Set: 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 /// Mixin used for computing [Id] data.
85 abstract class ComputerMixin {
Siggi Cherem (dart-lang) 2017/08/18 21:20:21 nit: rename to describe what it does and not what
Johnni Winther 2017/08/19 09:30:52 Mixin removed
86 Map<Id, ActualData> get actualMap;
87
88 void registerValue(
89 SourceSpan sourceSpan, Id id, String value, Object object) {
90 if (id != null && value != null) {
Siggi Cherem (dart-lang) 2017/08/18 21:20:21 note that you already guard agaisnt null id's on a
Johnni Winther 2017/08/19 09:30:52 Done.
91 actualMap[id] = new ActualData(id, value, sourceSpan, object);
92 }
93 }
94 }
95
96 /// Abstract AST visitor for computing [Id] data.
Siggi Cherem (dart-lang) 2017/08/18 21:20:21 nit: reword to: visitor for computing data corresp
Johnni Winther 2017/08/19 09:30:52 Done.
97 abstract class AbstractResolvedAstComputer extends ast.Visitor
Siggi Cherem (dart-lang) 2017/08/18 21:20:21 other naming ideas: - AbstractAstDataBuilder and
Johnni Winther 2017/08/19 09:30:52 Extractor it is.
98 with ComputerMixin {
99 final DiagnosticReporter reporter;
100 final Map<Id, ActualData> actualMap;
101 final ResolvedAst resolvedAst;
102
103 AbstractResolvedAstComputer(this.reporter, this.actualMap, this.resolvedAst);
104
105 TreeElements get elements => resolvedAst.elements;
76 106
77 ElementId computeElementId(AstElement element) { 107 ElementId computeElementId(AstElement element) {
78 String memberName = element.name; 108 String memberName = element.name;
79 if (element.isSetter) { 109 if (element.isSetter) {
80 memberName += '='; 110 memberName += '=';
81 } 111 }
82 String className = element.enclosingClass?.name; 112 String className = element.enclosingClass?.name;
83 return new ElementId.internal(memberName, className); 113 return new ElementId.internal(memberName, className);
84 } 114 }
85 115
86 NodeId computeAccessId(ast.Send node, AccessSemantics access) { 116 NodeId computeAccessId(ast.Send node, AccessSemantics access) {
87 switch (access.kind) { 117 switch (access.kind) {
88 case AccessKind.DYNAMIC_PROPERTY: 118 case AccessKind.DYNAMIC_PROPERTY:
89 return new NodeId(node.selector.getBeginToken().charOffset); 119 case AccessKind.LOCAL_VARIABLE:
120 case AccessKind.FINAL_LOCAL_VARIABLE:
121 case AccessKind.LOCAL_FUNCTION:
122 case AccessKind.PARAMETER:
123 case AccessKind.FINAL_PARAMETER:
124 case AccessKind.EXPRESSION:
125 return computeDefaultNodeId(node.selector);
90 default: 126 default:
91 return null; 127 return null;
92 } 128 }
93 } 129 }
94 130
95 NodeId computeNodeId(ast.Node node, AstElement element) { 131 void computeForElement(AstElement element) {
96 if (element != null && element.isLocal) { 132 ElementId id = computeElementId(element);
97 return new NodeId(node.getBeginToken().charOffset); 133 if (id == null) return;
98 } else if (node is ast.Send) { 134 String value = computeElementValue(element);
99 dynamic sendStructure = elements.getSendStructure(node); 135 registerValue(element.sourcePosition, id, value, element);
100 if (sendStructure == null) return null; 136 }
137
138 void computeForNode(ast.Node node, NodeId id, [AstElement element]) {
139 if (id == null) return;
140 String value = computeNodeValue(node, element);
141 SourceSpan sourceSpan = computeSourceSpan(node);
142 registerValue(sourceSpan, id, value, element ?? node);
143 }
144
145 SourceSpan computeSourceSpan(ast.Node node) {
146 return new SourceSpan(resolvedAst.sourceUri,
147 node.getBeginToken().charOffset, node.getEndToken().charEnd);
148 }
149
150 String computeElementValue(AstElement element);
Siggi Cherem (dart-lang) 2017/08/18 21:20:21 let's move these two up and add dart doc on them.
Johnni Winther 2017/08/19 09:30:52 Done.
151
152 String computeNodeValue(ast.Node node, AstElement element);
153
154 NodeId computeDefaultNodeId(ast.Node node) {
155 return new NodeId(node.getBeginToken().charOffset);
156 }
157
158 NodeId computeLoopNodeId(ast.Node node) {
159 return new NodeId(node.getBeginToken().charOffset);
160 }
161
162 NodeId computeGotoNodeId(ast.Node node) {
163 return new NodeId(node.getBeginToken().charOffset);
164 }
165
166 void run() {
167 resolvedAst.node.accept(this);
168 }
169
170 visitNode(ast.Node node) {
171 node.visitChildren(this);
172 }
173
174 visitVariableDefinitions(ast.VariableDefinitions node) {
175 for (ast.Node child in node.definitions) {
176 AstElement element = elements[child];
177 if (element == null) {
178 reportHere(reporter, child, 'No element for variable.');
179 } else if (!element.isLocal) {
180 computeForElement(element);
181 } else {
182 computeForNode(child, computeDefaultNodeId(child), element);
183 }
184 }
185 visitNode(node);
186 }
187
188 visitFunctionExpression(ast.FunctionExpression node) {
189 AstElement element = elements.getFunctionDefinition(node);
190 if (!element.isLocal) {
191 computeForElement(element);
192 } else {
193 computeForNode(node, computeDefaultNodeId(node), element);
194 }
195 visitNode(node);
196 }
197
198 visitSend(ast.Send node) {
199 dynamic sendStructure = elements.getSendStructure(node);
200 if (sendStructure != null) {
101 switch (sendStructure.kind) { 201 switch (sendStructure.kind) {
102 case SendStructureKind.GET: 202 case SendStructureKind.GET:
103 case SendStructureKind.INVOKE: 203 case SendStructureKind.INVOKE:
104 return computeAccessId(node, sendStructure.semantics); 204 case SendStructureKind.BINARY:
205 case SendStructureKind.EQUALS:
206 case SendStructureKind.NOT_EQUALS:
207 computeForNode(node, computeAccessId(node, sendStructure.semantics));
208 break;
105 default: 209 default:
106 } 210 }
107 } 211 }
108 return null; 212 visitNode(node);
213 }
214
215 visitLoop(ast.Loop node) {
216 computeForNode(node, computeLoopNodeId(node));
217 visitNode(node);
218 }
219
220 visitGotoStatement(ast.GotoStatement node) {
221 computeForNode(node, computeGotoNodeId(node));
222 visitNode(node);
109 } 223 }
110 } 224 }
111 225
112 /// Visitor that finds the AST node or element corresponding to an [Id]. 226 /// Abstract IR visitor for computing [Id] data.
113 class AstIdFinder extends ast.Visitor with AstEnumeratorMixin { 227 abstract class AbstractIrComputer extends ir.Visitor with ComputerMixin {
114 Id soughtId; 228 final Map<Id, ActualData> actualMap;
115 var /*AstElement|ast.Node*/ found;
116 final TreeElements elements;
117 229
118 AstIdFinder(this.elements); 230 AbstractIrComputer(this.actualMap);
119
120 /// Visits the subtree of [root] returns the [ast.Node] or [AstElement]
121 /// corresponding to [id].
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 }
134 }
135
136 visitNode(ast.Node node) {
137 if (found == null) {
138 node.visitChildren(this);
139 }
140 }
141
142 visitSend(ast.Send node) {
143 if (found == null) {
144 visitNode(node);
145 Id id = computeNodeId(node, null);
146 if (id == soughtId) {
147 found = node;
148 }
149 }
150 }
151
152 visitVariableDefinitions(ast.VariableDefinitions node) {
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) { 231 Id computeElementId(ir.Member node) {
195 String className; 232 String className;
196 if (node.enclosingClass != null) { 233 if (node.enclosingClass != null) {
197 className = node.enclosingClass.name; 234 className = node.enclosingClass.name;
198 } 235 }
199 String memberName = node.name.name; 236 String memberName = node.name.name;
200 if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) { 237 if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) {
201 memberName += '='; 238 memberName += '=';
202 } 239 }
203 return new ElementId.internal(memberName, className); 240 return new ElementId.internal(memberName, className);
204 } 241 }
205 242
206 Id computeNodeId(ir.TreeNode node) { 243 void computeForMember(ir.Member member) {
207 if (node is ir.MethodInvocation) { 244 ElementId id = computeElementId(member);
208 assert(node.fileOffset != ir.TreeNode.noOffset); 245 if (id == null) return;
209 return new NodeId(node.fileOffset); 246 String value = computeMemberValue(member);
210 } else if (node is ir.PropertyGet) { 247 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 } 248 }
240 249
241 defaultTreeNode(ir.TreeNode node) { 250 void computeForNode(ir.TreeNode node, NodeId id) {
242 if (found == null) { 251 if (id == null) return;
243 Id id = computeNodeId(node); 252 String value = computeNodeValue(node);
244 if (id == soughtId) { 253 registerValue(computeSourceSpan(node), id, value, node);
245 found = node; 254 }
246 return; 255
247 } 256 SourceSpan computeSourceSpan(ir.TreeNode node) {
248 node.visitChildren(this); 257 return new SourceSpan(
249 } 258 Uri.parse(node.location.file), node.fileOffset, node.fileOffset + 1);
259 }
260
261 String computeMemberValue(ir.Member member);
262
263 String computeNodeValue(ir.TreeNode node);
264
265 NodeId computeDefaultNodeId(ir.TreeNode node) {
266 assert(node.fileOffset != ir.TreeNode.noOffset);
267 return new NodeId(node.fileOffset);
268 }
269
270 NodeId computeLoopNodeId(ir.TreeNode node) => computeDefaultNodeId(node);
271 NodeId computeGotoNodeId(ir.TreeNode node) => computeDefaultNodeId(node);
272
273 void run(ir.Node root) {
274 root.accept(this);
275 }
276
277 defaultNode(ir.Node node) {
278 node.visitChildren(this);
250 } 279 }
251 280
252 defaultMember(ir.Member node) { 281 defaultMember(ir.Member node) {
253 if (found == null) { 282 computeForMember(node);
254 Id id = computeElementId(node); 283 super.defaultMember(node);
255 if (id == soughtId) { 284 }
256 found = node; 285
257 return; 286 visitMethodInvocation(ir.MethodInvocation node) {
258 } 287 computeForNode(node, computeDefaultNodeId(node));
259 defaultTreeNode(node); 288 super.visitMethodInvocation(node);
260 } 289 }
290
291 visitPropertyGet(ir.PropertyGet node) {
292 computeForNode(node, computeDefaultNodeId(node));
293 super.visitPropertyGet(node);
294 }
295
296 visitVariableDeclaration(ir.VariableDeclaration node) {
297 computeForNode(node, computeDefaultNodeId(node));
298 super.visitVariableDeclaration(node);
299 }
300
301 visitFunctionDeclaration(ir.FunctionDeclaration node) {
302 computeForNode(node, computeDefaultNodeId(node));
303 super.visitFunctionDeclaration(node);
304 }
305
306 visitFunctionExpression(ir.FunctionExpression node) {
307 computeForNode(node, computeDefaultNodeId(node));
308 super.visitFunctionExpression(node);
309 }
310
311 visitVariableGet(ir.VariableGet node) {
312 computeForNode(node, computeDefaultNodeId(node));
313 super.visitVariableGet(node);
314 }
315
316 visitDoStatement(ir.DoStatement node) {
317 computeForNode(node, computeLoopNodeId(node));
318 super.visitDoStatement(node);
319 }
320
321 visitForStatement(ir.ForStatement node) {
322 computeForNode(node, computeLoopNodeId(node));
323 super.visitForStatement(node);
324 }
325
326 visitForInStatement(ir.ForInStatement node) {
327 computeForNode(node, computeLoopNodeId(node));
328 super.visitForInStatement(node);
329 }
330
331 visitWhileStatement(ir.WhileStatement node) {
332 computeForNode(node, computeLoopNodeId(node));
333 super.visitWhileStatement(node);
334 }
335
336 visitBreakStatement(ir.BreakStatement node) {
337 computeForNode(node, computeGotoNodeId(node));
338 super.visitBreakStatement(node);
261 } 339 }
262 } 340 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698