diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index aa185dcee86..c841ff2d212 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -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> labeledElements = new HashMap>(); +// private final Map> labeledElements = new HashMap>(); private final JetControlFlowBuilder builder; private final BindingTrace trace; @@ -35,10 +37,10 @@ public class JetControlFlowProcessor { } public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List 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 stack = labeledElements.get(labelName); - if (stack == null) { - stack = new Stack(); - labeledElements.put(labelName, stack); - } - stack.push(labeledElement); - } +// private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) { +// Stack stack = labeledElements.get(labelName); +// if (stack == null) { +// stack = new Stack(); +// labeledElements.put(labelName, stack); +// } +// stack.push(labeledElement); +// } +// +// private void exitElement(JetElement element) { +// // TODO : really suboptimal +// for (Iterator>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) { +// Map.Entry> entry = mapIter.next(); +// Stack stack = entry.getValue(); +// for (Iterator 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>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) { - Map.Entry> entry = mapIter.next(); - Stack stack = entry.getValue(); - for (Iterator 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 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 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(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 7abaef85e08..2f2c58b1672 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -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 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 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) {