KT-281 fixed

This commit is contained in:
svtk
2011-09-07 12:23:24 +04:00
parent af38e0d41a
commit 2f4377d7c0
5 changed files with 96 additions and 85 deletions
@@ -19,21 +19,19 @@ public class JetControlFlowProcessor {
private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>(); private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
private final JetSemanticServices semanticServices;
private final JetControlFlowBuilder builder; private final JetControlFlowBuilder builder;
private final BindingTrace trace; private final BindingTrace trace;
public JetControlFlowProcessor(JetSemanticServices semanticServices, BindingTrace trace, JetControlFlowBuilder builder) { public JetControlFlowProcessor(BindingTrace trace, JetControlFlowBuilder builder) {
this.semanticServices = semanticServices;
this.builder = builder; this.builder = builder;
this.trace = trace; this.trace = trace;
} }
public void generate(@NotNull JetElement subroutineElement, @NotNull JetExpression body) { public void generate(@NotNull JetElement subroutineElement, @NotNull JetExpression body) {
generateSubroutineControlFlow(subroutineElement, Collections.singletonList(body), false); generateSubroutineControlFlow(subroutineElement, Collections.singletonList(body));
} }
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body, boolean preferBlocks) { public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body) {
if (subroutineElement instanceof JetNamedDeclaration) { if (subroutineElement instanceof JetNamedDeclaration) {
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement; JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration); enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration);
@@ -41,7 +39,7 @@ public class JetControlFlowProcessor {
boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression; boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression;
builder.enterSubroutine(subroutineElement, functionLiteral); builder.enterSubroutine(subroutineElement, functionLiteral);
for (JetElement statement : body) { for (JetElement statement : body) {
statement.accept(new CFPVisitor(preferBlocks, false)); statement.accept(new CFPVisitor(false));
} }
builder.exitSubroutine(subroutineElement, functionLiteral); builder.exitSubroutine(subroutineElement, functionLiteral);
} }
@@ -91,22 +89,22 @@ public class JetControlFlowProcessor {
} }
private class CFPVisitor extends JetVisitorVoid { private class CFPVisitor extends JetVisitorVoid {
private final boolean preferBlock; // private final boolean preferBlock;
private final boolean inCondition; private final boolean inCondition;
private CFPVisitor(boolean preferBlock, boolean inCondition) { private CFPVisitor(boolean inCondition) {
this.preferBlock = preferBlock; // this.preferBlock = preferBlock;
this.inCondition = inCondition; this.inCondition = inCondition;
} }
private void value(@Nullable JetElement element, boolean preferBlock, boolean inCondition) { private void value(@Nullable JetElement element, boolean inCondition) {
if (element == null) return; if (element == null) return;
CFPVisitor visitor; CFPVisitor visitor;
if (this.preferBlock == preferBlock && this.inCondition == inCondition) { if (this.inCondition == inCondition) {
visitor = this; visitor = this;
} }
else { else {
visitor = new CFPVisitor(preferBlock, inCondition); visitor = new CFPVisitor(inCondition);
} }
element.accept(visitor); element.accept(visitor);
exitElement(element); exitElement(element);
@@ -116,7 +114,7 @@ public class JetControlFlowProcessor {
public void visitParenthesizedExpression(JetParenthesizedExpression expression) { public void visitParenthesizedExpression(JetParenthesizedExpression expression) {
JetExpression innerExpression = expression.getExpression(); JetExpression innerExpression = expression.getExpression();
if (innerExpression != null) { if (innerExpression != null) {
value(innerExpression, false, inCondition); value(innerExpression, inCondition);
} }
} }
@@ -154,7 +152,7 @@ public class JetControlFlowProcessor {
JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression); JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression);
if (deparenthesized != null) { if (deparenthesized != null) {
enterLabeledElement(labelName, deparenthesized); enterLabeledElement(labelName, deparenthesized);
value(labeledExpression, false, inCondition); value(labeledExpression, inCondition);
} }
} }
@@ -163,11 +161,11 @@ public class JetControlFlowProcessor {
IElementType operationType = expression.getOperationReference().getReferencedNameElementType(); IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
JetExpression right = expression.getRight(); JetExpression right = expression.getRight();
if (operationType == JetTokens.ANDAND) { if (operationType == JetTokens.ANDAND) {
value(expression.getLeft(), false, true); value(expression.getLeft(), true);
Label resultLabel = builder.createUnboundLabel(); Label resultLabel = builder.createUnboundLabel();
builder.jumpOnFalse(resultLabel); builder.jumpOnFalse(resultLabel);
if (right != null) { if (right != null) {
value(right, false, true); value(right, true);
} }
builder.bindLabel(resultLabel); builder.bindLabel(resultLabel);
if (!inCondition) { if (!inCondition) {
@@ -175,11 +173,11 @@ public class JetControlFlowProcessor {
} }
} }
else if (operationType == JetTokens.OROR) { else if (operationType == JetTokens.OROR) {
value(expression.getLeft(), false, true); value(expression.getLeft(), true);
Label resultLabel = builder.createUnboundLabel(); Label resultLabel = builder.createUnboundLabel();
builder.jumpOnTrue(resultLabel); builder.jumpOnTrue(resultLabel);
if (right != null) { if (right != null) {
value(right, false, true); value(right, true);
} }
builder.bindLabel(resultLabel); builder.bindLabel(resultLabel);
if (!inCondition) { if (!inCondition) {
@@ -189,7 +187,7 @@ public class JetControlFlowProcessor {
else if (operationType == JetTokens.EQ) { else if (operationType == JetTokens.EQ) {
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
if (right != null) { if (right != null) {
value(right, false, false); value(right, false);
} }
if (left instanceof JetSimpleNameExpression) { if (left instanceof JetSimpleNameExpression) {
builder.write(expression, left); builder.write(expression, left);
@@ -201,8 +199,8 @@ public class JetControlFlowProcessor {
assert !(left instanceof JetPredicateExpression) : left; // TODO assert !(left instanceof JetPredicateExpression) : left; // TODO
assert !(left instanceof JetHashQualifiedExpression) : left; // TODO assert !(left instanceof JetHashQualifiedExpression) : left; // TODO
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) left; JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) left;
value(qualifiedExpression.getReceiverExpression(), false, false); value(qualifiedExpression.getReceiverExpression(), false);
value(expression.getOperationReference(), false, false); value(expression.getOperationReference(), false);
builder.write(expression, left); builder.write(expression, left);
} else { } else {
builder.unsupported(expression); // TODO builder.unsupported(expression); // TODO
@@ -211,13 +209,13 @@ public class JetControlFlowProcessor {
else if (JetTypeInferrer.assignmentOperationNames.containsKey(operationType)) { else if (JetTypeInferrer.assignmentOperationNames.containsKey(operationType)) {
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
if (left != null) { if (left != null) {
value(left, false, false); value(left, false);
} }
if (right != null) { if (right != null) {
value(right, false, false); value(right, false);
} }
if (left instanceof JetSimpleNameExpression || left instanceof JetArrayAccessExpression) { if (left instanceof JetSimpleNameExpression || left instanceof JetArrayAccessExpression) {
value(expression.getOperationReference(), false, false); value(expression.getOperationReference(), false);
builder.write(expression, left); builder.write(expression, left);
} }
else if (left != null) { else if (left != null) {
@@ -225,21 +223,21 @@ public class JetControlFlowProcessor {
} }
} }
else { else {
value(expression.getLeft(), false, false); value(expression.getLeft(), false);
if (right != null) { if (right != null) {
value(right, false, false); value(right, false);
} }
value(expression.getOperationReference(), false, false); value(expression.getOperationReference(), false);
builder.read(expression); builder.read(expression);
} }
} }
private void visitAssignToArrayAccess(JetBinaryExpression expression, JetArrayAccessExpression arrayAccessExpression) { private void visitAssignToArrayAccess(JetBinaryExpression expression, JetArrayAccessExpression arrayAccessExpression) {
for (JetExpression index : arrayAccessExpression.getIndexExpressions()) { for (JetExpression index : arrayAccessExpression.getIndexExpressions()) {
value(index, false, false); value(index, false);
} }
value(arrayAccessExpression.getArrayExpression(), false, false); value(arrayAccessExpression.getArrayExpression(), false);
value(expression.getOperationReference(), false, false); value(expression.getOperationReference(), false);
builder.write(expression, arrayAccessExpression); // TODO : ??? builder.write(expression, arrayAccessExpression); // TODO : ???
} }
@@ -254,8 +252,8 @@ public class JetControlFlowProcessor {
visitLabeledExpression(referencedName.substring(1), baseExpression); visitLabeledExpression(referencedName.substring(1), baseExpression);
} }
else { else {
value(baseExpression, false, false); value(baseExpression, false);
value(operationSign, false, false); value(operationSign, false);
boolean incrementOrDecrement = isIncrementOrDecrement(operationType); boolean incrementOrDecrement = isIncrementOrDecrement(operationType);
if (incrementOrDecrement) { if (incrementOrDecrement) {
@@ -275,13 +273,13 @@ public class JetControlFlowProcessor {
public void visitIfExpression(JetIfExpression expression) { public void visitIfExpression(JetIfExpression expression) {
JetExpression condition = expression.getCondition(); JetExpression condition = expression.getCondition();
if (condition != null) { if (condition != null) {
value(condition, false, true); value(condition, true);
} }
Label elseLabel = builder.createUnboundLabel(); Label elseLabel = builder.createUnboundLabel();
builder.jumpOnFalse(elseLabel); builder.jumpOnFalse(elseLabel);
JetExpression thenBranch = expression.getThen(); JetExpression thenBranch = expression.getThen();
if (thenBranch != null) { if (thenBranch != null) {
value(thenBranch, true, inCondition); value(thenBranch, inCondition);
} }
else { else {
builder.readUnit(expression); builder.readUnit(expression);
@@ -291,7 +289,7 @@ public class JetControlFlowProcessor {
builder.bindLabel(elseLabel); builder.bindLabel(elseLabel);
JetExpression elseBranch = expression.getElse(); JetExpression elseBranch = expression.getElse();
if (elseBranch != null) { if (elseBranch != null) {
value(elseBranch, true, inCondition); value(elseBranch, inCondition);
} }
else { else {
builder.readUnit(expression); builder.readUnit(expression);
@@ -311,7 +309,7 @@ public class JetControlFlowProcessor {
// This checks are needed for the case of having e.g. return inside finally: 'try {return} finally{return}' // This checks are needed for the case of having e.g. return inside finally: 'try {return} finally{return}'
if (working) return; if (working) return;
working = true; working = true;
value(finallyBlock.getFinalExpression(), true, inCondition); value(finallyBlock.getFinalExpression(), inCondition);
working = false; working = false;
} }
}); });
@@ -319,7 +317,7 @@ public class JetControlFlowProcessor {
Label onException = builder.createUnboundLabel(); Label onException = builder.createUnboundLabel();
builder.nondeterministicJump(onException); builder.nondeterministicJump(onException);
value(expression.getTryBlock(), true, inCondition); value(expression.getTryBlock(), inCondition);
List<JetCatchClause> catchClauses = expression.getCatchClauses(); List<JetCatchClause> catchClauses = expression.getCatchClauses();
if (!catchClauses.isEmpty()) { if (!catchClauses.isEmpty()) {
@@ -331,7 +329,7 @@ public class JetControlFlowProcessor {
JetCatchClause catchClause = iterator.next(); JetCatchClause catchClause = iterator.next();
JetExpression catchBody = catchClause.getCatchBody(); JetExpression catchBody = catchClause.getCatchBody();
if (catchBody != null) { if (catchBody != null) {
value(catchBody, true, false); value(catchBody, false);
} }
if (iterator.hasNext()) { if (iterator.hasNext()) {
builder.nondeterministicJump(afterCatches); builder.nondeterministicJump(afterCatches);
@@ -345,7 +343,7 @@ public class JetControlFlowProcessor {
if (finallyBlock != null) { if (finallyBlock != null) {
builder.exitTryFinally(); builder.exitTryFinally();
value(finallyBlock.getFinalExpression(), true, inCondition); value(finallyBlock.getFinalExpression(), inCondition);
} }
} }
@@ -356,14 +354,14 @@ public class JetControlFlowProcessor {
builder.bindLabel(loopInfo.getConditionEntryPoint()); builder.bindLabel(loopInfo.getConditionEntryPoint());
JetExpression condition = expression.getCondition(); JetExpression condition = expression.getCondition();
if (condition != null) { if (condition != null) {
value(condition, false, true); value(condition, true);
} }
builder.jumpOnFalse(loopInfo.getExitPoint()); builder.jumpOnFalse(loopInfo.getExitPoint());
builder.bindLabel(loopInfo.getBodyEntryPoint()); builder.bindLabel(loopInfo.getBodyEntryPoint());
JetExpression body = expression.getBody(); JetExpression body = expression.getBody();
if (body != null) { if (body != null) {
value(body, true, false); value(body, false);
} }
builder.jump(loopInfo.getEntryPoint()); builder.jump(loopInfo.getEntryPoint());
builder.exitLoop(expression); builder.exitLoop(expression);
@@ -377,12 +375,12 @@ public class JetControlFlowProcessor {
builder.bindLabel(loopInfo.getBodyEntryPoint()); builder.bindLabel(loopInfo.getBodyEntryPoint());
JetExpression body = expression.getBody(); JetExpression body = expression.getBody();
if (body != null) { if (body != null) {
value(body, true, false); value(body, false);
} }
builder.bindLabel(loopInfo.getConditionEntryPoint()); builder.bindLabel(loopInfo.getConditionEntryPoint());
JetExpression condition = expression.getCondition(); JetExpression condition = expression.getCondition();
if (condition != null) { if (condition != null) {
value(condition, false, true); value(condition, true);
} }
builder.jumpOnTrue(loopInfo.getEntryPoint()); builder.jumpOnTrue(loopInfo.getEntryPoint());
builder.exitLoop(expression); builder.exitLoop(expression);
@@ -393,7 +391,7 @@ public class JetControlFlowProcessor {
public void visitForExpression(JetForExpression expression) { public void visitForExpression(JetForExpression expression) {
JetExpression loopRange = expression.getLoopRange(); JetExpression loopRange = expression.getLoopRange();
if (loopRange != null) { if (loopRange != null) {
value(loopRange, false, false); value(loopRange, false);
} }
// TODO : primitive cases // TODO : primitive cases
Label loopExitPoint = builder.createUnboundLabel(); Label loopExitPoint = builder.createUnboundLabel();
@@ -407,7 +405,7 @@ public class JetControlFlowProcessor {
builder.bindLabel(loopInfo.getBodyEntryPoint()); builder.bindLabel(loopInfo.getBodyEntryPoint());
JetExpression body = expression.getBody(); JetExpression body = expression.getBody();
if (body != null) { if (body != null) {
value(body, true, false); value(body, false);
} }
builder.nondeterministicJump(loopInfo.getEntryPoint()); builder.nondeterministicJump(loopInfo.getEntryPoint());
@@ -462,7 +460,7 @@ public class JetControlFlowProcessor {
public void visitReturnExpression(JetReturnExpression expression) { public void visitReturnExpression(JetReturnExpression expression) {
JetExpression returnedExpression = expression.getReturnedExpression(); JetExpression returnedExpression = expression.getReturnedExpression();
if (returnedExpression != null) { if (returnedExpression != null) {
value(returnedExpression, false, false); value(returnedExpression, false);
} }
JetSimpleNameExpression labelElement = expression.getTargetLabel(); JetSimpleNameExpression labelElement = expression.getTargetLabel();
JetElement subroutine; JetElement subroutine;
@@ -487,8 +485,12 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitBlockExpression(JetBlockExpression expression) { public void visitBlockExpression(JetBlockExpression expression) {
for (JetElement statement : expression.getStatements()) { List<JetElement> statements = expression.getStatements();
value(statement, true, false); for (JetElement statement : statements) {
value(statement, false);
}
if (statements.isEmpty()) {
builder.readUnit(expression);
} }
} }
@@ -506,26 +508,16 @@ public class JetControlFlowProcessor {
JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression(); JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression();
if (bodyExpression != null) { if (bodyExpression != null) {
List<JetElement> statements = bodyExpression.getStatements(); List<JetElement> statements = bodyExpression.getStatements();
if (preferBlock && !functionLiteral.hasParameterSpecification()) { generateSubroutineControlFlow(expression, statements);
for (JetElement statement : statements) {
value(statement, true, false);
}
if (statements.isEmpty()) {
builder.readUnit(expression);
}
}
else {
generateSubroutineControlFlow(expression, statements, true);
}
} }
} }
@Override @Override
public void visitQualifiedExpression(JetQualifiedExpression expression) { public void visitQualifiedExpression(JetQualifiedExpression expression) {
value(expression.getReceiverExpression(), false, false); value(expression.getReceiverExpression(), false);
JetExpression selectorExpression = expression.getSelectorExpression(); JetExpression selectorExpression = expression.getSelectorExpression();
if (selectorExpression != null) { if (selectorExpression != null) {
value(selectorExpression, false, false); value(selectorExpression, false);
} }
builder.read(expression); builder.read(expression);
} }
@@ -534,24 +526,24 @@ public class JetControlFlowProcessor {
for (ValueArgument argument : call.getValueArguments()) { for (ValueArgument argument : call.getValueArguments()) {
JetExpression argumentExpression = argument.getArgumentExpression(); JetExpression argumentExpression = argument.getArgumentExpression();
if (argumentExpression != null) { if (argumentExpression != null) {
value(argumentExpression, false, false); value(argumentExpression, false);
} }
} }
for (JetExpression functionLiteral : call.getFunctionLiteralArguments()) { for (JetExpression functionLiteral : call.getFunctionLiteralArguments()) {
value(functionLiteral, false, false); value(functionLiteral, false);
} }
} }
@Override @Override
public void visitCallExpression(JetCallExpression expression) { public void visitCallExpression(JetCallExpression expression) {
for (JetTypeProjection typeArgument : expression.getTypeArguments()) { for (JetTypeProjection typeArgument : expression.getTypeArguments()) {
value(typeArgument, false, false); value(typeArgument, false);
} }
visitCall(expression); visitCall(expression);
value(expression.getCalleeExpression(), false, false); value(expression.getCalleeExpression(), false);
builder.read(expression); builder.read(expression);
} }
@@ -567,7 +559,7 @@ public class JetControlFlowProcessor {
public void visitProperty(JetProperty property) { public void visitProperty(JetProperty property) {
JetExpression initializer = property.getInitializer(); JetExpression initializer = property.getInitializer();
if (initializer != null) { if (initializer != null) {
value(initializer, false, false); value(initializer, false);
builder.write(property, property); builder.write(property, property);
} }
} }
@@ -575,7 +567,7 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitTupleExpression(JetTupleExpression expression) { public void visitTupleExpression(JetTupleExpression expression) {
for (JetExpression entry : expression.getEntries()) { for (JetExpression entry : expression.getEntries()) {
value(entry, false, false); value(entry, false);
} }
builder.read(expression); builder.read(expression);
} }
@@ -584,7 +576,7 @@ public class JetControlFlowProcessor {
public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) { public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) {
IElementType operationType = expression.getOperationSign().getReferencedNameElementType(); IElementType operationType = expression.getOperationSign().getReferencedNameElementType();
if (operationType == JetTokens.COLON || operationType == JetTokens.AS_KEYWORD || operationType == JetTokens.AS_SAFE) { if (operationType == JetTokens.COLON || operationType == JetTokens.AS_KEYWORD || operationType == JetTokens.AS_SAFE) {
value(expression.getLeft(), false, false); value(expression.getLeft(), false);
builder.read(expression); builder.read(expression);
} }
else { else {
@@ -596,7 +588,7 @@ public class JetControlFlowProcessor {
public void visitThrowExpression(JetThrowExpression expression) { public void visitThrowExpression(JetThrowExpression expression) {
JetExpression thrownExpression = expression.getThrownExpression(); JetExpression thrownExpression = expression.getThrownExpression();
if (thrownExpression != null) { if (thrownExpression != null) {
value(thrownExpression, false, false); value(thrownExpression, false);
} }
builder.jumpToError(expression); builder.jumpToError(expression);
} }
@@ -604,16 +596,16 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitArrayAccessExpression(JetArrayAccessExpression expression) { public void visitArrayAccessExpression(JetArrayAccessExpression expression) {
for (JetExpression index : expression.getIndexExpressions()) { for (JetExpression index : expression.getIndexExpressions()) {
value(index, false, false); value(index, false);
} }
value(expression.getArrayExpression(), false, false); value(expression.getArrayExpression(), false);
// TODO : read 'get' or 'set' function // TODO : read 'get' or 'set' function
builder.read(expression); builder.read(expression);
} }
@Override @Override
public void visitIsExpression(JetIsExpression expression) { public void visitIsExpression(JetIsExpression expression) {
value(expression.getLeftHandSide(), false, inCondition); value(expression.getLeftHandSide(), inCondition);
// TODO : builder.read(expression.getPattern()); // TODO : builder.read(expression.getPattern());
builder.read(expression); builder.read(expression);
} }
@@ -624,7 +616,7 @@ public class JetControlFlowProcessor {
// TODO : else must be the last // TODO : else must be the last
JetExpression subjectExpression = expression.getSubjectExpression(); JetExpression subjectExpression = expression.getSubjectExpression();
if (subjectExpression != null) { if (subjectExpression != null) {
value(subjectExpression, false, inCondition); value(subjectExpression, inCondition);
} }
Label doneLabel = builder.createUnboundLabel(); Label doneLabel = builder.createUnboundLabel();
@@ -649,13 +641,13 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitWhenConditionCall(JetWhenConditionCall condition) { public void visitWhenConditionCall(JetWhenConditionCall condition) {
value(condition.getCallSuffixExpression(), false, inCondition); // TODO : inCondition? value(condition.getCallSuffixExpression(), inCondition); // TODO : inCondition?
} }
@Override @Override
public void visitWhenConditionInRange(JetWhenConditionInRange condition) { public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
value(condition.getRangeExpression(), false, inCondition); // TODO : inCondition? value(condition.getRangeExpression(), inCondition); // TODO : inCondition?
value(condition.getOperationReference(), false, inCondition); // TODO : inCondition? value(condition.getOperationReference(), inCondition); // TODO : inCondition?
// TODO : read the call to contains()... // TODO : read the call to contains()...
} }
@@ -676,7 +668,7 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitExpressionPattern(JetExpressionPattern pattern) { public void visitExpressionPattern(JetExpressionPattern pattern) {
value(pattern.getExpression(), false, inCondition); value(pattern.getExpression(), inCondition);
} }
@Override @Override
@@ -686,7 +678,7 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitDecomposerPattern(JetDecomposerPattern pattern) { public void visitDecomposerPattern(JetDecomposerPattern pattern) {
value(pattern.getDecomposerExpression(), false, inCondition); value(pattern.getDecomposerExpression(), inCondition);
pattern.getArgumentList().accept(this); pattern.getArgumentList().accept(this);
} }
@@ -719,7 +711,7 @@ public class JetControlFlowProcessor {
builder.nondeterministicJump(nextLabel); builder.nondeterministicJump(nextLabel);
builder.bindLabel(bodyLabel); builder.bindLabel(bodyLabel);
value(whenEntry.getExpression(), true, inCondition); value(whenEntry.getExpression(), inCondition);
builder.jump(doneLabel); builder.jump(doneLabel);
builder.bindLabel(nextLabel); builder.bindLabel(nextLabel);
nextLabel = builder.createUnboundLabel(); nextLabel = builder.createUnboundLabel();
@@ -741,17 +733,17 @@ public class JetControlFlowProcessor {
// } // }
// } // }
// } // }
value(expression.getObjectDeclaration(), false, inCondition); value(expression.getObjectDeclaration(), inCondition);
builder.read(expression); builder.read(expression);
} }
@Override @Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) { public void visitObjectDeclaration(JetObjectDeclaration declaration) {
for (JetDelegationSpecifier delegationSpecifier : declaration.getDelegationSpecifiers()) { for (JetDelegationSpecifier delegationSpecifier : declaration.getDelegationSpecifiers()) {
value(delegationSpecifier, false, inCondition); value(delegationSpecifier, inCondition);
} }
for (JetDeclaration jetDeclaration : declaration.getDeclarations()) { for (JetDeclaration jetDeclaration : declaration.getDeclarations()) {
FOR_LOCAL_CLASSES.value(jetDeclaration, false, false); FOR_LOCAL_CLASSES.value(jetDeclaration, false);
} }
} }
@@ -760,7 +752,7 @@ public class JetControlFlowProcessor {
for (JetStringTemplateEntry entry : expression.getEntries()) { for (JetStringTemplateEntry entry : expression.getEntries()) {
if (entry instanceof JetStringTemplateEntryWithExpression) { if (entry instanceof JetStringTemplateEntryWithExpression) {
JetStringTemplateEntryWithExpression entryWithExpression = (JetStringTemplateEntryWithExpression) entry; JetStringTemplateEntryWithExpression entryWithExpression = (JetStringTemplateEntryWithExpression) entry;
value(entryWithExpression.getExpression(), true, false); value(entryWithExpression.getExpression(), false);
} }
} }
builder.read(expression); builder.read(expression);
@@ -777,7 +769,7 @@ public class JetControlFlowProcessor {
} }
} }
private final CFPVisitor FOR_LOCAL_CLASSES = new CFPVisitor(false, false) { private final CFPVisitor FOR_LOCAL_CLASSES = new CFPVisitor(false) {
@Override @Override
public void visitNamedFunction(JetNamedFunction function) { public void visitNamedFunction(JetNamedFunction function) {
// Nothing // Nothing
@@ -802,7 +802,7 @@ public class ClassDescriptorResolver {
} }
}; };
JetControlFlowInstructionsGenerator instructionsGenerator = new JetControlFlowInstructionsGenerator(wrappedTrace); JetControlFlowInstructionsGenerator instructionsGenerator = new JetControlFlowInstructionsGenerator(wrappedTrace);
new JetControlFlowProcessor(semanticServices, trace, instructionsGenerator).generate(declaration, bodyExpression); new JetControlFlowProcessor(trace, instructionsGenerator).generate(declaration, bodyExpression);
wrappedTrace.close(); wrappedTrace.close();
return new JetFlowInformationProvider() { return new JetFlowInformationProvider() {
@Override @Override
+3
View File
@@ -84,6 +84,7 @@ fun foo(a : Boolean, b : Int) : Unit {}
--------------------- ---------------------
l0: l0:
<START> <START>
read (Unit)
l1: l1:
<END> <END>
error: error:
@@ -94,6 +95,7 @@ fun genfun<T>() : Unit {}
--------------------- ---------------------
l0: l0:
<START> <START>
read (Unit)
l1: l1:
<END> <END>
error: error:
@@ -104,6 +106,7 @@ fun flfun(f : fun () : Any) : Unit {}
--------------------- ---------------------
l0: l0:
<START> <START>
read (Unit)
l1: l1:
<END> <END>
error: error:
@@ -3,6 +3,7 @@ fun empty() {}
--------------------- ---------------------
l0: l0:
<START> <START>
read (Unit)
l1: l1:
<END> <END>
error: error:
@@ -148,3 +148,18 @@ fun f(): Int {
} }
fun f(): Int = if (1 < 2) 1 else returnNothing() fun f(): Int = if (1 < 2) 1 else returnNothing()
fun blockNoReturnIfEmptyIf(): Int {
if (1 < 2) <error>{}</error> else <error>{}</error>
}
fun blockNoReturnIfUnitInOneBranch(): Int {
if (1 < 2) {
return 1
} else {
if (3 < 4) <error>{
}</error> else {
return 21
}
}
}