Unused code removed
This commit is contained in:
@@ -39,8 +39,8 @@ 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.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.calls.TailRecursionKind;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.tail.TailRecursionKind;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiver;
|
||||
@@ -55,10 +55,9 @@ import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.BACK
|
||||
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.FORWARD;
|
||||
import static org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState.*;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.tail.TailRecursionKind.*;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.TailRecursionKind.*;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
|
||||
|
||||
public class JetFlowInformationProvider {
|
||||
@@ -680,7 +679,7 @@ public class JetFlowInformationProvider {
|
||||
|
||||
boolean sameThisObject = sameThisObject(resolvedCall);
|
||||
|
||||
TailRecursionKind kind = isTail && sameThisObject ? MIGHT_BE : NON_TAIL;
|
||||
TailRecursionKind kind = isTail && sameThisObject ? TAIL_CALL : NON_TAIL;
|
||||
|
||||
KindAndCall kindAndCall = calls.get(element);
|
||||
calls.put(element,
|
||||
@@ -696,9 +695,8 @@ public class JetFlowInformationProvider {
|
||||
JetElement element = entry.getKey();
|
||||
KindAndCall kindAndCall = entry.getValue();
|
||||
switch (kindAndCall.kind) {
|
||||
case MIGHT_BE:
|
||||
case IN_RETURN:
|
||||
trace.record(TAIL_RECURSION_CALL, kindAndCall.call, TailRecursionKind.IN_RETURN);
|
||||
case TAIL_CALL:
|
||||
trace.record(TAIL_RECURSION_CALL, kindAndCall.call, TailRecursionKind.TAIL_CALL);
|
||||
trace.record(BindingContext.HAS_TAIL_CALLS, (FunctionDescriptor) subroutineDescriptor);
|
||||
break;
|
||||
case IN_TRY:
|
||||
@@ -745,14 +743,14 @@ public class JetFlowInformationProvider {
|
||||
resultingKind = kind;
|
||||
}
|
||||
else {
|
||||
if (check(kind, existingKind, IN_TRY, MIGHT_BE)) {
|
||||
if (check(kind, existingKind, IN_TRY, TAIL_CALL)) {
|
||||
resultingKind = IN_TRY;
|
||||
}
|
||||
else if (check(kind, existingKind, IN_TRY, NON_TAIL)) {
|
||||
resultingKind = IN_TRY;
|
||||
}
|
||||
else {
|
||||
// MIGHT_BE, NON_TAIL
|
||||
// TAIL_CALL, NON_TAIL
|
||||
resultingKind = NON_TAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,37 +1028,4 @@ public class JetPsiUtil {
|
||||
expression;
|
||||
return (JetToken) elementType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T> T visitUpwardToRoot(
|
||||
@NotNull PsiElement element,
|
||||
@NotNull JetVisitor<BacktraceVisitorStatus<T>, VisitorData<T>> visitor,
|
||||
T def
|
||||
) {
|
||||
List<PsiElement> track = new ArrayList<PsiElement>();
|
||||
List<PsiElement> view = Collections.unmodifiableList(track);
|
||||
@NotNull
|
||||
BacktraceVisitorStatus<T> lastStatus = new BacktraceVisitorStatus<T>(def, true);
|
||||
VisitorData<T> data = new VisitorData<T>(view);
|
||||
|
||||
do {
|
||||
track.add(element);
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof JetElement) {
|
||||
JetElement jet = (JetElement) parent;
|
||||
data.last = element;
|
||||
data.data = lastStatus.getData();
|
||||
|
||||
BacktraceVisitorStatus<T> status = jet.accept(visitor, data);
|
||||
if (status == null) {
|
||||
throw new IllegalStateException("visitor has returned null status");
|
||||
}
|
||||
lastStatus = status;
|
||||
}
|
||||
|
||||
element = parent;
|
||||
} while (element != null && !lastStatus.isAbortTrace());
|
||||
|
||||
return lastStatus.getData();
|
||||
}
|
||||
}
|
||||
|
||||
-8
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
@@ -78,14 +77,7 @@ public class CallResolverExtensionProvider {
|
||||
extensions.add(new InlineCallResolverExtension(descriptor));
|
||||
}
|
||||
}
|
||||
if (isAnnotatedAsTailRecursive(declarationDescriptor)) {
|
||||
extensions.add(TailRecursionDetectorExtension.INSTANCE);
|
||||
}
|
||||
// add your extensions here
|
||||
extensions.add(DEFAULT);
|
||||
}
|
||||
|
||||
private static boolean isAnnotatedAsTailRecursive(DeclarationDescriptor descriptor) {
|
||||
return KotlinBuiltIns.getInstance().isTailRecursive(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RecursiveCallRecorderResolverExtension extends RecursiveCallResolverExtension {
|
||||
|
||||
public static final RecursiveCallRecorderResolverExtension INSTANCE = new RecursiveCallRecorderResolverExtension();
|
||||
|
||||
@Override
|
||||
protected <F extends CallableDescriptor> void runImpl(
|
||||
@NotNull JetCallExpression callExpression,
|
||||
@NotNull ResolvedCall<F> resolvedCall,
|
||||
@NotNull BasicCallResolutionContext context
|
||||
) {
|
||||
DeclarationDescriptor declarationDescriptor = context.scope.getContainingDeclaration();
|
||||
|
||||
List<JetCallExpression> expressions =
|
||||
context.trace.get(BindingContext.FUNCTION_RECURSIVE_CALL_EXPRESSIONS, declarationDescriptor);
|
||||
|
||||
if (expressions == null) {
|
||||
expressions = new ArrayList<JetCallExpression>(2);
|
||||
context.trace.record(BindingContext.FUNCTION_RECURSIVE_CALL_EXPRESSIONS, declarationDescriptor, expressions);
|
||||
}
|
||||
|
||||
expressions.add(callExpression);
|
||||
}
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||
|
||||
public class TailRecursionDetectorExtension extends RecursiveCallResolverExtension {
|
||||
|
||||
public static final TailRecursionDetectorExtension INSTANCE = new TailRecursionDetectorExtension();
|
||||
|
||||
@Override
|
||||
protected <F extends CallableDescriptor> void runImpl(
|
||||
@NotNull JetCallExpression callExpression,
|
||||
@NotNull ResolvedCall<F> resolvedCall,
|
||||
@NotNull BasicCallResolutionContext context
|
||||
) {
|
||||
BindingTrace trace = context.trace;
|
||||
|
||||
TailRecursionKind recursionKind =
|
||||
JetPsiUtil.visitUpwardToRoot(callExpression, new TailRecursionDetectorVisitor(), TailRecursionKind.MIGHT_BE);
|
||||
|
||||
trace.record(BindingContext.TAIL_RECURSION_CALL,
|
||||
callExpression,
|
||||
recursionKind);
|
||||
|
||||
switch (recursionKind) {
|
||||
case NON_TAIL:
|
||||
trace.report(Errors.NON_TAIL_RECURSIVE_CALL.on(callExpression));
|
||||
break;
|
||||
case IN_TRY:
|
||||
trace.report(Errors.TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED.on(callExpression));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
-205
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
public class TailRecursionDetectorVisitor extends JetVisitor<BacktraceVisitorStatus<TailRecursionKind>, VisitorData<TailRecursionKind>> {
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitNamedFunction(
|
||||
@NotNull JetNamedFunction function, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
return new BacktraceVisitorStatus<TailRecursionKind>(data.data, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitTryExpression(
|
||||
@NotNull JetTryExpression expression, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
return noTailRecursion(TailRecursionKind.IN_TRY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitCatchSection(
|
||||
@NotNull JetCatchClause catchClause, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
return continueTrace(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitFinallySection(
|
||||
@NotNull JetFinallySection finallySection, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
return continueTrace(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitBlockExpression(
|
||||
@NotNull JetBlockExpression expression, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
|
||||
if (data.data.isReturn()) return continueTrace(data);
|
||||
|
||||
PsiElement child = data.last;
|
||||
|
||||
JetElement last = findLastJetElement(expression.getLastChild());
|
||||
if (last != child) { // if last statement
|
||||
if (!(last instanceof JetReturnExpression)) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
|
||||
JetReturnExpression returnExpression = (JetReturnExpression) last;
|
||||
if (returnExpression.getReturnedExpression() != null) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
|
||||
if (findLastJetElement(returnExpression.getPrevSibling()) != child) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
}
|
||||
|
||||
return continueTrace(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitWhenExpression(
|
||||
@NotNull JetWhenExpression expression, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
if (expression.getSubjectExpression() == data.last) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
|
||||
return continueTrace(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitWhenEntry(
|
||||
@NotNull JetWhenEntry jetWhenEntry, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
return continueTrace(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitWhenConditionExpression(
|
||||
@NotNull JetWhenConditionWithExpression condition, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitIfExpression(
|
||||
@NotNull JetIfExpression expression, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
if (expression.getCondition() == data.last) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
|
||||
return continueTrace(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitBinaryExpression(
|
||||
@NotNull JetBinaryExpression expression, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
if (expression.getOperationToken() == JetTokens.ELVIS) {
|
||||
if (expression.getLeft() == data.last) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
else if (expression.getRight() == data.last) {
|
||||
return continueTrace(data);
|
||||
}
|
||||
else {
|
||||
return noTailRecursion();
|
||||
}
|
||||
}
|
||||
|
||||
return super.visitBinaryExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitQualifiedExpression(
|
||||
@NotNull JetQualifiedExpression expression, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
if (!(expression.getReceiverExpression() instanceof JetThisExpression)) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
|
||||
return continueTrace(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitReturnExpression(
|
||||
@NotNull JetReturnExpression expression, VisitorData<TailRecursionKind> data
|
||||
) {
|
||||
JetExpression returned = expression.getReturnedExpression();
|
||||
if (returned == null) {
|
||||
throw new IllegalStateException("Bad case: how could we reach void return?");
|
||||
}
|
||||
|
||||
return continueTrace(data, TailRecursionKind.IN_RETURN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BacktraceVisitorStatus<TailRecursionKind> visitJetElement(
|
||||
@NotNull JetElement element, VisitorData<TailRecursionKind> state
|
||||
) {
|
||||
if (element instanceof JetContainerNode) {
|
||||
return continueTrace(state);
|
||||
}
|
||||
|
||||
if (state.data == TailRecursionKind.MIGHT_BE) {
|
||||
return noTailRecursion();
|
||||
}
|
||||
|
||||
return continueTrace(state);
|
||||
}
|
||||
|
||||
private static BacktraceVisitorStatus<TailRecursionKind> noTailRecursion() {
|
||||
return new BacktraceVisitorStatus<TailRecursionKind>(TailRecursionKind.NON_TAIL, true);
|
||||
}
|
||||
|
||||
private static BacktraceVisitorStatus<TailRecursionKind> noTailRecursion(TailRecursionKind status) {
|
||||
return new BacktraceVisitorStatus<TailRecursionKind>(status, true);
|
||||
}
|
||||
|
||||
private static BacktraceVisitorStatus<TailRecursionKind> continueTrace(VisitorData<TailRecursionKind> data) {
|
||||
return continueTrace(data, TailRecursionKind.MIGHT_BE);
|
||||
}
|
||||
|
||||
private static BacktraceVisitorStatus<TailRecursionKind> continueTrace(VisitorData<TailRecursionKind> data, TailRecursionKind desiredStatus) {
|
||||
TailRecursionKind newStatus = data.data.and(desiredStatus);
|
||||
return new BacktraceVisitorStatus<TailRecursionKind>(newStatus, !newStatus.isDoGenerateTailRecursion());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetElement findLastJetElement(@Nullable PsiElement rightNode) {
|
||||
PsiElement node = rightNode;
|
||||
while (node != null) {
|
||||
if (node instanceof JetElement) {
|
||||
return (JetElement) node;
|
||||
}
|
||||
node = node.getPrevSibling();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,7 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
public enum TailRecursionKind {
|
||||
MIGHT_BE(true),
|
||||
IN_RETURN(true),
|
||||
TAIL_CALL(true),
|
||||
IN_TRY(false),
|
||||
NON_TAIL(false);
|
||||
|
||||
@@ -31,31 +30,4 @@ public enum TailRecursionKind {
|
||||
public boolean isDoGenerateTailRecursion() {
|
||||
return doGenerateTailRecursion;
|
||||
}
|
||||
|
||||
public boolean isReturn() {
|
||||
return this == IN_RETURN;
|
||||
}
|
||||
|
||||
public TailRecursionKind and(TailRecursionKind b) {
|
||||
if (this == b) {
|
||||
return this;
|
||||
}
|
||||
if (!this.isDoGenerateTailRecursion()) {
|
||||
return this;
|
||||
}
|
||||
if (!b.isDoGenerateTailRecursion()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (isOneOf(this, b, IN_RETURN)) {
|
||||
return IN_RETURN;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private static boolean isOneOf(TailRecursionKind a, TailRecursionKind b, TailRecursionKind value) {
|
||||
return a == value || b == value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user