Added loop parameter, catch parameter to flow
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.cfg;
|
package org.jetbrains.jet.lang.cfg;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -30,21 +31,94 @@ public class JetControlFlowProcessor {
|
|||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate(@NotNull JetElement subroutineElement, @NotNull JetExpression body) {
|
public void generate(@NotNull JetDeclaration subroutineElement, @NotNull JetExpression body) {
|
||||||
generateSubroutineControlFlow(subroutineElement, Collections.singletonList(body));
|
generateSubroutineControlFlow(subroutineElement, Collections.singletonList(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body) {
|
public void generateSubroutineControlFlow(@NotNull JetDeclaration subroutineElement, @NotNull List<? extends JetElement> body) {
|
||||||
boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression;
|
builder.enterSubroutine(subroutineElement);
|
||||||
builder.enterSubroutine(subroutineElement, functionLiteral);
|
|
||||||
for (JetElement statement : body) {
|
for (JetElement statement : body) {
|
||||||
statement.accept(new CFPVisitor(false));
|
statement.accept(new CFPVisitor(false));
|
||||||
}
|
}
|
||||||
builder.exitSubroutine(subroutineElement, functionLiteral);
|
builder.exitSubroutine(subroutineElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CFPVisitor extends JetVisitorVoid {
|
private class CFPVisitor extends JetVisitorVoid {
|
||||||
private final boolean inCondition;
|
private final boolean inCondition;
|
||||||
|
private final JetVisitorVoid conditionVisitor = new JetVisitorVoid() {
|
||||||
|
@Override
|
||||||
|
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
||||||
|
value(condition.getCallSuffixExpression(), CFPVisitor.this.inCondition); // TODO : inCondition?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
||||||
|
value(condition.getRangeExpression(), CFPVisitor.this.inCondition); // TODO : inCondition?
|
||||||
|
value(condition.getOperationReference(), CFPVisitor.this.inCondition); // TODO : inCondition?
|
||||||
|
// TODO : read the call to contains()...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) {
|
||||||
|
JetPattern pattern = condition.getPattern();
|
||||||
|
if (pattern != null) {
|
||||||
|
pattern.accept(patternVisitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJetElement(JetElement element) {
|
||||||
|
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private final JetVisitorVoid patternVisitor = new JetVisitorVoid() {
|
||||||
|
@Override
|
||||||
|
public void visitTypePattern(JetTypePattern typePattern) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitWildcardPattern(JetWildcardPattern pattern) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitExpressionPattern(JetExpressionPattern pattern) {
|
||||||
|
value(pattern.getExpression(), inCondition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTuplePattern(JetTuplePattern pattern) {
|
||||||
|
List<JetTuplePatternEntry> entries = pattern.getEntries();
|
||||||
|
for (JetTuplePatternEntry entry : entries) {
|
||||||
|
JetPattern entryPattern = entry.getPattern();
|
||||||
|
if (entryPattern != null) {
|
||||||
|
entryPattern.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDecomposerPattern(JetDecomposerPattern pattern) {
|
||||||
|
value(pattern.getDecomposerExpression(), inCondition);
|
||||||
|
pattern.getArgumentList().accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitBindingPattern(JetBindingPattern pattern) {
|
||||||
|
JetProperty variableDeclaration = pattern.getVariableDeclaration();
|
||||||
|
builder.write(pattern, variableDeclaration);
|
||||||
|
JetWhenCondition condition = pattern.getCondition();
|
||||||
|
if (condition != null) {
|
||||||
|
condition.accept(conditionVisitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJetElement(JetElement element) {
|
||||||
|
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private CFPVisitor(boolean inCondition) {
|
private CFPVisitor(boolean inCondition) {
|
||||||
this.inCondition = inCondition;
|
this.inCondition = inCondition;
|
||||||
@@ -278,6 +352,10 @@ public class JetControlFlowProcessor {
|
|||||||
builder.bindLabel(onException);
|
builder.bindLabel(onException);
|
||||||
for (Iterator<JetCatchClause> iterator = catchClauses.iterator(); iterator.hasNext(); ) {
|
for (Iterator<JetCatchClause> iterator = catchClauses.iterator(); iterator.hasNext(); ) {
|
||||||
JetCatchClause catchClause = iterator.next();
|
JetCatchClause catchClause = iterator.next();
|
||||||
|
JetParameter catchParameter = catchClause.getCatchParameter();
|
||||||
|
if (catchParameter != null) {
|
||||||
|
builder.write(catchParameter, catchParameter);
|
||||||
|
}
|
||||||
JetExpression catchBody = catchClause.getCatchBody();
|
JetExpression catchBody = catchClause.getCatchBody();
|
||||||
if (catchBody != null) {
|
if (catchBody != null) {
|
||||||
value(catchBody, false);
|
value(catchBody, false);
|
||||||
@@ -344,6 +422,10 @@ public class JetControlFlowProcessor {
|
|||||||
if (loopRange != null) {
|
if (loopRange != null) {
|
||||||
value(loopRange, false);
|
value(loopRange, false);
|
||||||
}
|
}
|
||||||
|
JetParameter loopParameter = expression.getLoopParameter();
|
||||||
|
if (loopParameter != null) {
|
||||||
|
builder.write(loopParameter, loopParameter);
|
||||||
|
}
|
||||||
// TODO : primitive cases
|
// TODO : primitive cases
|
||||||
Label loopExitPoint = builder.createUnboundLabel();
|
Label loopExitPoint = builder.createUnboundLabel();
|
||||||
Label conditionEntryPoint = builder.createUnboundLabel();
|
Label conditionEntryPoint = builder.createUnboundLabel();
|
||||||
@@ -428,7 +510,11 @@ public class JetControlFlowProcessor {
|
|||||||
subroutine = builder.getCurrentSubroutine();
|
subroutine = builder.getCurrentSubroutine();
|
||||||
// TODO : a context check
|
// TODO : a context check
|
||||||
}
|
}
|
||||||
if (subroutine instanceof JetFunction || subroutine instanceof JetFunctionLiteralExpression) {
|
//todo cache JetFunctionLiteral instead
|
||||||
|
if (subroutine instanceof JetFunctionLiteralExpression) {
|
||||||
|
subroutine = ((JetFunctionLiteralExpression) subroutine).getFunctionLiteral();
|
||||||
|
}
|
||||||
|
if (subroutine instanceof JetFunction) {
|
||||||
if (returnedExpression == null) {
|
if (returnedExpression == null) {
|
||||||
builder.returnNoValue(expression, subroutine);
|
builder.returnNoValue(expression, subroutine);
|
||||||
}
|
}
|
||||||
@@ -465,10 +551,10 @@ public class JetControlFlowProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
||||||
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
||||||
JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression();
|
JetBlockExpression bodyExpression = functionLiteral.getBodyExpression();
|
||||||
if (bodyExpression != null) {
|
if (bodyExpression != null) {
|
||||||
List<JetElement> statements = bodyExpression.getStatements();
|
List<JetElement> statements = bodyExpression.getStatements();
|
||||||
generateSubroutineControlFlow(expression, statements);
|
generateSubroutineControlFlow(functionLiteral, statements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,8 +662,12 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitIsExpression(JetIsExpression expression) {
|
public void visitIsExpression(final JetIsExpression expression) {
|
||||||
value(expression.getLeftHandSide(), inCondition);
|
value(expression.getLeftHandSide(), inCondition);
|
||||||
|
JetPattern pattern = expression.getPattern();
|
||||||
|
if (pattern != null) {
|
||||||
|
pattern.accept(patternVisitor);
|
||||||
|
}
|
||||||
// TODO : builder.read(expression.getPattern());
|
// TODO : builder.read(expression.getPattern());
|
||||||
builder.read(expression);
|
builder.read(expression);
|
||||||
}
|
}
|
||||||
@@ -608,73 +698,7 @@ public class JetControlFlowProcessor {
|
|||||||
JetWhenCondition[] conditions = whenEntry.getConditions();
|
JetWhenCondition[] conditions = whenEntry.getConditions();
|
||||||
for (int i = 0; i < conditions.length; i++) {
|
for (int i = 0; i < conditions.length; i++) {
|
||||||
JetWhenCondition condition = conditions[i];
|
JetWhenCondition condition = conditions[i];
|
||||||
condition.accept(new JetVisitorVoid() {
|
condition.accept(conditionVisitor);
|
||||||
private final JetVisitorVoid conditionVisitor = this;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
|
||||||
value(condition.getCallSuffixExpression(), inCondition); // TODO : inCondition?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
|
||||||
value(condition.getRangeExpression(), inCondition); // TODO : inCondition?
|
|
||||||
value(condition.getOperationReference(), inCondition); // TODO : inCondition?
|
|
||||||
// TODO : read the call to contains()...
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) {
|
|
||||||
JetPattern pattern = condition.getPattern();
|
|
||||||
if (pattern != null) {
|
|
||||||
pattern.accept(new JetVisitorVoid() {
|
|
||||||
@Override
|
|
||||||
public void visitTypePattern(JetTypePattern typePattern) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitWildcardPattern(JetWildcardPattern pattern) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitExpressionPattern(JetExpressionPattern pattern) {
|
|
||||||
value(pattern.getExpression(), inCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitTuplePattern(JetTuplePattern pattern) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDecomposerPattern(JetDecomposerPattern pattern) {
|
|
||||||
value(pattern.getDecomposerExpression(), inCondition);
|
|
||||||
pattern.getArgumentList().accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitBindingPattern(JetBindingPattern pattern) {
|
|
||||||
JetWhenCondition condition = pattern.getCondition();
|
|
||||||
if (condition != null) {
|
|
||||||
condition.accept(conditionVisitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitJetElement(JetElement element) {
|
|
||||||
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitJetElement(JetElement element) {
|
|
||||||
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (i + 1 < conditions.length) {
|
if (i + 1 < conditions.length) {
|
||||||
builder.nondeterministicJump(bodyLabel);
|
builder.nondeterministicJump(bodyLabel);
|
||||||
}
|
}
|
||||||
@@ -701,12 +725,35 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
|
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
|
||||||
for (JetDelegationSpecifier delegationSpecifier : declaration.getDelegationSpecifiers()) {
|
Queue<Label> declarationLabels = new LinkedList<Label>();
|
||||||
value(delegationSpecifier, inCondition);
|
List<JetDeclaration> declarations = declaration.getDeclarations();
|
||||||
|
for (JetDeclaration localDeclaration : declarations) {
|
||||||
|
declarationLabels.add(builder.createUnboundLabel());
|
||||||
}
|
}
|
||||||
for (JetDeclaration jetDeclaration : declaration.getDeclarations()) {
|
builder.nondeterministicJump(Lists.newArrayList(declarationLabels));
|
||||||
FOR_LOCAL_CLASSES.value(jetDeclaration, false);
|
for (JetDeclaration localDeclaration : declarations) {
|
||||||
|
if (localDeclaration instanceof JetNamedDeclaration) {
|
||||||
|
if (localDeclaration instanceof JetFunction) {
|
||||||
|
//TODO
|
||||||
|
generate(localDeclaration, ((JetFunction) localDeclaration).getBodyExpression());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
generate(localDeclaration, localDeclaration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//todo
|
||||||
|
generate(declaration, localDeclaration);
|
||||||
|
}
|
||||||
|
builder.bindLabel(declarationLabels.remove());
|
||||||
}
|
}
|
||||||
|
// for (JetDelegationSpecifier delegationSpecifier : declaration.getDelegationSpecifiers()) {
|
||||||
|
// value(delegationSpecifier, inCondition);
|
||||||
|
// }
|
||||||
|
// for (JetDeclaration jetDeclaration : declaration.getDeclarations()) {
|
||||||
|
// //FOR_LOCAL_CLASSES.
|
||||||
|
// value(jetDeclaration, false);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -359,9 +359,10 @@ l0:
|
|||||||
r(1) NEXT:[r(a)] PREV:[<START>]
|
r(1) NEXT:[r(a)] PREV:[<START>]
|
||||||
r(a) NEXT:[r(..)] PREV:[r(1)]
|
r(a) NEXT:[r(..)] PREV:[r(1)]
|
||||||
r(..) NEXT:[r(1..a)] PREV:[r(a)]
|
r(..) NEXT:[r(1..a)] PREV:[r(a)]
|
||||||
r(1..a) NEXT:[jmp?(l2)] PREV:[r(..)]
|
r(1..a) NEXT:[w(i)] PREV:[r(..)]
|
||||||
|
w(i) NEXT:[jmp?(l2)] PREV:[r(1..a)]
|
||||||
l3:
|
l3:
|
||||||
jmp?(l2) NEXT:[read (Unit), jmp?(l6)] PREV:[r(1..a)]
|
jmp?(l2) NEXT:[read (Unit), jmp?(l6)] PREV:[w(i)]
|
||||||
l4:
|
l4:
|
||||||
l5:
|
l5:
|
||||||
jmp?(l6) NEXT:[r(2), r(1)] PREV:[jmp?(l2), jmp(l4), jmp?(l4)]
|
jmp?(l6) NEXT:[r(2), r(1)] PREV:[jmp?(l2), jmp(l4), jmp?(l4)]
|
||||||
@@ -408,9 +409,10 @@ l0:
|
|||||||
r(1) NEXT:[r(a)] PREV:[jmp?(l2)]
|
r(1) NEXT:[r(a)] PREV:[jmp?(l2)]
|
||||||
r(a) NEXT:[r(..)] PREV:[r(1)]
|
r(a) NEXT:[r(..)] PREV:[r(1)]
|
||||||
r(..) NEXT:[r(1..a)] PREV:[r(a)]
|
r(..) NEXT:[r(1..a)] PREV:[r(a)]
|
||||||
r(1..a) NEXT:[jmp?(l3)] PREV:[r(..)]
|
r(1..a) NEXT:[w(i)] PREV:[r(..)]
|
||||||
|
w(i) NEXT:[jmp?(l3)] PREV:[r(1..a)]
|
||||||
l4:
|
l4:
|
||||||
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[r(1..a)]
|
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[w(i)]
|
||||||
l5:
|
l5:
|
||||||
l6:
|
l6:
|
||||||
r(1) NEXT:[r(2)] PREV:[jmp?(l3), jmp(l5), jmp?(l5)]
|
r(1) NEXT:[r(2)] PREV:[jmp?(l3), jmp(l5), jmp?(l5)]
|
||||||
@@ -455,9 +457,10 @@ l0:
|
|||||||
r(1) NEXT:[r(a)] PREV:[jmp?(l2)]
|
r(1) NEXT:[r(a)] PREV:[jmp?(l2)]
|
||||||
r(a) NEXT:[r(..)] PREV:[r(1)]
|
r(a) NEXT:[r(..)] PREV:[r(1)]
|
||||||
r(..) NEXT:[r(1..a)] PREV:[r(a)]
|
r(..) NEXT:[r(1..a)] PREV:[r(a)]
|
||||||
r(1..a) NEXT:[jmp?(l3)] PREV:[r(..)]
|
r(1..a) NEXT:[w(i)] PREV:[r(..)]
|
||||||
|
w(i) NEXT:[jmp?(l3)] PREV:[r(1..a)]
|
||||||
l4:
|
l4:
|
||||||
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[r(1..a)]
|
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[w(i)]
|
||||||
l5:
|
l5:
|
||||||
l6:
|
l6:
|
||||||
r(1) NEXT:[r(2)] PREV:[jmp?(l3), jmp(l5), jmp?(l5)]
|
r(1) NEXT:[r(2)] PREV:[jmp?(l3), jmp(l5), jmp?(l5)]
|
||||||
|
|||||||
Reference in New Issue
Block a user