Pseudocode: Track PSI elements which correspond to jump instructions
This commit is contained in:
@@ -63,12 +63,12 @@ public interface JetControlFlowBuilder {
|
||||
void bindLabel(@NotNull Label label);
|
||||
|
||||
// Jumps
|
||||
void jump(@NotNull Label label);
|
||||
void jumpOnFalse(@NotNull Label label);
|
||||
void jumpOnTrue(@NotNull Label label);
|
||||
void nondeterministicJump(@NotNull Label label); // Maybe, jump to label
|
||||
void nondeterministicJump(@NotNull List<Label> label);
|
||||
void jumpToError();
|
||||
void jump(@NotNull Label label, @NotNull JetElement element);
|
||||
void jumpOnFalse(@NotNull Label label, @NotNull JetElement element);
|
||||
void jumpOnTrue(@NotNull Label label, @NotNull JetElement element);
|
||||
void nondeterministicJump(@NotNull Label label, @NotNull JetElement element); // Maybe, jump to label
|
||||
void nondeterministicJump(@NotNull List<Label> label, @NotNull JetElement element);
|
||||
void jumpToError(@NotNull JetElement element);
|
||||
|
||||
void returnValue(@NotNull JetExpression returnExpression, @NotNull JetElement subroutine);
|
||||
void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine);
|
||||
|
||||
+12
-12
@@ -100,33 +100,33 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jump(@NotNull Label label) {
|
||||
getDelegateBuilder().jump(label);
|
||||
public void jump(@NotNull Label label, @NotNull JetElement element) {
|
||||
getDelegateBuilder().jump(label, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label) {
|
||||
getDelegateBuilder().jumpOnFalse(label);
|
||||
public void jumpOnFalse(@NotNull Label label, @NotNull JetElement element) {
|
||||
getDelegateBuilder().jumpOnFalse(label, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label) {
|
||||
getDelegateBuilder().jumpOnTrue(label);
|
||||
public void jumpOnTrue(@NotNull Label label, @NotNull JetElement element) {
|
||||
getDelegateBuilder().jumpOnTrue(label, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(@NotNull Label label) {
|
||||
getDelegateBuilder().nondeterministicJump(label);
|
||||
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element) {
|
||||
getDelegateBuilder().nondeterministicJump(label, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(@NotNull List<Label> labels) {
|
||||
getDelegateBuilder().nondeterministicJump(labels);
|
||||
public void nondeterministicJump(@NotNull List<Label> labels, @NotNull JetElement element) {
|
||||
getDelegateBuilder().nondeterministicJump(labels, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpToError() {
|
||||
getDelegateBuilder().jumpToError();
|
||||
public void jumpToError(@NotNull JetElement element) {
|
||||
getDelegateBuilder().jumpToError(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowInstructionsGenerator;
|
||||
@@ -92,8 +93,12 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
private void processLocalDeclaration(@NotNull JetDeclaration subroutine) {
|
||||
JetElement parent = PsiTreeUtil.getParentOfType(subroutine, JetElement.class);
|
||||
assert parent != null;
|
||||
|
||||
Label afterDeclaration = builder.createUnboundLabel();
|
||||
builder.nondeterministicJump(afterDeclaration);
|
||||
|
||||
builder.nondeterministicJump(afterDeclaration, parent);
|
||||
generate(subroutine);
|
||||
builder.bindLabel(afterDeclaration);
|
||||
}
|
||||
@@ -157,7 +162,10 @@ public class JetControlFlowProcessor {
|
||||
|
||||
private void checkNothingType(JetElement element) {
|
||||
if (!(element instanceof JetExpression)) return;
|
||||
|
||||
JetExpression expression = JetPsiUtil.deparenthesize((JetExpression) element);
|
||||
if (expression == null) return;
|
||||
|
||||
if (expression instanceof JetStatementExpression || expression instanceof JetTryExpression
|
||||
|| expression instanceof JetIfExpression || expression instanceof JetWhenExpression) {
|
||||
return;
|
||||
@@ -165,7 +173,7 @@ public class JetControlFlowProcessor {
|
||||
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) {
|
||||
builder.jumpToError();
|
||||
builder.jumpToError(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +253,7 @@ public class JetControlFlowProcessor {
|
||||
if (operationType == ANDAND) {
|
||||
generateInstructions(expression.getLeft(), IN_CONDITION);
|
||||
Label resultLabel = builder.createUnboundLabel();
|
||||
builder.jumpOnFalse(resultLabel);
|
||||
builder.jumpOnFalse(resultLabel, expression);
|
||||
if (right != null) {
|
||||
generateInstructions(right, IN_CONDITION);
|
||||
}
|
||||
@@ -257,7 +265,7 @@ public class JetControlFlowProcessor {
|
||||
else if (operationType == OROR) {
|
||||
generateInstructions(expression.getLeft(), IN_CONDITION);
|
||||
Label resultLabel = builder.createUnboundLabel();
|
||||
builder.jumpOnTrue(resultLabel);
|
||||
builder.jumpOnTrue(resultLabel, expression);
|
||||
if (right != null) {
|
||||
generateInstructions(right, IN_CONDITION);
|
||||
}
|
||||
@@ -287,7 +295,7 @@ public class JetControlFlowProcessor {
|
||||
else if (operationType == ELVIS) {
|
||||
generateInstructions(expression.getLeft(), NOT_IN_CONDITION);
|
||||
Label afterElvis = builder.createUnboundLabel();
|
||||
builder.jumpOnTrue(afterElvis);
|
||||
builder.jumpOnTrue(afterElvis, expression);
|
||||
if (right != null) {
|
||||
generateInstructions(right, NOT_IN_CONDITION);
|
||||
}
|
||||
@@ -398,7 +406,7 @@ public class JetControlFlowProcessor {
|
||||
generateInstructions(condition, IN_CONDITION);
|
||||
}
|
||||
Label elseLabel = builder.createUnboundLabel();
|
||||
builder.jumpOnFalse(elseLabel);
|
||||
builder.jumpOnFalse(elseLabel, expression);
|
||||
JetExpression thenBranch = expression.getThen();
|
||||
if (thenBranch != null) {
|
||||
generateInstructions(thenBranch, context);
|
||||
@@ -407,7 +415,7 @@ public class JetControlFlowProcessor {
|
||||
builder.loadUnit(expression);
|
||||
}
|
||||
Label resultLabel = builder.createUnboundLabel();
|
||||
builder.jump(resultLabel);
|
||||
builder.jump(resultLabel, expression);
|
||||
builder.bindLabel(elseLabel);
|
||||
JetExpression elseBranch = expression.getElse();
|
||||
if (elseBranch != null) {
|
||||
@@ -472,18 +480,18 @@ public class JetControlFlowProcessor {
|
||||
Label onException = null;
|
||||
if (hasCatches) {
|
||||
onException = builder.createUnboundLabel("onException");
|
||||
builder.nondeterministicJump(onException);
|
||||
builder.nondeterministicJump(onException, expression);
|
||||
}
|
||||
Label onExceptionToFinallyBlock = null;
|
||||
if (finallyBlock != null) {
|
||||
onExceptionToFinallyBlock = builder.createUnboundLabel("onExceptionToFinallyBlock");
|
||||
builder.nondeterministicJump(onExceptionToFinallyBlock);
|
||||
builder.nondeterministicJump(onExceptionToFinallyBlock, expression);
|
||||
}
|
||||
generateInstructions(expression.getTryBlock(), context);
|
||||
|
||||
if (hasCatches) {
|
||||
Label afterCatches = builder.createUnboundLabel("afterCatches");
|
||||
builder.jump(afterCatches);
|
||||
builder.jump(afterCatches, expression);
|
||||
|
||||
builder.bindLabel(onException);
|
||||
LinkedList<Label> catchLabels = Lists.newLinkedList();
|
||||
@@ -492,7 +500,7 @@ public class JetControlFlowProcessor {
|
||||
catchLabels.add(builder.createUnboundLabel("catch " + i));
|
||||
}
|
||||
if (!catchLabels.isEmpty()) {
|
||||
builder.nondeterministicJump(catchLabels);
|
||||
builder.nondeterministicJump(catchLabels, expression);
|
||||
}
|
||||
boolean isFirst = true;
|
||||
for (JetCatchClause catchClause : catchClauses) {
|
||||
@@ -512,7 +520,7 @@ public class JetControlFlowProcessor {
|
||||
if (catchBody != null) {
|
||||
generateInstructions(catchBody, NOT_IN_CONDITION);
|
||||
}
|
||||
builder.jump(afterCatches);
|
||||
builder.jump(afterCatches, expression);
|
||||
builder.exitLexicalScope(catchClause);
|
||||
}
|
||||
|
||||
@@ -523,10 +531,10 @@ public class JetControlFlowProcessor {
|
||||
builder.exitTryFinally();
|
||||
|
||||
Label skipFinallyToErrorBlock = builder.createUnboundLabel("skipFinallyToErrorBlock");
|
||||
builder.jump(skipFinallyToErrorBlock);
|
||||
builder.jump(skipFinallyToErrorBlock, expression);
|
||||
builder.bindLabel(onExceptionToFinallyBlock);
|
||||
finallyBlockGenerator.generate();
|
||||
builder.jumpToError();
|
||||
builder.jumpToError(expression);
|
||||
builder.bindLabel(skipFinallyToErrorBlock);
|
||||
|
||||
finallyBlockGenerator.generate();
|
||||
@@ -545,7 +553,7 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
boolean conditionIsTrueConstant = CompileTimeConstantUtils.canBeReducedToBooleanConstant(condition, trace, true);
|
||||
if (!conditionIsTrueConstant) {
|
||||
builder.jumpOnFalse(loopInfo.getExitPoint());
|
||||
builder.jumpOnFalse(loopInfo.getExitPoint(), expression);
|
||||
}
|
||||
|
||||
builder.bindLabel(loopInfo.getBodyEntryPoint());
|
||||
@@ -553,7 +561,7 @@ public class JetControlFlowProcessor {
|
||||
if (body != null) {
|
||||
generateInstructions(body, NOT_IN_CONDITION);
|
||||
}
|
||||
builder.jump(loopInfo.getEntryPoint());
|
||||
builder.jump(loopInfo.getEntryPoint(), expression);
|
||||
builder.exitLoop(expression);
|
||||
builder.loadUnit(expression);
|
||||
}
|
||||
@@ -574,7 +582,7 @@ public class JetControlFlowProcessor {
|
||||
if (condition != null) {
|
||||
generateInstructions(condition, IN_CONDITION);
|
||||
}
|
||||
builder.jumpOnTrue(loopInfo.getEntryPoint());
|
||||
builder.jumpOnTrue(loopInfo.getEntryPoint(), expression);
|
||||
builder.exitLoop(expression);
|
||||
builder.loadUnit(expression);
|
||||
builder.exitLexicalScope(expression);
|
||||
@@ -595,7 +603,7 @@ public class JetControlFlowProcessor {
|
||||
Label conditionEntryPoint = builder.createUnboundLabel();
|
||||
|
||||
builder.bindLabel(conditionEntryPoint);
|
||||
builder.nondeterministicJump(loopExitPoint);
|
||||
builder.nondeterministicJump(loopExitPoint, expression);
|
||||
|
||||
LoopInfo loopInfo = builder.enterLoop(expression, loopExitPoint, conditionEntryPoint);
|
||||
|
||||
@@ -607,7 +615,7 @@ public class JetControlFlowProcessor {
|
||||
generateInstructions(body, NOT_IN_CONDITION);
|
||||
}
|
||||
|
||||
builder.nondeterministicJump(loopInfo.getEntryPoint());
|
||||
builder.nondeterministicJump(loopInfo.getEntryPoint(), expression);
|
||||
builder.exitLoop(expression);
|
||||
builder.loadUnit(expression);
|
||||
builder.exitLexicalScope(expression);
|
||||
@@ -642,7 +650,7 @@ public class JetControlFlowProcessor {
|
||||
JetElement loop = getCorrespondingLoop(expression);
|
||||
if (loop != null) {
|
||||
checkJumpDoesNotCrossFunctionBoundary(expression, loop);
|
||||
builder.jump(builder.getExitPoint(loop));
|
||||
builder.jump(builder.getExitPoint(loop), expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,7 +659,7 @@ public class JetControlFlowProcessor {
|
||||
JetElement loop = getCorrespondingLoop(expression);
|
||||
if (loop != null) {
|
||||
checkJumpDoesNotCrossFunctionBoundary(expression, loop);
|
||||
builder.jump(builder.getEntryPoint(loop));
|
||||
builder.jump(builder.getEntryPoint(loop), expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -921,18 +929,18 @@ public class JetControlFlowProcessor {
|
||||
JetWhenCondition condition = conditions[i];
|
||||
condition.accept(conditionVisitor, context);
|
||||
if (i + 1 < conditions.length) {
|
||||
builder.nondeterministicJump(bodyLabel);
|
||||
builder.nondeterministicJump(bodyLabel, expression);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isElse) {
|
||||
nextLabel = builder.createUnboundLabel();
|
||||
builder.nondeterministicJump(nextLabel);
|
||||
builder.nondeterministicJump(nextLabel, expression);
|
||||
}
|
||||
|
||||
builder.bindLabel(bodyLabel);
|
||||
generateInstructions(whenEntry.getExpression(), context);
|
||||
builder.jump(doneLabel);
|
||||
builder.jump(doneLabel, expression);
|
||||
|
||||
if (!isElse) {
|
||||
builder.bindLabel(nextLabel);
|
||||
|
||||
@@ -243,10 +243,19 @@ public class JetFlowInformationProvider {
|
||||
private Set<JetElement> collectUnreachableCode() {
|
||||
Collection<JetElement> unreachableElements = Lists.newArrayList();
|
||||
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
|
||||
if (deadInstruction instanceof JetElementInstruction &&
|
||||
!(deadInstruction instanceof LoadUnitValueInstruction)) {
|
||||
unreachableElements.add(((JetElementInstruction) deadInstruction).getElement());
|
||||
if (!(deadInstruction instanceof JetElementInstruction) || deadInstruction instanceof LoadUnitValueInstruction) continue;
|
||||
|
||||
JetElement element = ((JetElementInstruction) deadInstruction).getElement();
|
||||
|
||||
if (deadInstruction instanceof JumpInstruction) {
|
||||
boolean isJumpElement = element instanceof JetBreakExpression
|
||||
|| element instanceof JetContinueExpression
|
||||
|| element instanceof JetReturnExpression
|
||||
|| element instanceof JetThrowExpression;
|
||||
if (!isJumpElement) continue;
|
||||
}
|
||||
|
||||
unreachableElements.add(element);
|
||||
}
|
||||
// This is needed in order to highlight only '1 < 2' and not '1', '<' and '2' as well
|
||||
return JetPsiUtil.findRootExpressions(unreachableElements);
|
||||
|
||||
+4
-3
@@ -18,16 +18,17 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public abstract class AbstractJumpInstruction extends InstructionImpl {
|
||||
public abstract class AbstractJumpInstruction extends JetElementInstructionImpl implements JumpInstruction {
|
||||
private final Label targetLabel;
|
||||
private Instruction resolvedTarget;
|
||||
|
||||
public AbstractJumpInstruction(Label targetLabel, LexicalScope lexicalScope) {
|
||||
super(lexicalScope);
|
||||
public AbstractJumpInstruction(@NotNull JetElement element, Label targetLabel, LexicalScope lexicalScope) {
|
||||
super(element, lexicalScope);
|
||||
this.targetLabel = targetLabel;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -27,8 +28,8 @@ public class ConditionalJumpInstruction extends AbstractJumpInstruction {
|
||||
private Instruction nextOnTrue;
|
||||
private Instruction nextOnFalse;
|
||||
|
||||
public ConditionalJumpInstruction(boolean onTrue, LexicalScope lexicalScope, Label targetLabel) {
|
||||
super(targetLabel, lexicalScope);
|
||||
public ConditionalJumpInstruction(@NotNull JetElement element, boolean onTrue, LexicalScope lexicalScope, Label targetLabel) {
|
||||
super(element, targetLabel, lexicalScope);
|
||||
this.onTrue = onTrue;
|
||||
}
|
||||
|
||||
@@ -76,6 +77,6 @@ public class ConditionalJumpInstruction extends AbstractJumpInstruction {
|
||||
|
||||
@Override
|
||||
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
|
||||
return new ConditionalJumpInstruction(onTrue, lexicalScope, newLabel);
|
||||
return new ConditionalJumpInstruction(element, onTrue, lexicalScope, newLabel);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-12
@@ -298,21 +298,21 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jump(@NotNull Label label) {
|
||||
public void jump(@NotNull Label label, @NotNull JetElement element) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new UnconditionalJumpInstruction(label, getCurrentScope()));
|
||||
add(new UnconditionalJumpInstruction(element, label, getCurrentScope()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label) {
|
||||
public void jumpOnFalse(@NotNull Label label, @NotNull JetElement element) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new ConditionalJumpInstruction(false, getCurrentScope(), label));
|
||||
add(new ConditionalJumpInstruction(element, false, getCurrentScope(), label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label) {
|
||||
public void jumpOnTrue(@NotNull Label label, @NotNull JetElement element) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new ConditionalJumpInstruction(true, getCurrentScope(), label));
|
||||
add(new ConditionalJumpInstruction(element, true, getCurrentScope(), label));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -321,22 +321,22 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(@NotNull Label label) {
|
||||
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new NondeterministicJumpInstruction(label, getCurrentScope()));
|
||||
add(new NondeterministicJumpInstruction(element, label, getCurrentScope()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(@NotNull List<Label> labels) {
|
||||
public void nondeterministicJump(@NotNull List<Label> labels, @NotNull JetElement element) {
|
||||
//todo
|
||||
//handleJumpInsideTryFinally(label);
|
||||
add(new NondeterministicJumpInstruction(labels, getCurrentScope()));
|
||||
add(new NondeterministicJumpInstruction(element, labels, getCurrentScope()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpToError() {
|
||||
public void jumpToError(@NotNull JetElement element) {
|
||||
handleJumpInsideTryFinally(error);
|
||||
add(new UnconditionalJumpInstruction(error, getCurrentScope()));
|
||||
add(new UnconditionalJumpInstruction(element, error, getCurrentScope()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -350,6 +350,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
add(new ThrowExceptionInstruction(expression, getCurrentScope(), error));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitTryFinally() {
|
||||
BlockInfo pop = allBlocks.pop();
|
||||
assert pop instanceof TryFinallyBlockInfo;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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;/**/
|
||||
|
||||
public interface JumpInstruction extends Instruction {
|
||||
}
|
||||
+7
-6
@@ -20,22 +20,23 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class NondeterministicJumpInstruction extends InstructionImpl{
|
||||
public class NondeterministicJumpInstruction extends JetElementInstructionImpl implements JumpInstruction {
|
||||
private Instruction next;
|
||||
private final List<Label> targetLabels;
|
||||
private final Map<Label, Instruction> resolvedTargets;
|
||||
|
||||
public NondeterministicJumpInstruction(List<Label> targetLabels, LexicalScope lexicalScope) {
|
||||
super(lexicalScope);
|
||||
public NondeterministicJumpInstruction(@NotNull JetElement element, List<Label> targetLabels, LexicalScope lexicalScope) {
|
||||
super(element, lexicalScope);
|
||||
this.targetLabels = Lists.newArrayList(targetLabels);
|
||||
resolvedTargets = Maps.newLinkedHashMap();
|
||||
}
|
||||
|
||||
public NondeterministicJumpInstruction(Label targetLabel, LexicalScope lexicalScope) {
|
||||
this(Lists.newArrayList(targetLabel), lexicalScope);
|
||||
public NondeterministicJumpInstruction(@NotNull JetElement element, Label targetLabel, LexicalScope lexicalScope) {
|
||||
this(element, Lists.newArrayList(targetLabel), lexicalScope);
|
||||
}
|
||||
|
||||
public List<Label> getTargetLabels() {
|
||||
@@ -103,6 +104,6 @@ public class NondeterministicJumpInstruction extends InstructionImpl{
|
||||
}
|
||||
|
||||
private Instruction createCopy(@NotNull List<Label> newTargetLabels) {
|
||||
return new NondeterministicJumpInstruction(newTargetLabels, lexicalScope);
|
||||
return new NondeterministicJumpInstruction(getElement(), newTargetLabels, lexicalScope);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-11
@@ -21,18 +21,8 @@ import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
public class ReturnNoValueInstruction extends AbstractJumpInstruction implements ReturnInstruction {
|
||||
|
||||
private final JetElement element;
|
||||
|
||||
public ReturnNoValueInstruction(@NotNull JetElement element, LexicalScope lexicalScope, Label targetLabel) {
|
||||
super(targetLabel, lexicalScope);
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetElement getElement() {
|
||||
return element;
|
||||
super(element, targetLabel, lexicalScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-14
@@ -18,20 +18,18 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
public class ReturnValueInstruction extends AbstractJumpInstruction implements ReturnInstruction {
|
||||
|
||||
private final JetElement element;
|
||||
|
||||
public ReturnValueInstruction(@NotNull JetExpression returnExpression, @NotNull LexicalScope lexicalScope, @NotNull Label targetLabel) {
|
||||
super(targetLabel, lexicalScope);
|
||||
this.element = returnExpression;
|
||||
public ReturnValueInstruction(
|
||||
@NotNull JetExpression returnExpression,
|
||||
@NotNull LexicalScope lexicalScope,
|
||||
@NotNull Label targetLabel) {
|
||||
super(returnExpression, targetLabel, lexicalScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(InstructionVisitor visitor) {
|
||||
public void accept(@NotNull InstructionVisitor visitor) {
|
||||
visitor.visitReturnValue(this);
|
||||
}
|
||||
|
||||
@@ -45,12 +43,6 @@ public class ReturnValueInstruction extends AbstractJumpInstruction implements R
|
||||
return "ret(*) " + getTargetLabel();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
|
||||
return new ReturnValueInstruction((JetExpression) element, lexicalScope, newLabel);
|
||||
|
||||
+9
-15
@@ -18,26 +18,20 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetThrowExpression;
|
||||
|
||||
public class ThrowExceptionInstruction extends AbstractJumpInstruction implements JetElementInstruction {
|
||||
private final JetThrowExpression expression;
|
||||
|
||||
public ThrowExceptionInstruction(@NotNull JetThrowExpression expression, @NotNull LexicalScope lexicalScope, @NotNull Label errorLabel) {
|
||||
super(errorLabel, lexicalScope);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetExpression getElement() {
|
||||
return expression;
|
||||
public class ThrowExceptionInstruction extends AbstractJumpInstruction {
|
||||
public ThrowExceptionInstruction(
|
||||
@NotNull JetThrowExpression expression,
|
||||
@NotNull LexicalScope lexicalScope,
|
||||
@NotNull Label errorLabel
|
||||
) {
|
||||
super(expression, errorLabel, lexicalScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "throw (" + expression.getText() + ")";
|
||||
return "throw (" + element.getText() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,6 +46,6 @@ public class ThrowExceptionInstruction extends AbstractJumpInstruction implement
|
||||
|
||||
@Override
|
||||
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
|
||||
return new ThrowExceptionInstruction(expression, lexicalScope, newLabel);
|
||||
return new ThrowExceptionInstruction((JetThrowExpression) element, lexicalScope, newLabel);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -18,12 +18,11 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
public class UnconditionalJumpInstruction extends AbstractJumpInstruction {
|
||||
|
||||
|
||||
public UnconditionalJumpInstruction(Label targetLabel, @NotNull LexicalScope lexicalScope) {
|
||||
super(targetLabel, lexicalScope);
|
||||
public UnconditionalJumpInstruction(@NotNull JetElement element, Label targetLabel, @NotNull LexicalScope lexicalScope) {
|
||||
super(element, targetLabel, lexicalScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,6 +42,6 @@ public class UnconditionalJumpInstruction extends AbstractJumpInstruction {
|
||||
|
||||
@Override
|
||||
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
|
||||
return new UnconditionalJumpInstruction(newLabel, lexicalScope);
|
||||
return new UnconditionalJumpInstruction(element, newLabel, lexicalScope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ class C {
|
||||
@a {
|
||||
<!NOT_A_LOOP_LABEL!>break@f<!>
|
||||
break
|
||||
break@b
|
||||
<!UNREACHABLE_CODE!>break@b<!>
|
||||
<!NOT_A_LOOP_LABEL!>break@a<!>
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@ class C {
|
||||
@a {
|
||||
<!NOT_A_LOOP_LABEL!>continue@f<!>
|
||||
continue
|
||||
continue@b
|
||||
<!UNREACHABLE_CODE!>continue@b<!>
|
||||
<!NOT_A_LOOP_LABEL!>continue@a<!>
|
||||
})
|
||||
|
||||
@@ -82,4 +82,4 @@ class C {
|
||||
}
|
||||
a<!UNSAFE_CALL!>.<!>compareTo("2")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ class C {
|
||||
@a {
|
||||
<error>break@f</error>
|
||||
break
|
||||
break@b
|
||||
<warning>break@b</warning>
|
||||
<error>break@a</error>
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@ class C {
|
||||
@a {
|
||||
<error>continue@f</error>
|
||||
continue
|
||||
continue@b
|
||||
<warning>continue@b</warning>
|
||||
<error>continue@a</error>
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user