Labeled expressions supported in the type inferrer

This commit is contained in:
Andrey Breslav
2011-03-31 21:27:38 +04:00
parent 87d07007a0
commit 01105c8c41
5 changed files with 42 additions and 24 deletions
@@ -1,22 +1,26 @@
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.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import java.util.Collections; import java.util.*;
import java.util.Iterator;
import java.util.List;
/** /**
* @author abreslav * @author abreslav
*/ */
public class JetControlFlowProcessor { public class JetControlFlowProcessor {
private JetControlFlowBuilder builder; private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
public JetControlFlowProcessor(JetControlFlowBuilder builder) { private final JetSemanticServices semanticServices;
private final JetControlFlowBuilder builder;
public JetControlFlowProcessor(JetSemanticServices semanticServices, JetControlFlowBuilder builder) {
this.semanticServices = semanticServices;
this.builder = builder; this.builder = builder;
} }
@@ -32,11 +36,25 @@ public class JetControlFlowProcessor {
builder.exitSubroutine(subroutineElement); builder.exitSubroutine(subroutineElement);
} }
private void registerLabeledElement(@NotNull JetSimpleNameExpression label, @NotNull JetExpression labeledExpression) { private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
throw new UnsupportedOperationException(); // TODO Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null) {
stack = new Stack<JetElement>();
labeledElements.put(labelName, stack);
}
stack.push(labeledElement);
} }
private JetElement resolveLabel(JetSimpleNameExpression labelElement) { 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();
// }
// }
}
private JetElement resolveLabel(@NotNull String labelName, @NotNull ASTNode labelNode) {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
@@ -70,7 +88,7 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression) { public void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression) {
registerLabeledElement(expression.getTargetLabel(), expression.getLabeledExpression()); enterLabeledElement(expression.getLabelName(), expression.getLabeledExpression());
value(expression.getLabeledExpression(), false); value(expression.getLabeledExpression(), false);
} }
@@ -216,7 +234,7 @@ public class JetControlFlowProcessor {
} }
JetSimpleNameExpression labelElement = expression.getTargetLabel(); JetSimpleNameExpression labelElement = expression.getTargetLabel();
JetElement subroutine = (labelElement != null) JetElement subroutine = (labelElement != null)
? resolveLabel(labelElement) ? resolveLabel(expression.getLabelName(), expression.getTargetLabel().getNode())
: builder.getCurrentSubroutine(); : builder.getCurrentSubroutine();
if (returnedExpression == null) { if (returnedExpression == null) {
builder.returnNoValue(subroutine); builder.returnNoValue(subroutine);
@@ -24,4 +24,10 @@ public class JetLabelQualifiedExpression extends JetExpression {
return findChildByClass(JetExpression.class); return findChildByClass(JetExpression.class);
} }
@Nullable
public String getLabelName() {
JetSimpleNameExpression labelElement = getTargetLabel();
assert labelElement == null || labelElement.getText().startsWith("@");
return labelElement == null ? null : labelElement.getText().substring(1);
}
} }
@@ -24,15 +24,4 @@ public class JetThisExpression extends JetLabelQualifiedExpression {
return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE); return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
} }
@Nullable
public JetSimpleNameExpression getLabelElement() {
return findChildByClass(JetSimpleNameExpression.class);
}
@Nullable
public String getLabelName() {
JetSimpleNameExpression labelElement = getLabelElement();
assert labelElement == null || labelElement.getText().startsWith("@");
return labelElement == null ? null : labelElement.getText().substring(1);
}
} }
@@ -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(instructionsGenerator).generate(function, bodyExpression); new JetControlFlowProcessor(semanticServices, instructionsGenerator).generate(function, bodyExpression);
Pseudocode pseudocode = instructionsGenerator.getPseudocode(); Pseudocode pseudocode = instructionsGenerator.getPseudocode();
pseudocode.postProcess(); pseudocode.postProcess();
pseudocode.dumpInstructions(System.out); pseudocode.dumpInstructions(System.out);
@@ -558,10 +558,10 @@ public class JetTypeInferrer {
} }
} }
else if (size == 0) { else if (size == 0) {
semanticServices.getErrorHandler().unresolvedReference(expression.getLabelElement()); semanticServices.getErrorHandler().unresolvedReference(expression.getTargetLabel());
} }
else { else {
JetSimpleNameExpression labelElement = expression.getLabelElement(); JetSimpleNameExpression labelElement = expression.getTargetLabel();
assert labelElement != null; assert labelElement != null;
semanticServices.getErrorHandler().genericError(labelElement.getNode(), "Ambiguous label"); semanticServices.getErrorHandler().genericError(labelElement.getNode(), "Ambiguous label");
} }
@@ -989,6 +989,11 @@ public class JetTypeInferrer {
@Override @Override
public void visitUnaryExpression(JetUnaryExpression expression) { public void visitUnaryExpression(JetUnaryExpression expression) {
JetSimpleNameExpression operationSign = expression.getOperationSign(); JetSimpleNameExpression operationSign = expression.getOperationSign();
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
// TODO : Some processing for the label?
result = getType(expression.getBaseExpression());
return;
}
IElementType operationType = operationSign.getReferencedNameElementType(); IElementType operationType = operationSign.getReferencedNameElementType();
String name = unaryOperationNames.get(operationType); String name = unaryOperationNames.get(operationType);
if (name == null) { if (name == null) {