Some CF generated for closures
This commit is contained in:
@@ -94,6 +94,8 @@ public interface JetNodeTypes {
|
|||||||
JetNodeType OPERATION_REFERENCE = new JetNodeType("OPERATION_REFERENCE", JetSimpleNameExpression.class);
|
JetNodeType OPERATION_REFERENCE = new JetNodeType("OPERATION_REFERENCE", JetSimpleNameExpression.class);
|
||||||
JetNodeType LABEL_REFERENCE = new JetNodeType("LABEL_REFERENCE", JetSimpleNameExpression.class);
|
JetNodeType LABEL_REFERENCE = new JetNodeType("LABEL_REFERENCE", JetSimpleNameExpression.class);
|
||||||
|
|
||||||
|
JetNodeType LABEL_QUALIFIER = new JetNodeType("LABEL_QUALIFIER", JetContainerNode.class);
|
||||||
|
|
||||||
JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class);
|
JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class);
|
||||||
JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class);
|
JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class);
|
||||||
JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class);
|
JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class);
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
public void visitConstantExpression(JetConstantExpression expression) {
|
public void visitConstantExpression(JetConstantExpression expression) {
|
||||||
myStack.push(StackValue.constant(expression.getValue()));
|
myStack.push(StackValue.constant(expression.getValue()));
|
||||||
/*
|
/*
|
||||||
Object value = expression.getValue();
|
Object value = element.getValue();
|
||||||
v.aconst(value);
|
v.aconst(value);
|
||||||
|
|
||||||
if (value instanceof Integer) {
|
if (value instanceof Integer) {
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ public interface JetControlFlowBuilder {
|
|||||||
void exitTryFinally();
|
void exitTryFinally();
|
||||||
|
|
||||||
// Subroutines
|
// Subroutines
|
||||||
void enterSubroutine(@NotNull JetElement subroutine);
|
void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral);
|
||||||
void exitSubroutine(@NotNull JetElement subroutine);
|
void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
JetElement getCurrentSubroutine();
|
JetElement getCurrentSubroutine();
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package org.jetbrains.jet.lang.cfg;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetBlockExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
|
||||||
|
protected JetControlFlowBuilder builder;
|
||||||
|
|
||||||
|
public JetControlFlowBuilderAdapter(JetControlFlowBuilder builder) {
|
||||||
|
this.builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readNode(@NotNull JetExpression expression) {
|
||||||
|
builder.readNode(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public Label createUnboundLabel() {
|
||||||
|
return builder.createUnboundLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindLabel(@NotNull Label label) {
|
||||||
|
builder.bindLabel(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void jump(@NotNull Label label) {
|
||||||
|
builder.jump(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void jumpOnFalse(@NotNull Label label) {
|
||||||
|
builder.jumpOnFalse(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void jumpOnTrue(@NotNull Label label) {
|
||||||
|
builder.jumpOnTrue(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nondeterministicJump(Label label) {
|
||||||
|
builder.nondeterministicJump(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Label getEntryPoint(@NotNull JetElement labelElement) {
|
||||||
|
return builder.getEntryPoint(labelElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Label getExitPoint(@NotNull JetElement labelElement) {
|
||||||
|
return builder.getExitPoint(labelElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
||||||
|
return builder.enterLoop(expression, loopExitPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exitLoop(@NotNull JetExpression expression) {
|
||||||
|
builder.exitLoop(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JetElement getCurrentLoop() {
|
||||||
|
return builder.getCurrentLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
||||||
|
builder.enterTryFinally(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exitTryFinally() {
|
||||||
|
builder.exitTryFinally();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
||||||
|
builder.enterSubroutine(subroutine, isFunctionLiteral);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
||||||
|
builder.exitSubroutine(subroutine, functionLiteral);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JetElement getCurrentSubroutine() {
|
||||||
|
return builder.getCurrentSubroutine();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void returnValue(@NotNull JetElement subroutine) {
|
||||||
|
builder.returnValue(subroutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void returnNoValue(@NotNull JetElement subroutine) {
|
||||||
|
builder.returnNoValue(subroutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unsupported(JetElement element) {
|
||||||
|
builder.unsupported(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -155,8 +155,8 @@ package org.jetbrains.jet.lang.cfg;
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @Override
|
// @Override
|
||||||
// public void readNode(JetExpression expression) {
|
// public void readNode(JetExpression element) {
|
||||||
// createNode(expression);
|
// createNode(element);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @Override
|
// @Override
|
||||||
@@ -236,7 +236,7 @@ package org.jetbrains.jet.lang.cfg;
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @Override
|
// @Override
|
||||||
// public void enterTryFinally(JetBlockExpression expression) {
|
// public void enterTryFinally(JetBlockExpression element) {
|
||||||
// throw new UnsupportedOperationException(); // TODO
|
// throw new UnsupportedOperationException(); // TODO
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package org.jetbrains.jet.lang.cfg;
|
package org.jetbrains.jet.lang.cfg;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.types.BindingTrace;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -18,10 +19,12 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
private final JetSemanticServices semanticServices;
|
private final JetSemanticServices semanticServices;
|
||||||
private final JetControlFlowBuilder builder;
|
private final JetControlFlowBuilder builder;
|
||||||
|
private final BindingTrace trace;
|
||||||
|
|
||||||
public JetControlFlowProcessor(JetSemanticServices semanticServices, JetControlFlowBuilder builder) {
|
public JetControlFlowProcessor(JetSemanticServices semanticServices, BindingTrace trace, JetControlFlowBuilder builder) {
|
||||||
this.semanticServices = semanticServices;
|
this.semanticServices = semanticServices;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
|
this.trace = trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate(@NotNull JetElement subroutineElement, @NotNull JetExpression body) {
|
public void generate(@NotNull JetElement subroutineElement, @NotNull JetExpression body) {
|
||||||
@@ -29,11 +32,16 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body, boolean preferBlocks) {
|
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body, boolean preferBlocks) {
|
||||||
builder.enterSubroutine(subroutineElement);
|
if (subroutineElement instanceof JetNamedDeclaration) {
|
||||||
|
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
|
||||||
|
enterLabeledElement(namedDeclaration.getName(), namedDeclaration);
|
||||||
|
}
|
||||||
|
boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression;
|
||||||
|
builder.enterSubroutine(subroutineElement, functionLiteral);
|
||||||
for (JetElement statement : body) {
|
for (JetElement statement : body) {
|
||||||
statement.accept(new CFPVisitor(preferBlocks));
|
statement.accept(new CFPVisitor(preferBlocks));
|
||||||
}
|
}
|
||||||
builder.exitSubroutine(subroutineElement);
|
builder.exitSubroutine(subroutineElement, functionLiteral);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
|
private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
|
||||||
@@ -46,16 +54,36 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void exitElement(JetElement element) {
|
private void exitElement(JetElement element) {
|
||||||
// for (Iterator<Map.Entry<String, JetElement>> iterator = labeledElements.entrySet().iterator(); iterator.hasNext(); ) {
|
// TODO : really suboptimal
|
||||||
// Map.Entry<String, JetElement> entry = iterator.next();
|
for (Iterator<Map.Entry<String, Stack<JetElement>>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) {
|
||||||
// if (entry.getValue() == element) {
|
Map.Entry<String, Stack<JetElement>> entry = mapIter.next();
|
||||||
// iterator.remove();
|
Stack<JetElement> stack = entry.getValue();
|
||||||
// }
|
for (Iterator<JetElement> stackIter = stack.iterator(); stackIter.hasNext(); ) {
|
||||||
// }
|
JetElement recorded = stackIter.next();
|
||||||
|
if (recorded == element) {
|
||||||
|
stackIter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
mapIter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JetElement resolveLabel(@NotNull String labelName, @NotNull ASTNode labelNode) {
|
@Nullable
|
||||||
throw new UnsupportedOperationException(); // TODO
|
private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression) {
|
||||||
|
Stack<JetElement> stack = labeledElements.get(labelName);
|
||||||
|
if (stack == null || stack.isEmpty()) {
|
||||||
|
semanticServices.getErrorHandler().unresolvedReference(labelExpression);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (stack.size() > 1) {
|
||||||
|
semanticServices.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope");
|
||||||
|
}
|
||||||
|
|
||||||
|
JetElement result = stack.peek();
|
||||||
|
trace.recordLabelResolution(labelExpression, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CFPVisitor extends JetVisitor {
|
private class CFPVisitor extends JetVisitor {
|
||||||
@@ -74,6 +102,7 @@ public class JetControlFlowProcessor {
|
|||||||
visitor = new CFPVisitor(preferBlock);
|
visitor = new CFPVisitor(preferBlock);
|
||||||
}
|
}
|
||||||
element.accept(visitor);
|
element.accept(visitor);
|
||||||
|
exitElement(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -88,8 +117,14 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression) {
|
public void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression) {
|
||||||
enterLabeledElement(expression.getLabelName(), expression.getLabeledExpression());
|
String labelName = expression.getLabelName();
|
||||||
value(expression.getLabeledExpression(), false);
|
JetExpression labeledExpression = expression.getLabeledExpression();
|
||||||
|
visitLabeledExpression(labelName, labeledExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitLabeledExpression(@NotNull String labelName, @NotNull JetExpression labeledExpression) {
|
||||||
|
enterLabeledElement(labelName, labeledExpression);
|
||||||
|
value(labeledExpression, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -121,6 +156,17 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitUnaryExpression(JetUnaryExpression expression) {
|
||||||
|
IElementType operationType = expression.getOperationSign().getReferencedNameElementType();
|
||||||
|
if (JetTokens.LABELS.contains(operationType)) {
|
||||||
|
visitLabeledExpression(expression.getOperationSign().getReferencedName().substring(1), expression.getBaseExpression());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
visitElement(expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitIfExpression(JetIfExpression expression) {
|
public void visitIfExpression(JetIfExpression expression) {
|
||||||
value(expression.getCondition(), false);
|
value(expression.getCondition(), false);
|
||||||
@@ -135,7 +181,7 @@ public class JetControlFlowProcessor {
|
|||||||
value(elseBranch, true);
|
value(elseBranch, true);
|
||||||
}
|
}
|
||||||
builder.bindLabel(resultLabel);
|
builder.bindLabel(resultLabel);
|
||||||
// builder.readNode(expression);
|
// builder.readNode(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -210,7 +256,7 @@ public class JetControlFlowProcessor {
|
|||||||
public void visitBreakExpression(JetBreakExpression expression) {
|
public void visitBreakExpression(JetBreakExpression expression) {
|
||||||
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
||||||
Label exitPoint = (labelElement != null)
|
Label exitPoint = (labelElement != null)
|
||||||
? builder.getExitPoint(labelElement)
|
? builder.getExitPoint(resolveLabel(expression.getLabelName(), expression.getTargetLabel()))
|
||||||
: builder.getExitPoint(builder.getCurrentLoop());
|
: builder.getExitPoint(builder.getCurrentLoop());
|
||||||
builder.jump(exitPoint);
|
builder.jump(exitPoint);
|
||||||
}
|
}
|
||||||
@@ -219,7 +265,7 @@ public class JetControlFlowProcessor {
|
|||||||
public void visitContinueExpression(JetContinueExpression expression) {
|
public void visitContinueExpression(JetContinueExpression expression) {
|
||||||
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
||||||
if (labelElement != null) {
|
if (labelElement != null) {
|
||||||
builder.jump(builder.getEntryPoint(labelElement));
|
builder.jump(builder.getEntryPoint(resolveLabel(expression.getLabelName(), expression.getTargetLabel())));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
builder.jump(builder.getEntryPoint(builder.getCurrentLoop()));
|
builder.jump(builder.getEntryPoint(builder.getCurrentLoop()));
|
||||||
@@ -234,7 +280,7 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
||||||
JetElement subroutine = (labelElement != null)
|
JetElement subroutine = (labelElement != null)
|
||||||
? resolveLabel(expression.getLabelName(), expression.getTargetLabel().getNode())
|
? resolveLabel(expression.getLabelName(), expression.getTargetLabel())
|
||||||
: builder.getCurrentSubroutine();
|
: builder.getCurrentSubroutine();
|
||||||
if (returnedExpression == null) {
|
if (returnedExpression == null) {
|
||||||
builder.returnNoValue(subroutine);
|
builder.returnNoValue(subroutine);
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public abstract class ExpressionInstruction extends Instruction {
|
|
||||||
protected final JetExpression expression;
|
|
||||||
|
|
||||||
public ExpressionInstruction(@NotNull JetExpression expression) {
|
|
||||||
this.expression = expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JetExpression getExpression() {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class FunctionLiteralValueInstruction extends InstructionWithNext {
|
||||||
|
|
||||||
|
private Pseudocode body;
|
||||||
|
|
||||||
|
public FunctionLiteralValueInstruction(@NotNull JetElement element) {
|
||||||
|
super(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pseudocode getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(Pseudocode body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(InstructionVisitor visitor) {
|
||||||
|
visitor.visitFunctionLiteralValue(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "rf(" + element.getText() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,12 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class InstructionVisitor {
|
public class InstructionVisitor {
|
||||||
public void visitRead(ValueInstruction instruction) {
|
public void visitReadValue(ReadValueInstruction instruction) {
|
||||||
visitInstruction(instruction);
|
visitInstructionWithNext(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
||||||
|
visitInstructionWithNext(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
|
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
|
||||||
@@ -24,6 +28,14 @@ public class InstructionVisitor {
|
|||||||
visitJump(instruction);
|
visitJump(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||||
|
visitJump(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
|
||||||
|
visitInstructionWithNext(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
|
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
|
||||||
visitInstruction(instruction);
|
visitInstruction(instruction);
|
||||||
}
|
}
|
||||||
@@ -32,10 +44,10 @@ public class InstructionVisitor {
|
|||||||
visitInstruction(instruction);
|
visitInstruction(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitInstruction(Instruction instruction) {
|
public void visitInstructionWithNext(InstructionWithNext instruction) {
|
||||||
|
visitInstruction(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
public void visitInstruction(Instruction instruction) {
|
||||||
visitJump(instruction);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public abstract class InstructionWithNext extends ExpressionInstruction {
|
public abstract class InstructionWithNext extends JetElementInstruction {
|
||||||
private Instruction next;
|
private Instruction next;
|
||||||
|
|
||||||
public InstructionWithNext(JetExpression expression) {
|
protected InstructionWithNext(@NotNull JetElement element) {
|
||||||
super(expression);
|
super(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction getNext() {
|
public Instruction getNext() {
|
||||||
|
|||||||
+160
-106
@@ -1,7 +1,9 @@
|
|||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.cfg.JetControlFlowBuilder;
|
import org.jetbrains.jet.lang.cfg.JetControlFlowBuilder;
|
||||||
|
import org.jetbrains.jet.lang.cfg.JetControlFlowBuilderAdapter;
|
||||||
import org.jetbrains.jet.lang.cfg.Label;
|
import org.jetbrains.jet.lang.cfg.Label;
|
||||||
import org.jetbrains.jet.lang.psi.JetBlockExpression;
|
import org.jetbrains.jet.lang.psi.JetBlockExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
@@ -14,7 +16,55 @@ import java.util.Stack;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class JetControlFlowInstructionsGenerator implements JetControlFlowBuilder {
|
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
|
||||||
|
|
||||||
|
private int labelCount = 0;
|
||||||
|
private final Stack<JetControlFlowInstructionsGeneratorWorker> builders = new Stack<JetControlFlowInstructionsGeneratorWorker>();
|
||||||
|
|
||||||
|
public JetControlFlowInstructionsGenerator() {
|
||||||
|
super(null);
|
||||||
|
pushBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushBuilder() {
|
||||||
|
Pseudocode parentPseudocode = builder == null ? new Pseudocode(null) : builders.peek().getPseudocode();
|
||||||
|
JetControlFlowInstructionsGeneratorWorker worker = new JetControlFlowInstructionsGeneratorWorker(parentPseudocode);
|
||||||
|
builders.push(worker);
|
||||||
|
builder = worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JetControlFlowInstructionsGeneratorWorker popBuilder() {
|
||||||
|
JetControlFlowInstructionsGeneratorWorker worker = builders.pop();
|
||||||
|
builder = builders.peek();
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
||||||
|
if (isFunctionLiteral) {
|
||||||
|
pushBuilder();
|
||||||
|
builder.enterSubroutine(subroutine, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.enterSubroutine(subroutine, isFunctionLiteral);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
||||||
|
super.exitSubroutine(subroutine, functionLiteral);
|
||||||
|
if (functionLiteral) {
|
||||||
|
JetControlFlowInstructionsGeneratorWorker worker = popBuilder();
|
||||||
|
JetControlFlowInstructionsGeneratorWorker builder = builders.peek();
|
||||||
|
FunctionLiteralValueInstruction instruction = new FunctionLiteralValueInstruction(subroutine);
|
||||||
|
builder.add(instruction);
|
||||||
|
instruction.setBody(worker.getPseudocode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pseudocode getPseudocode() {
|
||||||
|
return builders.peek().getPseudocode();
|
||||||
|
}
|
||||||
|
|
||||||
private static class BlockInfo {
|
private static class BlockInfo {
|
||||||
private final JetElement element;
|
private final JetElement element;
|
||||||
@@ -40,137 +90,141 @@ public class JetControlFlowInstructionsGenerator implements JetControlFlowBuilde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Stack<BlockInfo> loopInfo = new Stack<BlockInfo>();
|
private class JetControlFlowInstructionsGeneratorWorker implements JetControlFlowBuilder {
|
||||||
private final Stack<BlockInfo> subroutineInfo = new Stack<BlockInfo>();
|
private final Stack<BlockInfo> loopInfo = new Stack<BlockInfo>();
|
||||||
private final Map<JetElement, BlockInfo> elementToBlockInfo = new HashMap<JetElement, BlockInfo>();
|
private final Stack<BlockInfo> subroutineInfo = new Stack<BlockInfo>();
|
||||||
|
|
||||||
private int labelCount = 0;
|
private final Map<JetElement, BlockInfo> elementToBlockInfo = new HashMap<JetElement, BlockInfo>();
|
||||||
|
|
||||||
private final Pseudocode pseudocode = new Pseudocode();
|
private final Pseudocode pseudocode;
|
||||||
|
|
||||||
public Pseudocode getPseudocode() {
|
private JetControlFlowInstructionsGeneratorWorker(@Nullable Pseudocode parent) {
|
||||||
return pseudocode;
|
this.pseudocode = new Pseudocode(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(Instruction instruction) {
|
public Pseudocode getPseudocode() {
|
||||||
pseudocode.getInstructions().add(instruction);
|
return pseudocode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private void add(Instruction instruction) {
|
||||||
@Override
|
pseudocode.addInstruction(instruction);
|
||||||
public final Label createUnboundLabel() {
|
}
|
||||||
return new Label("l" + labelCount++);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public final Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
@Override
|
||||||
Label label = createUnboundLabel();
|
public final Label createUnboundLabel() {
|
||||||
bindLabel(label);
|
return new Label("l" + labelCount++);
|
||||||
BlockInfo blockInfo = new BlockInfo(expression, label, loopExitPoint);
|
}
|
||||||
loopInfo.push(blockInfo);
|
|
||||||
elementToBlockInfo.put(expression, blockInfo);
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void exitLoop(@NotNull JetExpression expression) {
|
public final Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
||||||
BlockInfo info = loopInfo.pop();
|
Label label = createUnboundLabel();
|
||||||
elementToBlockInfo.remove(expression);
|
bindLabel(label);
|
||||||
bindLabel(info.getExitPoint());
|
BlockInfo blockInfo = new BlockInfo(expression, label, loopExitPoint);
|
||||||
}
|
loopInfo.push(blockInfo);
|
||||||
|
elementToBlockInfo.put(expression, blockInfo);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetElement getCurrentLoop() {
|
public final void exitLoop(@NotNull JetExpression expression) {
|
||||||
return loopInfo.empty() ? null : loopInfo.peek().getElement();
|
BlockInfo info = loopInfo.pop();
|
||||||
}
|
elementToBlockInfo.remove(expression);
|
||||||
|
bindLabel(info.getExitPoint());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterSubroutine(@NotNull JetElement subroutine) {
|
public JetElement getCurrentLoop() {
|
||||||
Label entryPoint = createUnboundLabel();
|
return loopInfo.empty() ? null : loopInfo.peek().getElement();
|
||||||
BlockInfo blockInfo = new BlockInfo(subroutine, entryPoint, createUnboundLabel());
|
}
|
||||||
subroutineInfo.push(blockInfo);
|
|
||||||
elementToBlockInfo.put(subroutine, blockInfo);
|
|
||||||
bindLabel(entryPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetElement getCurrentSubroutine() {
|
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
||||||
return subroutineInfo.empty() ? null : subroutineInfo.peek().getElement();
|
Label entryPoint = createUnboundLabel();
|
||||||
}
|
BlockInfo blockInfo = new BlockInfo(subroutine, entryPoint, createUnboundLabel());
|
||||||
|
subroutineInfo.push(blockInfo);
|
||||||
|
elementToBlockInfo.put(subroutine, blockInfo);
|
||||||
|
bindLabel(entryPoint);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Label getEntryPoint(@NotNull JetElement labelElement) {
|
public JetElement getCurrentSubroutine() {
|
||||||
return elementToBlockInfo.get(labelElement).getEntryPoint();
|
return subroutineInfo.empty() ? null : subroutineInfo.peek().getElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Label getExitPoint(@NotNull JetElement labelElement) {
|
public Label getEntryPoint(@NotNull JetElement labelElement) {
|
||||||
return elementToBlockInfo.get(labelElement).getExitPoint();
|
return elementToBlockInfo.get(labelElement).getEntryPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Label getExitPoint(@NotNull JetElement labelElement) {
|
||||||
|
return elementToBlockInfo.get(labelElement).getExitPoint();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitSubroutine(@NotNull JetElement subroutine) {
|
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
||||||
bindLabel(getExitPoint(subroutine));
|
bindLabel(getExitPoint(subroutine));
|
||||||
add(new SubroutineExitInstruction(subroutine));
|
add(new SubroutineExitInstruction(subroutine));
|
||||||
elementToBlockInfo.remove(subroutine);
|
elementToBlockInfo.remove(subroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnValue(@NotNull JetElement subroutine) {
|
public void returnValue(@NotNull JetElement subroutine) {
|
||||||
add(new ReturnValueInstruction(getExitPoint(subroutine)));
|
add(new ReturnValueInstruction(getExitPoint(subroutine)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnNoValue(@NotNull JetElement subroutine) {
|
public void returnNoValue(@NotNull JetElement subroutine) {
|
||||||
add(new ReturnNoValueInstruction(getExitPoint(subroutine)));
|
add(new ReturnNoValueInstruction(getExitPoint(subroutine)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readNode(@NotNull JetExpression expression) {
|
public void readNode(@NotNull JetExpression expression) {
|
||||||
add(new ValueInstruction(expression));
|
add(new ReadValueInstruction(expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void jump(@NotNull Label label) {
|
public void jump(@NotNull Label label) {
|
||||||
add(new UnconditionalJumpInstruction(label));
|
add(new UnconditionalJumpInstruction(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void jumpOnFalse(@NotNull Label label) {
|
public void jumpOnFalse(@NotNull Label label) {
|
||||||
add(new ConditionalJumpInstruction(false, label));
|
add(new ConditionalJumpInstruction(false, label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void jumpOnTrue(@NotNull Label label) {
|
public void jumpOnTrue(@NotNull Label label) {
|
||||||
add(new ConditionalJumpInstruction(true, label));
|
add(new ConditionalJumpInstruction(true, label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindLabel(@NotNull Label label) {
|
public void bindLabel(@NotNull Label label) {
|
||||||
pseudocode.getLabels().put(label, pseudocode.getInstructions().size());
|
pseudocode.addLabel(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nondeterministicJump(Label label) {
|
public void nondeterministicJump(Label label) {
|
||||||
add(new NondeterministicJumpInstruction(label));
|
add(new NondeterministicJumpInstruction(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitTryFinally() {
|
public void exitTryFinally() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unsupported(JetElement element) {
|
public void unsupported(JetElement element) {
|
||||||
throw new IllegalStateException("Unsupported element: " + element.getText() + " " + element);
|
add(new UnsupportedElementInstruction(element));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class JetElementInstruction extends Instruction {
|
||||||
|
protected final JetElement element;
|
||||||
|
|
||||||
|
public JetElementInstruction(@NotNull JetElement element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetElement getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.cfg.Label;
|
import org.jetbrains.jet.lang.cfg.Label;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
@@ -13,12 +14,28 @@ public class Pseudocode {
|
|||||||
private final List<Instruction> instructions = new ArrayList<Instruction>();
|
private final List<Instruction> instructions = new ArrayList<Instruction>();
|
||||||
private final Map<Label, Integer> labels = new LinkedHashMap<Label, Integer>();
|
private final Map<Label, Integer> labels = new LinkedHashMap<Label, Integer>();
|
||||||
|
|
||||||
public List<Instruction> getInstructions() {
|
@Nullable
|
||||||
return instructions;
|
private final Pseudocode parent;
|
||||||
|
|
||||||
|
public Pseudocode(Pseudocode parent) {
|
||||||
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Label, Integer> getLabels() {
|
public void addInstruction(Instruction instruction) {
|
||||||
return labels;
|
instructions.add(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLabel(Label label) {
|
||||||
|
labels.put(label, instructions.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Integer resolveLabel(Label targetLabel) {
|
||||||
|
Integer result = labels.get(targetLabel);
|
||||||
|
if (result == null && parent != null) {
|
||||||
|
return parent.resolveLabel(targetLabel);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postProcess() {
|
public void postProcess() {
|
||||||
@@ -27,7 +44,7 @@ public class Pseudocode {
|
|||||||
final int currentPosition = i;
|
final int currentPosition = i;
|
||||||
instruction.accept(new InstructionVisitor() {
|
instruction.accept(new InstructionVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void visitRead(ValueInstruction instruction) {
|
public void visitInstructionWithNext(InstructionWithNext instruction) {
|
||||||
instruction.setNext(getNextPosition(currentPosition));
|
instruction.setNext(getNextPosition(currentPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +74,12 @@ public class Pseudocode {
|
|||||||
visitJump(instruction);
|
visitJump(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
||||||
|
instruction.getBody().postProcess();
|
||||||
|
super.visitFunctionLiteralValue(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
|
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
|
||||||
// Nothing
|
// Nothing
|
||||||
@@ -72,7 +95,7 @@ public class Pseudocode {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Instruction getJumpTarget(@NotNull Label targetLabel) {
|
private Instruction getJumpTarget(@NotNull Label targetLabel) {
|
||||||
Integer targetPosition = labels.get(targetLabel);
|
Integer targetPosition = resolveLabel(targetLabel);
|
||||||
return getTargetInstruction(targetPosition);
|
return getTargetInstruction(targetPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +110,7 @@ public class Pseudocode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label label = ((UnconditionalJumpInstruction) targetInstruction).getTargetLabel();
|
Label label = ((UnconditionalJumpInstruction) targetInstruction).getTargetLabel();
|
||||||
targetPosition = labels.get(label);
|
targetPosition = resolveLabel(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,15 +134,19 @@ public class Pseudocode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void dumpGraph(@NotNull final PrintStream out) {
|
public void dumpGraph(@NotNull final PrintStream out) {
|
||||||
out.println("digraph g {");
|
String graphHeader = "digraph g";
|
||||||
|
dumpSubgraph(out, graphHeader, new int[1], "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dumpSubgraph(final PrintStream out, String graphHeader, final int[] count, String style) {
|
||||||
|
out.println(graphHeader + " {");
|
||||||
|
|
||||||
final Map<Instruction, String> nodeToName = new HashMap<Instruction, String>();
|
final Map<Instruction, String> nodeToName = new HashMap<Instruction, String>();
|
||||||
int count = 0;
|
|
||||||
for (Instruction node : instructions) {
|
for (Instruction node : instructions) {
|
||||||
if (node instanceof UnconditionalJumpInstruction) {
|
if (node instanceof UnconditionalJumpInstruction) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String name = "n" + count++;
|
String name = "n" + count[0]++;
|
||||||
nodeToName.put(node, name);
|
nodeToName.put(node, name);
|
||||||
String text = node.toString();
|
String text = node.toString();
|
||||||
int newline = text.indexOf("\n");
|
int newline = text.indexOf("\n");
|
||||||
@@ -133,11 +160,25 @@ public class Pseudocode {
|
|||||||
else if (node instanceof NondeterministicJumpInstruction) {
|
else if (node instanceof NondeterministicJumpInstruction) {
|
||||||
shape = "Mdiamond";
|
shape = "Mdiamond";
|
||||||
}
|
}
|
||||||
|
else if (node instanceof UnsupportedElementInstruction) {
|
||||||
|
shape = "box, fillcolor=red, style=filled";
|
||||||
|
}
|
||||||
|
else if (node instanceof FunctionLiteralValueInstruction) {
|
||||||
|
shape = "Mcircle";
|
||||||
|
}
|
||||||
out.println(name + "[label=\"" + text + "\", shape=" + shape + "];");
|
out.println(name + "[label=\"" + text + "\", shape=" + shape + "];");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Instruction fromInst : instructions) {
|
for (final Instruction fromInst : instructions) {
|
||||||
fromInst.accept(new InstructionVisitor() {
|
fromInst.accept(new InstructionVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
||||||
|
int index = count[0];
|
||||||
|
instruction.getBody().dumpSubgraph(out, "subgraph f" + index, count, "color=blue;\ntlabel = \"process #" + index + "\";");
|
||||||
|
printEdge(out, nodeToName.get(instruction), "n" + index, null);
|
||||||
|
visitInstructionWithNext(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
|
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
|
||||||
// Nothing
|
// Nothing
|
||||||
@@ -145,13 +186,13 @@ public class Pseudocode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitJump(AbstractJumpInstruction instruction) {
|
public void visitJump(AbstractJumpInstruction instruction) {
|
||||||
writeEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getResolvedTarget()), null);
|
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getResolvedTarget()), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||||
visitJump(instruction);
|
visitJump(instruction);
|
||||||
writeEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -167,13 +208,13 @@ public class Pseudocode {
|
|||||||
@Override
|
@Override
|
||||||
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
|
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
|
||||||
String from = nodeToName.get(instruction);
|
String from = nodeToName.get(instruction);
|
||||||
writeEdge(out, from, nodeToName.get(instruction.getNextOnFalse()), "no");
|
printEdge(out, from, nodeToName.get(instruction.getNextOnFalse()), "no");
|
||||||
writeEdge(out, from, nodeToName.get(instruction.getNextOnTrue()), "yes");
|
printEdge(out, from, nodeToName.get(instruction.getNextOnTrue()), "yes");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitRead(ValueInstruction instruction) {
|
public void visitInstructionWithNext(InstructionWithNext instruction) {
|
||||||
writeEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -187,11 +228,11 @@ public class Pseudocode {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
out.println(style);
|
||||||
out.println("}");
|
out.println("}");
|
||||||
out.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeEdge(PrintStream out, String from, String to, String label) {
|
private void printEdge(PrintStream out, String from, String to, String label) {
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
label = "[label=\"" + label + "\"]";
|
label = "[label=\"" + label + "\"]";
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -6,19 +6,19 @@ import org.jetbrains.jet.lang.psi.JetExpression;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class ValueInstruction extends InstructionWithNext {
|
public class ReadValueInstruction extends InstructionWithNext {
|
||||||
|
|
||||||
public ValueInstruction(@NotNull JetExpression expression) {
|
public ReadValueInstruction(@NotNull JetExpression expression) {
|
||||||
super(expression);
|
super(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(InstructionVisitor visitor) {
|
public void accept(InstructionVisitor visitor) {
|
||||||
visitor.visitRead(this);
|
visitor.visitReadValue(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "r(" + expression.getText() + ")";
|
return "r(" + element.getText() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class UnsupportedElementInstruction extends InstructionWithNext {
|
||||||
|
|
||||||
|
protected UnsupportedElementInstruction(@NotNull JetElement element) {
|
||||||
|
super(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(InstructionVisitor visitor) {
|
||||||
|
visitor.visitUnsupportedElementInstruction(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "unsupported(" + element + " : " + element.getText() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -227,9 +227,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* expression
|
* element
|
||||||
* : attributes expression
|
* : attributes element
|
||||||
* : "(" expression ")" // see tupleLiteral
|
* : "(" element ")" // see tupleLiteral
|
||||||
* : literalConstant
|
* : literalConstant
|
||||||
* : functionLiteral
|
* : functionLiteral
|
||||||
* : tupleLiteral
|
* : tupleLiteral
|
||||||
@@ -238,7 +238,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
* : expressionWithPrecedences
|
* : expressionWithPrecedences
|
||||||
* : if
|
* : if
|
||||||
* : try
|
* : try
|
||||||
* : "typeof" "(" expression ")"
|
* : "typeof" "(" element ")"
|
||||||
* : "new" constructorInvocation
|
* : "new" constructorInvocation
|
||||||
* : objectLiteral
|
* : objectLiteral
|
||||||
* : declaration
|
* : declaration
|
||||||
@@ -249,14 +249,14 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
*/
|
*/
|
||||||
public void parseExpression() {
|
public void parseExpression() {
|
||||||
if (!atSet(EXPRESSION_FIRST)) {
|
if (!atSet(EXPRESSION_FIRST)) {
|
||||||
error("Expecting an expression");
|
error("Expecting an element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
parseBinaryExpression(Precedence.ASSIGNMENT);
|
parseBinaryExpression(Precedence.ASSIGNMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* expression (operation expression)*
|
* element (operation element)*
|
||||||
*
|
*
|
||||||
* see the precedence table
|
* see the precedence table
|
||||||
*/
|
*/
|
||||||
@@ -427,7 +427,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* expression (getEntryPoint? functionLiteral)?
|
* element (getEntryPoint? functionLiteral)?
|
||||||
*/
|
*/
|
||||||
protected boolean parseCallWithClosure() {
|
protected boolean parseCallWithClosure() {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
@@ -447,9 +447,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* atomicExpression
|
* atomicExpression
|
||||||
* : tupleLiteral // or parenthesized expression
|
* : tupleLiteral // or parenthesized element
|
||||||
* : "this" getEntryPoint? ("<" type ">")?
|
* : "this" getEntryPoint? ("<" type ">")?
|
||||||
* : "typeof" "(" expression ")"
|
* : "typeof" "(" element ")"
|
||||||
* : "new" constructorInvocation
|
* : "new" constructorInvocation
|
||||||
* : objectLiteral
|
* : objectLiteral
|
||||||
* : jump
|
* : jump
|
||||||
@@ -535,8 +535,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
parseFunctionLiteral();
|
parseFunctionLiteral();
|
||||||
}
|
}
|
||||||
else if (!parseLiteralConstant()) {
|
else if (!parseLiteralConstant()) {
|
||||||
// TODO: better recovery if FIRST(expression) did not match
|
// TODO: better recovery if FIRST(element) did not match
|
||||||
errorWithRecovery("Expecting an expression", EXPRESSION_FOLLOW);
|
errorWithRecovery("Expecting an element", EXPRESSION_FOLLOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,7 +581,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* when
|
* when
|
||||||
* : "when" "(" (modifiers "val" SimpleName "=")? expression ")" "{"
|
* : "when" "(" (modifiers "val" SimpleName "=")? element ")" "{"
|
||||||
* whenEntry*
|
* whenEntry*
|
||||||
* "}"
|
* "}"
|
||||||
* ;
|
* ;
|
||||||
@@ -622,8 +622,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
/*
|
/*
|
||||||
* whenEntry
|
* whenEntry
|
||||||
* // TODO : consider empty after =>
|
* // TODO : consider empty after =>
|
||||||
* : whenConditionIf{","} (when | "=>" expression SEMI)
|
* : whenConditionIf{","} (when | "=>" element SEMI)
|
||||||
* : "else" ("continue" | "=>" expression SEMI)
|
* : "else" ("continue" | "=>" element SEMI)
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseWhenEntry() {
|
private void parseWhenEntry() {
|
||||||
@@ -633,7 +633,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
advance(); // ELSE_KEYWORD
|
advance(); // ELSE_KEYWORD
|
||||||
|
|
||||||
if (!at(CONTINUE_KEYWORD) && !at(DOUBLE_ARROW)) {
|
if (!at(CONTINUE_KEYWORD) && !at(DOUBLE_ARROW)) {
|
||||||
errorUntil("Expecting 'continue' or '=> expression'", TokenSet.create(CONTINUE_KEYWORD, DOUBLE_ARROW,
|
errorUntil("Expecting 'continue' or '=> element'", TokenSet.create(CONTINUE_KEYWORD, DOUBLE_ARROW,
|
||||||
RBRACE, EOL_OR_SEMICOLON));
|
RBRACE, EOL_OR_SEMICOLON));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,14 +641,14 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
advance(); // DOUBLE_ARROW
|
advance(); // DOUBLE_ARROW
|
||||||
|
|
||||||
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||||
error("Expecting an expression");
|
error("Expecting an element");
|
||||||
} else {
|
} else {
|
||||||
parseExpression();
|
parseExpression();
|
||||||
}
|
}
|
||||||
} else if (at(CONTINUE_KEYWORD)) {
|
} else if (at(CONTINUE_KEYWORD)) {
|
||||||
advance(); // CONTINUE_KEYWORD
|
advance(); // CONTINUE_KEYWORD
|
||||||
} else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
} else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||||
errorAndAdvance("Expecting 'continue' or '=> expression'");
|
errorAndAdvance("Expecting 'continue' or '=> element'");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parseWhenEntryNotElse();
|
parseWhenEntryNotElse();
|
||||||
@@ -659,7 +659,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* : whenConditionIf{","} (when | "=>" expression SEMI)
|
* : whenConditionIf{","} (when | "=>" element SEMI)
|
||||||
*/
|
*/
|
||||||
private void parseWhenEntryNotElse() {
|
private void parseWhenEntryNotElse() {
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -673,7 +673,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
} else {
|
} else {
|
||||||
expect(DOUBLE_ARROW, "Expecting '=>' or 'when'", WHEN_CONDITION_RECOVERY_SET);
|
expect(DOUBLE_ARROW, "Expecting '=>' or 'when'", WHEN_CONDITION_RECOVERY_SET);
|
||||||
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||||
error("Expecting an expression");
|
error("Expecting an element");
|
||||||
} else {
|
} else {
|
||||||
parseExpression();
|
parseExpression();
|
||||||
}
|
}
|
||||||
@@ -683,7 +683,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* whenConditionIf
|
* whenConditionIf
|
||||||
* : pattern ("if" "(" expression ")")?
|
* : pattern ("if" "(" element ")")?
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseWhenConditionIf() {
|
private void parseWhenConditionIf() {
|
||||||
@@ -705,9 +705,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* whenCondition
|
* whenCondition
|
||||||
* : expression
|
* : element
|
||||||
* : "." postfixExpression typeArguments? valueArguments?
|
* : "." postfixExpression typeArguments? valueArguments?
|
||||||
* : ("in" | "!in") expression
|
* : ("in" | "!in") element
|
||||||
* : ("is" | "!is") isRHS
|
* : ("is" | "!is") isRHS
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
@@ -718,7 +718,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
advance(); // IN_KEYWORD or NOT_IN
|
advance(); // IN_KEYWORD or NOT_IN
|
||||||
|
|
||||||
if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW)) {
|
if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW)) {
|
||||||
error("Expecting an expression");
|
error("Expecting an element");
|
||||||
} else {
|
} else {
|
||||||
parseExpression();
|
parseExpression();
|
||||||
}
|
}
|
||||||
@@ -739,7 +739,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW)) {
|
if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW)) {
|
||||||
error("Expecting an expression, is-condition or in-condition");
|
error("Expecting an element, is-condition or in-condition");
|
||||||
} else {
|
} else {
|
||||||
parseExpression();
|
parseExpression();
|
||||||
}
|
}
|
||||||
@@ -782,7 +782,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
myJetParsing.parseTypeRef();
|
myJetParsing.parseTypeRef();
|
||||||
if (at(AT)) {
|
if (at(AT)) {
|
||||||
errorAndAdvance("'@' is allowed only after a decomposer expression, not after a type");
|
errorAndAdvance("'@' is allowed only after a decomposer element, not after a type");
|
||||||
}
|
}
|
||||||
if (myBuilder.getCurrentOffset() < expressionEndOffset) {
|
if (myBuilder.getCurrentOffset() < expressionEndOffset) {
|
||||||
rollbackMarker.rollbackTo();
|
rollbackMarker.rollbackTo();
|
||||||
@@ -853,8 +853,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
* binding
|
* binding
|
||||||
* : "is" pattern
|
* : "is" pattern
|
||||||
* : "!is" pattern
|
* : "!is" pattern
|
||||||
* : "in" expression
|
* : "in" element
|
||||||
* : "!in" expression
|
* : "!in" element
|
||||||
* : ":" type
|
* : ":" type
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
@@ -882,7 +882,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* arrayAccess
|
* arrayAccess
|
||||||
* : "[" expression{","} "]"
|
* : "[" element{","} "]"
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseArrayAccess() {
|
private void parseArrayAccess() {
|
||||||
@@ -894,9 +894,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
advance(); // LBRACKET
|
advance(); // LBRACKET
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (at(COMMA)) errorAndAdvance("Expecting an index expression");
|
if (at(COMMA)) errorAndAdvance("Expecting an index element");
|
||||||
if (at(RBRACKET)) {
|
if (at(RBRACKET)) {
|
||||||
error("Expecting an index expression");
|
error("Expecting an index element");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parseExpression();
|
parseExpression();
|
||||||
@@ -1073,13 +1073,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* expressions
|
* expressions
|
||||||
* : SEMI* expression{SEMI+} SEMI*
|
* : SEMI* element{SEMI+} SEMI*
|
||||||
*/
|
*/
|
||||||
public void parseExpressions() {
|
public void parseExpressions() {
|
||||||
while (at(SEMICOLON)) advance(); // SEMICOLON
|
while (at(SEMICOLON)) advance(); // SEMICOLON
|
||||||
while (!eof() && !at(RBRACE)) {
|
while (!eof() && !at(RBRACE)) {
|
||||||
if (!atSet(EXPRESSION_FIRST)) {
|
if (!atSet(EXPRESSION_FIRST)) {
|
||||||
errorAndAdvance("Expecting an expression");
|
errorAndAdvance("Expecting an element");
|
||||||
}
|
}
|
||||||
if (atSet(EXPRESSION_FIRST)) {
|
if (atSet(EXPRESSION_FIRST)) {
|
||||||
parseExpression();
|
parseExpression();
|
||||||
@@ -1126,7 +1126,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* doWhile
|
* doWhile
|
||||||
* : "do" expression "while" "(" expression ")"
|
* : "do" element "while" "(" element ")"
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseDoWhile() {
|
private void parseDoWhile() {
|
||||||
@@ -1149,7 +1149,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* while
|
* while
|
||||||
* : "while" "(" expression ")" expression
|
* : "while" "(" element ")" element
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseWhile() {
|
private void parseWhile() {
|
||||||
@@ -1168,7 +1168,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* for
|
* for
|
||||||
* : "for" "(" attributes valOrVar? SimpleName (":" type)? "in" expression ")" expression
|
* : "for" "(" attributes valOrVar? SimpleName (":" type)? "in" element ")" element
|
||||||
* ;
|
* ;
|
||||||
*
|
*
|
||||||
* TODO: empty loop body (at the end of the block)?
|
* TODO: empty loop body (at the end of the block)?
|
||||||
@@ -1207,7 +1207,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* expression
|
* element
|
||||||
*/
|
*/
|
||||||
private void parseControlStructureBody() {
|
private void parseControlStructureBody() {
|
||||||
PsiBuilder.Marker body = mark();
|
PsiBuilder.Marker body = mark();
|
||||||
@@ -1263,7 +1263,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* if
|
* if
|
||||||
* : "if" "(" expression ")" expression SEMI? ("else" expression)?
|
* : "if" "(" element ")" element SEMI? ("else" element)?
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseIf() {
|
private void parseIf() {
|
||||||
@@ -1296,7 +1296,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "(" expression ")"
|
* "(" element ")"
|
||||||
*/
|
*/
|
||||||
private void parseCondition() {
|
private void parseCondition() {
|
||||||
myBuilder.disableNewlines();
|
myBuilder.disableNewlines();
|
||||||
@@ -1321,13 +1321,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
|
advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
|
||||||
|
|
||||||
if (!eol() && atSet(LABELS)) advance(); // LABELS
|
parseLabel();
|
||||||
|
|
||||||
marker.done(type);
|
marker.done(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "return" getEntryPoint? expression?
|
* "return" getEntryPoint? element?
|
||||||
*/
|
*/
|
||||||
private void parseReturn() {
|
private void parseReturn() {
|
||||||
assert _at(RETURN_KEYWORD);
|
assert _at(RETURN_KEYWORD);
|
||||||
@@ -1336,9 +1336,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
advance(); // RETURN_KEYWORD
|
advance(); // RETURN_KEYWORD
|
||||||
|
|
||||||
if (atSet(LABELS)) {
|
parseLabel();
|
||||||
advance(); // LABELS
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
|
if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
|
||||||
|
|
||||||
@@ -1346,7 +1344,22 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* : "throw" expression
|
* labels
|
||||||
|
*/
|
||||||
|
private void parseLabel() {
|
||||||
|
if (!eol() && atSet(LABELS)) {
|
||||||
|
PsiBuilder.Marker labelWrap = mark();
|
||||||
|
|
||||||
|
PsiBuilder.Marker mark = mark();
|
||||||
|
advance(); // LABELS
|
||||||
|
mark.done(LABEL_REFERENCE);
|
||||||
|
|
||||||
|
labelWrap.done(LABEL_QUALIFIER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* : "throw" element
|
||||||
*/
|
*/
|
||||||
private void parseThrow() {
|
private void parseThrow() {
|
||||||
assert _at(THROW_KEYWORD);
|
assert _at(THROW_KEYWORD);
|
||||||
@@ -1379,7 +1392,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "typeof" "(" expression ")"
|
* "typeof" "(" element ")"
|
||||||
*/
|
*/
|
||||||
private void parseTypeOf() {
|
private void parseTypeOf() {
|
||||||
assert _at(TYPEOF_KEYWORD);
|
assert _at(TYPEOF_KEYWORD);
|
||||||
@@ -1399,13 +1412,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tupleLiteral // Ambiguity when after a SimpleName (infix call). In this case (e) is treated as an expression in parentheses
|
* tupleLiteral // Ambiguity when after a SimpleName (infix call). In this case (e) is treated as an element in parentheses
|
||||||
* // to put a tuple, write write ((e))
|
* // to put a tuple, write write ((e))
|
||||||
* : "(" ((SimpleName "=")? expression){","} ")"
|
* : "(" ((SimpleName "=")? element){","} ")"
|
||||||
* ;
|
* ;
|
||||||
*
|
*
|
||||||
* expression
|
* element
|
||||||
* : "(" expression ")"
|
* : "(" element ")"
|
||||||
* ;
|
* ;
|
||||||
*
|
*
|
||||||
* TODO: duplication with valueArguments (but for the error messages)
|
* TODO: duplication with valueArguments (but for the error messages)
|
||||||
@@ -1422,7 +1435,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
while (true) {
|
while (true) {
|
||||||
while (at(COMMA)) {
|
while (at(COMMA)) {
|
||||||
tuple = true;
|
tuple = true;
|
||||||
errorAndAdvance("Expecting a tuple entry (expression)");
|
errorAndAdvance("Expecting a tuple entry (element)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at(IDENTIFIER) && lookahead(1) == EQ) {
|
if (at(IDENTIFIER) && lookahead(1) == EQ) {
|
||||||
@@ -1441,7 +1454,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
tuple = true;
|
tuple = true;
|
||||||
|
|
||||||
if (at(RPAR)) {
|
if (at(RPAR)) {
|
||||||
error("Expecting a tuple entry (expression)");
|
error("Expecting a tuple entry (element)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1463,11 +1476,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker mark = mark();
|
PsiBuilder.Marker mark = mark();
|
||||||
advance(); // THIS_KEYWORD
|
advance(); // THIS_KEYWORD
|
||||||
|
|
||||||
if (atSet(LABELS)) {
|
parseLabel();
|
||||||
PsiBuilder.Marker label = mark();
|
|
||||||
advance(); // LABELS
|
|
||||||
label.done(LABEL_REFERENCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (at(LT)) {
|
if (at(LT)) {
|
||||||
// This may be "this < foo" or "this<foo>", thus the backtracking
|
// This may be "this < foo" or "this<foo>", thus the backtracking
|
||||||
@@ -1492,7 +1501,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* valueArguments
|
* valueArguments
|
||||||
* : "(" (SimpleName "=")? ("out" | "ref")? expression{","} ")"
|
* : "(" (SimpleName "=")? ("out" | "ref")? element{","} ")"
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
public void parseValueArgumentList() {
|
public void parseValueArgumentList() {
|
||||||
@@ -1521,7 +1530,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (SimpleName "=")? ("out" | "ref")? expression
|
* (SimpleName "=")? ("out" | "ref")? element
|
||||||
*/
|
*/
|
||||||
private void parseValueArgument() {
|
private void parseValueArgument() {
|
||||||
PsiBuilder.Marker argument = mark();
|
PsiBuilder.Marker argument = mark();
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* attribute
|
* attribute
|
||||||
* // : SimpleName{"."} (valueArguments | "=" expression)?
|
* // : SimpleName{"."} (valueArguments | "=" element)?
|
||||||
* [for recovery: userType valueArguments?]
|
* [for recovery: userType valueArguments?]
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
@@ -683,7 +683,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
* : modifiers ("val" | "var")
|
* : modifiers ("val" | "var")
|
||||||
* typeParameters? (type "." | attributes)?
|
* typeParameters? (type "." | attributes)?
|
||||||
* SimpleName (":" type)?
|
* SimpleName (":" type)?
|
||||||
* ("=" expression SEMI?)?
|
* ("=" element SEMI?)?
|
||||||
* (getter? setter? | setter? getter?) SEMI?
|
* (getter? setter? | setter? getter?) SEMI?
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
@@ -883,7 +883,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
/*
|
/*
|
||||||
* functionBody
|
* functionBody
|
||||||
* : block
|
* : block
|
||||||
* : "=" expression
|
* : "=" element
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseFunctionBody() {
|
private void parseFunctionBody() {
|
||||||
@@ -975,7 +975,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
* ;
|
* ;
|
||||||
*
|
*
|
||||||
* explicitDelegation
|
* explicitDelegation
|
||||||
* : userType "by" expression
|
* : userType "by" element
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseDelegationSpecifier() {
|
private void parseDelegationSpecifier() {
|
||||||
@@ -1336,7 +1336,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
* ;
|
* ;
|
||||||
*
|
*
|
||||||
* functionParameterRest
|
* functionParameterRest
|
||||||
* : parameter ("=" expression)?
|
* : parameter ("=" element)?
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
public void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
|
public void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
|
||||||
@@ -1376,7 +1376,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* functionParameter
|
* functionParameter
|
||||||
* : modifiers ("val" | "var")? parameter ("=" expression)?
|
* : modifiers ("val" | "var")? parameter ("=" element)?
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private boolean tryParseValueParameter() {
|
private boolean tryParseValueParameter() {
|
||||||
@@ -1408,7 +1408,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* functionParameterRest
|
* functionParameterRest
|
||||||
* : parameter ("=" expression)?
|
* : parameter ("=" element)?
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private boolean parseFunctionParameterRest() {
|
private boolean parseFunctionParameterRest() {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,4 +17,9 @@ public class JetContainerNode extends JetElement {
|
|||||||
protected <T> T findChildByClass(Class<T> aClass) {
|
protected <T> T findChildByClass(Class<T> aClass) {
|
||||||
return super.findChildByClass(aClass);
|
return super.findChildByClass(aClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // for visibility
|
||||||
|
protected PsiElement findChildByType(IElementType type) {
|
||||||
|
return super.findChildByType(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
@@ -19,9 +16,4 @@ public class JetContinueExpression extends JetLabelQualifiedExpression {
|
|||||||
visitor.visitContinueExpression(this);
|
visitor.visitContinueExpression(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getLabelName() {
|
|
||||||
PsiElement id = findChildByType(JetTokens.IDENTIFIER);
|
|
||||||
return id != null ? id.getText() : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.psi;
|
|||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -16,7 +16,9 @@ public class JetLabelQualifiedExpression extends JetExpression {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public JetSimpleNameExpression getTargetLabel() {
|
public JetSimpleNameExpression getTargetLabel() {
|
||||||
return (JetSimpleNameExpression) findChildByType(JetTokens.LABELS);
|
JetContainerNode qualifier = (JetContainerNode) findChildByType(JetNodeTypes.LABEL_QUALIFIER);
|
||||||
|
if (qualifier == null) return null;
|
||||||
|
return (JetSimpleNameExpression) qualifier.findChildByType(JetNodeTypes.LABEL_REFERENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable @IfNotParsed
|
@Nullable @IfNotParsed
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.util.Map;
|
|||||||
public class BindingTraceContext extends BindingTrace implements BindingContext {
|
public class BindingTraceContext extends BindingTrace implements BindingContext {
|
||||||
private final Map<JetExpression, JetType> expressionTypes = new HashMap<JetExpression, JetType>();
|
private final Map<JetExpression, JetType> expressionTypes = new HashMap<JetExpression, JetType>();
|
||||||
private final Map<JetReferenceExpression, DeclarationDescriptor> resolutionResults = new HashMap<JetReferenceExpression, DeclarationDescriptor>();
|
private final Map<JetReferenceExpression, DeclarationDescriptor> resolutionResults = new HashMap<JetReferenceExpression, DeclarationDescriptor>();
|
||||||
|
private final Map<JetReferenceExpression, PsiElement> labelResolutionResults = new HashMap<JetReferenceExpression, PsiElement>();
|
||||||
private final Map<JetTypeReference, JetType> types = new HashMap<JetTypeReference, JetType>();
|
private final Map<JetTypeReference, JetType> types = new HashMap<JetTypeReference, JetType>();
|
||||||
private final Map<DeclarationDescriptor, PsiElement> descriptorToDeclarations = new HashMap<DeclarationDescriptor, PsiElement>();
|
private final Map<DeclarationDescriptor, PsiElement> descriptorToDeclarations = new HashMap<DeclarationDescriptor, PsiElement>();
|
||||||
private final Map<PsiElement, DeclarationDescriptor> declarationsToDescriptors = new HashMap<PsiElement, DeclarationDescriptor>();
|
private final Map<PsiElement, DeclarationDescriptor> declarationsToDescriptors = new HashMap<PsiElement, DeclarationDescriptor>();
|
||||||
@@ -31,6 +32,11 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
|
|||||||
resolutionResults.put(expression, descriptor);
|
resolutionResults.put(expression, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element) {
|
||||||
|
labelResolutionResults.put(expression, element);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
|
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
|
||||||
resolutionResults.remove(referenceExpression);
|
resolutionResults.remove(referenceExpression);
|
||||||
@@ -107,7 +113,7 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
|
|||||||
public PsiElement resolveToDeclarationPsiElement(JetReferenceExpression referenceExpression) {
|
public PsiElement resolveToDeclarationPsiElement(JetReferenceExpression referenceExpression) {
|
||||||
DeclarationDescriptor declarationDescriptor = resolveReferenceExpression(referenceExpression);
|
DeclarationDescriptor declarationDescriptor = resolveReferenceExpression(referenceExpression);
|
||||||
if (declarationDescriptor == null) {
|
if (declarationDescriptor == null) {
|
||||||
return null;
|
return labelResolutionResults.get(referenceExpression);
|
||||||
}
|
}
|
||||||
return descriptorToDeclarations.get(declarationDescriptor.getOriginal());
|
return descriptorToDeclarations.get(declarationDescriptor.getOriginal());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ public class ClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bodyExpression == null) {
|
if (bodyExpression == null) {
|
||||||
semanticServices.getErrorHandler().genericError(function.getNode(), "This function must either declare a return type or have a body expression");
|
semanticServices.getErrorHandler().genericError(function.getNode(), "This function must either declare a return type or have a body element");
|
||||||
returnType = ErrorUtils.createErrorType("No type, no body");
|
returnType = ErrorUtils.createErrorType("No type, no body");
|
||||||
} else {
|
} else {
|
||||||
// TODO : Recursion possible
|
// TODO : Recursion possible
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ public class TopDownAnalyzer {
|
|||||||
if (bodyExpression != null) {
|
if (bodyExpression != null) {
|
||||||
System.out.println("-------------");
|
System.out.println("-------------");
|
||||||
JetControlFlowInstructionsGenerator instructionsGenerator = new JetControlFlowInstructionsGenerator();
|
JetControlFlowInstructionsGenerator instructionsGenerator = new JetControlFlowInstructionsGenerator();
|
||||||
new JetControlFlowProcessor(semanticServices, instructionsGenerator).generate(function, bodyExpression);
|
new JetControlFlowProcessor(semanticServices, trace, instructionsGenerator).generate(function, bodyExpression);
|
||||||
Pseudocode pseudocode = instructionsGenerator.getPseudocode();
|
Pseudocode pseudocode = instructionsGenerator.getPseudocode();
|
||||||
pseudocode.postProcess();
|
pseudocode.postProcess();
|
||||||
pseudocode.dumpInstructions(System.out);
|
pseudocode.dumpInstructions(System.out);
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ public class BindingTrace {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
|
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public class JetTypeInferrer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitJetElement(JetElement elem) {
|
public void visitJetElement(JetElement elem) {
|
||||||
semanticServices.getErrorHandler().genericError(elem.getNode(), "Unsupported in call expression"); // TODO : Message
|
semanticServices.getErrorHandler().genericError(elem.getNode(), "Unsupported in call element"); // TODO : Message
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return wrapForTracing(result[0], reference[0], argumentList, true);
|
return wrapForTracing(result[0], reference[0], argumentList, true);
|
||||||
@@ -894,7 +894,7 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
else if (selectorExpression != null) {
|
else if (selectorExpression != null) {
|
||||||
// TODO : not a simple name -> resolve in scope, expect property type or a function type
|
// TODO : not a simple name -> resolve in scope, expect property type or a function type
|
||||||
semanticServices.getErrorHandler().genericError(selectorExpression.getNode(), "Unsupported selector expression type: " + selectorExpression);
|
semanticServices.getErrorHandler().genericError(selectorExpression.getNode(), "Unsupported selector element type: " + selectorExpression);
|
||||||
}
|
}
|
||||||
return receiverType;
|
return receiverType;
|
||||||
}
|
}
|
||||||
@@ -1312,7 +1312,7 @@ public class JetTypeInferrer {
|
|||||||
String counterpartName = binaryOperationNames.get(assignmentOperationCounterparts.get(operationType));
|
String counterpartName = binaryOperationNames.get(assignmentOperationCounterparts.get(operationType));
|
||||||
getTypeForBinaryCall(expression, counterpartName, scope, true);
|
getTypeForBinaryCall(expression, counterpartName, scope, true);
|
||||||
}
|
}
|
||||||
result = null; // not an expression
|
result = null; // not an element
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1335,7 +1335,7 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = null; // This is not an expression
|
result = null; // This is not an element
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign) {
|
private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign) {
|
||||||
|
|||||||
@@ -640,7 +640,7 @@ class _JetLexer implements FlexLexer {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the text matched by the current regular expression.
|
* Returns the text matched by the current regular element.
|
||||||
*/
|
*/
|
||||||
public final CharSequence yytext() {
|
public final CharSequence yytext() {
|
||||||
return zzBuffer.subSequence(zzStartRead, zzMarkedPos);
|
return zzBuffer.subSequence(zzStartRead, zzMarkedPos);
|
||||||
@@ -727,7 +727,7 @@ class _JetLexer implements FlexLexer {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resumes scanning until the next regular expression is matched,
|
* Resumes scanning until the next regular element is matched,
|
||||||
* the end of input is encountered or an I/O-Error occurs.
|
* the end of input is encountered or an I/O-Error occurs.
|
||||||
*
|
*
|
||||||
* @return the next token
|
* @return the next token
|
||||||
|
|||||||
@@ -30,17 +30,17 @@ JetFile: Expressions_ERR.jet
|
|||||||
REFERENCE_EXPRESSION
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('dfsd')
|
PsiElement(IDENTIFIER)('dfsd')
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(RPAR)(')')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(RPAR)(')')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
PsiElement(BAD_CHARACTER)('~')
|
PsiElement(BAD_CHARACTER)('~')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
@@ -49,10 +49,10 @@ JetFile: Expressions_ERR.jet
|
|||||||
REFERENCE_EXPRESSION
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('srgsdfg')
|
PsiElement(IDENTIFIER)('srgsdfg')
|
||||||
PsiWhiteSpace('\n\n ')
|
PsiWhiteSpace('\n\n ')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
PsiElement(BAD_CHARACTER)('~')
|
PsiElement(BAD_CHARACTER)('~')
|
||||||
PsiWhiteSpace('\n\n ')
|
PsiWhiteSpace('\n\n ')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
PsiElement(RBRACKET)(']')
|
PsiElement(RBRACKET)(']')
|
||||||
PsiWhiteSpace('\n')
|
PsiWhiteSpace('\n')
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
@@ -60,7 +60,7 @@ JetFile: When_ERR.jet
|
|||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
PsiElement(in)('in')
|
PsiElement(in)('in')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
@@ -71,7 +71,7 @@ JetFile: When_ERR.jet
|
|||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
PsiElement(NOT_IN)('!in')
|
PsiElement(NOT_IN)('!in')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
@@ -81,7 +81,7 @@ JetFile: When_ERR.jet
|
|||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
PsiErrorElement:Expecting an expression, is-condition or in-condition
|
PsiErrorElement:Expecting an element, is-condition or in-condition
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
@@ -90,7 +90,7 @@ JetFile: When_ERR.jet
|
|||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
PsiElement(else)('else')
|
PsiElement(else)('else')
|
||||||
PsiErrorElement:Expecting 'continue' or '=> expression'
|
PsiErrorElement:Expecting 'continue' or '=> element'
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
@@ -112,7 +112,7 @@ JetFile: When_ERR.jet
|
|||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
@@ -122,59 +122,59 @@ JetFile: When_ERR.jet
|
|||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
PsiElement(in)('in')
|
PsiElement(in)('in')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
PsiElement(NOT_IN)('!in')
|
PsiElement(NOT_IN)('!in')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
PsiElement(NOT_IN)('!in')
|
PsiElement(NOT_IN)('!in')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(SEMICOLON)(';')
|
PsiElement(SEMICOLON)(';')
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
WHEN_CONDITION
|
WHEN_CONDITION
|
||||||
PsiErrorElement:Expecting an expression, is-condition or in-condition
|
PsiErrorElement:Expecting an element, is-condition or in-condition
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
PsiElement(else)('else')
|
PsiElement(else)('else')
|
||||||
PsiErrorElement:Expecting 'continue' or '=> expression'
|
PsiErrorElement:Expecting 'continue' or '=> element'
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
WHEN_ENTRY
|
WHEN_ENTRY
|
||||||
PsiElement(else)('else')
|
PsiElement(else)('else')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(DOUBLE_ARROW)('=>')
|
PsiElement(DOUBLE_ARROW)('=>')
|
||||||
PsiErrorElement:Expecting an expression
|
PsiErrorElement:Expecting an element
|
||||||
<empty list>
|
<empty list>
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
|
|||||||
Reference in New Issue
Block a user