Do not rely on JetCallExpressions in tail-call detection

Calls come in other forms too
This commit is contained in:
Andrey Breslav
2013-12-05 21:10:34 +04:00
parent 9ed0b009d4
commit 6d369b985f
5 changed files with 12 additions and 11 deletions
@@ -1595,9 +1595,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (returnedExpression != null) {
if (returnedExpression instanceof JetCallExpression) {
JetCallExpression callExpression = (JetCallExpression) returnedExpression;
if (tailRecursionGeneratorUtil.isTailRecursion(callExpression) && callExpression.getCalleeExpression() != null) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression());
if (resolvedCall != null) {
JetExpression calleeExpression = callExpression.getCalleeExpression();
if (calleeExpression != null) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression);
if (resolvedCall != null && tailRecursionGeneratorUtil.isTailRecursion(resolvedCall)) {
return tailRecursionGeneratorUtil.generateTailRecursion(resolvedCall, callExpression);
}
}
@@ -1932,7 +1933,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
}
if (tailRecursionGeneratorUtil.isTailRecursion(expression)) {
if (tailRecursionGeneratorUtil.isTailRecursion(resolvedCall)) {
return tailRecursionGeneratorUtil.generateTailRecursion(resolvedCall, expression);
}
@@ -61,8 +61,8 @@ public class TailRecursionGeneratorUtil {
this.state = state;
}
public boolean isTailRecursion(@NotNull JetCallExpression expression) {
TailRecursionKind status = state.getBindingContext().get(TAIL_RECURSION_CALL, expression);
public boolean isTailRecursion(@NotNull ResolvedCall<?> resolvedCall) {
TailRecursionKind status = state.getBindingContext().get(TAIL_RECURSION_CALL, resolvedCall);
return status != null && status.isDoGenerateTailRecursion();
}
@@ -336,8 +336,8 @@ public interface Errors {
DiagnosticFactory2<JetReferenceExpression, JetExpression, JetType> FUNCTION_EXPECTED = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<JetExpression, JetExpression, Boolean> FUNCTION_CALL_EXPECTED = DiagnosticFactory2.create(ERROR, CALL_EXPRESSION);
DiagnosticFactory0<JetCallExpression> NON_TAIL_RECURSIVE_CALL = DiagnosticFactory0.create(WARNING, CALL_EXPRESSION);
DiagnosticFactory0<JetCallExpression> TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED = DiagnosticFactory0.create(WARNING, CALL_EXPRESSION);
DiagnosticFactory0<PsiElement> NON_TAIL_RECURSIVE_CALL = DiagnosticFactory0.create(WARNING, CALL_EXPRESSION);
DiagnosticFactory0<PsiElement> TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED = DiagnosticFactory0.create(WARNING, CALL_EXPRESSION);
DiagnosticFactory0<PsiElement> NO_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS = DiagnosticFactory0.create(ERROR);
@@ -383,10 +383,10 @@ public class PositioningStrategies {
}
};
public static final PositioningStrategy<JetExpression> CALL_EXPRESSION = new PositioningStrategy<JetExpression>() {
public static final PositioningStrategy<PsiElement> CALL_EXPRESSION = new PositioningStrategy<PsiElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetExpression element) {
public List<TextRange> mark(@NotNull PsiElement element) {
if (element instanceof JetCallExpression) {
JetCallExpression callExpression = (JetCallExpression) element;
PsiElement endElement;
@@ -89,7 +89,7 @@ public interface BindingContext {
new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
WritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>> RESOLVED_CALL =
new BasicWritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>>(DO_NOTHING);
WritableSlice<JetCallExpression, TailRecursionKind> TAIL_RECURSION_CALL = new BasicWritableSlice<JetCallExpression, TailRecursionKind>(DO_NOTHING, true);
WritableSlice<ResolvedCall<?>, TailRecursionKind> TAIL_RECURSION_CALL = Slices.createSimpleSlice();
WritableSlice<FunctionDescriptor, Boolean> HAS_TAIL_CALLS = Slices.createSimpleSetSlice();
WritableSlice<JetElement, ConstraintSystemCompleter> CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice<JetElement, ConstraintSystemCompleter>(DO_NOTHING);
WritableSlice<JetElement, Call> CALL = new BasicWritableSlice<JetElement, Call>(DO_NOTHING);