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

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

Issue 3007903002: Support annotations on assignment and postfix operations (Closed)
Patch Set: Updated cf. comments Created 3 years, 3 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/common.dart';
6 import 'package:compiler/src/elements/elements.dart'; 6 import 'package:compiler/src/elements/elements.dart';
7 import 'package:compiler/src/resolution/access_semantics.dart'; 7 import 'package:compiler/src/resolution/access_semantics.dart';
8 import 'package:compiler/src/resolution/send_structure.dart'; 8 import 'package:compiler/src/resolution/send_structure.dart';
9 import 'package:compiler/src/resolution/tree_elements.dart'; 9 import 'package:compiler/src/resolution/tree_elements.dart';
10 import 'package:compiler/src/tree/nodes.dart' as ast; 10 import 'package:compiler/src/tree/nodes.dart' as ast;
11 import 'package:expect/expect.dart';
11 import 'package:kernel/ast.dart' as ir; 12 import 'package:kernel/ast.dart' as ir;
12 13
13 enum IdKind { 14 enum IdKind {
14 element, 15 element,
15 node, 16 node,
17 invoke,
18 update,
16 } 19 }
17 20
18 /// Id for a code point or element with type inference information. 21 /// Id for a code point or element with type inference information.
19 abstract class Id { 22 abstract class Id {
20 IdKind get kind; 23 IdKind get kind;
21 } 24 }
22 25
26 class IdValue {
27 final Id id;
28 final String value;
29
30 const IdValue(this.id, this.value);
31
32 int get hashCode => id.hashCode * 13 + value.hashCode * 17;
33
34 bool operator ==(other) {
35 if (identical(this, other)) return true;
36 if (other is! IdValue) return false;
37 return id == other.id && value == other.value;
38 }
39
40 String toString() {
41 switch (id.kind) {
42 case IdKind.element:
43 ElementId elementId = id;
44 return '$elementPrefix${elementId.name}:$value';
45 case IdKind.node:
46 return value;
47 case IdKind.invoke:
48 return '$invokePrefix$value';
49 case IdKind.update:
50 return '$updatePrefix$value';
51 }
52 throw new UnsupportedError("Unexpected id kind: ${id.kind}");
53 }
54
55 static const String elementPrefix = "element: ";
56 static const String invokePrefix = "invoke: ";
57 static const String updatePrefix = "update: ";
58
59 static IdValue decode(int offset, String text) {
60 Id id;
61 String expected;
62 if (text.startsWith(elementPrefix)) {
63 text = text.substring(elementPrefix.length);
64 int colonPos = text.indexOf(':');
65 id = new ElementId(text.substring(0, colonPos));
66 expected = text.substring(colonPos + 1);
67 } else if (text.startsWith(invokePrefix)) {
68 id = new NodeId(offset, IdKind.invoke);
69 expected = text.substring(invokePrefix.length);
70 } else if (text.startsWith(updatePrefix)) {
71 id = new NodeId(offset, IdKind.update);
72 expected = text.substring(updatePrefix.length);
73 } else {
74 id = new NodeId(offset, IdKind.node);
75 expected = text;
76 }
77 return new IdValue(id, expected);
78 }
79 }
80
23 /// Id for an element with type inference information. 81 /// Id for an element with type inference information.
24 // TODO(johnniwinther): Support local variables, functions and parameters. 82 // TODO(johnniwinther): Support local variables, functions and parameters.
25 class ElementId implements Id { 83 class ElementId implements Id {
26 final String className; 84 final String className;
27 final String memberName; 85 final String memberName;
28 86
29 factory ElementId(String text) { 87 factory ElementId(String text) {
30 int dotPos = text.indexOf('.'); 88 int dotPos = text.indexOf('.');
31 if (dotPos != -1) { 89 if (dotPos != -1) {
32 return new ElementId.internal( 90 return new ElementId.internal(
33 text.substring(dotPos + 1), text.substring(0, dotPos)); 91 text.substring(dotPos + 1), text.substring(0, dotPos));
34 } else { 92 } else {
35 return new ElementId.internal(text); 93 return new ElementId.internal(text);
36 } 94 }
37 } 95 }
38 96
39 ElementId.internal(this.memberName, [this.className]); 97 ElementId.internal(this.memberName, [this.className]);
40 98
41 int get hashCode => className.hashCode * 13 + memberName.hashCode * 17; 99 int get hashCode => className.hashCode * 13 + memberName.hashCode * 17;
42 100
43 bool operator ==(other) { 101 bool operator ==(other) {
44 if (identical(this, other)) return true; 102 if (identical(this, other)) return true;
45 if (other is! ElementId) return false; 103 if (other is! ElementId) return false;
46 return className == other.className && memberName == other.memberName; 104 return className == other.className && memberName == other.memberName;
47 } 105 }
48 106
49 IdKind get kind => IdKind.element; 107 IdKind get kind => IdKind.element;
50 108
51 String toString() => 109 String get name => className != null ? '$className.$memberName' : memberName;
52 className != null ? '$className.$memberName' : memberName; 110
111 String toString() => name;
53 } 112 }
54 113
55 /// Id for a code point with type inference information. 114 /// Id for a code point with type inference information.
56 // TODO(johnniwinther): Create an [NodeId]-based equivalence with the kernel IR. 115 // TODO(johnniwinther): Create an [NodeId]-based equivalence with the kernel IR.
57 class NodeId implements Id { 116 class NodeId implements Id {
58 final int value; 117 final int value;
118 final IdKind kind;
59 119
60 const NodeId(this.value); 120 const NodeId(this.value, this.kind);
61 121
62 int get hashCode => value.hashCode; 122 int get hashCode => value.hashCode * 13 + kind.hashCode * 17;
63 123
64 bool operator ==(other) { 124 bool operator ==(other) {
65 if (identical(this, other)) return true; 125 if (identical(this, other)) return true;
66 if (other is! NodeId) return false; 126 if (other is! NodeId) return false;
67 return value == other.value; 127 return value == other.value && kind == other.kind;
68 } 128 }
69 129
70 IdKind get kind => IdKind.node;
71
72 String toString() => '$kind:$value'; 130 String toString() => '$kind:$value';
73 } 131 }
74 132
75 class ActualData { 133 class ActualData {
76 final Id id; 134 final IdValue value;
77 final String value;
78 final SourceSpan sourceSpan; 135 final SourceSpan sourceSpan;
79 final Object object; 136 final Object object;
80 137
81 ActualData(this.id, this.value, this.sourceSpan, this.object); 138 ActualData(this.value, this.sourceSpan, this.object);
139 }
140
141 abstract class DataRegistry {
142 DiagnosticReporter get reporter;
143 Map<Id, ActualData> get actualMap;
144
145 void registerValue(
146 SourceSpan sourceSpan, Id id, String value, Object object) {
147 if (actualMap.containsKey(id)) {
148 ActualData existingData = actualMap[id];
149 reportHere(reporter, sourceSpan,
150 "Duplicate id ${id}, value=$value, object=$object");
151 reportHere(
152 reporter,
153 sourceSpan,
154 "Duplicate id ${id}, value=${existingData.value}, "
155 "object=${existingData.object}");
156 Expect.fail("Duplicate id $id.");
157 }
158 if (value != null) {
159 actualMap[id] =
160 new ActualData(new IdValue(id, value), sourceSpan, object);
161 }
162 }
82 } 163 }
83 164
84 /// Abstract AST visitor for computing data corresponding to a node or element, 165 /// Abstract AST visitor for computing data corresponding to a node or element,
85 // and record it with a generic [Id]. 166 // and record it with a generic [Id].
86 abstract class AstDataExtractor extends ast.Visitor { 167 abstract class AstDataExtractor extends ast.Visitor with DataRegistry {
87 final DiagnosticReporter reporter; 168 final DiagnosticReporter reporter;
88 final Map<Id, ActualData> actualMap; 169 final Map<Id, ActualData> actualMap;
89 final ResolvedAst resolvedAst; 170 final ResolvedAst resolvedAst;
90 171
91 AstDataExtractor(this.reporter, this.actualMap, this.resolvedAst); 172 AstDataExtractor(this.reporter, this.actualMap, this.resolvedAst);
92 173
93 /// Implement this to compute the data corresponding to [element]. 174 /// Implement this to compute the data corresponding to [element].
94 /// 175 ///
95 /// If `null` is returned, [element] has no associated data. 176 /// If `null` is returned, [element] has no associated data.
96 String computeElementValue(AstElement element); 177 String computeElementValue(Id id, AstElement element);
97 178
98 /// Implement this to compute the data corresponding to [node]. If [node] has 179 /// Implement this to compute the data corresponding to [node]. If [node] has
99 /// a corresponding [AstElement] this is provided in [element]. 180 /// a corresponding [AstElement] this is provided in [element].
100 /// 181 ///
101 /// If `null` is returned, [node] has no associated data. 182 /// If `null` is returned, [node] has no associated data.
102 String computeNodeValue(ast.Node node, AstElement element); 183 String computeNodeValue(Id id, ast.Node node, AstElement element);
103 184
104 TreeElements get elements => resolvedAst.elements; 185 TreeElements get elements => resolvedAst.elements;
105 186
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 }
112
113 ElementId computeElementId(AstElement element) { 187 ElementId computeElementId(AstElement element) {
114 String memberName = element.name; 188 String memberName = element.name;
115 if (element.isSetter) { 189 if (element.isSetter) {
116 memberName += '='; 190 memberName += '=';
117 } 191 }
118 String className = element.enclosingClass?.name; 192 String className = element.enclosingClass?.name;
119 return new ElementId.internal(memberName, className); 193 return new ElementId.internal(memberName, className);
120 } 194 }
121 195
122 NodeId computeAccessId(ast.Send node, AccessSemantics access) { 196 ast.Node computeAccessPosition(ast.Send node, AccessSemantics access) {
123 switch (access.kind) { 197 switch (access.kind) {
124 case AccessKind.DYNAMIC_PROPERTY: 198 case AccessKind.DYNAMIC_PROPERTY:
125 case AccessKind.LOCAL_VARIABLE: 199 case AccessKind.LOCAL_VARIABLE:
126 case AccessKind.FINAL_LOCAL_VARIABLE: 200 case AccessKind.FINAL_LOCAL_VARIABLE:
127 case AccessKind.LOCAL_FUNCTION: 201 case AccessKind.LOCAL_FUNCTION:
128 case AccessKind.PARAMETER: 202 case AccessKind.PARAMETER:
129 case AccessKind.FINAL_PARAMETER: 203 case AccessKind.FINAL_PARAMETER:
130 case AccessKind.EXPRESSION: 204 case AccessKind.EXPRESSION:
131 return computeDefaultNodeId(node.selector); 205 return node.selector;
132 default: 206 default:
133 return null; 207 return null;
134 } 208 }
209 }
210
211 ast.Node computeUpdatePosition(ast.Send node, AccessSemantics access) {
212 switch (access.kind) {
213 case AccessKind.DYNAMIC_PROPERTY:
214 case AccessKind.LOCAL_VARIABLE:
215 case AccessKind.PARAMETER:
216 return node.selector;
217 default:
218 return null;
219 }
135 } 220 }
136 221
137 void computeForElement(AstElement element) { 222 void computeForElement(AstElement element) {
138 ElementId id = computeElementId(element); 223 ElementId id = computeElementId(element);
139 if (id == null) return; 224 if (id == null) return;
140 String value = computeElementValue(element); 225 String value = computeElementValue(id, element);
141 registerValue(element.sourcePosition, id, value, element); 226 registerValue(element.sourcePosition, id, value, element);
142 } 227 }
143 228
144 void computeForNode(ast.Node node, NodeId id, [AstElement element]) { 229 void computeForNode(ast.Node node, NodeId id, [AstElement element]) {
145 if (id == null) return; 230 if (id == null) return;
146 String value = computeNodeValue(node, element); 231 String value = computeNodeValue(id, node, element);
147 SourceSpan sourceSpan = computeSourceSpan(node); 232 SourceSpan sourceSpan = computeSourceSpan(node);
148 registerValue(sourceSpan, id, value, element ?? node); 233 registerValue(sourceSpan, id, value, element ?? node);
149 } 234 }
150 235
151 SourceSpan computeSourceSpan(ast.Node node) { 236 SourceSpan computeSourceSpan(ast.Node node) {
152 return new SourceSpan(resolvedAst.sourceUri, 237 return new SourceSpan(resolvedAst.sourceUri,
153 node.getBeginToken().charOffset, node.getEndToken().charEnd); 238 node.getBeginToken().charOffset, node.getEndToken().charEnd);
154 } 239 }
155 240
156 NodeId computeDefaultNodeId(ast.Node node) { 241 NodeId computeDefaultNodeId(ast.Node node) {
157 return new NodeId(node.getBeginToken().charOffset); 242 return new NodeId(node.getBeginToken().charOffset, IdKind.node);
158 } 243 }
159 244
160 NodeId computeLoopNodeId(ast.Node node) => computeDefaultNodeId(node); 245 NodeId createAccessId(ast.Node node) {
246 return new NodeId(node.getBeginToken().charOffset, IdKind.node);
247 }
161 248
162 NodeId computeGotoNodeId(ast.Node node) => computeDefaultNodeId(node); 249 NodeId createInvokeId(ast.Node node) {
250 return new NodeId(node.getBeginToken().charOffset, IdKind.invoke);
251 }
163 252
164 NodeId computeSwitchNodeId(ast.SwitchStatement node) => 253 NodeId createUpdateId(ast.Node node) {
165 computeDefaultNodeId(node); 254 return new NodeId(node.getBeginToken().charOffset, IdKind.update);
255 }
166 256
167 NodeId computeSwitchCaseNodeId(ast.SwitchCase node) { 257 NodeId createLoopId(ast.Node node) => computeDefaultNodeId(node);
258
259 NodeId createGotoId(ast.Node node) => computeDefaultNodeId(node);
260
261 NodeId createSwitchId(ast.SwitchStatement node) => computeDefaultNodeId(node);
262
263 NodeId createSwitchCaseId(ast.SwitchCase node) {
168 ast.Node position; 264 ast.Node position;
169 for (ast.Node child in node.labelsAndCases) { 265 for (ast.Node child in node.labelsAndCases) {
170 if (child.asCaseMatch() != null) { 266 if (child.asCaseMatch() != null) {
171 ast.CaseMatch caseMatch = child; 267 ast.CaseMatch caseMatch = child;
172 position = caseMatch.expression; 268 position = caseMatch.expression;
173 break; 269 break;
174 } 270 }
175 } 271 }
176 return computeDefaultNodeId(position); 272 return computeDefaultNodeId(position);
177 } 273 }
(...skipping 28 matching lines...) Expand all
206 computeForNode(node, computeDefaultNodeId(node), element); 302 computeForNode(node, computeDefaultNodeId(node), element);
207 } 303 }
208 visitNode(node); 304 visitNode(node);
209 } 305 }
210 306
211 visitSend(ast.Send node) { 307 visitSend(ast.Send node) {
212 dynamic sendStructure = elements.getSendStructure(node); 308 dynamic sendStructure = elements.getSendStructure(node);
213 if (sendStructure != null) { 309 if (sendStructure != null) {
214 switch (sendStructure.kind) { 310 switch (sendStructure.kind) {
215 case SendStructureKind.GET: 311 case SendStructureKind.GET:
312 ast.Node position =
313 computeAccessPosition(node, sendStructure.semantics);
314 if (position != null) {
315 computeForNode(node, computeDefaultNodeId(position));
316 }
317 break;
216 case SendStructureKind.INVOKE: 318 case SendStructureKind.INVOKE:
217 case SendStructureKind.BINARY: 319 case SendStructureKind.BINARY:
218 case SendStructureKind.EQUALS: 320 case SendStructureKind.EQUALS:
219 case SendStructureKind.NOT_EQUALS: 321 case SendStructureKind.NOT_EQUALS:
220 computeForNode(node, computeAccessId(node, sendStructure.semantics)); 322 ast.Node position =
323 computeAccessPosition(node, sendStructure.semantics);
324 if (position != null) {
325 computeForNode(node, createInvokeId(position));
326 }
327 break;
328 case SendStructureKind.SET:
221 break; 329 break;
222 default: 330 default:
223 } 331 }
332 }
333 visitNode(node);
334 }
335
336 visitSendSet(ast.SendSet node) {
337 dynamic sendStructure = elements.getSendStructure(node);
338 if (sendStructure != null) {
339 switch (sendStructure.kind) {
340 case SendStructureKind.SET:
341 ast.Node position =
342 computeUpdatePosition(node, sendStructure.semantics);
343 if (position != null) {
344 computeForNode(node, createUpdateId(position));
345 }
346 break;
347 case SendStructureKind.POSTFIX:
348 computeForNode(node, createAccessId(node.selector));
349 computeForNode(node, createInvokeId(node.assignmentOperator));
350 computeForNode(node, createUpdateId(node.selector));
351 break;
352 default:
353 }
224 } 354 }
225 visitNode(node); 355 visitNode(node);
226 } 356 }
227 357
228 visitLoop(ast.Loop node) { 358 visitLoop(ast.Loop node) {
229 computeForNode(node, computeLoopNodeId(node)); 359 computeForNode(node, createLoopId(node));
230 visitNode(node); 360 visitNode(node);
231 } 361 }
232 362
233 visitGotoStatement(ast.GotoStatement node) { 363 visitGotoStatement(ast.GotoStatement node) {
234 computeForNode(node, computeGotoNodeId(node)); 364 computeForNode(node, createGotoId(node));
235 visitNode(node); 365 visitNode(node);
236 } 366 }
237 367
238 visitSwitchStatement(ast.SwitchStatement node) { 368 visitSwitchStatement(ast.SwitchStatement node) {
239 computeForNode(node, computeSwitchNodeId(node)); 369 computeForNode(node, createSwitchId(node));
240 visitNode(node); 370 visitNode(node);
241 } 371 }
242 372
243 visitSwitchCase(ast.SwitchCase node) { 373 visitSwitchCase(ast.SwitchCase node) {
244 computeForNode(node, computeSwitchCaseNodeId(node)); 374 computeForNode(node, createSwitchCaseId(node));
245 visitNode(node); 375 visitNode(node);
246 } 376 }
247 } 377 }
248 378
249 /// Abstract IR visitor for computing data corresponding to a node or element, 379 /// Abstract IR visitor for computing data corresponding to a node or element,
250 /// and record it with a generic [Id] 380 /// and record it with a generic [Id]
251 abstract class IrDataExtractor extends ir.Visitor { 381 abstract class IrDataExtractor extends ir.Visitor with DataRegistry {
382 final DiagnosticReporter reporter;
252 final Map<Id, ActualData> actualMap; 383 final Map<Id, ActualData> actualMap;
253 384
254 void registerValue(
255 SourceSpan sourceSpan, Id id, String value, Object object) {
256 if (value != null) {
257 actualMap[id] = new ActualData(id, value, sourceSpan, object);
258 }
259 }
260
261 /// Implement this to compute the data corresponding to [member]. 385 /// Implement this to compute the data corresponding to [member].
262 /// 386 ///
263 /// If `null` is returned, [member] has no associated data. 387 /// If `null` is returned, [member] has no associated data.
264 String computeMemberValue(ir.Member member); 388 String computeMemberValue(Id id, ir.Member member);
265 389
266 /// Implement this to compute the data corresponding to [node]. 390 /// Implement this to compute the data corresponding to [node].
267 /// 391 ///
268 /// If `null` is returned, [node] has no associated data. 392 /// If `null` is returned, [node] has no associated data.
269 String computeNodeValue(ir.TreeNode node); 393 String computeNodeValue(Id id, ir.TreeNode node);
270 394
271 IrDataExtractor(this.actualMap); 395 IrDataExtractor(this.reporter, this.actualMap);
272 Id computeElementId(ir.Member node) { 396 Id computeElementId(ir.Member node) {
273 String className; 397 String className;
274 if (node.enclosingClass != null) { 398 if (node.enclosingClass != null) {
275 className = node.enclosingClass.name; 399 className = node.enclosingClass.name;
276 } 400 }
277 String memberName = node.name.name; 401 String memberName = node.name.name;
278 if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) { 402 if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) {
279 memberName += '='; 403 memberName += '=';
280 } 404 }
281 return new ElementId.internal(memberName, className); 405 return new ElementId.internal(memberName, className);
282 } 406 }
283 407
284 void computeForMember(ir.Member member) { 408 void computeForMember(ir.Member member) {
285 ElementId id = computeElementId(member); 409 ElementId id = computeElementId(member);
286 if (id == null) return; 410 if (id == null) return;
287 String value = computeMemberValue(member); 411 String value = computeMemberValue(id, member);
288 registerValue(computeSourceSpan(member), id, value, member); 412 registerValue(computeSourceSpan(member), id, value, member);
289 } 413 }
290 414
291 void computeForNode(ir.TreeNode node, NodeId id) { 415 void computeForNode(ir.TreeNode node, NodeId id) {
292 if (id == null) return; 416 if (id == null) return;
293 String value = computeNodeValue(node); 417 String value = computeNodeValue(id, node);
294 registerValue(computeSourceSpan(node), id, value, node); 418 registerValue(computeSourceSpan(node), id, value, node);
295 } 419 }
296 420
297 SourceSpan computeSourceSpan(ir.TreeNode node) { 421 SourceSpan computeSourceSpan(ir.TreeNode node) {
298 return new SourceSpan( 422 return new SourceSpan(
299 Uri.parse(node.location.file), node.fileOffset, node.fileOffset + 1); 423 Uri.parse(node.location.file), node.fileOffset, node.fileOffset + 1);
300 } 424 }
301 425
302 NodeId computeDefaultNodeId(ir.TreeNode node) { 426 NodeId computeDefaultNodeId(ir.TreeNode node) {
303 assert(node.fileOffset != ir.TreeNode.noOffset); 427 assert(node.fileOffset != ir.TreeNode.noOffset);
304 return new NodeId(node.fileOffset); 428 return new NodeId(node.fileOffset, IdKind.node);
305 } 429 }
306 430
307 NodeId computeLoopNodeId(ir.TreeNode node) => computeDefaultNodeId(node); 431 NodeId createInvokeId(ir.TreeNode node) {
308 NodeId computeGotoNodeId(ir.TreeNode node) => computeDefaultNodeId(node); 432 assert(node.fileOffset != ir.TreeNode.noOffset);
309 NodeId computeSwitchNodeId(ir.SwitchStatement node) => 433 return new NodeId(node.fileOffset, IdKind.invoke);
310 computeDefaultNodeId(node); 434 }
311 NodeId computeSwitchCaseNodeId(ir.SwitchCase node) => 435
312 new NodeId(node.expressionOffsets.first); 436 NodeId createUpdateId(ir.TreeNode node) {
437 assert(node.fileOffset != ir.TreeNode.noOffset);
438 return new NodeId(node.fileOffset, IdKind.update);
439 }
440
441 NodeId createLoopId(ir.TreeNode node) => computeDefaultNodeId(node);
442 NodeId createGotoId(ir.TreeNode node) => computeDefaultNodeId(node);
443 NodeId createSwitchId(ir.SwitchStatement node) => computeDefaultNodeId(node);
444 NodeId createSwitchCaseId(ir.SwitchCase node) =>
445 new NodeId(node.expressionOffsets.first, IdKind.node);
313 446
314 void run(ir.Node root) { 447 void run(ir.Node root) {
315 root.accept(this); 448 root.accept(this);
316 } 449 }
317 450
318 defaultNode(ir.Node node) { 451 defaultNode(ir.Node node) {
319 node.visitChildren(this); 452 node.visitChildren(this);
320 } 453 }
321 454
322 defaultMember(ir.Member node) { 455 defaultMember(ir.Member node) {
323 computeForMember(node); 456 computeForMember(node);
324 super.defaultMember(node); 457 super.defaultMember(node);
325 } 458 }
326 459
327 visitMethodInvocation(ir.MethodInvocation node) { 460 visitMethodInvocation(ir.MethodInvocation node) {
328 computeForNode(node, computeDefaultNodeId(node)); 461 computeForNode(node, createInvokeId(node));
329 super.visitMethodInvocation(node); 462 super.visitMethodInvocation(node);
330 } 463 }
331 464
332 visitPropertyGet(ir.PropertyGet node) { 465 visitPropertyGet(ir.PropertyGet node) {
333 computeForNode(node, computeDefaultNodeId(node)); 466 computeForNode(node, computeDefaultNodeId(node));
334 super.visitPropertyGet(node); 467 super.visitPropertyGet(node);
335 } 468 }
336 469
337 visitVariableDeclaration(ir.VariableDeclaration node) { 470 visitVariableDeclaration(ir.VariableDeclaration node) {
338 computeForNode(node, computeDefaultNodeId(node)); 471 if (node.parent is! ir.FunctionDeclaration) {
472 computeForNode(node, computeDefaultNodeId(node));
473 }
339 super.visitVariableDeclaration(node); 474 super.visitVariableDeclaration(node);
340 } 475 }
341 476
342 visitFunctionDeclaration(ir.FunctionDeclaration node) { 477 visitFunctionDeclaration(ir.FunctionDeclaration node) {
343 computeForNode(node, computeDefaultNodeId(node)); 478 computeForNode(node, computeDefaultNodeId(node));
344 super.visitFunctionDeclaration(node); 479 super.visitFunctionDeclaration(node);
345 } 480 }
346 481
347 visitFunctionExpression(ir.FunctionExpression node) { 482 visitFunctionExpression(ir.FunctionExpression node) {
348 computeForNode(node, computeDefaultNodeId(node)); 483 computeForNode(node, computeDefaultNodeId(node));
349 super.visitFunctionExpression(node); 484 super.visitFunctionExpression(node);
350 } 485 }
351 486
352 visitVariableGet(ir.VariableGet node) { 487 visitVariableGet(ir.VariableGet node) {
353 computeForNode(node, computeDefaultNodeId(node)); 488 computeForNode(node, computeDefaultNodeId(node));
354 super.visitVariableGet(node); 489 super.visitVariableGet(node);
355 } 490 }
356 491
492 visitPropertySet(ir.PropertySet node) {
493 computeForNode(node, createUpdateId(node));
494 super.visitPropertySet(node);
495 }
496
497 visitVariableSet(ir.VariableSet node) {
498 computeForNode(node, createUpdateId(node));
499 super.visitVariableSet(node);
500 }
501
357 visitDoStatement(ir.DoStatement node) { 502 visitDoStatement(ir.DoStatement node) {
358 computeForNode(node, computeLoopNodeId(node)); 503 computeForNode(node, createLoopId(node));
359 super.visitDoStatement(node); 504 super.visitDoStatement(node);
360 } 505 }
361 506
362 visitForStatement(ir.ForStatement node) { 507 visitForStatement(ir.ForStatement node) {
363 computeForNode(node, computeLoopNodeId(node)); 508 computeForNode(node, createLoopId(node));
364 super.visitForStatement(node); 509 super.visitForStatement(node);
365 } 510 }
366 511
367 visitForInStatement(ir.ForInStatement node) { 512 visitForInStatement(ir.ForInStatement node) {
368 computeForNode(node, computeLoopNodeId(node)); 513 computeForNode(node, createLoopId(node));
369 super.visitForInStatement(node); 514 super.visitForInStatement(node);
370 } 515 }
371 516
372 visitWhileStatement(ir.WhileStatement node) { 517 visitWhileStatement(ir.WhileStatement node) {
373 computeForNode(node, computeLoopNodeId(node)); 518 computeForNode(node, createLoopId(node));
374 super.visitWhileStatement(node); 519 super.visitWhileStatement(node);
375 } 520 }
376 521
377 visitBreakStatement(ir.BreakStatement node) { 522 visitBreakStatement(ir.BreakStatement node) {
378 computeForNode(node, computeGotoNodeId(node)); 523 computeForNode(node, createGotoId(node));
379 super.visitBreakStatement(node); 524 super.visitBreakStatement(node);
380 } 525 }
381 526
382 visitSwitchStatement(ir.SwitchStatement node) { 527 visitSwitchStatement(ir.SwitchStatement node) {
383 computeForNode(node, computeSwitchNodeId(node)); 528 computeForNode(node, createSwitchId(node));
384 super.visitSwitchStatement(node); 529 super.visitSwitchStatement(node);
385 } 530 }
386 531
387 visitSwitchCase(ir.SwitchCase node) { 532 visitSwitchCase(ir.SwitchCase node) {
388 computeForNode(node, computeSwitchCaseNodeId(node)); 533 computeForNode(node, createSwitchCaseId(node));
389 super.visitSwitchCase(node); 534 super.visitSwitchCase(node);
390 } 535 }
391 536
392 visitContinueSwitchStatement(ir.ContinueSwitchStatement node) { 537 visitContinueSwitchStatement(ir.ContinueSwitchStatement node) {
393 computeForNode(node, computeGotoNodeId(node)); 538 computeForNode(node, createGotoId(node));
394 super.visitContinueSwitchStatement(node); 539 super.visitContinueSwitchStatement(node);
395 } 540 }
396 } 541 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698