diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java index 552084df28f..b67b07c2f58 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilder.java @@ -160,7 +160,4 @@ public interface JetControlFlowBuilder { @NotNull PseudoValue rValue, @NotNull AccessTarget target, @NotNull Map receiverValues); - - // Other - void unsupported(JetElement element); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java index ec87389ba6b..d2dae8c717d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowBuilderAdapter.java @@ -242,11 +242,6 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil getDelegateBuilder().returnNoValue(returnExpression, subroutine); } - @Override - public void unsupported(JetElement element) { - getDelegateBuilder().unsupported(element); - } - @Override public void write( @NotNull JetElement assignment, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index b47ed777e11..9808bd84336 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -458,7 +458,6 @@ public class JetControlFlowProcessor { Map receiverValues = SmartFMap.emptyMap(); AccessTarget accessTarget = AccessTarget.BlackBox.INSTANCE$; - boolean unsupported = false; if (left instanceof JetSimpleNameExpression || left instanceof JetQualifiedExpression) { accessTarget = getResolvedCallAccessTarget(PsiUtilPackage.getQualifiedElementSelector(left)); if (accessTarget instanceof AccessTarget.Call) { @@ -468,17 +467,8 @@ public class JetControlFlowProcessor { else if (left instanceof JetProperty) { accessTarget = getDeclarationAccessTarget(left); } - else { - unsupported = true; - } - PseudoValue rhsValue = rhsDeferredValue.invoke(); - if (unsupported) { - builder.unsupported(parentExpression); // TODO - } - else { - recordWrite(left, accessTarget, rhsValue, receiverValues, parentExpression); - } + recordWrite(left, accessTarget, rhsDeferredValue.invoke(), receiverValues, parentExpression); } private void generateArrayAssignment( @@ -558,9 +548,13 @@ public class JetControlFlowProcessor { @NotNull Map receiverValues, @NotNull JetExpression parentExpression ) { - VariableDescriptor descriptor = BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), left, false); - if (descriptor != null) { - PseudoValue rValue = rightValue != null ? rightValue : createSyntheticValue(parentExpression, MagicKind.UNRECOGNIZED_WRITE_RHS); + if (target == AccessTarget.BlackBox.instance$) { + List values = ContainerUtil.createMaybeSingletonList(rightValue); + builder.magic(parentExpression, parentExpression, values, defaultTypeMap(values), MagicKind.UNSUPPORTED_ELEMENT); + } + else { + PseudoValue rValue = + rightValue != null ? rightValue : createSyntheticValue(parentExpression, MagicKind.UNRECOGNIZED_WRITE_RHS); builder.write(parentExpression, left, rValue, target, receiverValues); } } @@ -1097,7 +1091,7 @@ public class JetControlFlowProcessor { } else { generateInstructions(receiverExpression); - createNonSyntheticValue(expression, MagicKind.UNSUPPORTED_OPERATION, receiverExpression); + createNonSyntheticValue(expression, MagicKind.UNSUPPORTED_ELEMENT, receiverExpression); } } @@ -1209,7 +1203,7 @@ public class JetControlFlowProcessor { } else { visitJetElement(expression); - createNonSyntheticValue(expression, MagicKind.UNSUPPORTED_OPERATION, left); + createNonSyntheticValue(expression, MagicKind.UNSUPPORTED_ELEMENT, left); } } @@ -1403,6 +1397,11 @@ public class JetControlFlowProcessor { builder.magic(specifier, specifier, arguments, PseudocodePackage.expectedTypeFor(expectedTypePredicate, arguments), MagicKind.VALUE_CONSUMER); } + @Override + public void visitDelegationToSuperClassSpecifier(@NotNull JetDelegatorToSuperClass specifier) { + // Do not generate UNSUPPORTED_ELEMENT here + } + @Override public void visitDelegationSpecifierList(@NotNull JetDelegationSpecifierList list) { list.acceptChildren(this); @@ -1425,13 +1424,14 @@ public class JetControlFlowProcessor { @Override public void visitJetElement(@NotNull JetElement element) { - builder.unsupported(element); + createNonSyntheticValue(element, MagicKind.UNSUPPORTED_ELEMENT); } private boolean generateCall(@Nullable JetElement callElement) { if (callElement == null) return false; return checkAndGenerateCall(callElement, getResolvedCall(callElement, trace.getBindingContext())); } + private boolean checkAndGenerateCall(@NotNull JetElement callElement, @Nullable ResolvedCall resolvedCall) { if (resolvedCall == null) { builder.compilationError(callElement, "No resolved call"); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java index a1615bb2f81..3f229c14ac1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/JetControlFlowInstructionsGenerator.java @@ -386,11 +386,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd assert pop instanceof TryFinallyBlockInfo; } - @Override - public void unsupported(JetElement element) { - add(new UnsupportedElementInstruction(element, getCurrentScope())); - } - @Override public void repeatPseudocode(@NotNull Label startLabel, @NotNull Label finishLabel) { pseudocode.repeatPart(startLabel, finishLabel); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitor.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitor.kt index 42280d9810c..3f1966200cf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitor.kt @@ -62,10 +62,6 @@ public open class InstructionVisitor() { visitInstruction(instruction) } - public open fun visitUnsupportedElementInstruction(instruction: UnsupportedElementInstruction) { - visitInstructionWithNext(instruction) - } - public open fun visitSubroutineExit(instruction: SubroutineExitInstruction) { visitInstruction(instruction) } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitorWithResult.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitorWithResult.kt index 4e135df27f1..023cf6f85f8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitorWithResult.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionVisitorWithResult.kt @@ -64,10 +64,6 @@ public abstract class InstructionVisitorWithResult() { return visitInstruction(instruction) } - public open fun visitUnsupportedElementInstruction(instruction: UnsupportedElementInstruction): R { - return visitInstructionWithNext(instruction) - } - public open fun visitSubroutineExit(instruction: SubroutineExitInstruction): R { return visitInstruction(instruction) } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/eval/operationInstructions.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/eval/operationInstructions.kt index 97e8685ace0..23b5d577751 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/eval/operationInstructions.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/eval/operationInstructions.kt @@ -147,7 +147,7 @@ public enum class MagicKind { VALUE_CONSUMER // unrecognized operations UNRESOLVED_CALL - UNSUPPORTED_OPERATION + UNSUPPORTED_ELEMENT UNRECOGNIZED_WRITE_RHS FAKE_INITIALIZER } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/special/UnsupportedElementInstruction.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/special/UnsupportedElementInstruction.kt deleted file mode 100644 index 9997c0be26a..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/special/UnsupportedElementInstruction.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.lang.cfg.pseudocode.instructions.special - -import org.jetbrains.jet.lang.psi.JetElement -import org.jetbrains.jet.lang.cfg.pseudocode.instructions.LexicalScope -import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionWithNext -import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionVisitor -import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionVisitorWithResult -import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionImpl - -public class UnsupportedElementInstruction( - element: JetElement, - lexicalScope: LexicalScope -) : InstructionWithNext(element, lexicalScope) { - override fun accept(visitor: InstructionVisitor) { - visitor.visitUnsupportedElementInstruction(this) - } - - override fun accept(visitor: InstructionVisitorWithResult): R { - return visitor.visitUnsupportedElementInstruction(this) - } - - override fun toString(): String = - "unsupported(" + element + " : " + render(element) + ")" - - override fun createCopy(): InstructionImpl = - UnsupportedElementInstruction(element, lexicalScope) -} \ No newline at end of file diff --git a/compiler/testData/cfg/declarations/classesAndObjects/delegationByExpression.instructions b/compiler/testData/cfg/declarations/classesAndObjects/delegationByExpression.instructions index c896956b781..2045d3927fd 100644 --- a/compiler/testData/cfg/declarations/classesAndObjects/delegationByExpression.instructions +++ b/compiler/testData/cfg/declarations/classesAndObjects/delegationByExpression.instructions @@ -21,7 +21,6 @@ L0: v(b: Int) magic[FAKE_INITIALIZER](b: Int) -> w(b|) - unsupported(DELEGATOR_SUPER_CLASS : T) L1: NEXT:[] error: diff --git a/compiler/testData/cfg/declarations/local/ObjectExpression.instructions b/compiler/testData/cfg/declarations/local/ObjectExpression.instructions index db433ddbaca..9b5064482a0 100644 --- a/compiler/testData/cfg/declarations/local/ObjectExpression.instructions +++ b/compiler/testData/cfg/declarations/local/ObjectExpression.instructions @@ -31,13 +31,12 @@ class B : A { --------------------- L0: 1 - unsupported(DELEGATOR_SUPER_CLASS : A) L1: - NEXT:[] + NEXT:[] error: - PREV:[] + PREV:[] sink: - PREV:[, ] + PREV:[, ] ===================== == foo == override fun foo() = 10 diff --git a/compiler/testData/cfg/expressions/assignmentToThis.instructions b/compiler/testData/cfg/expressions/assignmentToThis.instructions index 5ed2bd6e808..b0bca6f7a78 100644 --- a/compiler/testData/cfg/expressions/assignmentToThis.instructions +++ b/compiler/testData/cfg/expressions/assignmentToThis.instructions @@ -10,11 +10,11 @@ L0: w(c|) 2 mark({ this = c }) r(c) -> - unsupported(BINARY_EXPRESSION : this = c) + magic[UNSUPPORTED_ELEMENT](this = c|) -> L1: - 1 NEXT:[] + 1 NEXT:[] error: - PREV:[] + PREV:[] sink: - PREV:[, ] + PREV:[, ] ===================== diff --git a/compiler/testData/cfg/expressions/assignmentToThis.values b/compiler/testData/cfg/expressions/assignmentToThis.values index 7588f0c7036..3121c81908d 100644 --- a/compiler/testData/cfg/expressions/assignmentToThis.values +++ b/compiler/testData/cfg/expressions/assignmentToThis.values @@ -3,6 +3,8 @@ fun Int.bar(c: C) { this = c } --------------------- - : {<: [ERROR : C]} NEW: magic[FAKE_INITIALIZER](c: C) -> -c : * NEW: r(c) -> + : {<: [ERROR : C]} NEW: magic[FAKE_INITIALIZER](c: C) -> +c : * NEW: r(c) -> +this = c : * NEW: magic[UNSUPPORTED_ELEMENT](this = c|) -> +{ this = c } : * COPY ===================== diff --git a/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.instructions b/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.instructions index 0b85abfa93a..f9dff87e9cf 100644 --- a/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.instructions +++ b/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.instructions @@ -11,11 +11,11 @@ L0: 2 mark({ s. }) mark(s.) r(s) -> - magic[UNSUPPORTED_OPERATION](s.|) -> + magic[UNSUPPORTED_ELEMENT](s.|) -> L1: - 1 NEXT:[] + 1 NEXT:[] error: - PREV:[] + PREV:[] sink: - PREV:[, ] + PREV:[, ] ===================== diff --git a/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.values b/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.values index 96c93440950..96efe38af27 100644 --- a/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.values +++ b/compiler/testData/cfg/expressions/qualifiedExpressionWithoutSelector.values @@ -3,8 +3,8 @@ fun foo(s: String) { s. } --------------------- - : String NEW: magic[FAKE_INITIALIZER](s: String) -> -s : * NEW: r(s) -> -s. : * NEW: magic[UNSUPPORTED_OPERATION](s.|) -> -{ s. } : * COPY + : String NEW: magic[FAKE_INITIALIZER](s: String) -> +s : * NEW: r(s) -> +s. : * NEW: magic[UNSUPPORTED_ELEMENT](s.|) -> +{ s. } : * COPY ===================== diff --git a/compiler/testData/cfg/expressions/unresolvedWriteLHS.instructions b/compiler/testData/cfg/expressions/unresolvedWriteLHS.instructions new file mode 100644 index 00000000000..fb7f381dd94 --- /dev/null +++ b/compiler/testData/cfg/expressions/unresolvedWriteLHS.instructions @@ -0,0 +1,18 @@ +== foo == +fun foo() { + x = "" +} +--------------------- +L0: + 1 + 2 mark({ x = "" }) + mark("") + r("") -> + magic[UNSUPPORTED_ELEMENT](x = ""|) -> +L1: + 1 NEXT:[] +error: + PREV:[] +sink: + PREV:[, ] +===================== diff --git a/compiler/testData/cfg/expressions/unresolvedWriteLHS.kt b/compiler/testData/cfg/expressions/unresolvedWriteLHS.kt new file mode 100644 index 00000000000..028ae3b76e4 --- /dev/null +++ b/compiler/testData/cfg/expressions/unresolvedWriteLHS.kt @@ -0,0 +1,3 @@ +fun foo() { + x = "" +} \ No newline at end of file diff --git a/compiler/testData/cfg/expressions/unresolvedWriteLHS.values b/compiler/testData/cfg/expressions/unresolvedWriteLHS.values new file mode 100644 index 00000000000..70ca650ecb8 --- /dev/null +++ b/compiler/testData/cfg/expressions/unresolvedWriteLHS.values @@ -0,0 +1,9 @@ +== foo == +fun foo() { + x = "" +} +--------------------- +"" : * NEW: r("") -> +x = "" : * NEW: magic[UNSUPPORTED_ELEMENT](x = ""|) -> +{ x = "" } : * COPY +===================== diff --git a/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java b/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java index 878996e3845..c37fd0222cd 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java +++ b/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java @@ -24,6 +24,8 @@ import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeImpl; import org.jetbrains.jet.lang.cfg.pseudocode.instructions.Instruction; import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionVisitor; import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionWithNext; +import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.MagicInstruction; +import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.MagicKind; import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.*; import org.jetbrains.jet.lang.cfg.pseudocode.instructions.special.*; import org.jetbrains.jet.lang.psi.JetElement; @@ -155,7 +157,7 @@ public class CFGraphToDotFilePrinter { else if (node instanceof NondeterministicJumpInstruction) { shape = "Mdiamond"; } - else if (node instanceof UnsupportedElementInstruction) { + else if (node instanceof MagicInstruction && ((MagicInstruction) node).getKind() == MagicKind.UNSUPPORTED_ELEMENT) { shape = "box, fillcolor=red, style=filled"; } else if (node instanceof LocalFunctionDeclarationInstruction) { diff --git a/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java b/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java index 5202f45ea51..8a8a6891e59 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java @@ -434,6 +434,11 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest { doTest("compiler/testData/cfg/expressions/unresolvedProperty.kt"); } + @TestMetadata("unresolvedWriteLHS.kt") + public void testUnresolvedWriteLHS() throws Exception { + doTest("compiler/testData/cfg/expressions/unresolvedWriteLHS.kt"); + } + @TestMetadata("unusedExpressionSimpleName.kt") public void testUnusedExpressionSimpleName() throws Exception { doTest("compiler/testData/cfg/expressions/unusedExpressionSimpleName.kt"); diff --git a/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java b/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java index 1f9f1c327fe..db48dbf0dfd 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java @@ -438,6 +438,11 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest { doTest("compiler/testData/cfg/expressions/unresolvedProperty.kt"); } + @TestMetadata("unresolvedWriteLHS.kt") + public void testUnresolvedWriteLHS() throws Exception { + doTest("compiler/testData/cfg/expressions/unresolvedWriteLHS.kt"); + } + @TestMetadata("unusedExpressionSimpleName.kt") public void testUnusedExpressionSimpleName() throws Exception { doTest("compiler/testData/cfg/expressions/unusedExpressionSimpleName.kt");