diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt index 89c95d1b951..f98e16f8333 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiFactory.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.psi import com.intellij.lang.ASTNode -import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.psi.PsiComment @@ -27,14 +26,11 @@ import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.LocalTimeCounter import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.idea.JetFileType -import org.jetbrains.kotlin.lexer.JetKeywordToken import org.jetbrains.kotlin.lexer.JetModifierKeywordToken import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.JetPsiFactory.CallableBuilder.Target import org.jetbrains.kotlin.resolve.ImportPath -import java.io.PrintWriter -import java.io.StringWriter public fun JetPsiFactory(project: Project?): JetPsiFactory = JetPsiFactory(project!!) public fun JetPsiFactory(elementForProject: PsiElement): JetPsiFactory = JetPsiFactory(elementForProject.getProject()) @@ -262,9 +258,13 @@ public class JetPsiFactory(private val project: Project) { return createDeclaration("enum class E {$text}").getDeclarations()[0] as JetEnumEntry } + public fun createEnumEntryInitializerList(): JetInitializerList { + return createEnumEntry("Entry()").initializerList!! + } + public fun createEnumEntrySuperclassReferenceExpression(): JetEnumEntrySuperclassReferenceExpression { - val userType = createEnumEntry("Entry()").getInitializerList()!!.getInitializers()[0].getTypeReference()!!.getTypeElement() as JetUserType - return userType.getReferenceExpression() as JetEnumEntrySuperclassReferenceExpression + val userType = createEnumEntryInitializerList().initializers[0].typeReference!!.typeElement as JetUserType + return userType.referenceExpression as JetEnumEntrySuperclassReferenceExpression } public fun createWhenEntry(entryText: String): JetWhenEntry { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt index f1f8fe12bc8..6641dca8722 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt @@ -110,12 +110,12 @@ private fun JetElement.getConstructorCallDescriptor(): DeclarationDescriptor? { return null } -public fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) { +public fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Unit) { processDelegationCallKotlinConstructorUsages(scope, process) processDelegationCallJavaConstructorUsages(scope, process) } -private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) { +private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Unit) { val element = unwrapped val klass = when (element) { is JetConstructor<*> -> element.getContainingClassOrObject() @@ -130,7 +130,7 @@ private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: Searc processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process) } -private fun PsiElement.processDelegationCallJavaConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) { +private fun PsiElement.processDelegationCallJavaConstructorUsages(scope: SearchScope, process: (JetCallElement) -> Unit) { if (this is KotlinLightElement<*, *>) return // TODO: Temporary hack to avoid NPE while KotlinNoOriginLightMethod is around if (this is KotlinNoOriginLightMethod) return @@ -145,7 +145,7 @@ private fun processInheritorsDelegatingCallToSpecifiedConstructor( klass: PsiElement, scope: SearchScope, descriptor: ConstructorDescriptor, - process: (JetConstructorDelegationCall) -> Unit + process: (JetCallElement) -> Unit ) { HierarchySearchRequest(klass, scope, false).searchInheritors().forEach() { val unwrapped = it.unwrapped @@ -156,7 +156,7 @@ private fun processInheritorsDelegatingCallToSpecifiedConstructor( } private fun processClassDelegationCallsToSpecifiedConstructor( - klass: JetClass, constructor: DeclarationDescriptor, process: (JetConstructorDelegationCall) -> Unit + klass: JetClass, constructor: DeclarationDescriptor, process: (JetCallElement) -> Unit ) { for (secondaryConstructor in klass.getSecondaryConstructors()) { val delegationCallDescriptor = secondaryConstructor.getDelegationCall().getConstructorCallDescriptor() @@ -164,6 +164,15 @@ private fun processClassDelegationCallsToSpecifiedConstructor( process(secondaryConstructor.getDelegationCall()) } } + if (!klass.isEnum()) return + for (declaration in klass.declarations) { + if (declaration is JetEnumEntry) { + val delegationCall = declaration.getDelegationSpecifiers().firstOrNull() + if (delegationCall is JetDelegatorToSuperCall && constructor == delegationCall.calleeExpression.getConstructorCallDescriptor()) { + process(delegationCall) + } + } + } } // Check if reference resolves to extension function whose receiver is the same as declaration's parent (or its superclass) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java index f34af9e8377..068159396b1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java @@ -252,7 +252,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro } private static void findOneMethodUsages( - @NotNull JetCallableDefinitionUsage functionUsageInfo, + @NotNull final JetCallableDefinitionUsage functionUsageInfo, final JetChangeInfo changeInfo, final Set result ) { @@ -333,10 +333,16 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro UsagesSearchPackage.processDelegationCallConstructorUsages( functionPsi, functionPsi.getUseScope(), - new Function1() { + new Function1() { @Override - public Unit invoke(JetConstructorDelegationCall element) { - result.add(new JetConstructorDelegationCallUsage(element, changeInfo)); + public Unit invoke(JetCallElement element) { + if (element instanceof JetConstructorDelegationCall) { + result.add(new JetConstructorDelegationCallUsage((JetConstructorDelegationCall) element, changeInfo)); + } + else if (element instanceof JetDelegatorToSuperCall) { + result.add(new JetFunctionCallUsage(element, functionUsageInfo)); + + } return null; } } @@ -478,10 +484,12 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro UsagesSearchPackage.processDelegationCallConstructorUsages( psiMethod, psiMethod.getUseScope(), - new Function1() { + new Function1() { @Override - public Unit invoke(JetConstructorDelegationCall element) { - result.add(new JavaConstructorDeferredUsageInDelegationCall(element)); + public Unit invoke(JetCallElement element) { + if (element instanceof JetConstructorDelegationCall) { + result.add(new JavaConstructorDeferredUsageInDelegationCall((JetConstructorDelegationCall) element)); + } return null; } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetEnumEntryWithoutSuperCallUsage.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetEnumEntryWithoutSuperCallUsage.kt index d770acd3b2b..c8e2e4e166b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetEnumEntryWithoutSuperCallUsage.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetEnumEntryWithoutSuperCallUsage.kt @@ -17,24 +17,18 @@ package org.jetbrains.kotlin.idea.refactoring.changeSignature.usages import com.intellij.usageView.UsageInfo -import org.jetbrains.kotlin.psi.JetEnumEntry import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeInfo -import org.jetbrains.kotlin.psi.JetPsiFactory -import org.jetbrains.kotlin.psi.JetClass -import org.jetbrains.kotlin.psi.JetDelegatorToSuperCall -import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.psi.* public class JetEnumEntryWithoutSuperCallUsage(enumEntry: JetEnumEntry) : JetUsageInfo(enumEntry) { override fun processUsage(changeInfo: JetChangeInfo, element: JetEnumEntry, allUsages: Array): Boolean { - if (changeInfo.getNewParameters().size() > 0) { + if (changeInfo.newParameters.size() > 0) { val psiFactory = JetPsiFactory(element) - val enumClass = element.getStrictParentOfType()!! - val delegatorToSuperCall = element.addAfter( - psiFactory.createDelegatorToSuperCall("${enumClass.getName()}()"), + val delegatorToSuperCall = (element.addAfter( + psiFactory.createEnumEntryInitializerList(), element.getNameAsDeclaration() - ) as JetDelegatorToSuperCall - element.addBefore(psiFactory.createColon(), delegatorToSuperCall) + ) as JetInitializerList).initializers[0] as JetDelegatorToSuperCall return JetFunctionCallUsage(delegatorToSuperCall, changeInfo.methodDescriptor.originalPrimaryCallable) .processUsage(changeInfo, delegatorToSuperCall, allUsages) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java index dc53ba1645c..91f286d08da 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java @@ -120,9 +120,10 @@ public class JetFunctionCallUsage extends JetUsageInfo { private boolean shouldSkipUsage(JetCallElement element) { // TODO: We probable need more clever processing of invalid calls, but for now default to Java-like behaviour - // TODO: Investigate why resolved call is not recorded for enum constructor call if (resolvedCall == null && !(element instanceof JetDelegatorToSuperCall)) return true; if (resolvedCall != null && !resolvedCall.getStatus().isSuccess()) { + // TODO: investigate why arguments are not recorded for enum constructor call + if (element instanceof JetDelegatorToSuperCall && element.getParent().getParent() instanceof JetEnumEntry) return false; for (ValueArgument valueArgument : resolvedCall.getCall().getValueArguments()) { if (!(resolvedCall.getArgumentMapping(valueArgument) instanceof ArgumentMatch)) return true; } diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt index f19a1c53617..71d28abf410 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt @@ -4,9 +4,9 @@ // ERROR: No value passed for parameter foo enum class E { - A - B - C + A, + B, + C; val t: Int = foo } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt.after index 6658c0b9639..0519649fcde 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt.after +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumClass.kt.after @@ -4,9 +4,9 @@ // ERROR: No value passed for parameter foo enum class E(foo: Int) { - A : E() - B : E() - C : E() + A(), + B(), + C(); val t: Int = foo } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt index 1ed916b1595..4e59e50c408 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt @@ -4,9 +4,9 @@ // ERROR: No value passed for parameter foo enum class E { - A + A, B { val t: Int = foo - } + }, C } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after index 29222a924b4..840a21eeea3 100644 --- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inPropertyInitializerInEnumEntry.kt.after @@ -4,9 +4,9 @@ // ERROR: No value passed for parameter foo enum class E(val foo: Int) { - A : E() - B : E() { + A(), + B() { val t: Int = foo - } - C : E() + }, + C() } \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsAfter.kt b/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsAfter.kt index 37104f82419..8b46e7a9da7 100644 --- a/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsAfter.kt +++ b/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsAfter.kt @@ -1,4 +1,4 @@ enum class E(n: Int) { - A : E(1) - B : E(1) + A(1), + B(1) } \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsBefore.kt b/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsBefore.kt index 76bf0650929..55b0ec1bbeb 100644 --- a/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsBefore.kt +++ b/idea/testData/refactoring/changeSignature/EnumEntriesWithoutSuperCallsBefore.kt @@ -1,4 +1,4 @@ enum class E { - A + A, B } \ No newline at end of file