diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt index 3c1653f2b55..6c86cfa94f7 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt @@ -50,23 +50,25 @@ fun Project.projectScope(): GlobalSearchScope = GlobalSearchScope.projectScope(t fun PsiFile.fileScope(): GlobalSearchScope = GlobalSearchScope.fileScope(this) -fun GlobalSearchScope.restrictToKotlinSources() = GlobalSearchScope.getScopeRestrictedByFileTypes(this, KotlinFileType.INSTANCE) +fun GlobalSearchScope.restrictByFileType(fileType: FileType) = GlobalSearchScope.getScopeRestrictedByFileTypes(this, fileType) -fun SearchScope.restrictToKotlinSources(): SearchScope { - return when (this) { - is GlobalSearchScope -> restrictToKotlinSources() - is LocalSearchScope -> { - val ktElements = scope.filter { it.containingFile is KtFile } - when (ktElements.size) { - 0 -> GlobalSearchScope.EMPTY_SCOPE - scope.size -> this - else -> LocalSearchScope(ktElements.toTypedArray()) - } +fun SearchScope.restrictByFileType(fileType: FileType) = when (this) { + is GlobalSearchScope -> restrictByFileType(fileType) + is LocalSearchScope -> { + val elements = scope.filter { it.containingFile.fileType == fileType } + when (elements.size) { + 0 -> GlobalSearchScope.EMPTY_SCOPE + scope.size -> this + else -> LocalSearchScope(elements.toTypedArray()) } - else -> this } + else -> this } +fun GlobalSearchScope.restrictToKotlinSources() = restrictByFileType(KotlinFileType.INSTANCE) + +fun SearchScope.restrictToKotlinSources() = restrictByFileType(KotlinFileType.INSTANCE) + fun SearchScope.excludeKotlinSources(): SearchScope = excludeFileTypes(KotlinFileType.INSTANCE) fun SearchScope.excludeFileTypes(vararg fileTypes: FileType): SearchScope { diff --git a/idea/resources/intentionDescriptions/AddJvmStaticIntention/description.html b/idea/resources/intentionDescriptions/AddJvmStaticIntention/description.html index 837b11d23a8..b5be1d9e8ec 100644 --- a/idea/resources/intentionDescriptions/AddJvmStaticIntention/description.html +++ b/idea/resources/intentionDescriptions/AddJvmStaticIntention/description.html @@ -1,5 +1,5 @@ -This intention adds @JvmStatic annotation to main() method in an object. +This intention adds @JvmStatic annotation to the specified function or property of an object declaration. diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddJvmStaticIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddJvmStaticIntention.kt index a514f96027c..0c665a9f334 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AddJvmStaticIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AddJvmStaticIntention.kt @@ -17,32 +17,84 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.codeInsight.intention.LowPriorityAction +import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.editor.Editor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.idea.MainFunctionDetector -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiReferenceExpression +import com.intellij.psi.search.searches.ReferencesSearch +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.elements.KtLightElement +import org.jetbrains.kotlin.asJava.elements.KtLightField +import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress +import org.jetbrains.kotlin.idea.search.restrictByFileType import org.jetbrains.kotlin.idea.util.addAnnotation +import org.jetbrains.kotlin.idea.util.application.runReadAction +import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.findAnnotation +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.KtObjectDeclaration +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject -class AddJvmStaticIntention : SelfTargetingIntention( - KtNamedFunction::class.java, - "Add '@JvmStatic' annotation" +class AddJvmStaticIntention : SelfTargetingRangeIntention( + KtNamedDeclaration::class.java, + "Add '@JvmStatic' annotation" ), LowPriorityAction { + private val JvmStaticFqName = FqName("kotlin.jvm.JvmStatic") + private val JvmFieldFqName = FqName("kotlin.jvm.JvmField") - private val annotationFqName = FqName("kotlin.jvm.JvmStatic") + override fun startInWriteAction() = false - override fun isApplicableTo(element: KtNamedFunction, caretOffset: Int): Boolean { - if (element.findAnnotation(annotationFqName) != null) return false - if (element.isTopLevel) return false - val detector = MainFunctionDetector { function -> - function.resolveToDescriptorIfAny() as? FunctionDescriptor + override fun applicabilityRange(element: KtNamedDeclaration): TextRange? { + if (element !is KtNamedFunction && element !is KtProperty) return null + + if (element.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return null + if (element.hasModifier(KtTokens.OPEN_KEYWORD)) return null + if (element.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return null + + val containingObject = element.containingClassOrObject as? KtObjectDeclaration ?: return null + if (containingObject.isObjectLiteral()) return null + if (element is KtProperty) { + if (element.hasModifier(KtTokens.CONST_KEYWORD)) return null + if (element.findAnnotation(JvmFieldFqName) != null) return null } - return detector.isMain(element, false) + if (element.findAnnotation(JvmStaticFqName) != null) return null + return element.nameIdentifier?.textRange } - override fun applyTo(element: KtNamedFunction, editor: Editor?) { - element.addAnnotation(annotationFqName) + override fun applyTo(element: KtNamedDeclaration, editor: Editor?) { + val containingObject = element.containingClassOrObject as? KtObjectDeclaration ?: return + val isCompanionMember = containingObject.isCompanion() + val instanceFieldName = if (isCompanionMember) containingObject.name else JvmAbi.INSTANCE_FIELD + val instanceFieldContainingClass = if (isCompanionMember) (containingObject.containingClassOrObject ?: return) else containingObject + val project = element.project + + val expressionsToReplaceWithQualifier = + project.runSynchronouslyWithProgress("Looking for usages in Java files...", true) { + runReadAction { + val searchScope = element.useScope.restrictByFileType(JavaFileType.INSTANCE) + ReferencesSearch + .search(element, searchScope) + .mapNotNull { + val refExpr = it.element as? PsiReferenceExpression ?: return@mapNotNull null + if ((refExpr.resolve() as? KtLightElement<*, *>)?.kotlinOrigin != element) return@mapNotNull null + val qualifierExpr = refExpr.qualifierExpression as? PsiReferenceExpression ?: return@mapNotNull null + if (qualifierExpr.qualifierExpression == null) return@mapNotNull null + val instanceField = qualifierExpr.resolve() as? KtLightField ?: return@mapNotNull null + if (instanceField.name != instanceFieldName) return@mapNotNull null + if ((instanceField.containingClass as? KtLightClass)?.kotlinOrigin != instanceFieldContainingClass) return@mapNotNull null + qualifierExpr + } + } + } ?: return + + runWriteAction { + element.addAnnotation(JvmStaticFqName) + expressionsToReplaceWithQualifier.forEach { it.replace(it.qualifierExpression!!) } + } } } diff --git a/idea/testData/intentions/addJvmStatic/abstractVal.kt b/idea/testData/intentions/addJvmStatic/abstractVal.kt new file mode 100644 index 00000000000..2574ff51c10 --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/abstractVal.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false +// ERROR: Abstract property 'foo' in non-abstract class 'Test' + +object Test { + abstract val foo: Int +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/constVal.kt b/idea/testData/intentions/addJvmStatic/constVal.kt new file mode 100644 index 00000000000..bb139646d66 --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/constVal.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false + +object Test { + const val foo = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/inAnonymousObject.kt b/idea/testData/intentions/addJvmStatic/funInAnonymousObject.kt similarity index 100% rename from idea/testData/intentions/addJvmStatic/inAnonymousObject.kt rename to idea/testData/intentions/addJvmStatic/funInAnonymousObject.kt diff --git a/idea/testData/intentions/addJvmStatic/inClass.kt b/idea/testData/intentions/addJvmStatic/funInClass.kt similarity index 100% rename from idea/testData/intentions/addJvmStatic/inClass.kt rename to idea/testData/intentions/addJvmStatic/funInClass.kt diff --git a/idea/testData/intentions/addJvmStatic/hasJvmStatic.kt b/idea/testData/intentions/addJvmStatic/funWithJvmStatic.kt similarity index 100% rename from idea/testData/intentions/addJvmStatic/hasJvmStatic.kt rename to idea/testData/intentions/addJvmStatic/funWithJvmStatic.kt diff --git a/idea/testData/intentions/addJvmStatic/inCompanionObject.kt b/idea/testData/intentions/addJvmStatic/inCompanionObject.kt deleted file mode 100644 index 81ddf128729..00000000000 --- a/idea/testData/intentions/addJvmStatic/inCompanionObject.kt +++ /dev/null @@ -1,8 +0,0 @@ -// WITH_RUNTIME - -class Test { - companion object { - fun main(args: Array) { - } - } -} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/inCompanionObject.kt.after b/idea/testData/intentions/addJvmStatic/inCompanionObject.kt.after deleted file mode 100644 index 7b14edcab2d..00000000000 --- a/idea/testData/intentions/addJvmStatic/inCompanionObject.kt.after +++ /dev/null @@ -1,9 +0,0 @@ -// WITH_RUNTIME - -class Test { - companion object { - @JvmStatic - fun main(args: Array) { - } - } -} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/inObjedct.kt b/idea/testData/intentions/addJvmStatic/inObjedct.kt deleted file mode 100644 index a0b87f27b85..00000000000 --- a/idea/testData/intentions/addJvmStatic/inObjedct.kt +++ /dev/null @@ -1,6 +0,0 @@ -// WITH_RUNTIME - -object Test { - fun main(args: Array) { - } -} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/mainJvmName.kt b/idea/testData/intentions/addJvmStatic/mainJvmName.kt deleted file mode 100644 index ebd68374e7d..00000000000 --- a/idea/testData/intentions/addJvmStatic/mainJvmName.kt +++ /dev/null @@ -1,7 +0,0 @@ -// WITH_RUNTIME - -object Test { - @JvmName("main") - fun test(args: Array) { - } -} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/mainJvmName.kt.after b/idea/testData/intentions/addJvmStatic/mainJvmName.kt.after deleted file mode 100644 index 06e0126fbfd..00000000000 --- a/idea/testData/intentions/addJvmStatic/mainJvmName.kt.after +++ /dev/null @@ -1,8 +0,0 @@ -// WITH_RUNTIME - -object Test { - @JvmStatic - @JvmName("main") - fun test(args: Array) { - } -} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/notMainJvmName.kt b/idea/testData/intentions/addJvmStatic/notMainJvmName.kt deleted file mode 100644 index f2b31b2ad06..00000000000 --- a/idea/testData/intentions/addJvmStatic/notMainJvmName.kt +++ /dev/null @@ -1,8 +0,0 @@ -// WITH_RUNTIME -// IS_APPLICABLE: false - -object Test { - @JvmName("test") - fun main(args: Array) { - } -} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/notMainMethod.kt b/idea/testData/intentions/addJvmStatic/notMainMethod.kt deleted file mode 100644 index f118e5af40b..00000000000 --- a/idea/testData/intentions/addJvmStatic/notMainMethod.kt +++ /dev/null @@ -1,6 +0,0 @@ -// IS_APPLICABLE: false - -object Test { - fun test(args: Array) { - } -} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/openVal.kt b/idea/testData/intentions/addJvmStatic/openVal.kt new file mode 100644 index 00000000000..8fa54546104 --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/openVal.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false + +object Test { + open val foo = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/overrideVal.kt b/idea/testData/intentions/addJvmStatic/overrideVal.kt new file mode 100644 index 00000000000..4cb528047bd --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/overrideVal.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false + +interface I { + val foo: Int +} + +object Test : I { + override val foo = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/inTopLevel.kt b/idea/testData/intentions/addJvmStatic/topLevelFun.kt similarity index 100% rename from idea/testData/intentions/addJvmStatic/inTopLevel.kt rename to idea/testData/intentions/addJvmStatic/topLevelFun.kt diff --git a/idea/testData/intentions/addJvmStatic/topLevelVal.kt b/idea/testData/intentions/addJvmStatic/topLevelVal.kt new file mode 100644 index 00000000000..7dcf9c1b6f1 --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/topLevelVal.kt @@ -0,0 +1,3 @@ +// IS_APPLICABLE: false + +val foo = 1 \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/valInAnonymousObject.kt b/idea/testData/intentions/addJvmStatic/valInAnonymousObject.kt new file mode 100644 index 00000000000..77b67c92271 --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/valInAnonymousObject.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false + +private fun test() = object { + val foo = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/valInClass.kt b/idea/testData/intentions/addJvmStatic/valInClass.kt new file mode 100644 index 00000000000..356c043cda0 --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/valInClass.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false + +class Test { + val foo = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/valWithJvmField.kt b/idea/testData/intentions/addJvmStatic/valWithJvmField.kt new file mode 100644 index 00000000000..6fd4d157a8a --- /dev/null +++ b/idea/testData/intentions/addJvmStatic/valWithJvmField.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false + +object Test { + @JvmField + val foo = 1 +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmStatic/inObjedct.kt.after b/idea/testData/intentions/addJvmStatic/valWithJvmStatic.kt similarity index 50% rename from idea/testData/intentions/addJvmStatic/inObjedct.kt.after rename to idea/testData/intentions/addJvmStatic/valWithJvmStatic.kt index 41077952c1f..087302f9ff0 100644 --- a/idea/testData/intentions/addJvmStatic/inObjedct.kt.after +++ b/idea/testData/intentions/addJvmStatic/valWithJvmStatic.kt @@ -1,7 +1,7 @@ // WITH_RUNTIME +// IS_APPLICABLE: false object Test { @JvmStatic - fun main(args: Array) { - } + val foo = 1 } \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/addJvmStaticToCompanionObjectFun.test b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/addJvmStaticToCompanionObjectFun.test new file mode 100644 index 00000000000..bd9a3e67f9a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/addJvmStaticToCompanionObjectFun.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test/test.kt", + "intentionClass": "org.jetbrains.kotlin.idea.intentions.AddJvmStaticIntention", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/after/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/after/test/J.java new file mode 100644 index 00000000000..b5557d3910a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/after/test/J.java @@ -0,0 +1,8 @@ +package test; + +class J { + void test(C.Companion companion) { + companion.foo("x"); + C.foo("y"); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/after/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/after/test/test.kt new file mode 100644 index 00000000000..da37b44d737 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/after/test/test.kt @@ -0,0 +1,8 @@ +package test + +class C { + companion object { + @JvmStatic + fun foo(s: String) {} + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/before/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/before/test/J.java new file mode 100644 index 00000000000..af23d9e8590 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/before/test/J.java @@ -0,0 +1,8 @@ +package test; + +class J { + void test(C.Companion companion) { + companion.foo("x"); + C.Companion.foo("y"); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/before/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/before/test/test.kt new file mode 100644 index 00000000000..08acdc7eae7 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/before/test/test.kt @@ -0,0 +1,7 @@ +package test + +class C { + companion object { + fun foo(s: String) {} + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/addJvmStaticToCompanionObjectProperty.test b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/addJvmStaticToCompanionObjectProperty.test new file mode 100644 index 00000000000..bd9a3e67f9a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/addJvmStaticToCompanionObjectProperty.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test/test.kt", + "intentionClass": "org.jetbrains.kotlin.idea.intentions.AddJvmStaticIntention", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/after/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/after/test/J.java new file mode 100644 index 00000000000..8f45460e1b2 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/after/test/J.java @@ -0,0 +1,11 @@ +package test; + +class J { + void test(C.Companion companion) { + companion.getFoo(); + companion.setFoo(1); + + C.getFoo(); + C.setFoo(2); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/after/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/after/test/test.kt new file mode 100644 index 00000000000..da026e6ae97 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/after/test/test.kt @@ -0,0 +1,8 @@ +package test + +class C { + companion object { + @JvmStatic + var foo: Int = 1 + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/before/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/before/test/J.java new file mode 100644 index 00000000000..6f87f4bbfe3 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/before/test/J.java @@ -0,0 +1,11 @@ +package test; + +class J { + void test(C.Companion companion) { + companion.getFoo(); + companion.setFoo(1); + + C.Companion.getFoo(); + C.Companion.setFoo(2); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/before/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/before/test/test.kt new file mode 100644 index 00000000000..41c85e22411 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/before/test/test.kt @@ -0,0 +1,7 @@ +package test + +class C { + companion object { + var foo: Int = 1 + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/addJvmStaticToNamedCompanionObjectFun.test b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/addJvmStaticToNamedCompanionObjectFun.test new file mode 100644 index 00000000000..bd9a3e67f9a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/addJvmStaticToNamedCompanionObjectFun.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test/test.kt", + "intentionClass": "org.jetbrains.kotlin.idea.intentions.AddJvmStaticIntention", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/after/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/after/test/J.java new file mode 100644 index 00000000000..3a8694a95a5 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/after/test/J.java @@ -0,0 +1,8 @@ +package test; + +class J { + void test(C.O companion) { + companion.foo("x"); + C.foo("y"); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/after/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/after/test/test.kt new file mode 100644 index 00000000000..9fdadce9d17 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/after/test/test.kt @@ -0,0 +1,8 @@ +package test + +class C { + companion object O { + @JvmStatic + fun foo(s: String) {} + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/before/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/before/test/J.java new file mode 100644 index 00000000000..dc0d4403faa --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/before/test/J.java @@ -0,0 +1,8 @@ +package test; + +class J { + void test(C.O companion) { + companion.foo("x"); + C.O.foo("y"); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/before/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/before/test/test.kt new file mode 100644 index 00000000000..3c5acf3101a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/before/test/test.kt @@ -0,0 +1,7 @@ +package test + +class C { + companion object O { + fun foo(s: String) {} + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/addJvmStaticToNamedCompanionObjectProperty.test b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/addJvmStaticToNamedCompanionObjectProperty.test new file mode 100644 index 00000000000..bd9a3e67f9a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/addJvmStaticToNamedCompanionObjectProperty.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test/test.kt", + "intentionClass": "org.jetbrains.kotlin.idea.intentions.AddJvmStaticIntention", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/after/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/after/test/J.java new file mode 100644 index 00000000000..955a1c8fd05 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/after/test/J.java @@ -0,0 +1,11 @@ +package test; + +class J { + void test(C.O companion) { + companion.getFoo(); + companion.setFoo(1); + + C.getFoo(); + C.setFoo(2); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/after/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/after/test/test.kt new file mode 100644 index 00000000000..e44f9f0c296 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/after/test/test.kt @@ -0,0 +1,8 @@ +package test + +class C { + companion object O { + @JvmStatic + var foo: Int = 1 + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/before/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/before/test/J.java new file mode 100644 index 00000000000..17665ee434a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/before/test/J.java @@ -0,0 +1,11 @@ +package test; + +class J { + void test(C.O companion) { + companion.getFoo(); + companion.setFoo(1); + + C.O.getFoo(); + C.O.setFoo(2); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/before/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/before/test/test.kt new file mode 100644 index 00000000000..467a28051b1 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/before/test/test.kt @@ -0,0 +1,7 @@ +package test + +class C { + companion object O { + var foo: Int = 1 + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/addJvmStaticToObjectFun.test b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/addJvmStaticToObjectFun.test new file mode 100644 index 00000000000..bd9a3e67f9a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/addJvmStaticToObjectFun.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test/test.kt", + "intentionClass": "org.jetbrains.kotlin.idea.intentions.AddJvmStaticIntention", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/after/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/after/test/J.java new file mode 100644 index 00000000000..8926f49f843 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/after/test/J.java @@ -0,0 +1,8 @@ +package test; + +class J { + void test(O o) { + o.foo("x"); + O.foo("y"); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/after/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/after/test/test.kt new file mode 100644 index 00000000000..ba805170cc7 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/after/test/test.kt @@ -0,0 +1,6 @@ +package test + +object O { + @JvmStatic + fun foo(s: String) {} +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/before/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/before/test/J.java new file mode 100644 index 00000000000..24b40800e13 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/before/test/J.java @@ -0,0 +1,8 @@ +package test; + +class J { + void test(O o) { + o.foo("x"); + O.INSTANCE.foo("y"); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/before/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/before/test/test.kt new file mode 100644 index 00000000000..dc72e2014ce --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectFun/before/test/test.kt @@ -0,0 +1,5 @@ +package test + +object O { + fun foo(s: String) {} +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/addJvmStaticToObjectProperty.test b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/addJvmStaticToObjectProperty.test new file mode 100644 index 00000000000..bd9a3e67f9a --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/addJvmStaticToObjectProperty.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test/test.kt", + "intentionClass": "org.jetbrains.kotlin.idea.intentions.AddJvmStaticIntention", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/after/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/after/test/J.java new file mode 100644 index 00000000000..08beda06f3c --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/after/test/J.java @@ -0,0 +1,11 @@ +package test; + +class J { + void test(O o) { + o.getFoo(); + o.setFoo(1); + + O.getFoo(); + O.setFoo(2); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/after/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/after/test/test.kt new file mode 100644 index 00000000000..5bca7b23ddb --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/after/test/test.kt @@ -0,0 +1,6 @@ +package test + +object O { + @JvmStatic + var foo: Int = 1 +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/before/test/J.java b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/before/test/J.java new file mode 100644 index 00000000000..676e6d0dbe6 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/before/test/J.java @@ -0,0 +1,11 @@ +package test; + +class J { + void test(O o) { + o.getFoo(); + o.setFoo(1); + + O.INSTANCE.getFoo(); + O.INSTANCE.setFoo(2); + } +} \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/before/test/test.kt b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/before/test/test.kt new file mode 100644 index 00000000000..efe9a0297b2 --- /dev/null +++ b/idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/before/test/test.kt @@ -0,0 +1,5 @@ +package test + +object O { + var foo: Int = 1 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 163700df7b0..19727d6e8fe 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -296,57 +296,81 @@ public class IntentionTestGenerated extends AbstractIntentionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/addJvmStatic"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } - @TestMetadata("hasJvmStatic.kt") - public void testHasJvmStatic() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/hasJvmStatic.kt"); + @TestMetadata("abstractVal.kt") + public void testAbstractVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/abstractVal.kt"); doTest(fileName); } - @TestMetadata("inAnonymousObject.kt") - public void testInAnonymousObject() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/inAnonymousObject.kt"); + @TestMetadata("constVal.kt") + public void testConstVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/constVal.kt"); doTest(fileName); } - @TestMetadata("inClass.kt") - public void testInClass() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/inClass.kt"); + @TestMetadata("funInAnonymousObject.kt") + public void testFunInAnonymousObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/funInAnonymousObject.kt"); doTest(fileName); } - @TestMetadata("inCompanionObject.kt") - public void testInCompanionObject() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/inCompanionObject.kt"); + @TestMetadata("funInClass.kt") + public void testFunInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/funInClass.kt"); doTest(fileName); } - @TestMetadata("inObjedct.kt") - public void testInObjedct() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/inObjedct.kt"); + @TestMetadata("funWithJvmStatic.kt") + public void testFunWithJvmStatic() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/funWithJvmStatic.kt"); doTest(fileName); } - @TestMetadata("inTopLevel.kt") - public void testInTopLevel() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/inTopLevel.kt"); + @TestMetadata("openVal.kt") + public void testOpenVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/openVal.kt"); doTest(fileName); } - @TestMetadata("mainJvmName.kt") - public void testMainJvmName() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/mainJvmName.kt"); + @TestMetadata("overrideVal.kt") + public void testOverrideVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/overrideVal.kt"); doTest(fileName); } - @TestMetadata("notMainJvmName.kt") - public void testNotMainJvmName() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/notMainJvmName.kt"); + @TestMetadata("topLevelFun.kt") + public void testTopLevelFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/topLevelFun.kt"); doTest(fileName); } - @TestMetadata("notMainMethod.kt") - public void testNotMainMethod() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/notMainMethod.kt"); + @TestMetadata("topLevelVal.kt") + public void testTopLevelVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/topLevelVal.kt"); + doTest(fileName); + } + + @TestMetadata("valInAnonymousObject.kt") + public void testValInAnonymousObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/valInAnonymousObject.kt"); + doTest(fileName); + } + + @TestMetadata("valInClass.kt") + public void testValInClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/valInClass.kt"); + doTest(fileName); + } + + @TestMetadata("valWithJvmField.kt") + public void testValWithJvmField() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/valWithJvmField.kt"); + doTest(fileName); + } + + @TestMetadata("valWithJvmStatic.kt") + public void testValWithJvmStatic() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/addJvmStatic/valWithJvmStatic.kt"); doTest(fileName); } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/MultiFileIntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/MultiFileIntentionTestGenerated.java index d2621bb36f7..d8977b0cbf9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/MultiFileIntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/MultiFileIntentionTestGenerated.java @@ -32,6 +32,42 @@ import java.util.regex.Pattern; @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public class MultiFileIntentionTestGenerated extends AbstractMultiFileIntentionTest { + @TestMetadata("addJvmStaticToCompanionObjectFun/addJvmStaticToCompanionObjectFun.test") + public void testAddJvmStaticToCompanionObjectFun_AddJvmStaticToCompanionObjectFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectFun/addJvmStaticToCompanionObjectFun.test"); + doTest(fileName); + } + + @TestMetadata("addJvmStaticToCompanionObjectProperty/addJvmStaticToCompanionObjectProperty.test") + public void testAddJvmStaticToCompanionObjectProperty_AddJvmStaticToCompanionObjectProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/addJvmStaticToCompanionObjectProperty/addJvmStaticToCompanionObjectProperty.test"); + doTest(fileName); + } + + @TestMetadata("addJvmStaticToNamedCompanionObjectFun/addJvmStaticToNamedCompanionObjectFun.test") + public void testAddJvmStaticToNamedCompanionObjectFun_AddJvmStaticToNamedCompanionObjectFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectFun/addJvmStaticToNamedCompanionObjectFun.test"); + doTest(fileName); + } + + @TestMetadata("addJvmStaticToNamedCompanionObjectProperty/addJvmStaticToNamedCompanionObjectProperty.test") + public void testAddJvmStaticToNamedCompanionObjectProperty_AddJvmStaticToNamedCompanionObjectProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/addJvmStaticToNamedCompanionObjectProperty/addJvmStaticToNamedCompanionObjectProperty.test"); + doTest(fileName); + } + + @TestMetadata("addJvmStaticToObjectFun/addJvmStaticToObjectFun.test") + public void testAddJvmStaticToObjectFun_AddJvmStaticToObjectFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/addJvmStaticToObjectFun/addJvmStaticToObjectFun.test"); + doTest(fileName); + } + + @TestMetadata("addJvmStaticToObjectProperty/addJvmStaticToObjectProperty.test") + public void testAddJvmStaticToObjectProperty_AddJvmStaticToObjectProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/multiFileIntentions/addJvmStaticToObjectProperty/addJvmStaticToObjectProperty.test"); + doTest(fileName); + } + public void testAllFilesPresentInMultiFileIntentions() throws Exception { KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClass(this.getClass(), new File("idea/testData/multiFileIntentions"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY); }