From 6e2fd76f537fd632a38111e5f7ebe5a8ac0b12dd Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 14 Apr 2011 21:13:49 +0400 Subject: [PATCH] ArrayAccess supported in CF --- .../jet/lang/cfg/JetControlFlowBuilder.java | 4 +- .../cfg/JetControlFlowBuilderAdapter.java | 8 +- .../jet/lang/cfg/JetControlFlowProcessor.java | 83 ++++++++++++++----- .../JetControlFlowInstructionsGenerator.java | 4 +- .../JetDelegatorByExpressionSpecifier.java | 6 ++ .../jet/lang/types/JetTypeInferrer.java | 2 +- idea/testData/cfg/ArrayAccess.instructions | 28 +++++++ idea/testData/cfg/ArrayAccess.jet | 7 ++ 8 files changed, 111 insertions(+), 31 deletions(-) create mode 100644 idea/testData/cfg/ArrayAccess.instructions create mode 100644 idea/testData/cfg/ArrayAccess.jet diff --git a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java index ec47c88c071..f60d03d93da 100644 --- a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java +++ b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java @@ -10,7 +10,7 @@ import org.jetbrains.jet.lang.psi.JetThrowExpression; * @author abreslav */ public interface JetControlFlowBuilder { - void readNode(@NotNull JetExpression expression); + void read(@NotNull JetExpression expression); void readUnit(@NotNull JetExpression expression); // General label management @@ -52,7 +52,7 @@ public interface JetControlFlowBuilder { void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine); - void writeNode(@NotNull JetElement assignment, @NotNull JetElement lValue); + void write(@NotNull JetElement assignment, @NotNull JetElement lValue); // Other void unsupported(JetElement element); diff --git a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java index 769bf232908..838843df9d9 100644 --- a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java +++ b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java @@ -17,8 +17,8 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder { } @Override - public void readNode(@NotNull JetExpression expression) { - builder.readNode(expression); + public void read(@NotNull JetExpression expression) { + builder.read(expression); } @Override @@ -130,7 +130,7 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder { } @Override - public void writeNode(@NotNull JetElement assignment, @NotNull JetElement lValue) { - builder.writeNode(assignment, lValue); + public void write(@NotNull JetElement assignment, @NotNull JetElement lValue) { + builder.write(assignment, lValue); } } diff --git a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 36b02ed0a68..925be4209a4 100644 --- a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -118,17 +118,17 @@ public class JetControlFlowProcessor { @Override public void visitThisExpression(JetThisExpression expression) { - builder.readNode(expression); + builder.read(expression); } @Override public void visitConstantExpression(JetConstantExpression expression) { - builder.readNode(expression); + builder.read(expression); } @Override public void visitSimpleNameExpression(JetSimpleNameExpression expression) { - builder.readNode(expression); + builder.read(expression); } @Override @@ -161,7 +161,7 @@ public class JetControlFlowProcessor { } builder.bindLabel(resultLabel); if (!inCondition) { - builder.readNode(expression); + builder.read(expression); } } else if (operationType == JetTokens.OROR) { @@ -173,18 +173,26 @@ public class JetControlFlowProcessor { } builder.bindLabel(resultLabel); if (!inCondition) { - builder.readNode(expression); + builder.read(expression); } } else if (operationType == JetTokens.EQ) { - JetExpression left = expression.getLeft(); + JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); if (right != null) { value(right, false, false); } if (left instanceof JetSimpleNameExpression) { - builder.writeNode(expression, left); + builder.write(expression, left); } - else { + else if (left instanceof JetArrayAccessExpression) { + JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left; + for (JetExpression index : arrayAccessExpression.getIndexExpressions()) { + value(index, false, false); + } + value(arrayAccessExpression.getArrayExpression(), false, false); + value(expression.getOperationReference(), false, false); + builder.write(expression, left); // TODO : ??? + } else { builder.unsupported(expression); } } @@ -195,7 +203,7 @@ public class JetControlFlowProcessor { value(right, false, false); } if (left instanceof JetSimpleNameExpression) { - builder.writeNode(expression, left); + builder.write(expression, left); } else { builder.unsupported(expression); @@ -207,7 +215,7 @@ public class JetControlFlowProcessor { value(right, false, false); } value(expression.getOperationReference(), false, false); - builder.readNode(expression); + builder.read(expression); } } @@ -227,10 +235,10 @@ public class JetControlFlowProcessor { boolean incrementOrDecrement = isIncrementOrDecrement(operationType); if (incrementOrDecrement) { - builder.writeNode(expression, baseExpression); + builder.write(expression, baseExpression); } - builder.readNode(expression); + builder.read(expression); } } @@ -472,7 +480,7 @@ public class JetControlFlowProcessor { if (selectorExpression != null) { value(selectorExpression, false, false); } - builder.readNode(expression); + builder.read(expression); } private void visitCall(JetCall call) { @@ -497,7 +505,7 @@ public class JetControlFlowProcessor { visitCall(expression); value(expression.getCalleeExpression(), false, false); - builder.readNode(expression); + builder.read(expression); } @Override @@ -505,7 +513,7 @@ public class JetControlFlowProcessor { // TODO : Instantiated class is loaded // TODO : type arguments? visitCall(expression); - builder.readNode(expression); + builder.read(expression); } @Override @@ -513,7 +521,7 @@ public class JetControlFlowProcessor { JetExpression initializer = property.getInitializer(); if (initializer != null) { value(initializer, false, false); - builder.writeNode(property, property); + builder.write(property, property); } } @@ -522,7 +530,7 @@ public class JetControlFlowProcessor { for (JetExpression entry : expression.getEntries()) { value(entry, false, false); } - builder.readNode(expression); + builder.read(expression); } @Override @@ -536,11 +544,6 @@ public class JetControlFlowProcessor { } } - @Override - public void visitTypeProjection(JetTypeProjection typeProjection) { - // TODO : Support Type Arguments. Class object may be initialized at this point"); - } - @Override public void visitThrowExpression(JetThrowExpression expression) { JetExpression thrownExpression = expression.getThrownExpression(); @@ -550,6 +553,42 @@ public class JetControlFlowProcessor { builder.jumpToError(expression); } + @Override + public void visitArrayAccessExpression(JetArrayAccessExpression expression) { + for (JetExpression index : expression.getIndexExpressions()) { + value(index, false, false); + } + value(expression.getArrayExpression(), false, false); + // TODO : read 'get' or 'set' function + builder.read(expression); + } + + @Override + public void visitTypeofExpression(JetTypeofExpression expression) { + value(expression.getBaseExpression(), false, false); + builder.read(expression); + } + + @Override + public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { + List delegationSpecifiers = expression.getDelegationSpecifiers(); + for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) { + if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) { + JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier; + JetExpression delegateExpression = specifier.getDelegateExpression(); + if (delegateExpression != null) { + value(delegateExpression, false, false); + } + } + } + builder.read(expression); + } + + @Override + public void visitTypeProjection(JetTypeProjection typeProjection) { + // TODO : Support Type Arguments. Class object may be initialized at this point"); + } + @Override public void visitJetElement(JetElement elem) { builder.unsupported(elem); diff --git a/idea/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java b/idea/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java index 03e660fc711..c892c41ed24 100644 --- a/idea/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java +++ b/idea/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java @@ -200,12 +200,12 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd } @Override - public void writeNode(@NotNull JetElement assignment, @NotNull JetElement lValue) { + public void write(@NotNull JetElement assignment, @NotNull JetElement lValue) { add(new WriteValueInstruction(assignment, lValue)); } @Override - public void readNode(@NotNull JetExpression expression) { + public void read(@NotNull JetExpression expression) { add(new ReadValueInstruction(expression)); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java b/idea/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java index f6ae3038ba3..8e791fd8c5b 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java @@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author max @@ -15,4 +16,9 @@ public class JetDelegatorByExpressionSpecifier extends JetDelegationSpecifier { public void accept(JetVisitor visitor) { visitor.visitDelegationByExpressionSpecifier(this); } + + @Nullable @IfNotParsed + public JetExpression getDelegateExpression() { + return findChildByClass(JetExpression.class); + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index c20cef4caa4..822d622ff77 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -593,7 +593,7 @@ public class JetTypeInferrer { @Override public void visitTypeofExpression(JetTypeofExpression expression) { - throw new UnsupportedOperationException("Return some reflection interface"); // TODO + semanticServices.getErrorHandler().genericError(expression.getNode(), "Return some reflection interface"); // TODO } @Override diff --git a/idea/testData/cfg/ArrayAccess.instructions b/idea/testData/cfg/ArrayAccess.instructions new file mode 100644 index 00000000000..1a2e454f773 --- /dev/null +++ b/idea/testData/cfg/ArrayAccess.instructions @@ -0,0 +1,28 @@ +== foo == +fun foo() { + val a = new Array + 3 + a[10] = 4 + 2 + a[10] +} +--------------------- +l0: + + r(new Array) + w(a) + r(3) + r(4) + r(10) + r(a) + r(=) + w(a[10]) + r(2) + r(10) + r(a) + r(a[10]) +l1: + +error: + +===================== diff --git a/idea/testData/cfg/ArrayAccess.jet b/idea/testData/cfg/ArrayAccess.jet new file mode 100644 index 00000000000..5b65ec3f10c --- /dev/null +++ b/idea/testData/cfg/ArrayAccess.jet @@ -0,0 +1,7 @@ +fun foo() { + val a = new Array + 3 + a[10] = 4 + 2 + a[10] +}