Labels resolve removed from control flow graph

This commit is contained in:
svtk
2011-10-12 15:53:41 +04:00
parent 06a7fa1f16
commit 8db6aa4ab4
2 changed files with 86 additions and 72 deletions
@@ -1,10 +1,12 @@
package org.jetbrains.jet.lang.cfg;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
@@ -20,7 +22,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
*/
public class JetControlFlowProcessor {
private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
// private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
private final JetControlFlowBuilder builder;
private final BindingTrace trace;
@@ -35,10 +37,10 @@ public class JetControlFlowProcessor {
}
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body) {
if (subroutineElement instanceof JetNamedDeclaration) {
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration);
}
// if (subroutineElement instanceof JetNamedDeclaration) {
// JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
// enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration);
// }
boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression;
builder.enterSubroutine(subroutineElement, functionLiteral);
for (JetElement statement : body) {
@@ -47,50 +49,50 @@ public class JetControlFlowProcessor {
builder.exitSubroutine(subroutineElement, functionLiteral);
}
private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null) {
stack = new Stack<JetElement>();
labeledElements.put(labelName, stack);
}
stack.push(labeledElement);
}
// private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
// Stack<JetElement> stack = labeledElements.get(labelName);
// if (stack == null) {
// stack = new Stack<JetElement>();
// labeledElements.put(labelName, stack);
// }
// stack.push(labeledElement);
// }
//
// private void exitElement(JetElement element) {
// // 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 void exitElement(JetElement element) {
// 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();
}
}
}
@Nullable
private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved) {
Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null || stack.isEmpty()) {
if (reportUnresolved) {
// trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
}
return null;
}
else if (stack.size() > 1) {
// trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope");
// trace.report(LABEL_NAME_CLASH.on(labelExpression));
}
JetElement result = stack.peek();
// trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
return result;
}
// @Nullable
// private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved) {
// Stack<JetElement> stack = labeledElements.get(labelName);
// if (stack == null || stack.isEmpty()) {
// if (reportUnresolved) {
//// trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
// }
// return null;
// }
// else if (stack.size() > 1) {
//// trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope");
//// trace.report(LABEL_NAME_CLASH.on(labelExpression));
// }
//
// JetElement result = stack.peek();
//// trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
// return result;
// }
private class CFPVisitor extends JetVisitorVoid {
private final boolean inCondition;
@@ -109,7 +111,7 @@ public class JetControlFlowProcessor {
visitor = new CFPVisitor(inCondition);
}
element.accept(visitor);
exitElement(element);
// exitElement(element);
}
@Override
@@ -122,12 +124,12 @@ public class JetControlFlowProcessor {
@Override
public void visitThisExpression(JetThisExpression expression) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
if (targetLabel != null) {
String labelName = expression.getLabelName();
assert labelName != null;
resolveLabel(labelName, targetLabel, false);
}
// JetSimpleNameExpression targetLabel = expression.getTargetLabel();
// if (targetLabel != null) {
// String labelName = expression.getLabelName();
// assert labelName != null;
// resolveLabel(labelName, targetLabel, false);
// }
builder.read(expression);
}
@@ -159,7 +161,7 @@ public class JetControlFlowProcessor {
private void visitLabeledExpression(@NotNull String labelName, @NotNull JetExpression labeledExpression) {
JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression);
if (deparenthesized != null) {
enterLabeledElement(labelName, deparenthesized);
// enterLabeledElement(labelName, deparenthesized);
value(labeledExpression, inCondition);
}
}
@@ -443,12 +445,20 @@ public class JetControlFlowProcessor {
if (labelName != null) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
assert targetLabel != null;
loop = resolveLabel(labelName, targetLabel, true);
if (!isLoop(loop)) {
// trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop");
PsiElement labeledElement = BindingContextUtils.resolveToDeclarationPsiElement(trace.getBindingContext(), targetLabel);
if (labeledElement instanceof JetLoopExpression) {
loop = (JetLoopExpression) labeledElement;
}
else {
trace.report(NOT_A_LOOP_LABEL.on(expression, targetLabel.getText()));
loop = null;
}
// loop = resolveLabel(labelName, targetLabel, true);
// if (!isLoop(loop)) {
//// trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop");
// trace.report(NOT_A_LOOP_LABEL.on(expression, targetLabel.getText()));
// loop = null;
// }
}
else {
loop = builder.getCurrentLoop();
@@ -460,11 +470,11 @@ public class JetControlFlowProcessor {
return loop;
}
private boolean isLoop(JetElement loop) {
return loop instanceof JetWhileExpression ||
loop instanceof JetDoWhileExpression ||
loop instanceof JetForExpression;
}
// private boolean isLoop(JetElement loop) {
// return loop instanceof JetWhileExpression ||
// loop instanceof JetDoWhileExpression ||
// loop instanceof JetForExpression;
// }
@Override
public void visitReturnExpression(JetReturnExpression expression) {
@@ -477,7 +487,10 @@ public class JetControlFlowProcessor {
if (labelElement != null) {
String labelName = expression.getLabelName();
assert labelName != null;
subroutine = resolveLabel(labelName, labelElement, true);
PsiElement labeledElement = BindingContextUtils.resolveToDeclarationPsiElement(trace.getBindingContext(), labelElement);
assert labeledElement instanceof JetElement;
subroutine = (JetElement) labeledElement;
//subroutine = resolveLabel(labelName, labelElement, true);
}
else {
subroutine = builder.getCurrentSubroutine();
@@ -1343,11 +1343,11 @@ public class JetTypeInferrer {
}
else if (size == 0) {
//todo (first we put to the context, then get from it)
labelsResolver.resolveLabel(labelName, targetLabel, false, context);
JetElement element = labelsResolver.resolveLabel(labelName, targetLabel, false, context);
// This uses the info written by the control flow processor
PsiElement psiElement = BindingContextUtils.resolveToDeclarationPsiElement(context.trace.getBindingContext(), targetLabel);
if (psiElement instanceof JetFunctionLiteralExpression) {
DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement);
//PsiElement psiElement = BindingContextUtils.resolveToDeclarationPsiElement(context.trace.getBindingContext(), targetLabel);
if (element instanceof JetFunctionLiteralExpression) {
DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
if (declarationDescriptor instanceof FunctionDescriptor) {
thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiver();
if (thisReceiver.exists()) {
@@ -2911,7 +2911,7 @@ public class JetTypeInferrer {
}
}
private void resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, TypeInferenceContext context) {
private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, TypeInferenceContext context) {
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
int size = declarationsByLabel.size();
@@ -2930,7 +2930,7 @@ public class JetTypeInferrer {
throw new UnsupportedOperationException(); // TODO
}
context.trace.record(LABEL_TARGET, labelExpression, element);
return;
return element;
}
Stack<JetElement> stack = labeledElements.get(labelName);
@@ -2938,7 +2938,7 @@ public class JetTypeInferrer {
if (reportUnresolved) {
context.trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
}
return;
return null;
}
else if (stack.size() > 1) {
context.trace.report(LABEL_NAME_CLASH.on(labelExpression));
@@ -2946,6 +2946,7 @@ public class JetTypeInferrer {
JetElement result = stack.peek();
context.trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
return result;
}
private void resolveCorrespondingLoopLabel(JetLabelQualifiedExpression expression, TypeInferenceContext context) {