Labels resolve removed from control flow graph
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user