Support secondary constructors and delegation calls in Change Signature.
Initial support of Find Usages
This commit is contained in:
committed by
Alexey Sedunov
parent
488754de7d
commit
e05cbf5e9f
@@ -359,6 +359,11 @@ public class JetPsiFactory(private val project: Project) {
|
||||
return createClass("class A: $text").getDelegationSpecifiers().first() as JetDelegatorToSuperCall
|
||||
}
|
||||
|
||||
public fun createConstructorDelegationCall(text: String): JetConstructorDelegationCall {
|
||||
val colonOrEmpty = if (text.isEmpty()) "" else ": "
|
||||
return createClass("class A { constructor()$colonOrEmpty$text {}").getSecondaryConstructors().first().getDelegationCall()!!
|
||||
}
|
||||
|
||||
public inner class IfChainBuilder() {
|
||||
private val sb = StringBuilder()
|
||||
private var first = true
|
||||
|
||||
@@ -83,7 +83,7 @@ public class JetSecondaryConstructor extends JetDeclarationStub<KotlinPlaceHolde
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement getColon() {
|
||||
return null;
|
||||
return findChildByType(JetTokens.COLON);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -54,6 +54,9 @@ public fun PsiReference.matchesTarget(candidateTarget: PsiElement): Boolean {
|
||||
|| it is JetObjectDeclaration && it.isCompanion() && it.getNonStrictParentOfType<JetClass>() == unwrappedCandidate
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (targets.any { unwrappedCandidate.isConstructorOf(it) }) return true
|
||||
}
|
||||
if (this is PsiReferenceExpression && candidateTarget is JetObjectDeclaration && unwrappedTargets.size() == 1) {
|
||||
val referredClass = unwrappedTargets.first()
|
||||
if (referredClass is JetClass && candidateTarget in referredClass.getCompanionObjects()) {
|
||||
|
||||
@@ -17,24 +17,34 @@
|
||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||
|
||||
import com.intellij.psi.PsiConstructorCall
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.codegen.PropertyCodegen
|
||||
import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.idea.references.*
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeUtils
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
||||
|
||||
val JetDeclaration.descriptor: DeclarationDescriptor?
|
||||
get() = this.analyze().get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
|
||||
|
||||
val JetDeclaration.constructor: ConstructorDescriptor?
|
||||
get() = this.analyze().get(BindingContext.CONSTRUCTOR, this)
|
||||
|
||||
val JetParameter.propertyDescriptor: PropertyDescriptor?
|
||||
get() = this.analyze().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, this)
|
||||
|
||||
@@ -57,23 +67,6 @@ fun PsiReference.isImportUsage(): Boolean =
|
||||
getElement()!!.getNonStrictParentOfType<JetImportDirective>() != null
|
||||
|
||||
fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean = with (getElement()!!) {
|
||||
fun getCallDescriptor(bindingContext: BindingContext): DeclarationDescriptor? {
|
||||
val constructorCalleeExpression = getNonStrictParentOfType<JetConstructorCalleeExpression>()
|
||||
if (constructorCalleeExpression != null) {
|
||||
return bindingContext.get(BindingContext.REFERENCE_TARGET, constructorCalleeExpression.getConstructorReferenceExpression())
|
||||
}
|
||||
|
||||
val callExpression = getNonStrictParentOfType<JetCallExpression>()
|
||||
if (callExpression != null) {
|
||||
val callee = callExpression.getCalleeExpression()
|
||||
if (callee is JetReferenceExpression) {
|
||||
return bindingContext.get(BindingContext.REFERENCE_TARGET, callee)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun checkJavaUsage(): Boolean {
|
||||
val call = getNonStrictParentOfType<PsiConstructorCall>()
|
||||
return call == getParent() && call?.resolveConstructor()?.getContainingClass()?.getNavigationElement() == jetClassOrObject
|
||||
@@ -82,9 +75,7 @@ fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean
|
||||
fun checkKotlinUsage(): Boolean {
|
||||
if (this !is JetElement) return false
|
||||
|
||||
val bindingContext = this.analyze()
|
||||
|
||||
val descriptor = getCallDescriptor(bindingContext)
|
||||
val descriptor = getConstructorCallDescriptor()
|
||||
if (descriptor !is ConstructorDescriptor) return false
|
||||
|
||||
return DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getContainingDeclaration()) == jetClassOrObject
|
||||
@@ -93,6 +84,76 @@ fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean
|
||||
checkJavaUsage() || checkKotlinUsage()
|
||||
}
|
||||
|
||||
private fun JetElement.getConstructorCallDescriptor(): DeclarationDescriptor? {
|
||||
val bindingContext = this.analyze()
|
||||
val constructorCalleeExpression = getNonStrictParentOfType<JetConstructorCalleeExpression>()
|
||||
if (constructorCalleeExpression != null) {
|
||||
return bindingContext.get(BindingContext.REFERENCE_TARGET, constructorCalleeExpression.getConstructorReferenceExpression())
|
||||
}
|
||||
|
||||
val callExpression = getNonStrictParentOfType<JetCallElement>()
|
||||
if (callExpression != null) {
|
||||
val callee = callExpression.getCalleeExpression()
|
||||
if (callee is JetReferenceExpression) {
|
||||
return bindingContext.get(BindingContext.REFERENCE_TARGET, callee)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
public fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) {
|
||||
processDelegationCallKotlinConstructorUsages(scope, process)
|
||||
processDelegationCallJavaConstructorUsages(scope, process)
|
||||
}
|
||||
|
||||
private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) {
|
||||
val klass = when (this) {
|
||||
is JetSecondaryConstructor -> getClassOrObject()
|
||||
is JetClass -> this
|
||||
else -> return
|
||||
}
|
||||
|
||||
if (klass !is JetClass || this !is JetDeclaration) return
|
||||
val descriptor = constructor ?: return
|
||||
|
||||
processClassDelegationCallsToSpecifiedConstructor(klass, descriptor, process)
|
||||
processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process)
|
||||
}
|
||||
|
||||
private fun PsiElement.processDelegationCallJavaConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) {
|
||||
if (!(this is PsiMethod && isConstructor())) return
|
||||
val klass = getContainingClass() ?: return
|
||||
val descriptor = getJavaMethodDescriptor() as? ConstructorDescriptor ?: return
|
||||
processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process)
|
||||
}
|
||||
|
||||
|
||||
private fun processInheritorsDelegatingCallToSpecifiedConstructor(
|
||||
klass: PsiElement,
|
||||
scope: SearchScope,
|
||||
descriptor: ConstructorDescriptor,
|
||||
process: (JetConstructorDelegationCall) -> Unit
|
||||
) {
|
||||
HierarchySearchRequest(klass, scope, false).searchInheritors().forEach() {
|
||||
val unwrapped = it.unwrapped
|
||||
if (unwrapped is JetClass) {
|
||||
processClassDelegationCallsToSpecifiedConstructor(unwrapped, descriptor, process)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processClassDelegationCallsToSpecifiedConstructor(
|
||||
klass: JetClass, constructor: DeclarationDescriptor, process: (JetConstructorDelegationCall) -> Unit
|
||||
) {
|
||||
for (secondaryConstructor in klass.getSecondaryConstructors()) {
|
||||
val delegationCallDescriptor = secondaryConstructor.getDelegationCall()?.getConstructorCallDescriptor()
|
||||
if (constructor == delegationCallDescriptor) {
|
||||
process(secondaryConstructor.getDelegationCall()!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if reference resolves to extension function whose receiver is the same as declaration's parent (or its superclass)
|
||||
// Used in extension search
|
||||
fun PsiReference.isExtensionOfDeclarationClassUsage(declaration: JetNamedDeclaration): Boolean =
|
||||
|
||||
@@ -36,6 +36,7 @@ public class JetElementDescriptionProvider : ElementDescriptionProvider {
|
||||
is JetClass -> if (targetElement.isTrait()) "trait" else "class"
|
||||
is JetObjectDeclaration -> "object"
|
||||
is JetNamedFunction -> "function"
|
||||
is JetSecondaryConstructor -> "constructor"
|
||||
is JetProperty -> "property"
|
||||
is JetTypeParameter -> "type parameter"
|
||||
is JetParameter -> "parameter"
|
||||
|
||||
@@ -20,21 +20,16 @@ import com.intellij.find.findUsages.FindUsagesHandler
|
||||
import com.intellij.find.findUsages.FindUsagesHandlerFactory
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
|
||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
|
||||
import org.jetbrains.kotlin.psi.JetProperty
|
||||
import com.intellij.find.findUsages.FindUsagesOptions
|
||||
import org.jetbrains.kotlin.psi.JetTypeParameter
|
||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinTypeParameterFindUsagesHandler
|
||||
import org.jetbrains.kotlin.psi.JetParameter
|
||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||
import com.intellij.find.findUsages.JavaFindUsagesHandlerFactory
|
||||
import org.jetbrains.kotlin.idea.findUsages.handlers.DelegatingFindMemberUsagesHandler
|
||||
import org.jetbrains.kotlin.plugin.findUsages.handlers.KotlinFindUsagesHandlerDecorator
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactory() {
|
||||
val javaHandlerFactory = JavaFindUsagesHandlerFactory(project)
|
||||
@@ -49,14 +44,15 @@ public class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandle
|
||||
element is JetNamedFunction ||
|
||||
element is JetProperty ||
|
||||
element is JetParameter ||
|
||||
element is JetTypeParameter
|
||||
element is JetTypeParameter ||
|
||||
element is JetSecondaryConstructor
|
||||
|
||||
public override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler? {
|
||||
val handler = when (element) {
|
||||
is JetClassOrObject ->
|
||||
KotlinFindClassUsagesHandler(element, this)
|
||||
|
||||
is JetNamedFunction, is JetProperty, is JetParameter -> {
|
||||
is JetNamedFunction, is JetProperty, is JetParameter, is JetSecondaryConstructor -> {
|
||||
val declaration = element as JetNamedDeclaration
|
||||
|
||||
if (forHighlightUsages) return KotlinFindMemberUsagesHandler.getInstance(declaration, this)
|
||||
|
||||
+17
@@ -26,11 +26,17 @@ import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.PsiElementProcessorAdapter;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.Processor;
|
||||
import jet.runtime.typeinfo.JetValueParameter;
|
||||
import kotlin.Function1;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil;
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.idea.findUsages.*;
|
||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindFunctionUsagesDialog;
|
||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindPropertyUsagesDialog;
|
||||
@@ -38,6 +44,7 @@ import org.jetbrains.kotlin.idea.search.declarationsSearch.DeclarationsSearchPac
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest;
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearch;
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchHelper;
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchPackage;
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchRequest;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
|
||||
@@ -155,6 +162,16 @@ public abstract class KotlinFindMemberUsagesHandler<T extends JetNamedDeclaratio
|
||||
processUsage(processor, ref);
|
||||
}
|
||||
|
||||
if (element instanceof JetSecondaryConstructor || element instanceof PsiMethod) {
|
||||
UsagesSearchPackage.processDelegationCallConstructorUsages(element, options.searchScope, new Function1<PsiElement, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(PsiElement element) {
|
||||
processUsage(processor, element);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (kotlinOptions.getSearchOverrides()) {
|
||||
DeclarationsSearchPackage.searchOverriders(
|
||||
new HierarchySearchRequest<PsiElement>(element, options.searchScope, true)
|
||||
|
||||
+4
@@ -71,6 +71,10 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
if (elementParent instanceof JetClass && ((JetClass) elementParent).getNameIdentifier() == element) {
|
||||
return elementParent;
|
||||
}
|
||||
if (elementParent instanceof JetSecondaryConstructor &&
|
||||
((JetSecondaryConstructor) elementParent).getConstructorKeyword() == element) {
|
||||
return elementParent;
|
||||
}
|
||||
|
||||
JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class);
|
||||
if (call == null) {
|
||||
|
||||
+39
-23
@@ -36,6 +36,7 @@ import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.idea.codeInsight.JetFileReferencesResolver;
|
||||
import org.jetbrains.kotlin.idea.refactoring.RefactoringPackage;
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.*;
|
||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference;
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchPackage;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -74,6 +76,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
}
|
||||
else {
|
||||
findSAMUsages(info, result);
|
||||
findConstructorDelegationUsages(info, result);
|
||||
}
|
||||
|
||||
return result.toArray(new UsageInfo[result.size()]);
|
||||
@@ -93,7 +96,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
private static void findOneMethodUsages(
|
||||
@NotNull JetFunctionDefinitionUsage<?> functionUsageInfo,
|
||||
JetChangeInfo changeInfo,
|
||||
Set<UsageInfo> result
|
||||
final Set<UsageInfo> result
|
||||
) {
|
||||
boolean isInherited = functionUsageInfo.isInherited();
|
||||
|
||||
@@ -164,6 +167,16 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UsagesSearchPackage.processDelegationCallConstructorUsages(functionPsi, functionPsi.getUseScope(),
|
||||
new Function1<JetConstructorDelegationCall, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(JetConstructorDelegationCall element) {
|
||||
result.add(new JetConstructorDelegationCallUsage(element));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void processInternalReferences(
|
||||
@@ -286,10 +299,30 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
JetType samCallType = context.get(BindingContext.EXPRESSION_TYPE, callExpression);
|
||||
if (samCallType == null) continue;
|
||||
|
||||
result.add(new KotlinSAMUsage(functionLiteral, functionDescriptor, samCallType));
|
||||
result.add(new DeferredSAMUsage(functionLiteral, functionDescriptor, samCallType));
|
||||
}
|
||||
}
|
||||
|
||||
private static void findConstructorDelegationUsages(@NotNull ChangeInfo changeInfo, @NotNull final Set<UsageInfo> result) {
|
||||
PsiElement method = changeInfo.getMethod();
|
||||
if (!(RefactoringPackage.isTrueJavaMethod(method))) return;
|
||||
|
||||
PsiMethod psiMethod = (PsiMethod) method;
|
||||
if (!psiMethod.isConstructor()) return;
|
||||
|
||||
UsagesSearchPackage.processDelegationCallConstructorUsages(
|
||||
psiMethod,
|
||||
psiMethod.getUseScope(),
|
||||
new Function1<JetConstructorDelegationCall, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(JetConstructorDelegationCall element) {
|
||||
result.add(new JavaConstructorDeferredUsageInDelegationCall(element));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiMap<PsiElement, String> findConflicts(ChangeInfo info, Ref<UsageInfo[]> refUsages) {
|
||||
MultiMap<PsiElement, String> result = new MultiMap<PsiElement, String>();
|
||||
@@ -467,7 +500,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
private JetMethodDescriptor originalJavaMethodDescriptor;
|
||||
|
||||
private static boolean isJavaMethodUsage(UsageInfo usageInfo) {
|
||||
if (usageInfo instanceof KotlinSAMUsage) return true;
|
||||
if (usageInfo instanceof JavaMethodDeferredKotlinUsage) return true;
|
||||
|
||||
// MoveRenameUsageInfo corresponds to non-Java usage of Java method
|
||||
return usageInfo instanceof MoveRenameUsageInfo
|
||||
@@ -475,26 +508,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static UsageInfo createReplacementUsage(
|
||||
UsageInfo originalUsageInfo,
|
||||
final JetChangeInfo javaMethodChangeInfo
|
||||
) {
|
||||
if (originalUsageInfo instanceof KotlinSAMUsage) {
|
||||
final KotlinSAMUsage samUsage = (KotlinSAMUsage) originalUsageInfo;
|
||||
return new JavaMethodKotlinUsageWithDelegate<JetFunction>(samUsage.getFunctionLiteral(), javaMethodChangeInfo) {
|
||||
private final JetFunctionDefinitionUsage<JetFunction> delegateUsage = new JetFunctionDefinitionUsage<JetFunction>(
|
||||
samUsage.getFunctionLiteral(),
|
||||
samUsage.getFunctionDescriptor(),
|
||||
javaMethodChangeInfo.getMethodDescriptor().getOriginalPrimaryFunction(),
|
||||
samUsage.getSamCallType()
|
||||
);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JetUsageInfo<JetFunction> getDelegateUsage() {
|
||||
return delegateUsage;
|
||||
}
|
||||
};
|
||||
private static UsageInfo createReplacementUsage(UsageInfo originalUsageInfo, JetChangeInfo javaMethodChangeInfo) {
|
||||
if (originalUsageInfo instanceof JavaMethodDeferredKotlinUsage) {
|
||||
return ((JavaMethodDeferredKotlinUsage<?>) originalUsageInfo).resolve(javaMethodChangeInfo);
|
||||
}
|
||||
|
||||
JetCallElement callElement = PsiTreeUtil.getParentOfType(originalUsageInfo.getElement(), JetCallElement.class);
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.refactoring.changeSignature.usages
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeInfo
|
||||
import org.jetbrains.kotlin.psi.JetConstructorDelegationCall
|
||||
import org.jetbrains.kotlin.psi.JetFunction
|
||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
|
||||
public abstract class JavaMethodDeferredKotlinUsage<T: PsiElement>(element: T): UsageInfo(element) {
|
||||
abstract fun resolve(javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<T>
|
||||
}
|
||||
|
||||
public class DeferredSAMUsage(
|
||||
val functionLiteral: JetFunctionLiteral,
|
||||
val functionDescriptor: FunctionDescriptor,
|
||||
val samCallType: JetType
|
||||
): JavaMethodDeferredKotlinUsage<JetFunctionLiteral>(functionLiteral) {
|
||||
override fun resolve(javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetFunctionLiteral> {
|
||||
return object : JavaMethodKotlinUsageWithDelegate<JetFunctionLiteral>(functionLiteral, javaMethodChangeInfo) {
|
||||
override val delegateUsage = JetFunctionDefinitionUsage(
|
||||
functionLiteral,
|
||||
functionDescriptor,
|
||||
javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction, samCallType
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class JavaConstructorDeferredUsageInDelegationCall(
|
||||
val delegationCall: JetConstructorDelegationCall
|
||||
): JavaMethodDeferredKotlinUsage<JetConstructorDelegationCall>(delegationCall) {
|
||||
override fun resolve(javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetConstructorDelegationCall> {
|
||||
return object : JavaMethodKotlinUsageWithDelegate<JetConstructorDelegationCall>(delegationCall, javaMethodChangeInfo) {
|
||||
override val delegateUsage = JetConstructorDelegationCallUsage(delegationCall)
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.refactoring.changeSignature.usages
|
||||
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeInfo
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.JetConstructorDelegationCall
|
||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||
import org.jetbrains.kotlin.psi.JetSecondaryConstructor
|
||||
|
||||
public class JetConstructorDelegationCallUsage(call: JetConstructorDelegationCall) : JetUsageInfo<JetConstructorDelegationCall>(call) {
|
||||
override fun processUsage(changeInfo: JetChangeInfo, element: JetConstructorDelegationCall): Boolean {
|
||||
val isThisCall = element.getCalleeExpression()!!.isThis()
|
||||
|
||||
val psiFactory = JetPsiFactory(element)
|
||||
var elementToWorkWith = element
|
||||
if (changeInfo.getNewParametersCount() > 0 && element.getCalleeExpression()!!.isEmpty()) {
|
||||
val delegationKindName = if (isThisCall) "this" else "super"
|
||||
elementToWorkWith =
|
||||
element.replace(psiFactory.createConstructorDelegationCall("$delegationKindName()")) as JetConstructorDelegationCall
|
||||
elementToWorkWith.getParent()!!.addBefore(psiFactory.createColon(), elementToWorkWith)
|
||||
}
|
||||
|
||||
val result = JetFunctionCallUsage(
|
||||
elementToWorkWith, changeInfo.methodDescriptor.originalPrimaryFunction).processUsage(changeInfo, elementToWorkWith)
|
||||
|
||||
if (changeInfo.getNewParametersCount() == 0 && !isThisCall && !elementToWorkWith.getCalleeExpression()!!.isEmpty()) {
|
||||
(elementToWorkWith.getParent() as? JetSecondaryConstructor)?.getColon()?.delete()
|
||||
elementToWorkWith.replace(psiFactory.createConstructorDelegationCall(""))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -179,9 +179,10 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
}
|
||||
}
|
||||
|
||||
boolean returnTypeIsNeeded = changeInfo.isRefactoringTarget(originalFunctionDescriptor)
|
||||
boolean returnTypeIsNeeded = (changeInfo.isRefactoringTarget(originalFunctionDescriptor)
|
||||
|| !(function instanceof JetFunctionLiteral)
|
||||
|| function.getTypeReference() != null;
|
||||
|| function.getTypeReference() != null) &&
|
||||
!(function instanceof JetSecondaryConstructor);
|
||||
if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) {
|
||||
function.setTypeReference(null);
|
||||
String returnTypeText = changeInfo.renderReturnType((JetFunctionDefinitionUsage<PsiElement>) this);
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.refactoring.changeSignature.usages
|
||||
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
|
||||
public class KotlinSAMUsage(
|
||||
val functionLiteral: JetFunctionLiteral,
|
||||
val functionDescriptor: FunctionDescriptor,
|
||||
val samCallType: JetType
|
||||
): UsageInfo(functionLiteral)
|
||||
Reference in New Issue
Block a user