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
|
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() {
|
public inner class IfChainBuilder() {
|
||||||
private val sb = StringBuilder()
|
private val sb = StringBuilder()
|
||||||
private var first = true
|
private var first = true
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class JetSecondaryConstructor extends JetDeclarationStub<KotlinPlaceHolde
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public PsiElement getColon() {
|
public PsiElement getColon() {
|
||||||
return null;
|
return findChildByType(JetTokens.COLON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ public fun PsiReference.matchesTarget(candidateTarget: PsiElement): Boolean {
|
|||||||
|| it is JetObjectDeclaration && it.isCompanion() && it.getNonStrictParentOfType<JetClass>() == unwrappedCandidate
|
|| 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) {
|
if (this is PsiReferenceExpression && candidateTarget is JetObjectDeclaration && unwrappedTargets.size() == 1) {
|
||||||
val referredClass = unwrappedTargets.first()
|
val referredClass = unwrappedTargets.first()
|
||||||
if (referredClass is JetClass && candidateTarget in referredClass.getCompanionObjects()) {
|
if (referredClass is JetClass && candidateTarget in referredClass.getCompanionObjects()) {
|
||||||
|
|||||||
@@ -17,24 +17,34 @@
|
|||||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||||
|
|
||||||
import com.intellij.psi.PsiConstructorCall
|
import com.intellij.psi.PsiConstructorCall
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
|
import com.intellij.psi.search.SearchScope
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.codegen.PropertyCodegen
|
import org.jetbrains.kotlin.codegen.PropertyCodegen
|
||||||
import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
||||||
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.idea.references.*
|
import org.jetbrains.kotlin.idea.references.*
|
||||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeUtils
|
import org.jetbrains.kotlin.idea.findUsages.UsageTypeUtils
|
||||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum
|
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
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?
|
val JetDeclaration.descriptor: DeclarationDescriptor?
|
||||||
get() = this.analyze().get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
|
get() = this.analyze().get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
|
||||||
|
|
||||||
|
val JetDeclaration.constructor: ConstructorDescriptor?
|
||||||
|
get() = this.analyze().get(BindingContext.CONSTRUCTOR, this)
|
||||||
|
|
||||||
val JetParameter.propertyDescriptor: PropertyDescriptor?
|
val JetParameter.propertyDescriptor: PropertyDescriptor?
|
||||||
get() = this.analyze().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, this)
|
get() = this.analyze().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, this)
|
||||||
|
|
||||||
@@ -57,13 +67,31 @@ fun PsiReference.isImportUsage(): Boolean =
|
|||||||
getElement()!!.getNonStrictParentOfType<JetImportDirective>() != null
|
getElement()!!.getNonStrictParentOfType<JetImportDirective>() != null
|
||||||
|
|
||||||
fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean = with (getElement()!!) {
|
fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean = with (getElement()!!) {
|
||||||
fun getCallDescriptor(bindingContext: BindingContext): DeclarationDescriptor? {
|
fun checkJavaUsage(): Boolean {
|
||||||
|
val call = getNonStrictParentOfType<PsiConstructorCall>()
|
||||||
|
return call == getParent() && call?.resolveConstructor()?.getContainingClass()?.getNavigationElement() == jetClassOrObject
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkKotlinUsage(): Boolean {
|
||||||
|
if (this !is JetElement) return false
|
||||||
|
|
||||||
|
val descriptor = getConstructorCallDescriptor()
|
||||||
|
if (descriptor !is ConstructorDescriptor) return false
|
||||||
|
|
||||||
|
return DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getContainingDeclaration()) == jetClassOrObject
|
||||||
|
}
|
||||||
|
|
||||||
|
checkJavaUsage() || checkKotlinUsage()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JetElement.getConstructorCallDescriptor(): DeclarationDescriptor? {
|
||||||
|
val bindingContext = this.analyze()
|
||||||
val constructorCalleeExpression = getNonStrictParentOfType<JetConstructorCalleeExpression>()
|
val constructorCalleeExpression = getNonStrictParentOfType<JetConstructorCalleeExpression>()
|
||||||
if (constructorCalleeExpression != null) {
|
if (constructorCalleeExpression != null) {
|
||||||
return bindingContext.get(BindingContext.REFERENCE_TARGET, constructorCalleeExpression.getConstructorReferenceExpression())
|
return bindingContext.get(BindingContext.REFERENCE_TARGET, constructorCalleeExpression.getConstructorReferenceExpression())
|
||||||
}
|
}
|
||||||
|
|
||||||
val callExpression = getNonStrictParentOfType<JetCallExpression>()
|
val callExpression = getNonStrictParentOfType<JetCallElement>()
|
||||||
if (callExpression != null) {
|
if (callExpression != null) {
|
||||||
val callee = callExpression.getCalleeExpression()
|
val callee = callExpression.getCalleeExpression()
|
||||||
if (callee is JetReferenceExpression) {
|
if (callee is JetReferenceExpression) {
|
||||||
@@ -74,23 +102,56 @@ fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkJavaUsage(): Boolean {
|
public fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) {
|
||||||
val call = getNonStrictParentOfType<PsiConstructorCall>()
|
processDelegationCallKotlinConstructorUsages(scope, process)
|
||||||
return call == getParent() && call?.resolveConstructor()?.getContainingClass()?.getNavigationElement() == jetClassOrObject
|
processDelegationCallJavaConstructorUsages(scope, process)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkKotlinUsage(): Boolean {
|
private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) {
|
||||||
if (this !is JetElement) return false
|
val klass = when (this) {
|
||||||
|
is JetSecondaryConstructor -> getClassOrObject()
|
||||||
val bindingContext = this.analyze()
|
is JetClass -> this
|
||||||
|
else -> return
|
||||||
val descriptor = getCallDescriptor(bindingContext)
|
|
||||||
if (descriptor !is ConstructorDescriptor) return false
|
|
||||||
|
|
||||||
return DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getContainingDeclaration()) == jetClassOrObject
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkJavaUsage() || checkKotlinUsage()
|
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)
|
// Check if reference resolves to extension function whose receiver is the same as declaration's parent (or its superclass)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class JetElementDescriptionProvider : ElementDescriptionProvider {
|
|||||||
is JetClass -> if (targetElement.isTrait()) "trait" else "class"
|
is JetClass -> if (targetElement.isTrait()) "trait" else "class"
|
||||||
is JetObjectDeclaration -> "object"
|
is JetObjectDeclaration -> "object"
|
||||||
is JetNamedFunction -> "function"
|
is JetNamedFunction -> "function"
|
||||||
|
is JetSecondaryConstructor -> "constructor"
|
||||||
is JetProperty -> "property"
|
is JetProperty -> "property"
|
||||||
is JetTypeParameter -> "type parameter"
|
is JetTypeParameter -> "type parameter"
|
||||||
is JetParameter -> "parameter"
|
is JetParameter -> "parameter"
|
||||||
|
|||||||
@@ -20,21 +20,16 @@ import com.intellij.find.findUsages.FindUsagesHandler
|
|||||||
import com.intellij.find.findUsages.FindUsagesHandlerFactory
|
import com.intellij.find.findUsages.FindUsagesHandlerFactory
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
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.KotlinFindClassUsagesHandler
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler
|
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler
|
||||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
|
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
|
||||||
import org.jetbrains.kotlin.psi.JetProperty
|
|
||||||
import com.intellij.find.findUsages.FindUsagesOptions
|
import com.intellij.find.findUsages.FindUsagesOptions
|
||||||
import org.jetbrains.kotlin.psi.JetTypeParameter
|
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinTypeParameterFindUsagesHandler
|
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 com.intellij.find.findUsages.JavaFindUsagesHandlerFactory
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.DelegatingFindMemberUsagesHandler
|
import org.jetbrains.kotlin.idea.findUsages.handlers.DelegatingFindMemberUsagesHandler
|
||||||
import org.jetbrains.kotlin.plugin.findUsages.handlers.KotlinFindUsagesHandlerDecorator
|
import org.jetbrains.kotlin.plugin.findUsages.handlers.KotlinFindUsagesHandlerDecorator
|
||||||
import com.intellij.openapi.extensions.Extensions
|
import com.intellij.openapi.extensions.Extensions
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
public class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactory() {
|
public class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactory() {
|
||||||
val javaHandlerFactory = JavaFindUsagesHandlerFactory(project)
|
val javaHandlerFactory = JavaFindUsagesHandlerFactory(project)
|
||||||
@@ -49,14 +44,15 @@ public class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandle
|
|||||||
element is JetNamedFunction ||
|
element is JetNamedFunction ||
|
||||||
element is JetProperty ||
|
element is JetProperty ||
|
||||||
element is JetParameter ||
|
element is JetParameter ||
|
||||||
element is JetTypeParameter
|
element is JetTypeParameter ||
|
||||||
|
element is JetSecondaryConstructor
|
||||||
|
|
||||||
public override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler? {
|
public override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler? {
|
||||||
val handler = when (element) {
|
val handler = when (element) {
|
||||||
is JetClassOrObject ->
|
is JetClassOrObject ->
|
||||||
KotlinFindClassUsagesHandler(element, this)
|
KotlinFindClassUsagesHandler(element, this)
|
||||||
|
|
||||||
is JetNamedFunction, is JetProperty, is JetParameter -> {
|
is JetNamedFunction, is JetProperty, is JetParameter, is JetSecondaryConstructor -> {
|
||||||
val declaration = element as JetNamedDeclaration
|
val declaration = element as JetNamedDeclaration
|
||||||
|
|
||||||
if (forHighlightUsages) return KotlinFindMemberUsagesHandler.getInstance(declaration, this)
|
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.PsiReference;
|
||||||
import com.intellij.psi.search.PsiElementProcessor;
|
import com.intellij.psi.search.PsiElementProcessor;
|
||||||
import com.intellij.psi.search.PsiElementProcessorAdapter;
|
import com.intellij.psi.search.PsiElementProcessorAdapter;
|
||||||
|
import com.intellij.psi.search.SearchScope;
|
||||||
import com.intellij.usageView.UsageInfo;
|
import com.intellij.usageView.UsageInfo;
|
||||||
import com.intellij.util.Processor;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil;
|
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.*;
|
||||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindFunctionUsagesDialog;
|
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindFunctionUsagesDialog;
|
||||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindPropertyUsagesDialog;
|
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.declarationsSearch.HierarchySearchRequest;
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearch;
|
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearch;
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchHelper;
|
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.idea.search.usagesSearch.UsagesSearchRequest;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
|
||||||
@@ -155,6 +162,16 @@ public abstract class KotlinFindMemberUsagesHandler<T extends JetNamedDeclaratio
|
|||||||
processUsage(processor, ref);
|
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()) {
|
if (kotlinOptions.getSearchOverrides()) {
|
||||||
DeclarationsSearchPackage.searchOverriders(
|
DeclarationsSearchPackage.searchOverriders(
|
||||||
new HierarchySearchRequest<PsiElement>(element, options.searchScope, true)
|
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) {
|
if (elementParent instanceof JetClass && ((JetClass) elementParent).getNameIdentifier() == element) {
|
||||||
return elementParent;
|
return elementParent;
|
||||||
}
|
}
|
||||||
|
if (elementParent instanceof JetSecondaryConstructor &&
|
||||||
|
((JetSecondaryConstructor) elementParent).getConstructorKeyword() == element) {
|
||||||
|
return elementParent;
|
||||||
|
}
|
||||||
|
|
||||||
JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class);
|
JetCallElement call = PsiTreeUtil.getParentOfType(element, JetCallExpression.class, JetDelegatorToSuperCall.class);
|
||||||
if (call == null) {
|
if (call == null) {
|
||||||
|
|||||||
+39
-23
@@ -36,6 +36,7 @@ import com.intellij.util.containers.HashSet;
|
|||||||
import com.intellij.util.containers.MultiMap;
|
import com.intellij.util.containers.MultiMap;
|
||||||
import kotlin.Function1;
|
import kotlin.Function1;
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
|
import kotlin.Unit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
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.RefactoringPackage;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.*;
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.*;
|
||||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference;
|
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.load.java.descriptors.JavaClassDescriptor;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
@@ -74,6 +76,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
findSAMUsages(info, result);
|
findSAMUsages(info, result);
|
||||||
|
findConstructorDelegationUsages(info, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.toArray(new UsageInfo[result.size()]);
|
return result.toArray(new UsageInfo[result.size()]);
|
||||||
@@ -93,7 +96,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
private static void findOneMethodUsages(
|
private static void findOneMethodUsages(
|
||||||
@NotNull JetFunctionDefinitionUsage<?> functionUsageInfo,
|
@NotNull JetFunctionDefinitionUsage<?> functionUsageInfo,
|
||||||
JetChangeInfo changeInfo,
|
JetChangeInfo changeInfo,
|
||||||
Set<UsageInfo> result
|
final Set<UsageInfo> result
|
||||||
) {
|
) {
|
||||||
boolean isInherited = functionUsageInfo.isInherited();
|
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(
|
private static void processInternalReferences(
|
||||||
@@ -286,10 +299,30 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
JetType samCallType = context.get(BindingContext.EXPRESSION_TYPE, callExpression);
|
JetType samCallType = context.get(BindingContext.EXPRESSION_TYPE, callExpression);
|
||||||
if (samCallType == null) continue;
|
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
|
@Override
|
||||||
public MultiMap<PsiElement, String> findConflicts(ChangeInfo info, Ref<UsageInfo[]> refUsages) {
|
public MultiMap<PsiElement, String> findConflicts(ChangeInfo info, Ref<UsageInfo[]> refUsages) {
|
||||||
MultiMap<PsiElement, String> result = new MultiMap<PsiElement, String>();
|
MultiMap<PsiElement, String> result = new MultiMap<PsiElement, String>();
|
||||||
@@ -467,7 +500,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
private JetMethodDescriptor originalJavaMethodDescriptor;
|
private JetMethodDescriptor originalJavaMethodDescriptor;
|
||||||
|
|
||||||
private static boolean isJavaMethodUsage(UsageInfo usageInfo) {
|
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
|
// MoveRenameUsageInfo corresponds to non-Java usage of Java method
|
||||||
return usageInfo instanceof MoveRenameUsageInfo
|
return usageInfo instanceof MoveRenameUsageInfo
|
||||||
@@ -475,26 +508,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static UsageInfo createReplacementUsage(
|
private static UsageInfo createReplacementUsage(UsageInfo originalUsageInfo, JetChangeInfo javaMethodChangeInfo) {
|
||||||
UsageInfo originalUsageInfo,
|
if (originalUsageInfo instanceof JavaMethodDeferredKotlinUsage) {
|
||||||
final JetChangeInfo javaMethodChangeInfo
|
return ((JavaMethodDeferredKotlinUsage<?>) originalUsageInfo).resolve(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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JetCallElement callElement = PsiTreeUtil.getParentOfType(originalUsageInfo.getElement(), JetCallElement.class);
|
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 instanceof JetFunctionLiteral)
|
||||||
|| function.getTypeReference() != null;
|
|| function.getTypeReference() != null) &&
|
||||||
|
!(function instanceof JetSecondaryConstructor);
|
||||||
if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) {
|
if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) {
|
||||||
function.setTypeReference(null);
|
function.setTypeReference(null);
|
||||||
String returnTypeText = changeInfo.renderReturnType((JetFunctionDefinitionUsage<PsiElement>) this);
|
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