Added loop parameter, catch parameter to flow

This commit is contained in:
svtk
2011-10-21 15:42:07 +04:00
parent ee561708dd
commit f0db1e8a21
2 changed files with 137 additions and 87 deletions
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.cfg;
import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
@@ -30,21 +31,94 @@ public class JetControlFlowProcessor {
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));
}
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body) {
boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression;
builder.enterSubroutine(subroutineElement, functionLiteral);
public void generateSubroutineControlFlow(@NotNull JetDeclaration subroutineElement, @NotNull List<? extends JetElement> body) {
builder.enterSubroutine(subroutineElement);
for (JetElement statement : body) {
statement.accept(new CFPVisitor(false));
}
builder.exitSubroutine(subroutineElement, functionLiteral);
builder.exitSubroutine(subroutineElement);
}
private class CFPVisitor extends JetVisitorVoid {
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) {
this.inCondition = inCondition;
@@ -278,6 +352,10 @@ public class JetControlFlowProcessor {
builder.bindLabel(onException);
for (Iterator<JetCatchClause> iterator = catchClauses.iterator(); iterator.hasNext(); ) {
JetCatchClause catchClause = iterator.next();
JetParameter catchParameter = catchClause.getCatchParameter();
if (catchParameter != null) {
builder.write(catchParameter, catchParameter);
}
JetExpression catchBody = catchClause.getCatchBody();
if (catchBody != null) {
value(catchBody, false);
@@ -344,6 +422,10 @@ public class JetControlFlowProcessor {
if (loopRange != null) {
value(loopRange, false);
}
JetParameter loopParameter = expression.getLoopParameter();
if (loopParameter != null) {
builder.write(loopParameter, loopParameter);
}
// TODO : primitive cases
Label loopExitPoint = builder.createUnboundLabel();
Label conditionEntryPoint = builder.createUnboundLabel();
@@ -428,7 +510,11 @@ public class JetControlFlowProcessor {
subroutine = builder.getCurrentSubroutine();
// 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) {
builder.returnNoValue(expression, subroutine);
}
@@ -465,10 +551,10 @@ public class JetControlFlowProcessor {
@Override
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression();
JetBlockExpression bodyExpression = functionLiteral.getBodyExpression();
if (bodyExpression != null) {
List<JetElement> statements = bodyExpression.getStatements();
generateSubroutineControlFlow(expression, statements);
generateSubroutineControlFlow(functionLiteral, statements);
}
}
@@ -576,8 +662,12 @@ public class JetControlFlowProcessor {
}
@Override
public void visitIsExpression(JetIsExpression expression) {
public void visitIsExpression(final JetIsExpression expression) {
value(expression.getLeftHandSide(), inCondition);
JetPattern pattern = expression.getPattern();
if (pattern != null) {
pattern.accept(patternVisitor);
}
// TODO : builder.read(expression.getPattern());
builder.read(expression);
}
@@ -608,73 +698,7 @@ public class JetControlFlowProcessor {
JetWhenCondition[] conditions = whenEntry.getConditions();
for (int i = 0; i < conditions.length; i++) {
JetWhenCondition condition = conditions[i];
condition.accept(new JetVisitorVoid() {
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());
}
});
condition.accept(conditionVisitor);
if (i + 1 < conditions.length) {
builder.nondeterministicJump(bodyLabel);
}
@@ -701,12 +725,35 @@ public class JetControlFlowProcessor {
@Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
for (JetDelegationSpecifier delegationSpecifier : declaration.getDelegationSpecifiers()) {
value(delegationSpecifier, inCondition);
Queue<Label> declarationLabels = new LinkedList<Label>();
List<JetDeclaration> declarations = declaration.getDeclarations();
for (JetDeclaration localDeclaration : declarations) {
declarationLabels.add(builder.createUnboundLabel());
}
for (JetDeclaration jetDeclaration : declaration.getDeclarations()) {
FOR_LOCAL_CLASSES.value(jetDeclaration, false);
builder.nondeterministicJump(Lists.newArrayList(declarationLabels));
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
+9 -6
View File
@@ -359,9 +359,10 @@ l0:
r(1) NEXT:[r(a)] PREV:[<START>]
r(a) NEXT:[r(..)] PREV:[r(1)]
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:
jmp?(l2) NEXT:[read (Unit), jmp?(l6)] PREV:[r(1..a)]
jmp?(l2) NEXT:[read (Unit), jmp?(l6)] PREV:[w(i)]
l4:
l5:
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(a) NEXT:[r(..)] PREV:[r(1)]
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:
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[r(1..a)]
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[w(i)]
l5:
l6:
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(a) NEXT:[r(..)] PREV:[r(1)]
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:
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[r(1..a)]
jmp?(l3) NEXT:[read (Unit), r(1)] PREV:[w(i)]
l5:
l6:
r(1) NEXT:[r(2)] PREV:[jmp?(l3), jmp(l5), jmp?(l5)]