Change Signature: Translate JetChangeInfo to Kotlin

This commit is contained in:
Alexey Sedunov
2014-12-18 15:47:53 +03:00
parent 2927fc9ede
commit ec5a01be31
7 changed files with 226 additions and 373 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2013 JetBrains s.r.o. * Copyright 2010-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,312 +14,177 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.jet.plugin.refactoring.changeSignature; package org.jetbrains.jet.plugin.refactoring.changeSignature
import com.intellij.lang.Language; import com.intellij.lang.Language
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiType; import com.intellij.psi.PsiType
import com.intellij.refactoring.changeSignature.*; import com.intellij.refactoring.changeSignature.*
import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageInfo
import com.intellij.util.Function; import com.intellij.util.Function
import com.intellij.util.VisibilityUtil; import com.intellij.util.VisibilityUtil
import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtil
import kotlin.Function1; import kotlin.Function1
import kotlin.KotlinPackage; import kotlin.Pair
import kotlin.Pair; import org.jetbrains.jet.asJava.*
import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.asJava.AsJavaPackage; import org.jetbrains.jet.lang.descriptors.Visibilities
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.Visibility
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.JetFunction
import org.jetbrains.jet.lang.descriptors.Visibilities; import org.jetbrains.jet.lang.psi.JetFunctionLiteral
import org.jetbrains.jet.lang.descriptors.Visibility; import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
import org.jetbrains.jet.lang.psi.JetFunction; import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.psi.JetFunctionLiteral; import org.jetbrains.jet.lang.types.TypeSubstitutor
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.plugin.JetLanguage
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.plugin.caches.resolve.*
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
import org.jetbrains.jet.plugin.JetLanguage; import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage; import java.util.HashMap
import org.jetbrains.jet.plugin.refactoring.changeSignature.usages.JetFunctionDefinitionUsage; import kotlin.properties.Delegates
import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers;
import java.util.Collection; public class JetChangeInfo(
import java.util.HashMap; val methodDescriptor: JetMethodDescriptor,
import java.util.List; private var name: String,
import java.util.Map; val newReturnType: JetType?,
var newReturnTypeText: String,
var newVisibility: Visibility,
parameterInfos: List<JetParameterInfo>,
val context: PsiElement
): ChangeInfo {
private val newParameters = parameterInfos.toArrayList()
private val originalPsiMethod: PsiMethod? = getCurrentPsiMethod()
public class JetChangeInfo implements ChangeInfo { private val oldNameToParameterIndex: Map<String, Int> by Delegates.lazy {
private final JetMethodDescriptor oldDescriptor; val map = HashMap<String, Int>()
private String newName;
private final JetType newReturnType;
private String newReturnTypeText;
private Visibility newVisibility;
private final List<JetParameterInfo> newParameters;
private final PsiElement context;
private Boolean parameterNamesChanged;
private Map<String, Integer> oldNameToParameterIndex;
private boolean primaryMethodUpdated;
@Nullable
private JavaChangeInfo javaChangeInfo;
private final PsiMethod originalPsiMethod;
public JetChangeInfo( val parameters = methodDescriptor.baseDescriptor.getValueParameters()
JetMethodDescriptor oldDescriptor, parameters.indices.forEach { i -> map[parameters.get(i).getName().asString()] = i }
String newName,
JetType newReturnType, map
String newReturnTypeText,
Visibility newVisibility,
List<JetParameterInfo> newParameters,
PsiElement context
) {
this.oldDescriptor = oldDescriptor;
this.newName = newName;
this.newReturnType = newReturnType;
this.newReturnTypeText = newReturnTypeText;
this.newVisibility = newVisibility;
this.newParameters = newParameters;
this.context = context;
this.originalPsiMethod = getCurrentPsiMethod();
} }
@Nullable public val isParameterSetOrOrderChanged: Boolean by Delegates.lazy {
private PsiMethod getCurrentPsiMethod() { newParameters.size() != methodDescriptor.getParametersCount() ||
List<PsiMethod> psiMethods = AsJavaPackage.toLightMethods(getMethod()); newParameters.indices.any { i -> newParameters.get(i).getOldIndex() != i }
assert psiMethods.size() <= 1 : "Multiple light methods: " + getMethod().getText();
return KotlinPackage.firstOrNull(psiMethods);
} }
public String getNewSignature(@NotNull JetFunctionDefinitionUsage inheritedFunction) { private var isPrimaryMethodUpdated: Boolean = false
StringBuilder buffer = new StringBuilder(); private var javaChangeInfo: JavaChangeInfo? = null
if (isConstructor()) { private fun getCurrentPsiMethod(): PsiMethod? {
buffer.append(newName); val psiMethods = getMethod().toLightMethods()
assert(psiMethods.size() <= 1) { "Multiple light methods: " + getMethod().getText() }
if (newVisibility != null && newVisibility != Visibilities.PUBLIC) return psiMethods.firstOrNull()
buffer.append(' ').append(newVisibility.toString()).append(' ');
}
else {
if (newVisibility != null && newVisibility != Visibilities.INTERNAL)
buffer.append(newVisibility.toString()).append(' ');
buffer.append(JetTokens.FUN_KEYWORD).append(' ').append(newName);
}
buffer.append(getNewParametersSignature(inheritedFunction, buffer.length()));
if (newReturnType != null && !KotlinBuiltIns.isUnit(newReturnType) && !isConstructor())
buffer.append(": ").append(newReturnTypeText);
return buffer.toString();
} }
public boolean isRefactoringTarget(FunctionDescriptor inheritedFunctionDescriptor) { public fun getOldParameterIndex(oldParameterName: String): Int? = oldNameToParameterIndex[oldParameterName]
return inheritedFunctionDescriptor != null &&
getMethod() == DescriptorToSourceUtils.descriptorToDeclaration(inheritedFunctionDescriptor); override fun isParameterTypesChanged(): Boolean = true
override fun isParameterNamesChanged(): Boolean = true
override fun isParameterSetOrOrderChanged(): Boolean = isParameterSetOrOrderChanged
public fun getNewParametersCount(): Int = newParameters.size()
override fun getNewParameters(): Array<JetParameterInfo> = newParameters.copyToArray()
public fun setNewParameter(index: Int, parameterInfo: JetParameterInfo) {
newParameters.set(index, parameterInfo)
} }
public String getNewParametersSignature( public fun addParameter(parameterInfo: JetParameterInfo) {
@NotNull JetFunctionDefinitionUsage inheritedFunction, newParameters.add(parameterInfo)
int indentLength
) {
boolean isLambda = inheritedFunction.getDeclaration() instanceof JetFunctionLiteral;
if (isLambda && newParameters.size() == 1 && !newParameters.get(0).requiresExplicitType(inheritedFunction)) {
return newParameters.get(0).getDeclarationSignature(0, inheritedFunction);
}
StringBuilder buffer = new StringBuilder("(");
String indent = StringUtil.repeatSymbol(' ', indentLength + 1);
for (int i = 0; i < newParameters.size(); i++) {
JetParameterInfo parameterInfo = newParameters.get(i);
if (i > 0) {
buffer.append(",");
buffer.append(indent);
}
buffer.append(parameterInfo.getDeclarationSignature(i, inheritedFunction));
}
buffer.append(")");
return buffer.toString();
} }
private boolean innerParameterSetOrOrderChanged() { public fun removeParameter(index: Int) {
if (newParameters.size() != oldDescriptor.getParametersCount())
return true;
for (int i = 0; i < newParameters.size(); i ++) {
if (newParameters.get(i).getOldIndex() != i)
return true;
}
return false;
}
private Map<String, Integer> initOldNameToParameterIndex() {
Map<String, Integer> map = new HashMap<String, Integer>();
FunctionDescriptor descriptor = oldDescriptor.getBaseDescriptor();
if (descriptor != null) {
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
for (int i = 0; i < parameters.size(); i++) {
ValueParameterDescriptor oldParameter = parameters.get(i);
map.put(oldParameter.getName().asString(), i);
}
}
return map;
}
public int getNewParametersCount() {
return newParameters.size();
}
@NotNull
@Override
public JetParameterInfo[] getNewParameters() {
return newParameters.toArray(new JetParameterInfo[newParameters.size()]);
}
public void setNewParameter(int index, JetParameterInfo parameterInfo) {
newParameters.set(index, parameterInfo);
}
public void addParameter(JetParameterInfo parameterInfo) {
newParameters.add(parameterInfo);
}
public void removeParameter(int index) {
newParameters.remove(index); newParameters.remove(index);
} }
@Override override fun isGenerateDelegate(): Boolean = false
public boolean isParameterSetOrOrderChanged() {
if (parameterNamesChanged == null)
parameterNamesChanged = innerParameterSetOrOrderChanged();
return parameterNamesChanged; override fun getNewName(): String = name
fun setNewName(value: String) {
name = value
} }
@Nullable override fun isNameChanged(): Boolean = name != methodDescriptor.getName()
public Integer getOldParameterIndex(String oldParameterName) {
if (oldNameToParameterIndex == null)
oldNameToParameterIndex = initOldNameToParameterIndex();
return oldNameToParameterIndex.get(oldParameterName); public fun isVisibilityChanged(): Boolean = newVisibility != methodDescriptor.getVisibility()
override fun getMethod(): PsiElement {
return methodDescriptor.getMethod()
} }
@Override override fun isReturnTypeChanged(): Boolean = newReturnTypeText != methodDescriptor.renderOriginalReturnType()
public boolean isParameterTypesChanged() {
return true; override fun getLanguage(): Language = JetLanguage.INSTANCE
public fun getNewSignature(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
val buffer = StringBuilder()
if (isConstructor) {
buffer.append(name)
if (newVisibility != Visibilities.PUBLIC) {
buffer.append(' ').append(newVisibility).append(' ')
}
}
else {
if (newVisibility != Visibilities.INTERNAL) {
buffer.append(newVisibility).append(' ')
}
buffer.append(JetTokens.FUN_KEYWORD).append(' ').append(name)
}
buffer.append(getNewParametersSignature(inheritedFunction, buffer.length()))
if (newReturnType != null && !KotlinBuiltIns.isUnit(newReturnType) && !isConstructor)
buffer.append(": ").append(newReturnTypeText)
return buffer.toString()
} }
@Override public fun isRefactoringTarget(inheritedFunctionDescriptor: FunctionDescriptor?): Boolean {
public boolean isParameterNamesChanged() { return inheritedFunctionDescriptor != null
return true; && getMethod() == DescriptorToSourceUtils.descriptorToDeclaration(inheritedFunctionDescriptor)
} }
@Override public fun getNewParametersSignature(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>, indentLength: Int): String {
public boolean isGenerateDelegate() { val isLambda = inheritedFunction.getDeclaration() is JetFunctionLiteral
return false; if (isLambda && newParameters.size() == 1 && !newParameters.get(0).requiresExplicitType(inheritedFunction)) {
return newParameters.get(0).getDeclarationSignature(0, inheritedFunction)
}
val indent = StringUtil.repeatSymbol(' ', indentLength + 1)
return newParameters.indices
.map { i -> newParameters[i].getDeclarationSignature(i, inheritedFunction) }
.joinToString(prefix = "(", separator = ",$indent", postfix = ")")
} }
public void setNewName(String newName) { public fun renderReturnType(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
this.newName = newName; val typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor() ?: return newReturnTypeText
val currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor() ?: return newReturnTypeText
return currentBaseFunction.getReturnType().renderTypeWithSubstitution(typeSubstitutor, newReturnTypeText, false)
} }
@Override public fun primaryMethodUpdated() {
public boolean isNameChanged() { isPrimaryMethodUpdated = true
return !newName.equals(oldDescriptor.getName()); javaChangeInfo = null
} }
public boolean isVisibilityChanged() { public fun getOrCreateJavaChangeInfo(): JavaChangeInfo? {
return !newVisibility.equals(oldDescriptor.getVisibility());
}
public Visibility getNewVisibility() {
return newVisibility;
}
public void setNewVisibility(Visibility newVisibility) {
this.newVisibility = newVisibility;
}
@Override
public PsiElement getMethod() {
return oldDescriptor.getMethod();
}
@Nullable
public FunctionDescriptor getOldDescriptor() {
return oldDescriptor.getBaseDescriptor();
}
public JetMethodDescriptor getFunctionDescriptor() {
return oldDescriptor;
}
public boolean isConstructor() {
return ChangeSignaturePackage.getIsConstructor(oldDescriptor);
}
public void setNewReturnTypeText(String newReturnTypeText) {
this.newReturnTypeText = newReturnTypeText;
}
@Override
public boolean isReturnTypeChanged() {
return !newReturnTypeText.equals(ChangeSignaturePackage.renderOriginalReturnType(oldDescriptor));
}
@Nullable
public String getOldName() {
PsiElement function = oldDescriptor.getMethod();
return function instanceof JetFunction ? ((JetFunction) function).getName() : null;
}
@Override
public String getNewName() {
return newName;
}
public PsiElement getContext() {
return context;
}
@Override
public Language getLanguage() {
return JetLanguage.INSTANCE;
}
@NotNull
public Collection<UsageInfo> getAffectedFunctions() {
return oldDescriptor.getAffectedFunctions();
}
public String renderReturnType(@NotNull JetFunctionDefinitionUsage inheritedFunction) {
TypeSubstitutor typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor();
if (typeSubstitutor == null) return newReturnTypeText;
FunctionDescriptor currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor();
if (currentBaseFunction == null) return newReturnTypeText;
JetType originalType = currentBaseFunction.getReturnType();
return ChangeSignaturePackage.renderTypeWithSubstitution(originalType, typeSubstitutor, newReturnTypeText, false);
}
@Nullable
public JavaChangeInfo getOrCreateJavaChangeInfo() {
if (javaChangeInfo == null) { if (javaChangeInfo == null) {
final PsiMethod currentPsiMethod = getCurrentPsiMethod(); val currentPsiMethod = getCurrentPsiMethod()
if (originalPsiMethod == null || currentPsiMethod == null) return null; if (originalPsiMethod == null || currentPsiMethod == null) return null
/* /*
* When primaryMethodUpdated is false, changes to the primary Kotlin declaration are already confirmed, but not yet applied. * When primaryMethodUpdated is false, changes to the primary Kotlin declaration are already confirmed, but not yet applied.
@@ -328,94 +193,77 @@ public class JetChangeInfo implements ChangeInfo {
* to use in JavaChangeInfo. However they are not actually used at this point since only parameter count and order matters here * to use in JavaChangeInfo. However they are not actually used at this point since only parameter count and order matters here
* So we resort to this hack and pass around "default" type (void) and visibility (package-local) * So we resort to this hack and pass around "default" type (void) and visibility (package-local)
*/ */
String javaVisibility = primaryMethodUpdated val javaVisibility = if (isPrimaryMethodUpdated)
? VisibilityUtil.getVisibilityModifier(currentPsiMethod.getModifierList()) VisibilityUtil.getVisibilityModifier(currentPsiMethod.getModifierList())
: PsiModifier.PACKAGE_LOCAL; else
PsiModifier.PACKAGE_LOCAL
JetParameterInfo[] newParameters = getNewParameters(); val newJavaParameters = newParameters.withIndices().map { pair ->
ParameterInfoImpl[] newJavaParameters = ContainerUtil.map2Array( val (i, info) = pair
KotlinPackage.withIndices(newParameters), val type = if (isPrimaryMethodUpdated)
new ParameterInfoImpl[newParameters.length], currentPsiMethod.getParameterList().getParameters()[i].getType()
new Function<Pair<? extends Integer, ? extends JetParameterInfo>, ParameterInfoImpl>() { else
@Override PsiType.VOID
public ParameterInfoImpl fun(Pair<? extends Integer, ? extends JetParameterInfo> pair) { ParameterInfoImpl(info.getOldIndex(), info.getName(), type, info.defaultValueForCall)
JetParameterInfo info = pair.getSecond(); }.copyToArray()
PsiType type = primaryMethodUpdated
? currentPsiMethod.getParameterList().getParameters()[pair.getFirst()].getType()
: PsiType.VOID;
return new ParameterInfoImpl(info.getOldIndex(), info.getName(), type, info.getDefaultValueForCall());
}
}
);
PsiType returnType = primaryMethodUpdated ? currentPsiMethod.getReturnType() : PsiType.VOID; val returnType = if (isPrimaryMethodUpdated) currentPsiMethod.getReturnType() else PsiType.VOID
javaChangeInfo = new ChangeSignatureProcessor( javaChangeInfo = ChangeSignatureProcessor(getMethod().getProject(),
getMethod().getProject(), originalPsiMethod, false, javaVisibility, getNewName(), returnType, newJavaParameters originalPsiMethod,
).getChangeInfo(); false,
javaChangeInfo.updateMethod(currentPsiMethod); javaVisibility,
getNewName(),
returnType,
newJavaParameters).getChangeInfo()
javaChangeInfo!!.updateMethod(currentPsiMethod)
} }
return javaChangeInfo; return javaChangeInfo
}
public void primaryMethodUpdated() {
primaryMethodUpdated = true;
javaChangeInfo = null;
}
@NotNull
public static JetChangeInfo fromJavaChangeInfo(
@NotNull ChangeInfo javaChangeInfo,
@NotNull JetMethodDescriptor originalChangeSignatureDescriptor
) {
PsiMethod method = (PsiMethod) javaChangeInfo.getMethod();
FunctionDescriptor functionDescriptor = ResolvePackage.getJavaMethodDescriptor(method);
final List<ValueParameterDescriptor> parameterDescriptors = functionDescriptor.getValueParameters();
//noinspection ConstantConditions
final List<ValueParameterDescriptor> originalParameterDescriptors =
originalChangeSignatureDescriptor.getBaseDescriptor().getValueParameters();
List<JetParameterInfo> newParameters = KotlinPackage.map(
KotlinPackage.withIndices(javaChangeInfo.getNewParameters()),
new Function1<Pair<? extends Integer, ? extends ParameterInfo>, JetParameterInfo>() {
@Override
public JetParameterInfo invoke(Pair<? extends Integer, ? extends ParameterInfo> pair) {
ParameterInfo info = pair.getSecond();
int oldIndex = info.getOldIndex();
JetType currentType = parameterDescriptors.get(pair.getFirst()).getType();
JetType originalType = oldIndex >= 0
? originalParameterDescriptors.get(oldIndex).getType()
: currentType;
String defaultValue = info.getDefaultValue();
JetParameterInfo jetParameterInfo =
new JetParameterInfo(oldIndex,
info.getName(),
originalType, null,
defaultValue != null ? defaultValue : "",
null,
null);
jetParameterInfo.setCurrentTypeText(IdeDescriptorRenderers.SOURCE_CODE.renderType(currentType));
return jetParameterInfo;
}
}
);
JetType returnType = functionDescriptor.getReturnType();
String returnTypeText = returnType != null ? IdeDescriptorRenderers.SOURCE_CODE.renderType(returnType) : "";
return new JetChangeInfo(
originalChangeSignatureDescriptor,
javaChangeInfo.getNewName(),
returnType,
returnTypeText,
functionDescriptor.getVisibility(),
newParameters,
method
);
} }
} }
public val JetChangeInfo.originalBaseFunctionDescriptor: FunctionDescriptor
get() = methodDescriptor.baseDescriptor
public val JetChangeInfo.isConstructor: Boolean get() = methodDescriptor.isConstructor
public val JetChangeInfo.oldName: String?
get() = (methodDescriptor.getMethod() as? JetFunction)?.getName()
public val JetChangeInfo.affectedFunctions: Collection<UsageInfo> get() = methodDescriptor.affectedFunctions
public fun ChangeInfo.toJetChangeInfo(originalChangeSignatureDescriptor: JetMethodDescriptor): JetChangeInfo {
val method = getMethod() as PsiMethod
val functionDescriptor = method.getJavaMethodDescriptor()
val parameterDescriptors = functionDescriptor.getValueParameters()
//noinspection ConstantConditions
val originalParameterDescriptors = originalChangeSignatureDescriptor.baseDescriptor.getValueParameters()
val newParameters = getNewParameters().withIndices().map { pair ->
val (i, info) = pair
val oldIndex = info.getOldIndex()
val currentType = parameterDescriptors[i].getType()
with(JetParameterInfo(originalIndex = oldIndex,
name = info.getName(),
type = if (oldIndex >= 0) originalParameterDescriptors[oldIndex].getType() else currentType,
defaultValueForCall = info.getDefaultValue() ?: "")) {
currentTypeText = IdeDescriptorRenderers.SOURCE_CODE.renderType(currentType)
this
}
}
val returnType = functionDescriptor.getReturnType()
val returnTypeText = if (returnType != null) IdeDescriptorRenderers.SOURCE_CODE.renderType(returnType) else ""
return JetChangeInfo(originalChangeSignatureDescriptor,
getNewName(),
returnType,
returnTypeText,
functionDescriptor.getVisibility(),
newParameters,
method)
}
@@ -48,7 +48,7 @@ public class JetChangeSignatureProcessor extends ChangeSignatureProcessorBase {
@NotNull @NotNull
@Override @Override
protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
String subject = getChangeInfo().isConstructor() ? "constructor" : "function"; String subject = ChangeSignaturePackage.getIsConstructor(getChangeInfo()) ? "constructor" : "function";
return new JetUsagesViewDescriptor(myChangeInfo.getMethod(), RefactoringBundle.message("0.to.change.signature", subject)); return new JetUsagesViewDescriptor(myChangeInfo.getMethod(), RefactoringBundle.message("0.to.change.signature", subject));
} }
@@ -69,7 +69,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
} }
private static void findAllMethodUsages(JetChangeInfo changeInfo, Set<UsageInfo> result) { private static void findAllMethodUsages(JetChangeInfo changeInfo, Set<UsageInfo> result) {
for (UsageInfo functionUsageInfo : changeInfo.getAffectedFunctions()) { for (UsageInfo functionUsageInfo : ChangeSignaturePackage.getAffectedFunctions(changeInfo)) {
if (functionUsageInfo instanceof JetFunctionDefinitionUsage) { if (functionUsageInfo instanceof JetFunctionDefinitionUsage) {
findOneMethodUsages((JetFunctionDefinitionUsage) functionUsageInfo, changeInfo, result); findOneMethodUsages((JetFunctionDefinitionUsage) functionUsageInfo, changeInfo, result);
} }
@@ -111,7 +111,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
} }
} }
String oldName = changeInfo.getOldName(); String oldName = ChangeSignaturePackage.getOldName(changeInfo);
if (oldName != null) if (oldName != null)
TextOccurrencesUtil.findNonCodeUsages(functionPsi, oldName, true, true, changeInfo.getNewName(), result); TextOccurrencesUtil.findNonCodeUsages(functionPsi, oldName, true, true, changeInfo.getNewName(), result);
@@ -203,7 +203,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
PsiElement function = info.getMethod(); PsiElement function = info.getMethod();
PsiElement element = function != null ? function : changeInfo.getContext(); PsiElement element = function != null ? function : changeInfo.getContext();
BindingContext bindingContext = ResolvePackage.analyze((JetElement) element); BindingContext bindingContext = ResolvePackage.analyze((JetElement) element);
FunctionDescriptor oldDescriptor = changeInfo.getOldDescriptor(); FunctionDescriptor oldDescriptor = ChangeSignaturePackage.getOriginalBaseFunctionDescriptor(changeInfo);
JetScope parametersScope = null; JetScope parametersScope = null;
DeclarationDescriptor containingDeclaration = oldDescriptor != null ? oldDescriptor.getContainingDeclaration() : null; DeclarationDescriptor containingDeclaration = oldDescriptor != null ? oldDescriptor.getContainingDeclaration() : null;
@@ -214,7 +214,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
JetScope functionScope = getFunctionScope(bindingContext, containingDeclaration); JetScope functionScope = getFunctionScope(bindingContext, containingDeclaration);
if (!changeInfo.isConstructor() && functionScope != null && !info.getNewName().isEmpty()) { if (!ChangeSignaturePackage.getIsConstructor(changeInfo) && functionScope != null && !info.getNewName().isEmpty()) {
for (FunctionDescriptor conflict : functionScope.getFunctions(Name.identifier(info.getNewName()))) { for (FunctionDescriptor conflict : functionScope.getFunctions(Name.identifier(info.getNewName()))) {
if (conflict == oldDescriptor) continue; if (conflict == oldDescriptor) continue;
@@ -236,7 +236,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
result.putValue(element, "Duplicating parameter '" + parameterName + "'"); result.putValue(element, "Duplicating parameter '" + parameterName + "'");
} }
if (parametersScope != null) { if (parametersScope != null) {
if (changeInfo.isConstructor() && valOrVar != JetValVar.None) { if (ChangeSignaturePackage.getIsConstructor(changeInfo) && valOrVar != JetValVar.None) {
for (VariableDescriptor property : parametersScope.getProperties(Name.identifier(parameterName))) { for (VariableDescriptor property : parametersScope.getProperties(Name.identifier(parameterName))) {
PsiElement propertyDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(property); PsiElement propertyDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(property);
@@ -320,7 +320,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
private final JetFunctionDefinitionUsage<JetFunction> delegateUsage = new JetFunctionDefinitionUsage<JetFunction>( private final JetFunctionDefinitionUsage<JetFunction> delegateUsage = new JetFunctionDefinitionUsage<JetFunction>(
samUsage.getFunctionLiteral(), samUsage.getFunctionLiteral(),
samUsage.getFunctionDescriptor(), samUsage.getFunctionDescriptor(),
javaMethodChangeInfo.getFunctionDescriptor().getOriginalPrimaryFunction(), javaMethodChangeInfo.getMethodDescriptor().getOriginalPrimaryFunction(),
samUsage.getSamCallType() samUsage.getSamCallType()
); );
@@ -453,7 +453,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
if (element == null) return false; if (element == null) return false;
if (isJavaMethodUsage && originalJavaMethodDescriptor != null) { if (isJavaMethodUsage && originalJavaMethodDescriptor != null) {
JetChangeInfo javaMethodChangeInfo = JetChangeInfo.fromJavaChangeInfo(changeInfo, originalJavaMethodDescriptor); JetChangeInfo javaMethodChangeInfo = ChangeSignaturePackage.toJetChangeInfo(changeInfo, originalJavaMethodDescriptor);
originalJavaMethodDescriptor = null; originalJavaMethodDescriptor = null;
for (int i = 0; i < usages.length; i++) { for (int i = 0; i < usages.length; i++) {
@@ -493,7 +493,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
if (!(changeInfo instanceof JetChangeInfo)) return false; if (!(changeInfo instanceof JetChangeInfo)) return false;
JetChangeInfo jetChangeInfo = (JetChangeInfo) changeInfo; JetChangeInfo jetChangeInfo = (JetChangeInfo) changeInfo;
for (JetFunctionDefinitionUsage primaryFunction : jetChangeInfo.getFunctionDescriptor().getPrimaryFunctions()) { for (JetFunctionDefinitionUsage primaryFunction : jetChangeInfo.getMethodDescriptor().getPrimaryFunctions()) {
primaryFunction.processUsage(jetChangeInfo, primaryFunction.getDeclaration()); primaryFunction.processUsage(jetChangeInfo, primaryFunction.getDeclaration());
} }
jetChangeInfo.primaryMethodUpdated(); jetChangeInfo.primaryMethodUpdated();
@@ -35,7 +35,7 @@ public abstract class JavaMethodKotlinUsageWithDelegate<T: PsiElement>(
public class JavaMethodKotlinCallUsage( public class JavaMethodKotlinCallUsage(
callElement: JetCallElement, callElement: JetCallElement,
javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetCallElement>(callElement, javaMethodChangeInfo) { javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetCallElement>(callElement, javaMethodChangeInfo) {
override protected val delegateUsage = JetFunctionCallUsage(psiElement, javaMethodChangeInfo.getFunctionDescriptor().originalPrimaryFunction) override protected val delegateUsage = JetFunctionCallUsage(psiElement, javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction)
} }
public class JavaMethodKotlinDerivedDefinitionUsage( public class JavaMethodKotlinDerivedDefinitionUsage(
@@ -46,7 +46,7 @@ public class JavaMethodKotlinDerivedDefinitionUsage(
override protected val delegateUsage = JetFunctionDefinitionUsage( override protected val delegateUsage = JetFunctionDefinitionUsage(
psiElement, psiElement,
functionDescriptor, functionDescriptor,
javaMethodChangeInfo.getFunctionDescriptor().originalPrimaryFunction, javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction,
null null
) )
} }
@@ -35,7 +35,7 @@ public class JetEnumEntryWithoutSuperCallUsage(enumEntry: JetEnumEntry) : JetUsa
) as JetDelegatorToSuperCall ) as JetDelegatorToSuperCall
element.addBefore(psiFactory.createColon(), delegatorToSuperCall) element.addBefore(psiFactory.createColon(), delegatorToSuperCall)
return JetFunctionCallUsage(delegatorToSuperCall, changeInfo.getFunctionDescriptor().originalPrimaryFunction) return JetFunctionCallUsage(delegatorToSuperCall, changeInfo.methodDescriptor.originalPrimaryFunction)
.processUsage(changeInfo, delegatorToSuperCall) .processUsage(changeInfo, delegatorToSuperCall)
} }
@@ -175,7 +175,7 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|| function.getTypeReference() != null; || function.getTypeReference() != null;
if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) { if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) {
function.setTypeReference(null); function.setTypeReference(null);
String returnTypeText = changeInfo.renderReturnType(this); String returnTypeText = changeInfo.renderReturnType((JetFunctionDefinitionUsage<PsiElement>) this);
//TODO use ChangeFunctionReturnTypeFix.invoke when JetTypeCodeFragment.getType() is ready //TODO use ChangeFunctionReturnTypeFix.invoke when JetTypeCodeFragment.getType() is ready
if (!KotlinBuiltIns.getInstance().getUnitType().toString().equals(returnTypeText)) { if (!KotlinBuiltIns.getInstance().getUnitType().toString().equals(returnTypeText)) {
@@ -203,11 +203,15 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
} }
} }
else { else {
newParameterList = psiFactory.createFunctionLiteralParameterList(changeInfo.getNewParametersSignature(this, 0)); newParameterList = psiFactory.createFunctionLiteralParameterList(changeInfo.getNewParametersSignature(
(JetFunctionDefinitionUsage<PsiElement>) this, 0)
);
} }
} }
else { else {
newParameterList = psiFactory.createParameterList(changeInfo.getNewParametersSignature(this, 0)); newParameterList = psiFactory.createParameterList(changeInfo.getNewParametersSignature(
(JetFunctionDefinitionUsage<PsiElement>) this, 0)
);
} }
if (newParameterList != null) { if (newParameterList != null) {
@@ -241,7 +241,7 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
BindingContext context = ResolvePackage.analyze(method); BindingContext context = ResolvePackage.analyze(method);
ChangeSignaturePackage ChangeSignaturePackage
.runChangeSignature(getProject(), changeInfo.getOldDescriptor(), empty, context, method, "test"); .runChangeSignature(getProject(), ChangeSignaturePackage.getOriginalBaseFunctionDescriptor(changeInfo), empty, context, method, "test");
} }
catch (RuntimeException e) { catch (RuntimeException e) {
assertTrue(e.getMessage().startsWith("Refactoring cannot be")); assertTrue(e.getMessage().startsWith("Refactoring cannot be"));
@@ -318,7 +318,8 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
public void testFunctionJavaUsagesAndOverridesAddParam() throws Exception { public void testFunctionJavaUsagesAndOverridesAddParam() throws Exception {
JetChangeInfo changeInfo = getChangeInfo(); JetChangeInfo changeInfo = getChangeInfo();
changeInfo.addParameter(new JetParameterInfo(-1, "s", KotlinBuiltIns.getInstance().getStringType(), null, "\"abc\"", null, null)); changeInfo.addParameter(new JetParameterInfo(-1, "s", KotlinBuiltIns.getInstance().getStringType(), null, "\"abc\"", null, null));
changeInfo.addParameter(new JetParameterInfo(-1, "o", KotlinBuiltIns.getInstance().getNullableAnyType(), null, "\"def\"", null, null)); changeInfo.addParameter(new JetParameterInfo(-1, "o", KotlinBuiltIns.getInstance().getNullableAnyType(), null, "\"def\"", null,
null));
doTest(changeInfo); doTest(changeInfo);
} }