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 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 BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.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) {
|
||||
myStack.push(StackValue.constant(expression.getValue()));
|
||||
/*
|
||||
Object value = expression.getValue();
|
||||
Object value = element.getValue();
|
||||
v.aconst(value);
|
||||
|
||||
if (value instanceof Integer) {
|
||||
|
||||
@@ -40,8 +40,8 @@ public interface JetControlFlowBuilder {
|
||||
void exitTryFinally();
|
||||
|
||||
// Subroutines
|
||||
void enterSubroutine(@NotNull JetElement subroutine);
|
||||
void exitSubroutine(@NotNull JetElement subroutine);
|
||||
void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral);
|
||||
void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral);
|
||||
|
||||
@Nullable
|
||||
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
|
||||
// public void readNode(JetExpression expression) {
|
||||
// createNode(expression);
|
||||
// public void readNode(JetExpression element) {
|
||||
// createNode(element);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
@@ -236,7 +236,7 @@ package org.jetbrains.jet.lang.cfg;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void enterTryFinally(JetBlockExpression expression) {
|
||||
// public void enterTryFinally(JetBlockExpression element) {
|
||||
// throw new UnsupportedOperationException(); // TODO
|
||||
// }
|
||||
//
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.BindingTrace;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.*;
|
||||
@@ -18,10 +19,12 @@ public class JetControlFlowProcessor {
|
||||
|
||||
private final JetSemanticServices semanticServices;
|
||||
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.builder = builder;
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
statement.accept(new CFPVisitor(preferBlocks));
|
||||
}
|
||||
builder.exitSubroutine(subroutineElement);
|
||||
builder.exitSubroutine(subroutineElement, functionLiteral);
|
||||
}
|
||||
|
||||
private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
|
||||
@@ -46,16 +54,36 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
private void exitElement(JetElement element) {
|
||||
// for (Iterator<Map.Entry<String, JetElement>> iterator = labeledElements.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
// Map.Entry<String, JetElement> entry = iterator.next();
|
||||
// if (entry.getValue() == element) {
|
||||
// iterator.remove();
|
||||
// }
|
||||
// }
|
||||
// TODO : really suboptimal
|
||||
for (Iterator<Map.Entry<String, Stack<JetElement>>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) {
|
||||
Map.Entry<String, Stack<JetElement>> entry = mapIter.next();
|
||||
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) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
@Nullable
|
||||
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 {
|
||||
@@ -74,6 +102,7 @@ public class JetControlFlowProcessor {
|
||||
visitor = new CFPVisitor(preferBlock);
|
||||
}
|
||||
element.accept(visitor);
|
||||
exitElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,8 +117,14 @@ public class JetControlFlowProcessor {
|
||||
|
||||
@Override
|
||||
public void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression) {
|
||||
enterLabeledElement(expression.getLabelName(), expression.getLabeledExpression());
|
||||
value(expression.getLabeledExpression(), false);
|
||||
String labelName = expression.getLabelName();
|
||||
JetExpression labeledExpression = expression.getLabeledExpression();
|
||||
visitLabeledExpression(labelName, labeledExpression);
|
||||
}
|
||||
|
||||
private void visitLabeledExpression(@NotNull String labelName, @NotNull JetExpression labeledExpression) {
|
||||
enterLabeledElement(labelName, labeledExpression);
|
||||
value(labeledExpression, false);
|
||||
}
|
||||
|
||||
@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
|
||||
public void visitIfExpression(JetIfExpression expression) {
|
||||
value(expression.getCondition(), false);
|
||||
@@ -135,7 +181,7 @@ public class JetControlFlowProcessor {
|
||||
value(elseBranch, true);
|
||||
}
|
||||
builder.bindLabel(resultLabel);
|
||||
// builder.readNode(expression);
|
||||
// builder.readNode(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -210,7 +256,7 @@ public class JetControlFlowProcessor {
|
||||
public void visitBreakExpression(JetBreakExpression expression) {
|
||||
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
||||
Label exitPoint = (labelElement != null)
|
||||
? builder.getExitPoint(labelElement)
|
||||
? builder.getExitPoint(resolveLabel(expression.getLabelName(), expression.getTargetLabel()))
|
||||
: builder.getExitPoint(builder.getCurrentLoop());
|
||||
builder.jump(exitPoint);
|
||||
}
|
||||
@@ -219,7 +265,7 @@ public class JetControlFlowProcessor {
|
||||
public void visitContinueExpression(JetContinueExpression expression) {
|
||||
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
||||
if (labelElement != null) {
|
||||
builder.jump(builder.getEntryPoint(labelElement));
|
||||
builder.jump(builder.getEntryPoint(resolveLabel(expression.getLabelName(), expression.getTargetLabel())));
|
||||
}
|
||||
else {
|
||||
builder.jump(builder.getEntryPoint(builder.getCurrentLoop()));
|
||||
@@ -234,7 +280,7 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
JetSimpleNameExpression labelElement = expression.getTargetLabel();
|
||||
JetElement subroutine = (labelElement != null)
|
||||
? resolveLabel(expression.getLabelName(), expression.getTargetLabel().getNode())
|
||||
? resolveLabel(expression.getLabelName(), expression.getTargetLabel())
|
||||
: builder.getCurrentSubroutine();
|
||||
if (returnedExpression == null) {
|
||||
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
|
||||
*/
|
||||
public class InstructionVisitor {
|
||||
public void visitRead(ValueInstruction instruction) {
|
||||
visitInstruction(instruction);
|
||||
public void visitReadValue(ReadValueInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
|
||||
@@ -24,6 +28,14 @@ public class InstructionVisitor {
|
||||
visitJump(instruction);
|
||||
}
|
||||
|
||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||
visitJump(instruction);
|
||||
}
|
||||
|
||||
public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
|
||||
visitInstruction(instruction);
|
||||
}
|
||||
@@ -32,10 +44,10 @@ public class InstructionVisitor {
|
||||
visitInstruction(instruction);
|
||||
}
|
||||
|
||||
public void visitInstruction(Instruction instruction) {
|
||||
public void visitInstructionWithNext(InstructionWithNext instruction) {
|
||||
visitInstruction(instruction);
|
||||
}
|
||||
|
||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||
visitJump(instruction);
|
||||
public void visitInstruction(Instruction instruction) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
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
|
||||
*/
|
||||
public abstract class InstructionWithNext extends ExpressionInstruction {
|
||||
public abstract class InstructionWithNext extends JetElementInstruction {
|
||||
private Instruction next;
|
||||
|
||||
public InstructionWithNext(JetExpression expression) {
|
||||
super(expression);
|
||||
protected InstructionWithNext(@NotNull JetElement element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
public Instruction getNext() {
|
||||
|
||||
+160
-106
@@ -1,7 +1,9 @@
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.psi.JetBlockExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
@@ -14,7 +16,55 @@ import java.util.Stack;
|
||||
/**
|
||||
* @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 final JetElement element;
|
||||
@@ -40,137 +90,141 @@ public class JetControlFlowInstructionsGenerator implements JetControlFlowBuilde
|
||||
}
|
||||
}
|
||||
|
||||
private final Stack<BlockInfo> loopInfo = new Stack<BlockInfo>();
|
||||
private final Stack<BlockInfo> subroutineInfo = new Stack<BlockInfo>();
|
||||
private final Map<JetElement, BlockInfo> elementToBlockInfo = new HashMap<JetElement, BlockInfo>();
|
||||
private class JetControlFlowInstructionsGeneratorWorker implements JetControlFlowBuilder {
|
||||
private final Stack<BlockInfo> loopInfo = new Stack<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() {
|
||||
return pseudocode;
|
||||
}
|
||||
private JetControlFlowInstructionsGeneratorWorker(@Nullable Pseudocode parent) {
|
||||
this.pseudocode = new Pseudocode(parent);
|
||||
}
|
||||
|
||||
private void add(Instruction instruction) {
|
||||
pseudocode.getInstructions().add(instruction);
|
||||
}
|
||||
public Pseudocode getPseudocode() {
|
||||
return pseudocode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public final Label createUnboundLabel() {
|
||||
return new Label("l" + labelCount++);
|
||||
}
|
||||
private void add(Instruction instruction) {
|
||||
pseudocode.addInstruction(instruction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
||||
Label label = createUnboundLabel();
|
||||
bindLabel(label);
|
||||
BlockInfo blockInfo = new BlockInfo(expression, label, loopExitPoint);
|
||||
loopInfo.push(blockInfo);
|
||||
elementToBlockInfo.put(expression, blockInfo);
|
||||
return label;
|
||||
}
|
||||
@NotNull
|
||||
@Override
|
||||
public final Label createUnboundLabel() {
|
||||
return new Label("l" + labelCount++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void exitLoop(@NotNull JetExpression expression) {
|
||||
BlockInfo info = loopInfo.pop();
|
||||
elementToBlockInfo.remove(expression);
|
||||
bindLabel(info.getExitPoint());
|
||||
}
|
||||
@Override
|
||||
public final Label enterLoop(@NotNull JetExpression expression, Label loopExitPoint) {
|
||||
Label label = createUnboundLabel();
|
||||
bindLabel(label);
|
||||
BlockInfo blockInfo = new BlockInfo(expression, label, loopExitPoint);
|
||||
loopInfo.push(blockInfo);
|
||||
elementToBlockInfo.put(expression, blockInfo);
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetElement getCurrentLoop() {
|
||||
return loopInfo.empty() ? null : loopInfo.peek().getElement();
|
||||
}
|
||||
@Override
|
||||
public final void exitLoop(@NotNull JetExpression expression) {
|
||||
BlockInfo info = loopInfo.pop();
|
||||
elementToBlockInfo.remove(expression);
|
||||
bindLabel(info.getExitPoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSubroutine(@NotNull JetElement subroutine) {
|
||||
Label entryPoint = createUnboundLabel();
|
||||
BlockInfo blockInfo = new BlockInfo(subroutine, entryPoint, createUnboundLabel());
|
||||
subroutineInfo.push(blockInfo);
|
||||
elementToBlockInfo.put(subroutine, blockInfo);
|
||||
bindLabel(entryPoint);
|
||||
}
|
||||
@Override
|
||||
public JetElement getCurrentLoop() {
|
||||
return loopInfo.empty() ? null : loopInfo.peek().getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetElement getCurrentSubroutine() {
|
||||
return subroutineInfo.empty() ? null : subroutineInfo.peek().getElement();
|
||||
}
|
||||
@Override
|
||||
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
||||
Label entryPoint = createUnboundLabel();
|
||||
BlockInfo blockInfo = new BlockInfo(subroutine, entryPoint, createUnboundLabel());
|
||||
subroutineInfo.push(blockInfo);
|
||||
elementToBlockInfo.put(subroutine, blockInfo);
|
||||
bindLabel(entryPoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getEntryPoint(@NotNull JetElement labelElement) {
|
||||
return elementToBlockInfo.get(labelElement).getEntryPoint();
|
||||
}
|
||||
@Override
|
||||
public JetElement getCurrentSubroutine() {
|
||||
return subroutineInfo.empty() ? null : subroutineInfo.peek().getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getExitPoint(@NotNull JetElement labelElement) {
|
||||
return elementToBlockInfo.get(labelElement).getExitPoint();
|
||||
}
|
||||
@Override
|
||||
public Label getEntryPoint(@NotNull JetElement labelElement) {
|
||||
return elementToBlockInfo.get(labelElement).getEntryPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getExitPoint(@NotNull JetElement labelElement) {
|
||||
return elementToBlockInfo.get(labelElement).getExitPoint();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void exitSubroutine(@NotNull JetElement subroutine) {
|
||||
bindLabel(getExitPoint(subroutine));
|
||||
add(new SubroutineExitInstruction(subroutine));
|
||||
elementToBlockInfo.remove(subroutine);
|
||||
}
|
||||
@Override
|
||||
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
||||
bindLabel(getExitPoint(subroutine));
|
||||
add(new SubroutineExitInstruction(subroutine));
|
||||
elementToBlockInfo.remove(subroutine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnValue(@NotNull JetElement subroutine) {
|
||||
add(new ReturnValueInstruction(getExitPoint(subroutine)));
|
||||
}
|
||||
@Override
|
||||
public void returnValue(@NotNull JetElement subroutine) {
|
||||
add(new ReturnValueInstruction(getExitPoint(subroutine)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnNoValue(@NotNull JetElement subroutine) {
|
||||
add(new ReturnNoValueInstruction(getExitPoint(subroutine)));
|
||||
}
|
||||
@Override
|
||||
public void returnNoValue(@NotNull JetElement subroutine) {
|
||||
add(new ReturnNoValueInstruction(getExitPoint(subroutine)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNode(@NotNull JetExpression expression) {
|
||||
add(new ValueInstruction(expression));
|
||||
}
|
||||
@Override
|
||||
public void readNode(@NotNull JetExpression expression) {
|
||||
add(new ReadValueInstruction(expression));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jump(@NotNull Label label) {
|
||||
add(new UnconditionalJumpInstruction(label));
|
||||
}
|
||||
@Override
|
||||
public void jump(@NotNull Label label) {
|
||||
add(new UnconditionalJumpInstruction(label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label) {
|
||||
add(new ConditionalJumpInstruction(false, label));
|
||||
}
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label) {
|
||||
add(new ConditionalJumpInstruction(false, label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label) {
|
||||
add(new ConditionalJumpInstruction(true, label));
|
||||
}
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label) {
|
||||
add(new ConditionalJumpInstruction(true, label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindLabel(@NotNull Label label) {
|
||||
pseudocode.getLabels().put(label, pseudocode.getInstructions().size());
|
||||
}
|
||||
@Override
|
||||
public void bindLabel(@NotNull Label label) {
|
||||
pseudocode.addLabel(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(Label label) {
|
||||
add(new NondeterministicJumpInstruction(label));
|
||||
}
|
||||
@Override
|
||||
public void nondeterministicJump(Label label) {
|
||||
add(new NondeterministicJumpInstruction(label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
@Override
|
||||
public void enterTryFinally(@NotNull JetBlockExpression expression) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitTryFinally() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
@Override
|
||||
public void exitTryFinally() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsupported(JetElement element) {
|
||||
throw new IllegalStateException("Unsupported element: " + element.getText() + " " + element);
|
||||
@Override
|
||||
public void unsupported(JetElement 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
|
||||
import java.io.PrintStream;
|
||||
@@ -13,12 +14,28 @@ public class Pseudocode {
|
||||
private final List<Instruction> instructions = new ArrayList<Instruction>();
|
||||
private final Map<Label, Integer> labels = new LinkedHashMap<Label, Integer>();
|
||||
|
||||
public List<Instruction> getInstructions() {
|
||||
return instructions;
|
||||
@Nullable
|
||||
private final Pseudocode parent;
|
||||
|
||||
public Pseudocode(Pseudocode parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public Map<Label, Integer> getLabels() {
|
||||
return labels;
|
||||
public void addInstruction(Instruction instruction) {
|
||||
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() {
|
||||
@@ -27,7 +44,7 @@ public class Pseudocode {
|
||||
final int currentPosition = i;
|
||||
instruction.accept(new InstructionVisitor() {
|
||||
@Override
|
||||
public void visitRead(ValueInstruction instruction) {
|
||||
public void visitInstructionWithNext(InstructionWithNext instruction) {
|
||||
instruction.setNext(getNextPosition(currentPosition));
|
||||
}
|
||||
|
||||
@@ -57,6 +74,12 @@ public class Pseudocode {
|
||||
visitJump(instruction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
||||
instruction.getBody().postProcess();
|
||||
super.visitFunctionLiteralValue(instruction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
|
||||
// Nothing
|
||||
@@ -72,7 +95,7 @@ public class Pseudocode {
|
||||
|
||||
@NotNull
|
||||
private Instruction getJumpTarget(@NotNull Label targetLabel) {
|
||||
Integer targetPosition = labels.get(targetLabel);
|
||||
Integer targetPosition = resolveLabel(targetLabel);
|
||||
return getTargetInstruction(targetPosition);
|
||||
}
|
||||
|
||||
@@ -87,7 +110,7 @@ public class Pseudocode {
|
||||
}
|
||||
|
||||
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) {
|
||||
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>();
|
||||
int count = 0;
|
||||
for (Instruction node : instructions) {
|
||||
if (node instanceof UnconditionalJumpInstruction) {
|
||||
continue;
|
||||
}
|
||||
String name = "n" + count++;
|
||||
String name = "n" + count[0]++;
|
||||
nodeToName.put(node, name);
|
||||
String text = node.toString();
|
||||
int newline = text.indexOf("\n");
|
||||
@@ -133,11 +160,25 @@ public class Pseudocode {
|
||||
else if (node instanceof NondeterministicJumpInstruction) {
|
||||
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 + "];");
|
||||
}
|
||||
|
||||
for (final Instruction fromInst : instructions) {
|
||||
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
|
||||
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
|
||||
// Nothing
|
||||
@@ -145,13 +186,13 @@ public class Pseudocode {
|
||||
|
||||
@Override
|
||||
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
|
||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||
visitJump(instruction);
|
||||
writeEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
||||
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,13 +208,13 @@ public class Pseudocode {
|
||||
@Override
|
||||
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
|
||||
String from = nodeToName.get(instruction);
|
||||
writeEdge(out, from, nodeToName.get(instruction.getNextOnFalse()), "no");
|
||||
writeEdge(out, from, nodeToName.get(instruction.getNextOnTrue()), "yes");
|
||||
printEdge(out, from, nodeToName.get(instruction.getNextOnFalse()), "no");
|
||||
printEdge(out, from, nodeToName.get(instruction.getNextOnTrue()), "yes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitRead(ValueInstruction instruction) {
|
||||
writeEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
||||
public void visitInstructionWithNext(InstructionWithNext instruction) {
|
||||
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,11 +228,11 @@ public class Pseudocode {
|
||||
}
|
||||
});
|
||||
}
|
||||
out.println(style);
|
||||
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) {
|
||||
label = "[label=\"" + label + "\"]";
|
||||
}
|
||||
|
||||
+4
-4
@@ -6,19 +6,19 @@ import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ValueInstruction extends InstructionWithNext {
|
||||
public class ReadValueInstruction extends InstructionWithNext {
|
||||
|
||||
public ValueInstruction(@NotNull JetExpression expression) {
|
||||
public ReadValueInstruction(@NotNull JetExpression expression) {
|
||||
super(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(InstructionVisitor visitor) {
|
||||
visitor.visitRead(this);
|
||||
visitor.visitReadValue(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
* : attributes expression
|
||||
* : "(" expression ")" // see tupleLiteral
|
||||
* element
|
||||
* : attributes element
|
||||
* : "(" element ")" // see tupleLiteral
|
||||
* : literalConstant
|
||||
* : functionLiteral
|
||||
* : tupleLiteral
|
||||
@@ -238,7 +238,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
* : expressionWithPrecedences
|
||||
* : if
|
||||
* : try
|
||||
* : "typeof" "(" expression ")"
|
||||
* : "typeof" "(" element ")"
|
||||
* : "new" constructorInvocation
|
||||
* : objectLiteral
|
||||
* : declaration
|
||||
@@ -249,14 +249,14 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
*/
|
||||
public void parseExpression() {
|
||||
if (!atSet(EXPRESSION_FIRST)) {
|
||||
error("Expecting an expression");
|
||||
error("Expecting an element");
|
||||
return;
|
||||
}
|
||||
parseBinaryExpression(Precedence.ASSIGNMENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* expression (operation expression)*
|
||||
* element (operation element)*
|
||||
*
|
||||
* see the precedence table
|
||||
*/
|
||||
@@ -427,7 +427,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* expression (getEntryPoint? functionLiteral)?
|
||||
* element (getEntryPoint? functionLiteral)?
|
||||
*/
|
||||
protected boolean parseCallWithClosure() {
|
||||
boolean success = false;
|
||||
@@ -447,9 +447,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* atomicExpression
|
||||
* : tupleLiteral // or parenthesized expression
|
||||
* : tupleLiteral // or parenthesized element
|
||||
* : "this" getEntryPoint? ("<" type ">")?
|
||||
* : "typeof" "(" expression ")"
|
||||
* : "typeof" "(" element ")"
|
||||
* : "new" constructorInvocation
|
||||
* : objectLiteral
|
||||
* : jump
|
||||
@@ -535,8 +535,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
parseFunctionLiteral();
|
||||
}
|
||||
else if (!parseLiteralConstant()) {
|
||||
// TODO: better recovery if FIRST(expression) did not match
|
||||
errorWithRecovery("Expecting an expression", EXPRESSION_FOLLOW);
|
||||
// TODO: better recovery if FIRST(element) did not match
|
||||
errorWithRecovery("Expecting an element", EXPRESSION_FOLLOW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,7 +581,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* when
|
||||
* : "when" "(" (modifiers "val" SimpleName "=")? expression ")" "{"
|
||||
* : "when" "(" (modifiers "val" SimpleName "=")? element ")" "{"
|
||||
* whenEntry*
|
||||
* "}"
|
||||
* ;
|
||||
@@ -622,8 +622,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
/*
|
||||
* whenEntry
|
||||
* // TODO : consider empty after =>
|
||||
* : whenConditionIf{","} (when | "=>" expression SEMI)
|
||||
* : "else" ("continue" | "=>" expression SEMI)
|
||||
* : whenConditionIf{","} (when | "=>" element SEMI)
|
||||
* : "else" ("continue" | "=>" element SEMI)
|
||||
* ;
|
||||
*/
|
||||
private void parseWhenEntry() {
|
||||
@@ -633,7 +633,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
advance(); // ELSE_KEYWORD
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -641,14 +641,14 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
advance(); // DOUBLE_ARROW
|
||||
|
||||
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||
error("Expecting an expression");
|
||||
error("Expecting an element");
|
||||
} else {
|
||||
parseExpression();
|
||||
}
|
||||
} else if (at(CONTINUE_KEYWORD)) {
|
||||
advance(); // CONTINUE_KEYWORD
|
||||
} else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||
errorAndAdvance("Expecting 'continue' or '=> expression'");
|
||||
errorAndAdvance("Expecting 'continue' or '=> element'");
|
||||
}
|
||||
} else {
|
||||
parseWhenEntryNotElse();
|
||||
@@ -659,7 +659,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* : whenConditionIf{","} (when | "=>" expression SEMI)
|
||||
* : whenConditionIf{","} (when | "=>" element SEMI)
|
||||
*/
|
||||
private void parseWhenEntryNotElse() {
|
||||
while (true) {
|
||||
@@ -673,7 +673,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
} else {
|
||||
expect(DOUBLE_ARROW, "Expecting '=>' or 'when'", WHEN_CONDITION_RECOVERY_SET);
|
||||
if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
|
||||
error("Expecting an expression");
|
||||
error("Expecting an element");
|
||||
} else {
|
||||
parseExpression();
|
||||
}
|
||||
@@ -683,7 +683,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* whenConditionIf
|
||||
* : pattern ("if" "(" expression ")")?
|
||||
* : pattern ("if" "(" element ")")?
|
||||
* ;
|
||||
*/
|
||||
private void parseWhenConditionIf() {
|
||||
@@ -705,9 +705,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* whenCondition
|
||||
* : expression
|
||||
* : element
|
||||
* : "." postfixExpression typeArguments? valueArguments?
|
||||
* : ("in" | "!in") expression
|
||||
* : ("in" | "!in") element
|
||||
* : ("is" | "!is") isRHS
|
||||
* ;
|
||||
*/
|
||||
@@ -718,7 +718,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
advance(); // IN_KEYWORD or NOT_IN
|
||||
|
||||
if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW)) {
|
||||
error("Expecting an expression");
|
||||
error("Expecting an element");
|
||||
} else {
|
||||
parseExpression();
|
||||
}
|
||||
@@ -739,7 +739,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
parseExpression();
|
||||
}
|
||||
@@ -782,7 +782,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
myJetParsing.parseTypeRef();
|
||||
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) {
|
||||
rollbackMarker.rollbackTo();
|
||||
@@ -853,8 +853,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
* binding
|
||||
* : "is" pattern
|
||||
* : "!is" pattern
|
||||
* : "in" expression
|
||||
* : "!in" expression
|
||||
* : "in" element
|
||||
* : "!in" element
|
||||
* : ":" type
|
||||
* ;
|
||||
*/
|
||||
@@ -882,7 +882,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* arrayAccess
|
||||
* : "[" expression{","} "]"
|
||||
* : "[" element{","} "]"
|
||||
* ;
|
||||
*/
|
||||
private void parseArrayAccess() {
|
||||
@@ -894,9 +894,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
advance(); // LBRACKET
|
||||
|
||||
while (true) {
|
||||
if (at(COMMA)) errorAndAdvance("Expecting an index expression");
|
||||
if (at(COMMA)) errorAndAdvance("Expecting an index element");
|
||||
if (at(RBRACKET)) {
|
||||
error("Expecting an index expression");
|
||||
error("Expecting an index element");
|
||||
break;
|
||||
}
|
||||
parseExpression();
|
||||
@@ -1073,13 +1073,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* expressions
|
||||
* : SEMI* expression{SEMI+} SEMI*
|
||||
* : SEMI* element{SEMI+} SEMI*
|
||||
*/
|
||||
public void parseExpressions() {
|
||||
while (at(SEMICOLON)) advance(); // SEMICOLON
|
||||
while (!eof() && !at(RBRACE)) {
|
||||
if (!atSet(EXPRESSION_FIRST)) {
|
||||
errorAndAdvance("Expecting an expression");
|
||||
errorAndAdvance("Expecting an element");
|
||||
}
|
||||
if (atSet(EXPRESSION_FIRST)) {
|
||||
parseExpression();
|
||||
@@ -1126,7 +1126,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* doWhile
|
||||
* : "do" expression "while" "(" expression ")"
|
||||
* : "do" element "while" "(" element ")"
|
||||
* ;
|
||||
*/
|
||||
private void parseDoWhile() {
|
||||
@@ -1149,7 +1149,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* while
|
||||
* : "while" "(" expression ")" expression
|
||||
* : "while" "(" element ")" element
|
||||
* ;
|
||||
*/
|
||||
private void parseWhile() {
|
||||
@@ -1168,7 +1168,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* 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)?
|
||||
@@ -1207,7 +1207,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* expression
|
||||
* element
|
||||
*/
|
||||
private void parseControlStructureBody() {
|
||||
PsiBuilder.Marker body = mark();
|
||||
@@ -1263,7 +1263,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* if
|
||||
* : "if" "(" expression ")" expression SEMI? ("else" expression)?
|
||||
* : "if" "(" element ")" element SEMI? ("else" element)?
|
||||
* ;
|
||||
*/
|
||||
private void parseIf() {
|
||||
@@ -1296,7 +1296,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* "(" expression ")"
|
||||
* "(" element ")"
|
||||
*/
|
||||
private void parseCondition() {
|
||||
myBuilder.disableNewlines();
|
||||
@@ -1321,13 +1321,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
|
||||
|
||||
if (!eol() && atSet(LABELS)) advance(); // LABELS
|
||||
parseLabel();
|
||||
|
||||
marker.done(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* "return" getEntryPoint? expression?
|
||||
* "return" getEntryPoint? element?
|
||||
*/
|
||||
private void parseReturn() {
|
||||
assert _at(RETURN_KEYWORD);
|
||||
@@ -1336,9 +1336,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
advance(); // RETURN_KEYWORD
|
||||
|
||||
if (atSet(LABELS)) {
|
||||
advance(); // LABELS
|
||||
}
|
||||
parseLabel();
|
||||
|
||||
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() {
|
||||
assert _at(THROW_KEYWORD);
|
||||
@@ -1379,7 +1392,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* "typeof" "(" expression ")"
|
||||
* "typeof" "(" element ")"
|
||||
*/
|
||||
private void parseTypeOf() {
|
||||
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))
|
||||
* : "(" ((SimpleName "=")? expression){","} ")"
|
||||
* : "(" ((SimpleName "=")? element){","} ")"
|
||||
* ;
|
||||
*
|
||||
* expression
|
||||
* : "(" expression ")"
|
||||
* element
|
||||
* : "(" element ")"
|
||||
* ;
|
||||
*
|
||||
* TODO: duplication with valueArguments (but for the error messages)
|
||||
@@ -1422,7 +1435,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
while (true) {
|
||||
while (at(COMMA)) {
|
||||
tuple = true;
|
||||
errorAndAdvance("Expecting a tuple entry (expression)");
|
||||
errorAndAdvance("Expecting a tuple entry (element)");
|
||||
}
|
||||
|
||||
if (at(IDENTIFIER) && lookahead(1) == EQ) {
|
||||
@@ -1441,7 +1454,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
tuple = true;
|
||||
|
||||
if (at(RPAR)) {
|
||||
error("Expecting a tuple entry (expression)");
|
||||
error("Expecting a tuple entry (element)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1463,11 +1476,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
PsiBuilder.Marker mark = mark();
|
||||
advance(); // THIS_KEYWORD
|
||||
|
||||
if (atSet(LABELS)) {
|
||||
PsiBuilder.Marker label = mark();
|
||||
advance(); // LABELS
|
||||
label.done(LABEL_REFERENCE);
|
||||
}
|
||||
parseLabel();
|
||||
|
||||
if (at(LT)) {
|
||||
// This may be "this < foo" or "this<foo>", thus the backtracking
|
||||
@@ -1492,7 +1501,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* valueArguments
|
||||
* : "(" (SimpleName "=")? ("out" | "ref")? expression{","} ")"
|
||||
* : "(" (SimpleName "=")? ("out" | "ref")? element{","} ")"
|
||||
* ;
|
||||
*/
|
||||
public void parseValueArgumentList() {
|
||||
@@ -1521,7 +1530,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* (SimpleName "=")? ("out" | "ref")? expression
|
||||
* (SimpleName "=")? ("out" | "ref")? element
|
||||
*/
|
||||
private void parseValueArgument() {
|
||||
PsiBuilder.Marker argument = mark();
|
||||
|
||||
@@ -311,7 +311,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* attribute
|
||||
* // : SimpleName{"."} (valueArguments | "=" expression)?
|
||||
* // : SimpleName{"."} (valueArguments | "=" element)?
|
||||
* [for recovery: userType valueArguments?]
|
||||
* ;
|
||||
*/
|
||||
@@ -683,7 +683,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
* : modifiers ("val" | "var")
|
||||
* typeParameters? (type "." | attributes)?
|
||||
* SimpleName (":" type)?
|
||||
* ("=" expression SEMI?)?
|
||||
* ("=" element SEMI?)?
|
||||
* (getter? setter? | setter? getter?) SEMI?
|
||||
* ;
|
||||
*/
|
||||
@@ -883,7 +883,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
/*
|
||||
* functionBody
|
||||
* : block
|
||||
* : "=" expression
|
||||
* : "=" element
|
||||
* ;
|
||||
*/
|
||||
private void parseFunctionBody() {
|
||||
@@ -975,7 +975,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
* ;
|
||||
*
|
||||
* explicitDelegation
|
||||
* : userType "by" expression
|
||||
* : userType "by" element
|
||||
* ;
|
||||
*/
|
||||
private void parseDelegationSpecifier() {
|
||||
@@ -1336,7 +1336,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
* ;
|
||||
*
|
||||
* functionParameterRest
|
||||
* : parameter ("=" expression)?
|
||||
* : parameter ("=" element)?
|
||||
* ;
|
||||
*/
|
||||
public void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
|
||||
@@ -1376,7 +1376,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* functionParameter
|
||||
* : modifiers ("val" | "var")? parameter ("=" expression)?
|
||||
* : modifiers ("val" | "var")? parameter ("=" element)?
|
||||
* ;
|
||||
*/
|
||||
private boolean tryParseValueParameter() {
|
||||
@@ -1408,7 +1408,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
* functionParameterRest
|
||||
* : parameter ("=" expression)?
|
||||
* : parameter ("=" element)?
|
||||
* ;
|
||||
*/
|
||||
private boolean parseFunctionParameterRest() {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -15,4 +17,9 @@ public class JetContainerNode extends JetElement {
|
||||
protected <T> T findChildByClass(Class<T> 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;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
@@ -19,9 +16,4 @@ public class JetContinueExpression extends JetLabelQualifiedExpression {
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -16,7 +16,9 @@ public class JetLabelQualifiedExpression extends JetExpression {
|
||||
|
||||
@Nullable
|
||||
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
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.Map;
|
||||
public class BindingTraceContext extends BindingTrace implements BindingContext {
|
||||
private final Map<JetExpression, JetType> expressionTypes = new HashMap<JetExpression, JetType>();
|
||||
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<DeclarationDescriptor, PsiElement> descriptorToDeclarations = new HashMap<DeclarationDescriptor, PsiElement>();
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element) {
|
||||
labelResolutionResults.put(expression, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
|
||||
resolutionResults.remove(referenceExpression);
|
||||
@@ -107,7 +113,7 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
|
||||
public PsiElement resolveToDeclarationPsiElement(JetReferenceExpression referenceExpression) {
|
||||
DeclarationDescriptor declarationDescriptor = resolveReferenceExpression(referenceExpression);
|
||||
if (declarationDescriptor == null) {
|
||||
return null;
|
||||
return labelResolutionResults.get(referenceExpression);
|
||||
}
|
||||
return descriptorToDeclarations.get(declarationDescriptor.getOriginal());
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class ClassDescriptorResolver {
|
||||
}
|
||||
} else {
|
||||
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");
|
||||
} else {
|
||||
// TODO : Recursion possible
|
||||
|
||||
@@ -234,7 +234,7 @@ public class TopDownAnalyzer {
|
||||
if (bodyExpression != null) {
|
||||
System.out.println("-------------");
|
||||
JetControlFlowInstructionsGenerator instructionsGenerator = new JetControlFlowInstructionsGenerator();
|
||||
new JetControlFlowProcessor(semanticServices, instructionsGenerator).generate(function, bodyExpression);
|
||||
new JetControlFlowProcessor(semanticServices, trace, instructionsGenerator).generate(function, bodyExpression);
|
||||
Pseudocode pseudocode = instructionsGenerator.getPseudocode();
|
||||
pseudocode.postProcess();
|
||||
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) {
|
||||
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ public class JetTypeInferrer {
|
||||
|
||||
@Override
|
||||
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);
|
||||
@@ -894,7 +894,7 @@ public class JetTypeInferrer {
|
||||
}
|
||||
else if (selectorExpression != null) {
|
||||
// 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;
|
||||
}
|
||||
@@ -1312,7 +1312,7 @@ public class JetTypeInferrer {
|
||||
String counterpartName = binaryOperationNames.get(assignmentOperationCounterparts.get(operationType));
|
||||
getTypeForBinaryCall(expression, counterpartName, scope, true);
|
||||
}
|
||||
result = null; // not an expression
|
||||
result = null; // not an element
|
||||
}
|
||||
|
||||
@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) {
|
||||
|
||||
@@ -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() {
|
||||
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.
|
||||
*
|
||||
* @return the next token
|
||||
|
||||
@@ -30,17 +30,17 @@ JetFile: Expressions_ERR.jet
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('dfsd')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(BAD_CHARACTER)('~')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
@@ -49,10 +49,10 @@ JetFile: Expressions_ERR.jet
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('srgsdfg')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(BAD_CHARACTER)('~')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -60,7 +60,7 @@ JetFile: When_ERR.jet
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION
|
||||
PsiElement(in)('in')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
@@ -71,7 +71,7 @@ JetFile: When_ERR.jet
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION
|
||||
PsiElement(NOT_IN)('!in')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
@@ -81,7 +81,7 @@ JetFile: When_ERR.jet
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION
|
||||
PsiErrorElement:Expecting an expression, is-condition or in-condition
|
||||
PsiErrorElement:Expecting an element, is-condition or in-condition
|
||||
<empty list>
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiWhiteSpace(' ')
|
||||
@@ -90,7 +90,7 @@ JetFile: When_ERR.jet
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
PsiElement(else)('else')
|
||||
PsiErrorElement:Expecting 'continue' or '=> expression'
|
||||
PsiErrorElement:Expecting 'continue' or '=> element'
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -112,7 +112,7 @@ JetFile: When_ERR.jet
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
@@ -122,59 +122,59 @@ JetFile: When_ERR.jet
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION
|
||||
PsiElement(in)('in')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION
|
||||
PsiElement(NOT_IN)('!in')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION
|
||||
PsiElement(NOT_IN)('!in')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION
|
||||
PsiErrorElement:Expecting an expression, is-condition or in-condition
|
||||
PsiErrorElement:Expecting an element, is-condition or in-condition
|
||||
<empty list>
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
PsiElement(else)('else')
|
||||
PsiErrorElement:Expecting 'continue' or '=> expression'
|
||||
PsiErrorElement:Expecting 'continue' or '=> element'
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
PsiElement(else)('else')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(DOUBLE_ARROW)('=>')
|
||||
PsiErrorElement:Expecting an expression
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
|
||||
Reference in New Issue
Block a user