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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1645053002: dart2js cps: Refactor tracking of side effects. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Clarification Created 4 years, 10 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_nodes; 4 library dart2js.ir_nodes;
5 5
6 import 'dart:collection'; 6 import 'dart:collection';
7 import 'cps_fragment.dart' show CpsFragment; 7 import 'cps_fragment.dart' show CpsFragment;
8 import 'cps_ir_nodes_sexpr.dart'; 8 import 'cps_ir_nodes_sexpr.dart';
9 import '../constants/values.dart' as values; 9 import '../constants/values.dart' as values;
10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; 10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
11 import '../elements/elements.dart'; 11 import '../elements/elements.dart';
12 import '../io/source_information.dart' show SourceInformation; 12 import '../io/source_information.dart' show SourceInformation;
13 import '../types/types.dart' show TypeMask; 13 import '../types/types.dart' show TypeMask;
14 import '../universe/selector.dart' show Selector; 14 import '../universe/selector.dart' show Selector;
15 import '../universe/side_effects.dart';
15 16
16 import 'builtin_operator.dart'; 17 import 'builtin_operator.dart';
17 export 'builtin_operator.dart'; 18 export 'builtin_operator.dart';
18 19
20 import 'effects.dart';
21
19 // These imports are only used for the JavaScript specific nodes. If we want to 22 // These imports are only used for the JavaScript specific nodes. If we want to
20 // support more than one native backend, we should probably create better 23 // support more than one native backend, we should probably create better
21 // abstractions for native code and its type and effect system. 24 // abstractions for native code and its type and effect system.
22 import '../js/js.dart' as js show Template, isNullGuardOnFirstArgument; 25 import '../js/js.dart' as js show Template, isNullGuardOnFirstArgument;
23 import '../native/native.dart' as native show NativeBehavior; 26 import '../native/native.dart' as native show NativeBehavior;
24 27
25 abstract class Node { 28 abstract class Node {
26 /// A pointer to the parent node. Is null until set by optimization passes. 29 /// A pointer to the parent node. Is null until set by optimization passes.
27 Node parent; 30 Node parent;
28 31
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 238
236 /// A named value. 239 /// A named value.
237 /// 240 ///
238 /// The identity of the [Primitive] object is the name of the value. 241 /// The identity of the [Primitive] object is the name of the value.
239 /// The subclass describes how to compute the value. 242 /// The subclass describes how to compute the value.
240 /// 243 ///
241 /// All primitives except [Parameter] must be bound by a [LetPrim]. 244 /// All primitives except [Parameter] must be bound by a [LetPrim].
242 abstract class Primitive extends Variable<Primitive> { 245 abstract class Primitive extends Variable<Primitive> {
243 Primitive() : super(null); 246 Primitive() : super(null);
244 247
248 int get effectFlags => Effects.none;
Siggi Cherem (dart-lang) 2016/02/17 20:53:23 + dartdoc Also, low-priority but, what do you thi
asgerf 2016/02/29 12:48:17 Done.
249
245 /// True if this primitive has a value that can be used by other expressions. 250 /// True if this primitive has a value that can be used by other expressions.
246 bool get hasValue; 251 bool get hasValue;
247 252
248 /// True if the primitive can be removed, assuming it has no uses 253 /// True if the primitive can be removed, assuming it has no uses
249 /// (this getter does not check if there are any uses). 254 /// (this getter does not check if there are any uses).
250 /// 255 ///
251 /// False must be returned for primitives that may throw, diverge, or have 256 /// False must be returned for primitives that may throw, diverge, or have
252 /// observable side-effects. 257 /// observable side-effects.
253 bool get isSafeForElimination; 258 bool get isSafeForElimination;
254 259
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 replaceUsesWith(newPrimitive); 343 replaceUsesWith(newPrimitive);
339 destroy(); 344 destroy();
340 LetPrim let = parent; 345 LetPrim let = parent;
341 fragment.insertBelow(let); 346 fragment.insertBelow(let);
342 let.remove(); 347 let.remove();
343 } 348 }
344 } 349 }
345 350
346 /// A primitive that is generally not safe for elimination, but may be marked 351 /// A primitive that is generally not safe for elimination, but may be marked
347 /// as safe by type propagation 352 /// as safe by type propagation
348 //
349 // TODO(asgerf): Store the flag in a bitmask in [Primitive] and get rid of this
350 // class.
351 abstract class UnsafePrimitive extends Primitive { 353 abstract class UnsafePrimitive extends Primitive {
354 int effectFlags = Effects.all;
352 bool isSafeForElimination = false; 355 bool isSafeForElimination = false;
353 bool isSafeForReordering = false; 356 bool isSafeForReordering = false;
354 } 357 }
355 358
356 /// Operands to invocations and primitives are always variables. They point to 359 /// Operands to invocations and primitives are always variables. They point to
357 /// their definition and are doubly-linked into a list of occurrences. 360 /// their definition and are doubly-linked into a list of occurrences.
358 class Reference<T extends Definition<T>> { 361 class Reference<T extends Definition<T>> {
359 T definition; 362 T definition;
360 Reference<T> previous; 363 Reference<T> previous;
361 Reference<T> next; 364 Reference<T> next;
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this); 1079 accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this);
1077 1080
1078 bool get hasValue => true; 1081 bool get hasValue => true;
1079 bool get isSafeForElimination => false; 1082 bool get isSafeForElimination => false;
1080 bool get isSafeForReordering => false; 1083 bool get isSafeForReordering => false;
1081 1084
1082 void setParentPointers() { 1085 void setParentPointers() {
1083 receiver.parent = this; 1086 receiver.parent = this;
1084 _setParentsOnList(arguments, this); 1087 _setParentsOnList(arguments, this);
1085 } 1088 }
1089
1090 int get effectFlags => getEffectsOfBuiltinMethod(method);
1086 } 1091 }
1087 1092
1088 /// Throw a value. 1093 /// Throw a value.
1089 /// 1094 ///
1090 /// Throw is an expression, i.e., it always occurs in tail position with 1095 /// Throw is an expression, i.e., it always occurs in tail position with
1091 /// respect to a body or expression. 1096 /// respect to a body or expression.
1092 class Throw extends TailExpression { 1097 class Throw extends TailExpression {
1093 Reference<Primitive> value; 1098 Reference<Primitive> value;
1094 1099
1095 Throw(Primitive value) : value = new Reference<Primitive>(value); 1100 Throw(Primitive value) : value = new Reference<Primitive>(value);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 accept(Visitor visitor) => visitor.visitSetField(this); 1276 accept(Visitor visitor) => visitor.visitSetField(this);
1272 1277
1273 bool get hasValue => false; 1278 bool get hasValue => false;
1274 bool get isSafeForElimination => false; 1279 bool get isSafeForElimination => false;
1275 bool get isSafeForReordering => false; 1280 bool get isSafeForReordering => false;
1276 1281
1277 void setParentPointers() { 1282 void setParentPointers() {
1278 object.parent = this; 1283 object.parent = this;
1279 value.parent = this; 1284 value.parent = this;
1280 } 1285 }
1286
1287 int get effectFlags => Effects.changesInstanceField;
1281 } 1288 }
1282 1289
1283 /// Directly reads from a field on a given object. 1290 /// Directly reads from a field on a given object.
1284 /// 1291 ///
1285 /// The [object] must either be `null` or an object that has [field]. 1292 /// The [object] must either be `null` or an object that has [field].
1286 class GetField extends Primitive { 1293 class GetField extends Primitive {
1287 final Reference<Primitive> object; 1294 final Reference<Primitive> object;
1288 FieldElement field; 1295 FieldElement field;
1296 bool isFinal = false;
Siggi Cherem (dart-lang) 2016/02/17 20:53:23 +dartdoc
asgerf 2016/02/29 12:48:17 Done.
1289 1297
1290 /// True if the object is known not to be null. 1298 /// True if the object is known not to be null.
1291 // TODO(asgerf): This is a placeholder until we agree on how to track 1299 // TODO(asgerf): This is a placeholder until we agree on how to track
1292 // side effects. 1300 // side effects.
1293 bool objectIsNotNull = false; 1301 bool objectIsNotNull = false;
1294 1302
1295 GetField(Primitive object, this.field) 1303 GetField(Primitive object, this.field)
1296 : this.object = new Reference<Primitive>(object); 1304 : this.object = new Reference<Primitive>(object);
1297 1305
1298 accept(Visitor visitor) => visitor.visitGetField(this); 1306 accept(Visitor visitor) => visitor.visitGetField(this);
1299 1307
1300 bool get hasValue => true; 1308 bool get hasValue => true;
1301 bool get isSafeForElimination => objectIsNotNull; 1309 bool get isSafeForElimination => objectIsNotNull;
1302 bool get isSafeForReordering => false; 1310 bool get isSafeForReordering => false;
1303 1311
1304 toString() => 'GetField($field)'; 1312 toString() => 'GetField($field)';
1305 1313
1306 void setParentPointers() { 1314 void setParentPointers() {
1307 object.parent = this; 1315 object.parent = this;
1308 } 1316 }
1317
1318 int get effectFlags => isFinal ? 0 : Effects.dependsOnInstanceField;
1309 } 1319 }
1310 1320
1311 /// Get the length of a string or native list. 1321 /// Get the length of a string or native list.
1312 class GetLength extends Primitive { 1322 class GetLength extends Primitive {
1313 final Reference<Primitive> object; 1323 final Reference<Primitive> object;
1324 bool isFinal = false;
1314 1325
1315 /// True if the object is known not to be null. 1326 /// True if the object is known not to be null.
1316 bool objectIsNotNull = false; 1327 bool objectIsNotNull = false;
1317 1328
1318 GetLength(Primitive object) : this.object = new Reference<Primitive>(object); 1329 GetLength(Primitive object) : this.object = new Reference<Primitive>(object);
1319 1330
1320 bool get hasValue => true; 1331 bool get hasValue => true;
1321 bool get isSafeForElimination => objectIsNotNull; 1332 bool get isSafeForElimination => objectIsNotNull;
1322 bool get isSafeForReordering => false; 1333 bool get isSafeForReordering => false;
1323 1334
1324 accept(Visitor v) => v.visitGetLength(this); 1335 accept(Visitor v) => v.visitGetLength(this);
1325 1336
1326 void setParentPointers() { 1337 void setParentPointers() {
1327 object.parent = this; 1338 object.parent = this;
1328 } 1339 }
1340
1341 int get effectFlags => isFinal ? 0 : Effects.dependsOnIndexableLength;
1329 } 1342 }
1330 1343
1331 /// Read an entry from an indexable object. 1344 /// Read an entry from an indexable object.
1332 /// 1345 ///
1333 /// [object] must be null or an indexable object, and [index] must be 1346 /// [object] must be null or an indexable object, and [index] must be
1334 /// an integer where `0 <= index < object.length`. 1347 /// an integer where `0 <= index < object.length`.
1335 class GetIndex extends Primitive { 1348 class GetIndex extends Primitive {
1336 final Reference<Primitive> object; 1349 final Reference<Primitive> object;
1337 final Reference<Primitive> index; 1350 final Reference<Primitive> index;
1338 1351
1339 /// True if the object is known not to be null. 1352 /// True if the object is known not to be null.
1340 bool objectIsNotNull = false; 1353 bool objectIsNotNull = false;
1341 1354
1342 GetIndex(Primitive object, Primitive index) 1355 GetIndex(Primitive object, Primitive index)
1343 : this.object = new Reference<Primitive>(object), 1356 : this.object = new Reference<Primitive>(object),
1344 this.index = new Reference<Primitive>(index); 1357 this.index = new Reference<Primitive>(index);
1345 1358
1346 bool get hasValue => true; 1359 bool get hasValue => true;
1347 bool get isSafeForElimination => objectIsNotNull; 1360 bool get isSafeForElimination => objectIsNotNull;
1348 bool get isSafeForReordering => false; 1361 bool get isSafeForReordering => false;
1349 1362
1350 accept(Visitor v) => v.visitGetIndex(this); 1363 accept(Visitor v) => v.visitGetIndex(this);
1351 1364
1352 void setParentPointers() { 1365 void setParentPointers() {
1353 object.parent = this; 1366 object.parent = this;
1354 index.parent = this; 1367 index.parent = this;
1355 } 1368 }
1369
1370 int get effectFlags => Effects.dependsOnIndexableContent;
1356 } 1371 }
1357 1372
1358 /// Set an entry on a native list. 1373 /// Set an entry on a native list.
1359 /// 1374 ///
1360 /// [object] must be null or a native list, and [index] must be an integer. 1375 /// [object] must be null or a native list, and [index] must be an integer
1376 /// within the bounds of the indexable object.
1377 ///
1378 /// [SetIndex] may not be used to alter the length of a JS array.
1361 /// 1379 ///
1362 /// The primitive itself has no value and may not be referenced. 1380 /// The primitive itself has no value and may not be referenced.
1363 class SetIndex extends Primitive { 1381 class SetIndex extends Primitive {
1364 final Reference<Primitive> object; 1382 final Reference<Primitive> object;
1365 final Reference<Primitive> index; 1383 final Reference<Primitive> index;
1366 final Reference<Primitive> value; 1384 final Reference<Primitive> value;
1367 1385
1368 SetIndex(Primitive object, Primitive index, Primitive value) 1386 SetIndex(Primitive object, Primitive index, Primitive value)
1369 : this.object = new Reference<Primitive>(object), 1387 : this.object = new Reference<Primitive>(object),
1370 this.index = new Reference<Primitive>(index), 1388 this.index = new Reference<Primitive>(index),
1371 this.value = new Reference<Primitive>(value); 1389 this.value = new Reference<Primitive>(value);
1372 1390
1373 bool get hasValue => false; 1391 bool get hasValue => false;
1374 bool get isSafeForElimination => false; 1392 bool get isSafeForElimination => false;
1375 bool get isSafeForReordering => false; 1393 bool get isSafeForReordering => false;
1376 1394
1377 accept(Visitor v) => v.visitSetIndex(this); 1395 accept(Visitor v) => v.visitSetIndex(this);
1378 1396
1379 void setParentPointers() { 1397 void setParentPointers() {
1380 object.parent = this; 1398 object.parent = this;
1381 index.parent = this; 1399 index.parent = this;
1382 value.parent = this; 1400 value.parent = this;
1383 } 1401 }
1402
1403 int get effectFlags => Effects.changesIndexableContent;
1384 } 1404 }
1385 1405
1386 /// Reads the value of a static field or tears off a static method. 1406 /// Reads the value of a static field or tears off a static method.
1387 /// 1407 ///
1388 /// If [GetStatic] is used to load a lazily initialized static field, it must 1408 /// If [GetStatic] is used to load a lazily initialized static field, it must
1389 /// have been initialized beforehand, and a [witness] must be set to restrict 1409 /// have been initialized beforehand, and a [witness] must be set to restrict
1390 /// code motion. 1410 /// code motion.
1391 class GetStatic extends Primitive { 1411 class GetStatic extends Primitive {
1392 /// Can be [FieldElement] or [FunctionElement]. 1412 /// Can be [FieldElement] or [FunctionElement].
1393 final Element element; 1413 final Element element;
1394 final SourceInformation sourceInformation; 1414 final SourceInformation sourceInformation;
1415 bool isFinal = false;
1395 1416
1396 /// If reading a lazily initialized field, [witness] must refer to a node 1417 /// If reading a lazily initialized field, [witness] must refer to a node
1397 /// that initializes the field or always occurs after the field initializer. 1418 /// that initializes the field or always occurs after the field initializer.
1398 /// 1419 ///
1399 /// The value of the witness is not used. 1420 /// The value of the witness is not used.
1400 Reference<Primitive> witness; 1421 Reference<Primitive> witness;
1401 1422
1402 GetStatic(this.element, [this.sourceInformation]); 1423 GetStatic(this.element, [this.sourceInformation]);
1403 1424
1404 /// Read a lazily initialized static field that is known to have been 1425 /// Read a lazily initialized static field that is known to have been
1405 /// initialized by [witness] or earlier. 1426 /// initialized by [witness] or earlier.
1406 GetStatic.witnessed(this.element, Primitive witness, [this.sourceInformation]) 1427 GetStatic.witnessed(this.element, Primitive witness, [this.sourceInformation])
1407 : witness = witness == null ? null : new Reference<Primitive>(witness); 1428 : witness = witness == null ? null : new Reference<Primitive>(witness);
1408 1429
1409 accept(Visitor visitor) => visitor.visitGetStatic(this); 1430 accept(Visitor visitor) => visitor.visitGetStatic(this);
1410 1431
1411 bool get hasValue => true; 1432 bool get hasValue => true;
1412 bool get isSafeForElimination => true; 1433 bool get isSafeForElimination => true;
1413 bool get isSafeForReordering { 1434 bool get isSafeForReordering => isFinal;
1414 return element is FunctionElement || element.isFinal;
1415 }
1416 1435
1417 void setParentPointers() { 1436 void setParentPointers() {
1418 if (witness != null) { 1437 if (witness != null) {
1419 witness.parent = this; 1438 witness.parent = this;
1420 } 1439 }
1421 } 1440 }
1441
1442 int get effectFlags => isFinal ? 0 : Effects.dependsOnStaticField;
1422 } 1443 }
1423 1444
1424 /// Sets the value of a static field. 1445 /// Sets the value of a static field.
1425 class SetStatic extends Primitive { 1446 class SetStatic extends Primitive {
1426 final FieldElement element; 1447 final FieldElement element;
1427 final Reference<Primitive> value; 1448 final Reference<Primitive> value;
1428 final SourceInformation sourceInformation; 1449 final SourceInformation sourceInformation;
1429 1450
1430 SetStatic(this.element, Primitive value, [this.sourceInformation]) 1451 SetStatic(this.element, Primitive value, [this.sourceInformation])
1431 : this.value = new Reference<Primitive>(value); 1452 : this.value = new Reference<Primitive>(value);
1432 1453
1433 accept(Visitor visitor) => visitor.visitSetStatic(this); 1454 accept(Visitor visitor) => visitor.visitSetStatic(this);
1434 1455
1435 bool get hasValue => false; 1456 bool get hasValue => false;
1436 bool get isSafeForElimination => false; 1457 bool get isSafeForElimination => false;
1437 bool get isSafeForReordering => false; 1458 bool get isSafeForReordering => false;
1438 1459
1439 void setParentPointers() { 1460 void setParentPointers() {
1440 value.parent = this; 1461 value.parent = this;
1441 } 1462 }
1463
1464 int get effectFlags => Effects.changesStaticField;
1442 } 1465 }
1443 1466
1444 /// Reads the value of a lazily initialized static field. 1467 /// Reads the value of a lazily initialized static field.
1445 /// 1468 ///
1446 /// If the field has not yet been initialized, its initializer is evaluated 1469 /// If the field has not yet been initialized, its initializer is evaluated
1447 /// and assigned to the field. 1470 /// and assigned to the field.
1448 class GetLazyStatic extends UnsafePrimitive { 1471 class GetLazyStatic extends UnsafePrimitive {
1449 final FieldElement element; 1472 final FieldElement element;
1450 final SourceInformation sourceInformation; 1473 final SourceInformation sourceInformation;
1474 bool isFinal = false;
1451 1475
1452 GetLazyStatic(this.element, [this.sourceInformation]); 1476 GetLazyStatic(this.element, [this.sourceInformation]);
1453 1477
1454 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); 1478 accept(Visitor visitor) => visitor.visitGetLazyStatic(this);
1455 1479
1456 bool get hasValue => true; 1480 bool get hasValue => true;
1457 1481
1458 void setParentPointers() {} 1482 void setParentPointers() {}
1483
1484 // TODO(asgerf): Track side effects of lazy field initializers.
1485 int get effectFlags => Effects.all;
1459 } 1486 }
1460 1487
1461 /// Creates an object for holding boxed variables captured by a closure. 1488 /// Creates an object for holding boxed variables captured by a closure.
1462 class CreateBox extends Primitive { 1489 class CreateBox extends Primitive {
1463 accept(Visitor visitor) => visitor.visitCreateBox(this); 1490 accept(Visitor visitor) => visitor.visitCreateBox(this);
1464 1491
1465 bool get hasValue => true; 1492 bool get hasValue => true;
1466 bool get isSafeForElimination => true; 1493 bool get isSafeForElimination => true;
1467 bool get isSafeForReordering => true; 1494 bool get isSafeForReordering => true;
1468 1495
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 1595
1569 class ForeignCode extends UnsafePrimitive { 1596 class ForeignCode extends UnsafePrimitive {
1570 final js.Template codeTemplate; 1597 final js.Template codeTemplate;
1571 final TypeMask storedType; 1598 final TypeMask storedType;
1572 final List<Reference<Primitive>> arguments; 1599 final List<Reference<Primitive>> arguments;
1573 final native.NativeBehavior nativeBehavior; 1600 final native.NativeBehavior nativeBehavior;
1574 final FunctionElement dependency; 1601 final FunctionElement dependency;
1575 1602
1576 ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments, 1603 ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments,
1577 this.nativeBehavior, {this.dependency}) 1604 this.nativeBehavior, {this.dependency})
1578 : this.arguments = _referenceList(arguments); 1605 : this.arguments = _referenceList(arguments) {
1606 effectFlags = Effects.from(nativeBehavior.sideEffects);
1607 }
1579 1608
1580 accept(Visitor visitor) => visitor.visitForeignCode(this); 1609 accept(Visitor visitor) => visitor.visitForeignCode(this);
1581 1610
1582 bool get hasValue => true; 1611 bool get hasValue => true;
1583 1612
1584 void setParentPointers() { 1613 void setParentPointers() {
1585 _setParentsOnList(arguments, this); 1614 _setParentsOnList(arguments, this);
1586 } 1615 }
1587 1616
1588 bool isNullGuardOnNullFirstArgument() { 1617 bool isNullGuardOnNullFirstArgument() {
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
2557 Variable originalVariable = original; 2586 Variable originalVariable = original;
2558 copy.type = originalVariable.type; 2587 copy.type = originalVariable.type;
2559 copy.hint = originalVariable.hint; 2588 copy.hint = originalVariable.hint;
2560 } 2589 }
2561 return _copies[original] = copy; 2590 return _copies[original] = copy;
2562 } 2591 }
2563 2592
2564 /// Get the copy of a [Reference]'s definition from the map. 2593 /// Get the copy of a [Reference]'s definition from the map.
2565 Definition getCopy(Reference reference) => _copies[reference.definition]; 2594 Definition getCopy(Reference reference) => _copies[reference.definition];
2566 2595
2596 /// Get the copy of a [Reference]'s definition from the map.
2597 Definition getCopyOrNull(Reference reference) => reference == null
2598 ? null
2599 : getCopy(reference);
2600
2567 /// Map a list of [Reference]s to the list of their definition's copies. 2601 /// Map a list of [Reference]s to the list of their definition's copies.
2568 List<Definition> getList(List<Reference> list) => list.map(getCopy).toList(); 2602 List<Definition> getList(List<Reference> list) => list.map(getCopy).toList();
2569 2603
2570 /// Copy a non-[Continuation] [Definition]. 2604 /// Copy a non-[Continuation] [Definition].
2571 Definition copy(Definition node) { 2605 Definition copy(Definition node) {
2572 assert (node is! Continuation); 2606 assert (node is! Continuation);
2573 return putCopy(node, visit(node)); 2607 return putCopy(node, visit(node));
2574 } 2608 }
2575 2609
2576 Definition visit(Node node) => node.accept(this); 2610 Definition visit(Node node) => node.accept(this);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2626 Definition visitSetStatic(SetStatic node) { 2660 Definition visitSetStatic(SetStatic node) {
2627 return new SetStatic(node.element, getCopy(node.value), 2661 return new SetStatic(node.element, getCopy(node.value),
2628 node.sourceInformation); 2662 node.sourceInformation);
2629 } 2663 }
2630 2664
2631 Definition visitSetField(SetField node) { 2665 Definition visitSetField(SetField node) {
2632 return new SetField(getCopy(node.object), node.field, getCopy(node.value)); 2666 return new SetField(getCopy(node.object), node.field, getCopy(node.value));
2633 } 2667 }
2634 2668
2635 Definition visitGetLazyStatic(GetLazyStatic node) { 2669 Definition visitGetLazyStatic(GetLazyStatic node) {
2636 return new GetLazyStatic(node.element, node.sourceInformation); 2670 return new GetLazyStatic(node.element, node.sourceInformation)
2671 ..isFinal = node.isFinal;
2637 } 2672 }
2638 2673
2639 Definition visitAwait(Await node) { 2674 Definition visitAwait(Await node) {
2640 return new Await(getCopy(node.input)); 2675 return new Await(getCopy(node.input));
2641 } 2676 }
2642 2677
2643 Definition visitYield(Yield node) { 2678 Definition visitYield(Yield node) {
2644 return new Yield(getCopy(node.input), node.hasStar); 2679 return new Yield(getCopy(node.input), node.hasStar);
2645 } 2680 }
2646 2681
(...skipping 12 matching lines...) Expand all
2659 2694
2660 Definition visitParameter(Parameter node) { 2695 Definition visitParameter(Parameter node) {
2661 return new Parameter(node.hint); 2696 return new Parameter(node.hint);
2662 } 2697 }
2663 2698
2664 Definition visitMutableVariable(MutableVariable node) { 2699 Definition visitMutableVariable(MutableVariable node) {
2665 return new MutableVariable(node.hint); 2700 return new MutableVariable(node.hint);
2666 } 2701 }
2667 2702
2668 Definition visitGetStatic(GetStatic node) { 2703 Definition visitGetStatic(GetStatic node) {
2669 return new GetStatic(node.element, node.sourceInformation); 2704 if (node.witness != null) {
2705 return new GetStatic.witnessed(node.element,
2706 getCopy(node.witness),
2707 node.sourceInformation);
2708 } else {
2709 return new GetStatic(node.element, node.sourceInformation);
2710 }
2670 } 2711 }
2671 2712
2672 Definition visitInterceptor(Interceptor node) { 2713 Definition visitInterceptor(Interceptor node) {
2673 return new Interceptor(getCopy(node.input), node.sourceInformation) 2714 return new Interceptor(getCopy(node.input), node.sourceInformation)
2674 ..interceptedClasses.addAll(node.interceptedClasses); 2715 ..interceptedClasses.addAll(node.interceptedClasses);
2675 } 2716 }
2676 2717
2677 Definition visitCreateInstance(CreateInstance node) { 2718 Definition visitCreateInstance(CreateInstance node) {
2678 return new CreateInstance( 2719 return new CreateInstance(
2679 node.classElement, 2720 node.classElement,
2680 getList(node.arguments), 2721 getList(node.arguments),
2681 node.typeInformation == null ? null : getCopy(node.typeInformation), 2722 node.typeInformation == null ? null : getCopy(node.typeInformation),
2682 node.sourceInformation); 2723 node.sourceInformation);
2683 } 2724 }
2684 2725
2685 Definition visitGetField(GetField node) { 2726 Definition visitGetField(GetField node) {
2686 return new GetField(getCopy(node.object), node.field); 2727 return new GetField(getCopy(node.object), node.field)
2728 ..isFinal = node.isFinal;
2687 } 2729 }
2688 2730
2689 Definition visitCreateBox(CreateBox node) { 2731 Definition visitCreateBox(CreateBox node) {
2690 return new CreateBox(); 2732 return new CreateBox();
2691 } 2733 }
2692 2734
2693 Definition visitReifyRuntimeType(ReifyRuntimeType node) { 2735 Definition visitReifyRuntimeType(ReifyRuntimeType node) {
2694 return new ReifyRuntimeType(getCopy(node.value), node.sourceInformation); 2736 return new ReifyRuntimeType(getCopy(node.value), node.sourceInformation);
2695 } 2737 }
2696 2738
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2745 Definition visitRefinement(Refinement node) { 2787 Definition visitRefinement(Refinement node) {
2746 return new Refinement(getCopy(node.value), node.refineType); 2788 return new Refinement(getCopy(node.value), node.refineType);
2747 } 2789 }
2748 2790
2749 Definition visitBoundsCheck(BoundsCheck node) { 2791 Definition visitBoundsCheck(BoundsCheck node) {
2750 if (node.hasNoChecks) { 2792 if (node.hasNoChecks) {
2751 return new BoundsCheck.noCheck(getCopy(node.object), 2793 return new BoundsCheck.noCheck(getCopy(node.object),
2752 node.sourceInformation); 2794 node.sourceInformation);
2753 } else { 2795 } else {
2754 return new BoundsCheck(getCopy(node.object), getCopy(node.index), 2796 return new BoundsCheck(getCopy(node.object), getCopy(node.index),
2755 node.length == null ? null : getCopy(node.length), 2797 getCopyOrNull(node.length),
2756 node.checks, 2798 node.checks,
2757 node.sourceInformation); 2799 node.sourceInformation);
2758 } 2800 }
2759 } 2801 }
2760 2802
2761 Definition visitNullCheck(NullCheck node) { 2803 Definition visitNullCheck(NullCheck node) {
2762 return new NullCheck(getCopy(node.value), node.sourceInformation, 2804 return new NullCheck(getCopy(node.value), node.sourceInformation,
2763 condition: node.condition == null ? null : getCopy(node.condition), 2805 condition: getCopyOrNull(node.condition),
2764 selector: node.selector, 2806 selector: node.selector,
2765 useSelector: node.useSelector); 2807 useSelector: node.useSelector);
2766 } 2808 }
2767 2809
2768 Definition visitForeignCode(ForeignCode node) { 2810 Definition visitForeignCode(ForeignCode node) {
2769 return new ForeignCode(node.codeTemplate, node.storedType, 2811 return new ForeignCode(node.codeTemplate, node.storedType,
2770 getList(node.arguments), 2812 getList(node.arguments),
2771 node.nativeBehavior, 2813 node.nativeBehavior,
2772 dependency: node.dependency); 2814 dependency: node.dependency);
2773 } 2815 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2906 plug(new Branch.loose(_definitions.getCopy(node.condition), 2948 plug(new Branch.loose(_definitions.getCopy(node.condition),
2907 _copies[node.trueContinuation.definition], 2949 _copies[node.trueContinuation.definition],
2908 _copies[node.falseContinuation.definition]) 2950 _copies[node.falseContinuation.definition])
2909 ..isStrictCheck = node.isStrictCheck); 2951 ..isStrictCheck = node.isStrictCheck);
2910 } 2952 }
2911 2953
2912 visitUnreachable(Unreachable node) { 2954 visitUnreachable(Unreachable node) {
2913 plug(new Unreachable()); 2955 plug(new Unreachable());
2914 } 2956 }
2915 } 2957 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698