Handle used postfix and (used) prefix in inferrer

Change-Id: Ia8befd70a937aeb4a8f0f32f98b28f0e6ec39f73
Reviewed-on: https://dart-review.googlesource.com/3886
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Johnni Winther
2017-09-07 13:42:09 +02:00
committed by commit-bot@chromium.org
parent 6c81e20c83
commit 54b57079a3
5 changed files with 58 additions and 6 deletions
@@ -322,4 +322,10 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
receiverType, _analyzedMember, arguments, _sideEffects,
inLoop: inLoop, isConditional: false);
}
@override
TypeInformation visitLet(ir.Let node) {
visit(node.variable);
return visit(node.body);
}
}
@@ -345,7 +345,9 @@ abstract class AstDataExtractor extends ast.Visitor with DataRegistry {
computeForNode(node, createUpdateId(position));
}
break;
case SendStructureKind.PREFIX:
case SendStructureKind.POSTFIX:
case SendStructureKind.COMPOUND:
computeForNode(node, createAccessId(node.selector));
computeForNode(node, createInvokeId(node.assignmentOperator));
computeForNode(node, createUpdateId(node.selector));
@@ -425,17 +427,20 @@ abstract class IrDataExtractor extends ir.Visitor with DataRegistry {
}
NodeId computeDefaultNodeId(ir.TreeNode node) {
assert(node.fileOffset != ir.TreeNode.noOffset);
assert(node.fileOffset != ir.TreeNode.noOffset,
"No fileOffset on $node (${node.runtimeType})");
return new NodeId(node.fileOffset, IdKind.node);
}
NodeId createInvokeId(ir.TreeNode node) {
assert(node.fileOffset != ir.TreeNode.noOffset);
assert(node.fileOffset != ir.TreeNode.noOffset,
"No fileOffset on ${node} (${node.runtimeType})");
return new NodeId(node.fileOffset, IdKind.invoke);
}
NodeId createUpdateId(ir.TreeNode node) {
assert(node.fileOffset != ir.TreeNode.noOffset);
assert(node.fileOffset != ir.TreeNode.noOffset,
"No fileOffset on ${node} (${node.runtimeType})");
return new NodeId(node.fileOffset, IdKind.update);
}
@@ -469,7 +474,8 @@ abstract class IrDataExtractor extends ir.Visitor with DataRegistry {
}
visitVariableDeclaration(ir.VariableDeclaration node) {
if (node.parent is! ir.FunctionDeclaration) {
if (node.name != null && node.parent is! ir.FunctionDeclaration) {
// Skip synthetic variables and function declaration variables.
computeForNode(node, computeDefaultNodeId(node));
}
super.visitVariableDeclaration(node);
@@ -486,7 +492,10 @@ abstract class IrDataExtractor extends ir.Visitor with DataRegistry {
}
visitVariableGet(ir.VariableGet node) {
computeForNode(node, computeDefaultNodeId(node));
if (node.variable.name != null) {
// Skip use of synthetic variables.
computeForNode(node, computeDefaultNodeId(node));
}
super.visitVariableGet(node);
}
@@ -496,7 +505,10 @@ abstract class IrDataExtractor extends ir.Visitor with DataRegistry {
}
visitVariableSet(ir.VariableSet node) {
computeForNode(node, createUpdateId(node));
if (node.variable.name != null) {
// Skip use of synthetic variables.
computeForNode(node, createUpdateId(node));
}
super.visitVariableSet(node);
}
@@ -292,6 +292,8 @@ Map<Id, IdValue> computeExpectedMap(AnnotatedCode code) {
Map<Id, IdValue> map = <Id, IdValue>{};
for (Annotation annotation in code.annotations) {
IdValue idValue = IdValue.decode(annotation.offset, annotation.text);
Expect.isFalse(map.containsKey(idValue.id),
"Duplicate annotations for ${idValue.id}.");
map[idValue.id] = idValue;
}
return map;
@@ -182,7 +182,9 @@ class ResolvedAstComputer extends AstDataExtractor with ComputerMixin {
String dynamicName = getDynamicName();
if (dynamicName != null) return computeSetName(dynamicName);
break;
case SendStructureKind.PREFIX:
case SendStructureKind.POSTFIX:
case SendStructureKind.COMPOUND:
String dynamicName = getDynamicName();
if (dynamicName != null) {
if (id.kind == IdKind.update) {
@@ -9,6 +9,10 @@ main() {
updatedLocal();
invokeLocal();
postfixLocal();
postfixLocalUsed();
prefixLocal();
prefixLocalUsed();
complexAssignmentLocal();
}
/*element: uninitializedLocal:[null]*/
@@ -44,3 +48,29 @@ postfixLocal() {
local2 /*invoke: [exact=JSUInt31]*/ ++;
return null;
}
/*element: postfixLocalUsed:[exact=JSUInt31]*/
postfixLocalUsed() {
var local2 = 0;
return local2 /*invoke: [exact=JSUInt31]*/ ++;
}
/*element: prefixLocal:[null]*/
prefixLocal() {
// ignore: UNUSED_LOCAL_VARIABLE
var local2 = 0;
/*invoke: [exact=JSUInt31]*/ ++local2;
return null;
}
/*element: prefixLocalUsed:[subclass=JSUInt32]*/
prefixLocalUsed() {
var local2 = 0;
return /*invoke: [exact=JSUInt31]*/ ++local2;
}
/*element: complexAssignmentLocal:[subclass=JSUInt32]*/
complexAssignmentLocal() {
var local2 = 0;
return local2 /*invoke: [exact=JSUInt31]*/ += 42;
}