Extract Function: Approximate non-resolvable types with nearest resolvable supertype when possible
#KT-7120 Fixed
This commit is contained in:
@@ -20,15 +20,12 @@ import com.google.common.base.Function;
|
|||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.TestOnly;
|
import org.jetbrains.annotations.TestOnly;
|
||||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.psi.JetClassBody;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.psi.JetClassOrObject;
|
|
||||||
import org.jetbrains.kotlin.psi.JetExpression;
|
|
||||||
import org.jetbrains.kotlin.psi.JetFile;
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||||
import org.jetbrains.kotlin.resolve.TraceBasedRedeclarationHandler;
|
import org.jetbrains.kotlin.resolve.TraceBasedRedeclarationHandler;
|
||||||
@@ -158,12 +155,12 @@ public final class JetScopeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetScope getResolutionScope(@NotNull JetExpression expression, @NotNull AnalysisResult analysisResult) {
|
public static JetScope getResolutionScope(@NotNull PsiElement element, @NotNull BindingContext context) {
|
||||||
PsiElement parent = expression.getParent();
|
PsiElement parent = element.getParent();
|
||||||
|
|
||||||
if (parent instanceof JetClassBody) {
|
if (parent instanceof JetClassBody) {
|
||||||
JetClassOrObject classOrObject = (JetClassOrObject) parent.getParent();
|
JetClassOrObject classOrObject = (JetClassOrObject) parent.getParent();
|
||||||
ClassDescriptor classDescriptor = analysisResult.getBindingContext().get(BindingContext.CLASS, classOrObject);
|
ClassDescriptor classDescriptor = context.get(BindingContext.CLASS, classOrObject);
|
||||||
if (classDescriptor instanceof ClassDescriptorWithResolutionScopes) {
|
if (classDescriptor instanceof ClassDescriptorWithResolutionScopes) {
|
||||||
return ((ClassDescriptorWithResolutionScopes) classDescriptor).getScopeForMemberDeclarationResolution();
|
return ((ClassDescriptorWithResolutionScopes) classDescriptor).getScopeForMemberDeclarationResolution();
|
||||||
}
|
}
|
||||||
@@ -171,10 +168,14 @@ public final class JetScopeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parent instanceof JetFile) {
|
if (parent instanceof JetFile) {
|
||||||
PackageViewDescriptor packageView = analysisResult.getModuleDescriptor().getPackage(((JetFile) parent).getPackageFqName());
|
PackageFragmentDescriptor packageFragment = context.get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, (JetFile) parent);
|
||||||
|
if (packageFragment == null) return null;
|
||||||
|
|
||||||
|
PackageViewDescriptor packageView = packageFragment.getContainingDeclaration().getPackage(((JetFile) parent).getPackageFqName());
|
||||||
return packageView != null ? packageView.getMemberScope() : null;
|
return packageView != null ? packageView.getMemberScope() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return analysisResult.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, expression);
|
JetExpression expression = PsiTreeUtil.getParentOfType(element, JetExpression.class, false);
|
||||||
|
return expression != null ? context.get(BindingContext.RESOLUTION_SCOPE, expression) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ import org.jetbrains.kotlin.types.*
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.resolve.jvm.kotlinSignature.CollectionClassMapping
|
import org.jetbrains.kotlin.resolve.jvm.kotlinSignature.CollectionClassMapping
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import java.util.LinkedHashSet
|
import java.util.LinkedHashSet
|
||||||
import org.jetbrains.kotlin.types.typeUtil.substitute
|
import org.jetbrains.kotlin.types.typeUtil.substitute
|
||||||
|
|
||||||
@@ -87,3 +90,19 @@ public fun JetType.nullability(): TypeNullability {
|
|||||||
else -> TypeNullability.NOT_NULL
|
else -> TypeNullability.NOT_NULL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun JetType.isResolvableInScope(scope: JetScope?, checkTypeParameters: Boolean): Boolean {
|
||||||
|
if (canBeReferencedViaImport()) return true
|
||||||
|
|
||||||
|
val descriptor = getConstructor().getDeclarationDescriptor()
|
||||||
|
if (descriptor == null || descriptor.getName().isSpecial()) return false
|
||||||
|
if (!checkTypeParameters && descriptor is TypeParameterDescriptor) return true
|
||||||
|
|
||||||
|
return scope != null && scope.getClassifier(descriptor.getName()) == descriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun JetType.approximateWithResolvableType(scope: JetScope?, checkTypeParameters: Boolean): JetType {
|
||||||
|
if (isError() || isResolvableInScope(scope, checkTypeParameters)) return this
|
||||||
|
return supertypes().firstOrNull { it.isResolvableInScope(scope, checkTypeParameters) }
|
||||||
|
?: KotlinBuiltIns.getInstance().getAnyType()
|
||||||
|
}
|
||||||
+7
-38
@@ -20,21 +20,15 @@ import com.intellij.codeInsight.intention.IntentionAction;
|
|||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import kotlin.Function1;
|
|
||||||
import kotlin.KotlinPackage;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters1;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters1;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2;
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||||
import org.jetbrains.kotlin.idea.imports.ImportsPackage;
|
|
||||||
import org.jetbrains.kotlin.idea.util.UtilPackage;
|
import org.jetbrains.kotlin.idea.util.UtilPackage;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -44,7 +38,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils;
|
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils;
|
||||||
import org.jetbrains.kotlin.types.JetType;
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -54,36 +47,12 @@ import java.util.List;
|
|||||||
public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFactory {
|
public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFactory {
|
||||||
private final static Logger LOG = Logger.getInstance(QuickFixFactoryForTypeMismatchError.class);
|
private final static Logger LOG = Logger.getInstance(QuickFixFactoryForTypeMismatchError.class);
|
||||||
|
|
||||||
private static boolean isResolvableType(@NotNull JetType type, @Nullable JetScope scope) {
|
|
||||||
if (ImportsPackage.canBeReferencedViaImport(type)) return true;
|
|
||||||
|
|
||||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
|
||||||
if (descriptor == null || descriptor.getName().isSpecial()) return false;
|
|
||||||
|
|
||||||
return scope != null && scope.getClassifier(descriptor.getName()) == descriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JetType approximateWithResolvableType(@NotNull JetType type, @Nullable final JetScope scope) {
|
|
||||||
if (isResolvableType(type, scope)) return type;
|
|
||||||
JetType superType = KotlinPackage.firstOrNull(
|
|
||||||
TypeUtils.getAllSupertypes(type),
|
|
||||||
new Function1<JetType, Boolean>() {
|
|
||||||
@Override
|
|
||||||
public Boolean invoke(JetType type) {
|
|
||||||
return isResolvableType(type, scope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return superType != null ? superType : KotlinBuiltIns.getInstance().getAnyType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
protected List<IntentionAction> doCreateActions(@NotNull Diagnostic diagnostic) {
|
protected List<IntentionAction> doCreateActions(@NotNull Diagnostic diagnostic) {
|
||||||
List<IntentionAction> actions = new LinkedList<IntentionAction>();
|
List<IntentionAction> actions = new LinkedList<IntentionAction>();
|
||||||
|
|
||||||
AnalysisResult analysisResult = ResolvePackage.analyzeFullyAndGetResult((JetFile) diagnostic.getPsiFile());
|
BindingContext context = ResolvePackage.analyzeFully((JetFile) diagnostic.getPsiFile());
|
||||||
BindingContext context = analysisResult.getBindingContext();
|
|
||||||
|
|
||||||
PsiElement diagnosticElement = diagnostic.getPsiElement();
|
PsiElement diagnosticElement = diagnostic.getPsiElement();
|
||||||
if (!(diagnosticElement instanceof JetExpression)) {
|
if (!(diagnosticElement instanceof JetExpression)) {
|
||||||
@@ -133,8 +102,8 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact
|
|||||||
JetExpression initializer = property.getInitializer();
|
JetExpression initializer = property.getInitializer();
|
||||||
if (QuickFixUtil.canEvaluateTo(initializer, expression) ||
|
if (QuickFixUtil.canEvaluateTo(initializer, expression) ||
|
||||||
(getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(property.getGetter(), expression))) {
|
(getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(property.getGetter(), expression))) {
|
||||||
JetScope scope = JetScopeUtils.getResolutionScope(property, analysisResult);
|
JetScope scope = JetScopeUtils.getResolutionScope(property, context);
|
||||||
JetType typeToInsert = approximateWithResolvableType(expressionType, scope);
|
JetType typeToInsert = UtilPackage.approximateWithResolvableType(expressionType, scope, false);
|
||||||
actions.add(new ChangeVariableTypeFix(property, typeToInsert));
|
actions.add(new ChangeVariableTypeFix(property, typeToInsert));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,8 +116,8 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact
|
|||||||
? BindingContextUtilPackage.getTargetFunction((JetReturnExpression) expressionParent, context)
|
? BindingContextUtilPackage.getTargetFunction((JetReturnExpression) expressionParent, context)
|
||||||
: PsiTreeUtil.getParentOfType(expression, JetFunction.class, true);
|
: PsiTreeUtil.getParentOfType(expression, JetFunction.class, true);
|
||||||
if (function instanceof JetFunction && QuickFixUtil.canFunctionOrGetterReturnExpression(function, expression)) {
|
if (function instanceof JetFunction && QuickFixUtil.canFunctionOrGetterReturnExpression(function, expression)) {
|
||||||
JetScope scope = JetScopeUtils.getResolutionScope(function, analysisResult);
|
JetScope scope = JetScopeUtils.getResolutionScope(function, context);
|
||||||
JetType typeToInsert = approximateWithResolvableType(expressionType, scope);
|
JetType typeToInsert = UtilPackage.approximateWithResolvableType(expressionType, scope, false);
|
||||||
actions.add(new ChangeFunctionReturnTypeFix((JetFunction) function, typeToInsert));
|
actions.add(new ChangeFunctionReturnTypeFix((JetFunction) function, typeToInsert));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,8 +156,8 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact
|
|||||||
? expressionType
|
? expressionType
|
||||||
: context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression());
|
: context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression());
|
||||||
if (correspondingParameter != null && valueArgumentType != null) {
|
if (correspondingParameter != null && valueArgumentType != null) {
|
||||||
JetScope scope = JetScopeUtils.getResolutionScope(valueArgument.getArgumentExpression(), analysisResult);
|
JetScope scope = JetScopeUtils.getResolutionScope(valueArgument.getArgumentExpression(), context);
|
||||||
JetType typeToInsert = approximateWithResolvableType(valueArgumentType, scope);
|
JetType typeToInsert = UtilPackage.approximateWithResolvableType(valueArgumentType, scope, true);
|
||||||
actions.add(new ChangeParameterTypeFix(correspondingParameter, typeToInsert));
|
actions.add(new ChangeParameterTypeFix(correspondingParameter, typeToInsert));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,14 +19,11 @@ package org.jetbrains.kotlin.idea.refactoring;
|
|||||||
import com.intellij.openapi.util.Ref;
|
import com.intellij.openapi.util.Ref;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes;
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor;
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.JetElement;
|
||||||
|
import org.jetbrains.kotlin.psi.JetExpression;
|
||||||
|
import org.jetbrains.kotlin.psi.JetVisitorVoid;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils;
|
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils;
|
||||||
@@ -76,7 +73,7 @@ public class JetNameValidatorImpl extends JetNameValidator {
|
|||||||
private boolean checkElement(String name, PsiElement sibling, final Set<JetScope> visitedScopes) {
|
private boolean checkElement(String name, PsiElement sibling, final Set<JetScope> visitedScopes) {
|
||||||
if (!(sibling instanceof JetElement)) return true;
|
if (!(sibling instanceof JetElement)) return true;
|
||||||
|
|
||||||
final AnalysisResult analysisResult = ResolvePackage.analyzeAndGetResult((JetElement) sibling);
|
final BindingContext context = ResolvePackage.analyze((JetElement) sibling);
|
||||||
final Name identifier = Name.identifier(name);
|
final Name identifier = Name.identifier(name);
|
||||||
|
|
||||||
final Ref<Boolean> result = new Ref<Boolean>(true);
|
final Ref<Boolean> result = new Ref<Boolean>(true);
|
||||||
@@ -90,7 +87,7 @@ public class JetNameValidatorImpl extends JetNameValidator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitExpression(@NotNull JetExpression expression) {
|
public void visitExpression(@NotNull JetExpression expression) {
|
||||||
JetScope resolutionScope = JetScopeUtils.getResolutionScope(expression, analysisResult);
|
JetScope resolutionScope = JetScopeUtils.getResolutionScope(expression, context);
|
||||||
|
|
||||||
if (resolutionScope != null) {
|
if (resolutionScope != null) {
|
||||||
if (!visitedScopes.add(resolutionScope)) return;
|
if (!visitedScopes.add(resolutionScope)) return;
|
||||||
|
|||||||
+32
-16
@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
|
|
||||||
import org.jetbrains.kotlin.idea.imports.importableFqNameSafe
|
import org.jetbrains.kotlin.idea.imports.importableFqNameSafe
|
||||||
import org.jetbrains.kotlin.idea.refactoring.*
|
import org.jetbrains.kotlin.idea.refactoring.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage
|
||||||
@@ -52,6 +51,8 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputVa
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValue.ParameterUpdate
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValue.ParameterUpdate
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValueBoxer.AsList
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValueBoxer.AsList
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
|
import org.jetbrains.kotlin.idea.util.approximateWithResolvableType
|
||||||
|
import org.jetbrains.kotlin.idea.util.isResolvableInScope
|
||||||
import org.jetbrains.kotlin.idea.util.makeNullable
|
import org.jetbrains.kotlin.idea.util.makeNullable
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
@@ -63,6 +64,8 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
@@ -127,7 +130,9 @@ private fun List<Instruction>.getExitPoints(): List<Instruction> =
|
|||||||
|
|
||||||
private fun List<Instruction>.getResultTypeAndExpressions(
|
private fun List<Instruction>.getResultTypeAndExpressions(
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
options: ExtractionOptions): Pair<JetType, List<JetExpression>> {
|
targetScope: JetScope?,
|
||||||
|
options: ExtractionOptions
|
||||||
|
): Pair<JetType, List<JetExpression>> {
|
||||||
fun instructionToExpression(instruction: Instruction, unwrapReturn: Boolean): JetExpression? {
|
fun instructionToExpression(instruction: Instruction, unwrapReturn: Boolean): JetExpression? {
|
||||||
return when (instruction) {
|
return when (instruction) {
|
||||||
is ReturnValueInstruction ->
|
is ReturnValueInstruction ->
|
||||||
@@ -148,7 +153,9 @@ private fun List<Instruction>.getResultTypeAndExpressions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val resultTypes = map(::instructionToType).filterNotNull()
|
val resultTypes = map(::instructionToType).filterNotNull()
|
||||||
val resultType = if (resultTypes.isNotEmpty()) CommonSupertypes.commonSupertype(resultTypes) else DEFAULT_RETURN_TYPE
|
var commonSupertype = if (resultTypes.isNotEmpty()) CommonSupertypes.commonSupertype(resultTypes) else DEFAULT_RETURN_TYPE
|
||||||
|
val resultType = if (options.allowSpecialClassNames) commonSupertype else commonSupertype.approximateWithResolvableType(targetScope, false)
|
||||||
|
|
||||||
val expressions = map { instructionToExpression(it, false) }.filterNotNull()
|
val expressions = map { instructionToExpression(it, false) }.filterNotNull()
|
||||||
|
|
||||||
return resultType to expressions
|
return resultType to expressions
|
||||||
@@ -217,6 +224,7 @@ private fun ExtractionData.analyzeControlFlow(
|
|||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
modifiedVarDescriptors: Map<VariableDescriptor, List<JetExpression>>,
|
modifiedVarDescriptors: Map<VariableDescriptor, List<JetExpression>>,
|
||||||
options: ExtractionOptions,
|
options: ExtractionOptions,
|
||||||
|
targetScope: JetScope?,
|
||||||
parameters: Set<Parameter>
|
parameters: Set<Parameter>
|
||||||
): Pair<ControlFlow, ErrorMessage?> {
|
): Pair<ControlFlow, ErrorMessage?> {
|
||||||
val exitPoints = localInstructions.getExitPoints()
|
val exitPoints = localInstructions.getExitPoints()
|
||||||
@@ -269,8 +277,8 @@ private fun ExtractionData.analyzeControlFlow(
|
|||||||
val nonLocallyUsedDeclarations = getLocalDeclarationsWithNonLocalUsages(pseudocode, localInstructions, bindingContext)
|
val nonLocallyUsedDeclarations = getLocalDeclarationsWithNonLocalUsages(pseudocode, localInstructions, bindingContext)
|
||||||
val (declarationsToCopy, declarationsToReport) = nonLocallyUsedDeclarations.partition { it is JetProperty && it.isLocal() }
|
val (declarationsToCopy, declarationsToReport) = nonLocallyUsedDeclarations.partition { it is JetProperty && it.isLocal() }
|
||||||
|
|
||||||
val (typeOfDefaultFlow, defaultResultExpressions) = defaultExits.getResultTypeAndExpressions(bindingContext, options)
|
val (typeOfDefaultFlow, defaultResultExpressions) = defaultExits.getResultTypeAndExpressions(bindingContext, targetScope, options)
|
||||||
val (returnValueType, valuedReturnExpressions) = valuedReturnExits.getResultTypeAndExpressions(bindingContext, options)
|
val (returnValueType, valuedReturnExpressions) = valuedReturnExits.getResultTypeAndExpressions(bindingContext, targetScope, options)
|
||||||
|
|
||||||
val emptyControlFlow =
|
val emptyControlFlow =
|
||||||
ControlFlow(Collections.emptyList(), { OutputValueBoxer.AsTuple(it, module) }, declarationsToCopy)
|
ControlFlow(Collections.emptyList(), { OutputValueBoxer.AsTuple(it, module) }, declarationsToCopy)
|
||||||
@@ -421,14 +429,14 @@ fun TypeParameter.collectReferencedTypes(bindingContext: BindingContext): List<J
|
|||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JetType.isExtractable(): Boolean {
|
private fun JetType.isExtractable(targetScope: JetScope?): Boolean {
|
||||||
return collectReferencedTypes(true).fold(true) { (extractable, typeToCheck) ->
|
return collectReferencedTypes(true).fold(true) { (extractable, typeToCheck) ->
|
||||||
val parameterTypeDescriptor = typeToCheck.getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor
|
val parameterTypeDescriptor = typeToCheck.getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor
|
||||||
val typeParameter = parameterTypeDescriptor?.let {
|
val typeParameter = parameterTypeDescriptor?.let {
|
||||||
DescriptorToSourceUtils.descriptorToDeclaration(it)
|
DescriptorToSourceUtils.descriptorToDeclaration(it)
|
||||||
} as? JetTypeParameter
|
} as? JetTypeParameter
|
||||||
|
|
||||||
extractable && (typeParameter != null || typeToCheck.canBeReferencedViaImport())
|
extractable && (typeParameter != null || typeToCheck.isResolvableInScope(targetScope, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,6 +444,7 @@ private fun JetType.processTypeIfExtractable(
|
|||||||
typeParameters: MutableSet<TypeParameter>,
|
typeParameters: MutableSet<TypeParameter>,
|
||||||
nonDenotableTypes: MutableSet<JetType>,
|
nonDenotableTypes: MutableSet<JetType>,
|
||||||
options: ExtractionOptions,
|
options: ExtractionOptions,
|
||||||
|
targetScope: JetScope?,
|
||||||
processTypeArguments: Boolean = true
|
processTypeArguments: Boolean = true
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return collectReferencedTypes(processTypeArguments).fold(true) { (extractable, typeToCheck) ->
|
return collectReferencedTypes(processTypeArguments).fold(true) { (extractable, typeToCheck) ->
|
||||||
@@ -450,7 +459,7 @@ private fun JetType.processTypeIfExtractable(
|
|||||||
extractable
|
extractable
|
||||||
}
|
}
|
||||||
|
|
||||||
typeToCheck.canBeReferencedViaImport() ->
|
typeToCheck.isResolvableInScope(targetScope, false) ->
|
||||||
extractable
|
extractable
|
||||||
|
|
||||||
options.allowSpecialClassNames && typeToCheck.isSpecial() ->
|
options.allowSpecialClassNames && typeToCheck.isSpecial() ->
|
||||||
@@ -470,7 +479,8 @@ private fun JetType.processTypeIfExtractable(
|
|||||||
private class MutableParameter(
|
private class MutableParameter(
|
||||||
override val argumentText: String,
|
override val argumentText: String,
|
||||||
override val originalDescriptor: DeclarationDescriptor,
|
override val originalDescriptor: DeclarationDescriptor,
|
||||||
override val receiverCandidate: Boolean
|
override val receiverCandidate: Boolean,
|
||||||
|
private val targetScope: JetScope?
|
||||||
): Parameter {
|
): Parameter {
|
||||||
// All modifications happen in the same thread
|
// All modifications happen in the same thread
|
||||||
private var writable: Boolean = true
|
private var writable: Boolean = true
|
||||||
@@ -525,7 +535,7 @@ private class MutableParameter(
|
|||||||
|
|
||||||
override fun getParameterTypeCandidates(allowSpecialClassNames: Boolean): List<JetType> {
|
override fun getParameterTypeCandidates(allowSpecialClassNames: Boolean): List<JetType> {
|
||||||
return if (!allowSpecialClassNames) {
|
return if (!allowSpecialClassNames) {
|
||||||
parameterTypeCandidates.filter { it.isExtractable() }
|
parameterTypeCandidates.filter { it.isExtractable(targetScope) }
|
||||||
} else {
|
} else {
|
||||||
parameterTypeCandidates
|
parameterTypeCandidates
|
||||||
}
|
}
|
||||||
@@ -560,6 +570,7 @@ private fun ExtractionData.inferParametersInfo(
|
|||||||
commonParent: PsiElement,
|
commonParent: PsiElement,
|
||||||
pseudocode: Pseudocode,
|
pseudocode: Pseudocode,
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
|
targetScope: JetScope?,
|
||||||
modifiedVarDescriptors: Set<VariableDescriptor>
|
modifiedVarDescriptors: Set<VariableDescriptor>
|
||||||
): ParametersInfo {
|
): ParametersInfo {
|
||||||
val info = ParametersInfo()
|
val info = ParametersInfo()
|
||||||
@@ -610,7 +621,7 @@ private fun ExtractionData.inferParametersInfo(
|
|||||||
|
|
||||||
if (referencedClassDescriptor != null) {
|
if (referencedClassDescriptor != null) {
|
||||||
if (!referencedClassDescriptor.getDefaultType().processTypeIfExtractable(
|
if (!referencedClassDescriptor.getDefaultType().processTypeIfExtractable(
|
||||||
info.typeParameters, info.nonDenotableTypes, options, false
|
info.typeParameters, info.nonDenotableTypes, options, targetScope, false
|
||||||
)) continue
|
)) continue
|
||||||
|
|
||||||
info.replacementMap[refInfo.offsetInBody] = FqNameReplacement(originalDescriptor.importableFqNameSafe)
|
info.replacementMap[refInfo.offsetInBody] = FqNameReplacement(originalDescriptor.importableFqNameSafe)
|
||||||
@@ -642,7 +653,7 @@ private fun ExtractionData.inferParametersInfo(
|
|||||||
else
|
else
|
||||||
(thisExpr ?: ref).getText() ?: throw AssertionError("'this' reference shouldn't be empty: code fragment = $codeFragmentText")
|
(thisExpr ?: ref).getText() ?: throw AssertionError("'this' reference shouldn't be empty: code fragment = $codeFragmentText")
|
||||||
|
|
||||||
MutableParameter(argumentText, descriptorToExtract, extractThis)
|
MutableParameter(argumentText, descriptorToExtract, extractThis, targetScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extractThis) {
|
if (!extractThis) {
|
||||||
@@ -681,7 +692,9 @@ private fun ExtractionData.inferParametersInfo(
|
|||||||
)
|
)
|
||||||
|
|
||||||
for ((descriptorToExtract, parameter) in extractedDescriptorToParameter) {
|
for ((descriptorToExtract, parameter) in extractedDescriptorToParameter) {
|
||||||
if (!parameter.getParameterType(options.allowSpecialClassNames).processTypeIfExtractable(info.typeParameters, info.nonDenotableTypes, options)) continue
|
if (!parameter
|
||||||
|
.getParameterType(options.allowSpecialClassNames)
|
||||||
|
.processTypeIfExtractable(info.typeParameters, info.nonDenotableTypes, options, targetScope)) continue
|
||||||
|
|
||||||
with (parameter) {
|
with (parameter) {
|
||||||
if (currentName == null) {
|
if (currentName == null) {
|
||||||
@@ -693,7 +706,7 @@ private fun ExtractionData.inferParametersInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (typeToCheck in info.typeParameters.flatMapTo(HashSet<JetType>()) { it.collectReferencedTypes(bindingContext) }) {
|
for (typeToCheck in info.typeParameters.flatMapTo(HashSet<JetType>()) { it.collectReferencedTypes(bindingContext) }) {
|
||||||
typeToCheck.processTypeIfExtractable(info.typeParameters, info.nonDenotableTypes, options)
|
typeToCheck.processTypeIfExtractable(info.typeParameters, info.nonDenotableTypes, options, targetScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -765,6 +778,8 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
|
|||||||
val bindingContext = commonParent.getContextForContainingDeclarationBody()
|
val bindingContext = commonParent.getContextForContainingDeclarationBody()
|
||||||
if (bindingContext == null) return noContainerError
|
if (bindingContext == null) return noContainerError
|
||||||
|
|
||||||
|
val targetScope = JetScopeUtils.getResolutionScope(targetSibling, bindingContext)
|
||||||
|
|
||||||
val pseudocodeDeclaration =
|
val pseudocodeDeclaration =
|
||||||
PsiTreeUtil.getParentOfType(commonParent, javaClass<JetDeclarationWithBody>(), javaClass<JetClassOrObject>())
|
PsiTreeUtil.getParentOfType(commonParent, javaClass<JetDeclarationWithBody>(), javaClass<JetClassOrObject>())
|
||||||
?: commonParent.getNonStrictParentOfType<JetProperty>()
|
?: commonParent.getNonStrictParentOfType<JetProperty>()
|
||||||
@@ -786,7 +801,7 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
|
|||||||
|
|
||||||
val modifiedVarDescriptorsWithExpressions = localInstructions.getModifiedVarDescriptors(bindingContext)
|
val modifiedVarDescriptorsWithExpressions = localInstructions.getModifiedVarDescriptors(bindingContext)
|
||||||
|
|
||||||
val paramsInfo = inferParametersInfo(commonParent, pseudocode, bindingContext, modifiedVarDescriptorsWithExpressions.keySet())
|
val paramsInfo = inferParametersInfo(commonParent, pseudocode, bindingContext, targetScope, modifiedVarDescriptorsWithExpressions.keySet())
|
||||||
if (paramsInfo.errorMessage != null) {
|
if (paramsInfo.errorMessage != null) {
|
||||||
return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(paramsInfo.errorMessage!!))
|
return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(paramsInfo.errorMessage!!))
|
||||||
}
|
}
|
||||||
@@ -803,12 +818,13 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
|
|||||||
bindingContext,
|
bindingContext,
|
||||||
modifiedVarDescriptorsForControlFlow,
|
modifiedVarDescriptorsForControlFlow,
|
||||||
options,
|
options,
|
||||||
|
targetScope,
|
||||||
paramsInfo.parameters
|
paramsInfo.parameters
|
||||||
)
|
)
|
||||||
controlFlowMessage?.let { messages.add(it) }
|
controlFlowMessage?.let { messages.add(it) }
|
||||||
|
|
||||||
val returnType = controlFlow.outputValueBoxer.returnType
|
val returnType = controlFlow.outputValueBoxer.returnType
|
||||||
returnType.processTypeIfExtractable(paramsInfo.typeParameters, paramsInfo.nonDenotableTypes, options)
|
returnType.processTypeIfExtractable(paramsInfo.typeParameters, paramsInfo.nonDenotableTypes, options, targetScope)
|
||||||
|
|
||||||
if (paramsInfo.nonDenotableTypes.isNotEmpty()) {
|
if (paramsInfo.nonDenotableTypes.isNotEmpty()) {
|
||||||
val typeStr = paramsInfo.nonDenotableTypes.map {it.renderForMessage()}.sort()
|
val typeStr = paramsInfo.nonDenotableTypes.map {it.renderForMessage()}.sort()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ LineBreakpoint created at ceObject.kt:5
|
|||||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
ceObject.kt:5
|
ceObject.kt:5
|
||||||
Compile bytecode for (object: T {}).test()
|
Compile bytecode for (object: T {}).test()
|
||||||
|
Compile bytecode for (object: T { fun a() = 1 }).a()
|
||||||
Compile bytecode for object: T {}
|
Compile bytecode for object: T {}
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
|||||||
+3
@@ -12,5 +12,8 @@ trait T {
|
|||||||
// EXPRESSION: (object: T {}).test()
|
// EXPRESSION: (object: T {}).test()
|
||||||
// RESULT: 1: I
|
// RESULT: 1: I
|
||||||
|
|
||||||
|
// EXPRESSION: (object: T { fun a() = 1 }).a()
|
||||||
|
// RESULT: 1: I
|
||||||
|
|
||||||
// EXPRESSION: object: T {}
|
// EXPRESSION: object: T {}
|
||||||
// RESULT: instance of packageForDebugger.PackageForDebuggerPackage$debugFile$@packagePartHASH$myFun$1(id=ID): LpackageForDebugger/PackageForDebuggerPackage$debugFile$@packagePartHASH$myFun$1;
|
// RESULT: instance of packageForDebugger.PackageForDebuggerPackage$debugFile$@packagePartHASH$myFun$1(id=ID): LpackageForDebugger/PackageForDebuggerPackage$debugFile$@packagePartHASH$myFun$1;
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
Cannot extract method since following types are not denotable in the target scope: <no name provided>
|
Following declarations are used outside of selected code fragment: override fun call(): Int
|
||||||
+3
-13
@@ -1,15 +1,5 @@
|
|||||||
trait Callable<T> {
|
trait T
|
||||||
fun call(): T
|
|
||||||
}
|
|
||||||
|
|
||||||
fun foo(a: Int): Int {
|
fun foo(): T {
|
||||||
// SIBLING:
|
return <selection>object: T() {}</selection>
|
||||||
val o = object: Callable<Int> {
|
|
||||||
val b: Int = 1
|
|
||||||
|
|
||||||
override fun call(): Int {
|
|
||||||
return <selection>a + b</selection>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return o.call()
|
|
||||||
}
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
trait T
|
||||||
|
|
||||||
|
fun foo(): T {
|
||||||
|
return t()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun t() = object : T() {}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
trait Callable<T> {
|
||||||
|
fun call(): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(a: Int): Int {
|
||||||
|
// SIBLING:
|
||||||
|
val o = object: Callable<Int> {
|
||||||
|
val b: Int = 1
|
||||||
|
|
||||||
|
override fun call(): Int {
|
||||||
|
return <selection>a + b</selection>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return o.call()
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
trait T
|
||||||
|
|
||||||
|
fun foo(): T {
|
||||||
|
class A: T
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun bar(): T {
|
||||||
|
return <selection>A()</selection>
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
trait T
|
||||||
|
|
||||||
|
fun foo(): T {
|
||||||
|
class A: T
|
||||||
|
|
||||||
|
fun a() = A()
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun bar(): T {
|
||||||
|
return a()
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// PARAM_DESCRIPTOR: val a: foo.A defined in foo.bar
|
||||||
|
// PARAM_TYPES: T
|
||||||
|
trait T
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(): T {
|
||||||
|
class A: T
|
||||||
|
|
||||||
|
fun bar(): T {
|
||||||
|
val a = A()
|
||||||
|
return <selection>a</selection>
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// PARAM_DESCRIPTOR: val a: foo.A defined in foo.bar
|
||||||
|
// PARAM_TYPES: T
|
||||||
|
trait T
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(): T {
|
||||||
|
class A: T
|
||||||
|
|
||||||
|
fun bar(): T {
|
||||||
|
val a = A()
|
||||||
|
return t(a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun t(a: T) = a
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// PARAM_DESCRIPTOR: val a: foo.A defined in foo.bar
|
||||||
|
// PARAM_TYPES: foo.A, T
|
||||||
|
trait T
|
||||||
|
|
||||||
|
fun foo(): T {
|
||||||
|
class A: T
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun bar(): T {
|
||||||
|
val a = A()
|
||||||
|
return <selection>a</selection>
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// PARAM_DESCRIPTOR: val a: foo.A defined in foo.bar
|
||||||
|
// PARAM_TYPES: foo.A, T
|
||||||
|
trait T
|
||||||
|
|
||||||
|
fun foo(): T {
|
||||||
|
class A: T
|
||||||
|
|
||||||
|
fun a(a: A) = a
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun bar(): T {
|
||||||
|
val a = A()
|
||||||
|
return a(a)
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
trait T
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(): T {
|
||||||
|
class A: T
|
||||||
|
|
||||||
|
fun bar(): A {
|
||||||
|
val a = A()
|
||||||
|
return <selection>a</selection>
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
Cannot extract method since following types are not denotable in the target scope: A
|
||||||
+30
@@ -1897,11 +1897,41 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
|||||||
doExtractFunctionTest(fileName);
|
doExtractFunctionTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("anonymousObjectWithCall.kt")
|
||||||
|
public void testAnonymousObjectWithCall() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/nonDenotableTypes/anonymousObjectWithCall.kt");
|
||||||
|
doExtractFunctionTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localClass.kt")
|
@TestMetadata("localClass.kt")
|
||||||
public void testLocalClass() throws Exception {
|
public void testLocalClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/nonDenotableTypes/localClass.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/nonDenotableTypes/localClass.kt");
|
||||||
doExtractFunctionTest(fileName);
|
doExtractFunctionTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassWithSuperclass.kt")
|
||||||
|
public void testLocalClassWithSuperclass() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/nonDenotableTypes/localClassWithSuperclass.kt");
|
||||||
|
doExtractFunctionTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassWithSuperclassParameter.kt")
|
||||||
|
public void testLocalClassWithSuperclassParameter() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/nonDenotableTypes/localClassWithSuperclassParameter.kt");
|
||||||
|
doExtractFunctionTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassWithSuperclassParameterInLocalFun.kt")
|
||||||
|
public void testLocalClassWithSuperclassParameterInLocalFun() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/nonDenotableTypes/localClassWithSuperclassParameterInLocalFun.kt");
|
||||||
|
doExtractFunctionTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassWithSuperclassParameterNoApproximation.kt")
|
||||||
|
public void testLocalClassWithSuperclassParameterNoApproximation() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/nonDenotableTypes/localClassWithSuperclassParameterNoApproximation.kt");
|
||||||
|
doExtractFunctionTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user