diff --git a/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt b/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt index ab7a8ce98c2f..ace5b4b204a9 100644 --- a/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt +++ b/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt @@ -25,14 +25,17 @@ import com.intellij.psi.search.PsiShortNamesCache import com.intellij.util.Processor import com.intellij.util.containers.ContainerUtil import com.intellij.util.containers.HashSet +import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.defaultImplsChild import org.jetbrains.kotlin.asJava.finder.JavaElementFinder +import org.jetbrains.kotlin.asJava.getAccessorNamesCandidatesByPropertyName import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName -import org.jetbrains.kotlin.idea.stubindex.KotlinClassShortNameIndex -import org.jetbrains.kotlin.idea.stubindex.KotlinFileFacadeShortNameIndex -import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope +import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.load.java.getPropertyNamesCandidatesByAccessorName import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues import java.util.* class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() { @@ -85,30 +88,79 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() dest.addAll(allClassNames) } - override fun getMethodsByName(name: String, scope: GlobalSearchScope): Array - = emptyArray() + override fun getMethodsByName(name: String, scope: GlobalSearchScope): Array { + return getMethodSequenceByName(name, scope).toList().toTypedArray() + } - override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array - = emptyArray() + fun getMethodSequenceByName(name: String, scope: GlobalSearchScope): Sequence { + val propertiesIndex = KotlinPropertyShortNameIndex.getInstance() + val functionIndex = KotlinFunctionShortNameIndex.getInstance() - override fun getFieldsByNameIfNotMoreThan(s: String, scope: GlobalSearchScope, i: Int): Array - = emptyArray() + val kotlinFunctionsPsi = functionIndex.get(name, project, scope).asSequence() + .flatMap { LightClassUtil.getLightClassMethods(it).asSequence() } + .filter { it.name == name } + + val propertyAccessorsPsi = sequenceOfLazyValues({ getPropertyNamesCandidatesByAccessorName(Name.identifier(name)) }) + .flatMap { it.asSequence() } + .flatMap { propertiesIndex.get(it.asString(), project, scope).asSequence() } + .flatMap { LightClassUtil.getLightClassPropertyMethods(it).allDeclarations.asSequence() } + .filter { it.name == name } + .map { it as? PsiMethod } + + return sequenceOfLazyValues({ kotlinFunctionsPsi }, { propertyAccessorsPsi }).flatMap { it }.filterNotNull() + } + + override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array { + require(maxCount >= 0) + val psiMethods = getMethodSequenceByName(name, scope) + val limitedByMaxCount = psiMethods.take(maxCount).toList() + if (limitedByMaxCount.size == 0) + return PsiMethod.EMPTY_ARRAY + return limitedByMaxCount.toTypedArray() + } + + override fun getFieldsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array { + require(maxCount >= 0) + val psiFields = getFieldSequenceByName(name, scope) + val limitedByMaxCount = psiFields.take(maxCount).toList() + if (limitedByMaxCount.size == 0) + return PsiField.EMPTY_ARRAY + return limitedByMaxCount.toTypedArray() + } override fun processMethodsWithName(name: String, scope: GlobalSearchScope, processor: Processor): Boolean = ContainerUtil.process(getMethodsByName(name, scope), processor) - override fun getAllMethodNames(): Array - = emptyArray() + override fun getAllMethodNames(): Array { + val functionIndex = KotlinFunctionShortNameIndex.getInstance() + val functionNames = functionIndex.getAllKeys(project) + + val propertiesIndex = KotlinPropertyShortNameIndex.getInstance() + val propertyAccessorNames = propertiesIndex.getAllKeys(project) + .flatMap(::getAccessorNamesCandidatesByPropertyName) + + return (functionNames + propertyAccessorNames).toTypedArray() + } override fun getAllMethodNames(set: HashSet) { + set.addAll(allMethodNames) } - override fun getFieldsByName(name: String, scope: GlobalSearchScope): Array - = emptyArray() + fun getFieldSequenceByName(name: String, scope: GlobalSearchScope): Sequence { + return KotlinPropertyShortNameIndex.getInstance().get(name, project, scope).asSequence() + .map { LightClassUtil.getLightClassBackingField(it) } + .filterNotNull() + } - override fun getAllFieldNames(): Array - = emptyArray() + override fun getFieldsByName(name: String, scope: GlobalSearchScope): Array { + return getFieldSequenceByName(name, scope).toList().toTypedArray() + } + + override fun getAllFieldNames(): Array { + return KotlinPropertyShortNameIndex.getInstance().getAllKeys(project).toTypedArray() + } override fun getAllFieldNames(set: HashSet) { + set.addAll(allFieldNames) } } diff --git a/plugins/kotlin/core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt b/plugins/kotlin/core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt index e0ee84d89efe..c03f0b1429f8 100644 --- a/plugins/kotlin/core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt +++ b/plugins/kotlin/core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt @@ -18,18 +18,24 @@ package org.jetbrains.kotlin.idea.core import com.intellij.codeInsight.JavaProjectCodeInsightSettings import com.intellij.openapi.progress.ProgressManager +import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiFile import com.intellij.psi.PsiMember import com.intellij.psi.PsiModifier +import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.PsiShortNamesCache import com.intellij.psi.stubs.StringStubIndexExtension import com.intellij.util.indexing.IdFilter +import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.caches.resolve.* import org.jetbrains.kotlin.idea.core.extension.KotlinIndicesHelperExtension +import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInFileType import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.idea.search.excludeKotlinSources import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.idea.util.CallType @@ -59,6 +65,7 @@ class KotlinIndicesHelper( private val moduleDescriptor = resolutionFacade.moduleDescriptor private val project = resolutionFacade.project + private val scopeWithoutKotlin = scope.excludeKotlinSources() as GlobalSearchScope private val descriptorFilter: (DeclarationDescriptor) -> Boolean = filter@ { if (it.isHiddenInResolution()) return@filter false @@ -202,9 +209,10 @@ class KotlinIndicesHelper( } fun getJvmCallablesByName(name: String): Collection { - val javaDeclarations = PsiShortNamesCache.getInstance(project).getFieldsByName(name, scope).asSequence() + - PsiShortNamesCache.getInstance(project).getMethodsByName(name, scope).asSequence() + val javaDeclarations = PsiShortNamesCache.getInstance(project).getFieldsByName(name, scopeWithoutKotlin).asSequence() + + PsiShortNamesCache.getInstance(project).getMethodsByName(name, scopeWithoutKotlin).asSequence() return javaDeclarations + .filterNot { it is KtLightElement<*,*> } .mapNotNull { (it as PsiMember).getJavaMemberDescriptor(resolutionFacade) as? CallableDescriptor } .filter(descriptorFilter) .toSet() @@ -298,11 +306,11 @@ class KotlinIndicesHelper( val shortNamesCache = PsiShortNamesCache.getInstance(project) val allMethodNames = hashSetOf() - shortNamesCache.processAllMethodNames({ name -> if (nameFilter(name)) allMethodNames.add(name); true }, scope, idFilter) + shortNamesCache.processAllMethodNames({ name -> if (nameFilter(name)) allMethodNames.add(name); true }, scopeWithoutKotlin, idFilter) for (name in allMethodNames) { ProgressManager.checkCanceled() - for (method in shortNamesCache.getMethodsByName(name, scope)) { + for (method in shortNamesCache.getMethodsByName(name, scopeWithoutKotlin).filterNot { it is KtLightElement<*, *> }) { if (!method.hasModifierProperty(PsiModifier.STATIC)) continue if (filterOutPrivate && method.hasModifierProperty(PsiModifier.PRIVATE)) continue if (method.containingClass?.parent !is PsiFile) continue // only top-level classes @@ -321,11 +329,11 @@ class KotlinIndicesHelper( } val allFieldNames = hashSetOf() - shortNamesCache.processAllFieldNames({ name -> if (nameFilter(name)) allFieldNames.add(name); true }, scope, idFilter) + shortNamesCache.processAllFieldNames({ name -> if (nameFilter(name)) allFieldNames.add(name); true }, scopeWithoutKotlin, idFilter) for (name in allFieldNames) { ProgressManager.checkCanceled() - for (field in shortNamesCache.getFieldsByName(name, scope)) { + for (field in shortNamesCache.getFieldsByName(name, scopeWithoutKotlin).filterNot { it is KtLightElement<*, *> }) { if (!field.hasModifierProperty(PsiModifier.STATIC)) continue if (filterOutPrivate && field.hasModifierProperty(PsiModifier.PRIVATE)) continue val descriptor = field.getJavaFieldDescriptor() ?: continue diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/goto/gotoContributors.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/goto/gotoContributors.kt index e5bca7cf6f11..219d7f6c319f 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/goto/gotoContributors.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/goto/gotoContributors.kt @@ -24,10 +24,12 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.stubs.StubIndex +import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInFileType import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.psi.KtEnumEntry import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.psiUtil.containingClass import java.util.* class KotlinGotoClassContributor : GotoClassContributor { @@ -78,8 +80,14 @@ class KotlinGotoSymbolContributor : ChooseByNameContributor { val noLibrarySourceScope = KotlinSourceFilterScope.projectSourceAndClassFiles(baseScope, project) val result = ArrayList() - result += KotlinFunctionShortNameIndex.getInstance().get(name, project, noLibrarySourceScope) - result += KotlinPropertyShortNameIndex.getInstance().get(name, project, noLibrarySourceScope) + result += KotlinFunctionShortNameIndex.getInstance().get(name, project, noLibrarySourceScope).filter { + val method = LightClassUtil.getLightClassMethod(it) + method == null || it.name != method.name + } + result += KotlinPropertyShortNameIndex.getInstance().get(name, project, noLibrarySourceScope).filter { + LightClassUtil.getLightClassBackingField(it) == null || + it.containingClass()?.isInterface() ?: false + } result += KotlinClassShortNameIndex.getInstance().get(name, project, BuiltInClassesScope(noLibrarySourceScope)) result += KotlinTypeAliasShortNameIndex.getInstance().get(name, project, noLibrarySourceScope) diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCacheTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCacheTest.kt new file mode 100644 index 000000000000..f7cfd73a64c0 --- /dev/null +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCacheTest.kt @@ -0,0 +1,273 @@ +/* + * Copyright 2010-2016 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.caches + +import com.intellij.openapi.projectRoots.Sdk +import com.intellij.psi.PsiField +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiModifier +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.search.PsiShortNamesCache +import com.sun.tools.javac.util.Convert.shortName +import org.jetbrains.kotlin.asJava.elements.KtLightField +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName +import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.idea.test.KotlinCodeInsightTestCase +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.test.KotlinTestUtils + +class KotlinShortNamesCacheTest : KotlinCodeInsightTestCase() { + + lateinit var cacheInstance: PsiShortNamesCache + + override fun setUp() { + super.setUp() + cacheInstance = KotlinShortNamesCache(project) + ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, testProjectJdk) + } + + override fun tearDown() { + ConfigLibraryUtil.unConfigureKotlinRuntimeAndSdk(myModule, testProjectJdk) + super.tearDown() + + } + + override fun getModule() = myModule!! + + fun testGetMethodsByNameIfNotMoreThanLimits() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestData1.kt") + configureByFile(file) + val scope = GlobalSearchScope.allScope(project) + assertSize(2, cacheInstance.getMethodsByNameIfNotMoreThan("foobar", scope, 2)) + assertSize(3, cacheInstance.getMethodsByNameIfNotMoreThan("foobar", scope, 3)) + assertSize(3, cacheInstance.getMethodsByNameIfNotMoreThan("foobar", scope, Int.MAX_VALUE)) + } + + fun testGetFieldsByNameIfNotMoreThanLimits() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestData1.kt") + configureByFile(file) + val scope = GlobalSearchScope.allScope(project) + assertSize(2, cacheInstance.getFieldsByNameIfNotMoreThan("barfoo", scope, 2)) + assertSize(3, cacheInstance.getFieldsByNameIfNotMoreThan("barfoo", scope, 3)) + assertSize(3, cacheInstance.getFieldsByNameIfNotMoreThan("barfoo", scope, Int.MAX_VALUE)) + } + + fun testGetAllFields() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestData2.kt") + configureByFile(file) + val allFieldNameList = cacheInstance.allFieldNames.asList() + assertContainsElements(allFieldNameList, "foobar") + assertContainsElements(allFieldNameList, "barfoo") + } + + fun testGetAllMethods() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestData2.kt") + configureByFile(file) + val allMethodNameList = cacheInstance.allMethodNames.asList() + assertContainsElements(allMethodNameList, "getFoobar") + assertContainsElements(allMethodNameList, "getBarfoo") + assertContainsElements(allMethodNameList, "setFoobar") + assertContainsElements(allMethodNameList, "setBarfoo") + assertContainsElements(allMethodNameList, "method1") + assertContainsElements(allMethodNameList, "method2") + assertContainsElements(allMethodNameList, "methodInBoth") + } + + fun testGetAllClasses() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestDataClasses.kt") + configureByFile(file) + val allClassNameList = cacheInstance.allClassNames.asList() + assertContainsElements(allClassNameList, "C1") + assertContainsElements(allClassNameList, "O1") + } + + fun methodArrayDebugToString(a: Array) + = a.map { "${(it as KtLightMethod).clsDelegate.getKotlinFqName()} static=${it.hasModifierProperty(PsiModifier.STATIC)}" }.joinToString("\n") + + fun accessorArrayDebugToString(a: Array) + = a.map { "${(it as KtLightMethod).clsDelegate.getKotlinFqName()} property=${(it.lightMethodOrigin?.originalElement as KtProperty).fqName} static=${it.hasModifierProperty(PsiModifier.STATIC)}" }.joinToString("\n") + + fun checkMethodFound(methods: Array, stringFqName: String, static: Boolean) { + assertNotNull("Method $stringFqName with static=$static not found\n" + methodArrayDebugToString(methods), + methods.find { + stringFqName == (it as KtLightMethod).clsDelegate.getKotlinFqName().toString() + && + it.hasModifierProperty(PsiModifier.STATIC) == static + }) + } + + fun checkIsSingleMethodFound(scope: GlobalSearchScope, stringFqName: String, static: Boolean, query: String = shortName(stringFqName)) { + cacheInstance.getMethodsByName(query, scope).let { + checkMethodFound(it, stringFqName, static) + assertSize(1, it) + } + } + + fun checkIsSingleMethodFoundCompanion(scope: GlobalSearchScope, delegateFqName: String, originalFqName: String, query: String = shortName(originalFqName)) { + cacheInstance.getMethodsByName(query, scope).let { + checkMethodFound(it, delegateFqName, true) + checkMethodFound(it, originalFqName, false) + assertEquals((it[0] as KtLightMethod).kotlinOrigin, (it[1] as KtLightMethod).kotlinOrigin) + assertSize(2, it) + } + } + + fun checkIsVarAccessorsFound(scope: GlobalSearchScope, stringVarFqName: String, getFqName: String, setFqName: String, static: Boolean) { + val varName = shortName(stringVarFqName) + + cacheInstance.getMethodsByName(JvmAbi.getterName(varName), scope).let { + checkAccessorFound(it, getFqName, stringVarFqName, static) + assertSize(1, it) + } + cacheInstance.getMethodsByName(JvmAbi.setterName(varName), scope).let { + checkAccessorFound(it, setFqName, stringVarFqName, static) + assertSize(1, it) + } + } + + fun checkIsVarAccessorsFound(scope: GlobalSearchScope, stringVarFqName: String, static: Boolean) { + val (getter, setter) = accessorsFqNameStringFor(stringVarFqName) + checkIsVarAccessorsFound(scope, stringVarFqName, getter, setter, static) + } + + fun checkIsVarAccessorsFoundCompanion(scope: GlobalSearchScope, stringVarFqName: String, getterFqName: String, setterFqName: String, + delegateGetterFqName: String, delegateSetterFqName: String) { + val varName = shortName(stringVarFqName) + + + cacheInstance.getMethodsByName(JvmAbi.getterName(varName), scope).let { + checkAccessorFound(it, delegateGetterFqName, stringVarFqName, true) + checkAccessorFound(it, getterFqName, stringVarFqName, false) + assertSize(2, it) + } + cacheInstance.getMethodsByName(JvmAbi.setterName(varName), scope).let { + checkAccessorFound(it, delegateSetterFqName, stringVarFqName, true) + checkAccessorFound(it, setterFqName, stringVarFqName, false) + assertSize(2, it) + } + } + + fun checkIsVarAccessorsFoundCompanion(scope: GlobalSearchScope, stringVarFqName: String) { + val (getter, setter) = accessorsFqNameStringFor(stringVarFqName) + val varFqName = FqName(stringVarFqName) + val varName = varFqName.shortName().asString() + val companionParent = varFqName.parent().parent().asString() + + checkIsVarAccessorsFoundCompanion(scope, stringVarFqName, getter, setter, + companionParent + "." + JvmAbi.getterName(varName), + companionParent + "." + JvmAbi.setterName(varName)) + } + + fun accessorsFqNameStringFor(stringVarFqName: String): Pair { + val varFqName = FqName(stringVarFqName) + val varShortName = varFqName.shortName().asString() + val stringVarParentFqName = varFqName.parent().asString() + return Pair(stringVarParentFqName + "." + JvmAbi.getterName(varShortName), + stringVarParentFqName + "." + JvmAbi.setterName(varShortName)) + } + + fun checkAccessorFound(methods: Array, stringFqName: String, propertyFqName: String, static: Boolean) { + assertNotNull("Accessor $stringFqName property=$propertyFqName static=$static not found\n" + accessorArrayDebugToString(methods), + methods.find { + stringFqName == (it as KtLightMethod).clsDelegate.getKotlinFqName().toString() + && + (it.lightMethodOrigin?.originalElement as KtProperty).fqName?.asString() == propertyFqName + && + it.hasModifierProperty(PsiModifier.STATIC) == static + }) + } + + fun testGetMethodsByNameWithFunctions() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestDataMethods.kt") + configureByFile(file) + val scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(myModule) + checkIsSingleMethodFound(scope, "KotlinShortNamesCacheTestDataMethodsKt.topLevelFunction", true) + checkIsSingleMethodFound(scope, "B1.staticMethodOfObject", true) + checkIsSingleMethodFound(scope, "B1.nonStaticMethodOfObject", false) + checkIsSingleMethodFound(scope, "C1.methodOfClass", false) + checkIsSingleMethodFoundCompanion(scope, "C1.staticMethodOfCompanion", "C1.Companion.staticMethodOfCompanion") + checkIsSingleMethodFound(scope, "C1.Companion.nonStaticMethodOfCompanion", false) + } + + fun doTestGetMethodsByNameWithAccessors(file: String) { + + configureByFile(file) + val scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(myModule) + checkIsVarAccessorsFound(scope, "topLevelVar", "KotlinShortNameCacheTestData.getTopLevelVar", + "KotlinShortNameCacheTestData.setTopLevelVar", true) + + checkIsVarAccessorsFound(scope, "B1.staticObjectVar", true) + checkIsVarAccessorsFound(scope, "B1.nonStaticObjectVar", false) + checkIsVarAccessorsFound(scope, "C1.classVar", false) + checkIsVarAccessorsFoundCompanion(scope, "C1.Companion.staticCompanionVar") + checkIsVarAccessorsFound(scope, "C1.Companion.nonStaticCompanionVar", false) + } + + fun testGetMethodsByNameWithDefaultPropertyAccessors() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestDataDefaultProperties.kt") + doTestGetMethodsByNameWithAccessors(file) + } + + fun testGetMethodsByNameWithCustomPropertyAccessors() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestDataCustomProperties.kt") + doTestGetMethodsByNameWithAccessors(file) + } + + fun checkFieldFound(methods: Array, stringFqName: String, static: Boolean) { + assertNotNull("Field $stringFqName with static=$static not found\n" + fieldArrayDebugToString(methods), + methods.find { + stringFqName == (it as KtLightField).clsDelegate.getKotlinFqName().toString() + && + it.hasModifierProperty(PsiModifier.STATIC) == static + }) + } + + fun fieldArrayDebugToString(a: Array) + = a.map { "${(it as KtLightField).clsDelegate.getKotlinFqName()} property=${(it.kotlinOrigin as KtProperty).fqName} static=${it.hasModifierProperty(PsiModifier.STATIC)}" }.joinToString("\n") + + + fun checkIsSingleFieldFound(scope: GlobalSearchScope, stringFqName: String, static: Boolean, query: String = shortName(stringFqName)) { + cacheInstance.getFieldsByName(query, scope).let { + checkFieldFound(it, stringFqName, static) + assertSize(1, it) + } + } + + fun testGetFieldsByName() { + val file = KotlinTestUtils.navigationMetadata("idea/testData/cache/kotlinShortNamesCacheTestDataFields.kt") + configureByFile(file) + val scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(myModule) + checkIsSingleFieldFound(scope, "KotlinShortNamesCacheTestDataFieldsKt.topLevelVar", true) + checkIsSingleFieldFound(scope, "B1.objectVar", true) + checkIsSingleFieldFound(scope, "C1.classVar", false) + checkIsSingleFieldFound(scope, "C1.companionVar", true) + } + + + override fun getTestProjectJdk(): Sdk? { + return PluginTestCaseBase.mockJdk() + } + + override fun getTestDataPath(): String { + return KotlinTestUtils.getHomeDirectory() + "/" + } + +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index 62802c49707e..ba96c764a1ac 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -167,6 +167,78 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes doTestWithExtraFile(fileName); } + @TestMetadata("importKotlinCompanionPropertyAsFieldFromJava.test") + public void testImportKotlinCompanionPropertyAsFieldFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinCompanionPropertyAsFieldFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinCompanionStaticFunctionFromJava.test") + public void testImportKotlinCompanionStaticFunctionFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinCompanionStaticFunctionFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinCompanionStaticPropertyDefaultGetterFromJava.test") + public void testImportKotlinCompanionStaticPropertyDefaultGetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultGetterFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinCompanionStaticPropertyDefaultSetterFromJava.test") + public void testImportKotlinCompanionStaticPropertyDefaultSetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultSetterFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinCompanionStaticPropertyOverloadedGetterFromJava.test") + public void testImportKotlinCompanionStaticPropertyOverloadedGetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedGetterFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinCompanionStaticPropertyOverloadedSetterFromJava.test") + public void testImportKotlinCompanionStaticPropertyOverloadedSetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedSetterFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinPropertyAsFieldFromJava.test") + public void testImportKotlinPropertyAsFieldFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinPropertyAsFieldFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinStaticFunctionFromJava.test") + public void testImportKotlinStaticFunctionFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinStaticFunctionFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinStaticPropertyDefaultGetterFromJava.test") + public void testImportKotlinStaticPropertyDefaultGetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultGetterFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinStaticPropertyDefaultSetterFromJava.test") + public void testImportKotlinStaticPropertyDefaultSetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultSetterFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinStaticPropertyOverloadedGetterFromJava.test") + public void testImportKotlinStaticPropertyOverloadedGetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedGetterFromJava.test"); + doTestWithExtraFile(fileName); + } + + @TestMetadata("importKotlinStaticPropertyOverloadedSetterFromJava.test") + public void testImportKotlinStaticPropertyOverloadedSetterFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedSetterFromJava.test"); + doTestWithExtraFile(fileName); + } + @TestMetadata("importTrait.before.Main.kt") public void testImportTrait() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/importTrait.before.Main.kt"); diff --git a/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestData1.kt b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestData1.kt new file mode 100644 index 000000000000..8bdc3ed919e8 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestData1.kt @@ -0,0 +1,22 @@ + +object B1 { + @JvmStatic + fun foobar() {} + + @JvmField + val barfoo = "" +} +object B2 { + @JvmStatic + fun foobar() {} + + @JvmField + val barfoo = "" +} +object B3 { + @JvmStatic + fun foobar() {} + + @JvmField + val barfoo = "" +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestData2.kt b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestData2.kt new file mode 100644 index 000000000000..35dcd9ff7123 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestData2.kt @@ -0,0 +1,16 @@ +object B1 { + @JvmField + val foobar = "" + + fun method1(){} + + fun methodInBoth(){} +} + +object B2 { + val barfoo = "" + + fun method2(){} + + fun methodInBoth(){} +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataClasses.kt b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataClasses.kt new file mode 100644 index 000000000000..8ee0501036b4 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataClasses.kt @@ -0,0 +1,7 @@ +class C1 { + +} + +object O1 { + +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataCustomProperties.kt b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataCustomProperties.kt new file mode 100644 index 000000000000..cf90c43d172b --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataCustomProperties.kt @@ -0,0 +1,52 @@ +@file:JvmName("KotlinShortNameCacheTestData") + +var topLevelVar: String + get() { + return "" + } + set(value) { + } + + +object B1 { + @JvmStatic + var staticObjectVar: String + get() { + return "" + } + set(value) { + } + + var nonStaticObjectVar: String + get() { + return "" + } + set(value) { + } +} + +class C1 { + var classVar: String + get() { + return "" + } + set(value) { + } + + companion object { + @JvmStatic + var staticCompanionVar: String + get() { + return "" + } + set(value) { + } + + var nonStaticCompanionVar: String + get() { + return "" + } + set(value) { + } + } +} diff --git a/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataDefaultProperties.kt b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataDefaultProperties.kt new file mode 100644 index 000000000000..43f2a068280e --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataDefaultProperties.kt @@ -0,0 +1,22 @@ +@file:JvmName("KotlinShortNameCacheTestData") + +var topLevelVar = "" + + +object B1 { + @JvmStatic + var staticObjectVar = "" + + var nonStaticObjectVar = "" +} + +class C1 { + var classVar = "" + + companion object { + @JvmStatic + var staticCompanionVar = "" + + var nonStaticCompanionVar = "" + } +} diff --git a/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataFields.kt b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataFields.kt new file mode 100644 index 000000000000..a1e19507b28a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataFields.kt @@ -0,0 +1,17 @@ +@JvmField +var topLevelVar = "" + +object B1 { + @JvmField + var objectVar = "" +} + +class C1 { + @JvmField + var classVar = "" + + companion object { + @JvmField + var companionVar = "" + } +} diff --git a/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataMethods.kt b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataMethods.kt new file mode 100644 index 000000000000..1297a53df827 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/cache/kotlinShortNamesCacheTestDataMethods.kt @@ -0,0 +1,27 @@ + +fun topLevelFunction(){ + +} + +object B1 { + @JvmStatic + fun staticMethodOfObject() { + } + + fun nonStaticMethodOfObject() { + } +} + +class C1 { + fun methodOfClass() { + } + + companion object { + @JvmStatic + fun staticMethodOfCompanion() { + } + + fun nonStaticMethodOfCompanion() { + } + } +} diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionPropertyAsFieldFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionPropertyAsFieldFromJava.test new file mode 100644 index 000000000000..d0ff41469725 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionPropertyAsFieldFromJava.test @@ -0,0 +1,47 @@ +// FILE: bar/Foo.before.java +// "Static import constant 'foo.Bar.Companion.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Rename reference +// ACTION: Create field 'foobar' +// ACTION: Create parameter 'foobar' +// ACTION: Create local variable 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + foobar + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + companion object { + @JvmField var foobar = "foobar" + } +} + +// FILE: bar/Foo.after.java +// "Static import constant 'foo.Bar.Companion.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Rename reference +// ACTION: Create field 'foobar' +// ACTION: Create parameter 'foobar' +// ACTION: Create local variable 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.Companion.foobar; + +public class Foo { + public void main() + { + foobar + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticFunctionFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticFunctionFromJava.test new file mode 100644 index 000000000000..6230b1b4e143 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticFunctionFromJava.test @@ -0,0 +1,43 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + foobar(); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +class Bar { + companion object { + @JvmStatic + fun foobar() { + } + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.foobar; + +public class Foo { + public void main() + { + foobar(); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultGetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultGetterFromJava.test new file mode 100644 index 000000000000..df5cec769066 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultGetterFromJava.test @@ -0,0 +1,41 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + getValue(); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + companion object { + @JvmStatic val value = "foobar"; + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.getValue; + +public class Foo { + public void main() + { + getValue(); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultSetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultSetterFromJava.test new file mode 100644 index 000000000000..5ae9fd6f96cb --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyDefaultSetterFromJava.test @@ -0,0 +1,41 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + companion object { + @JvmStatic var variable: String; + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.setVariable; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedGetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedGetterFromJava.test new file mode 100644 index 000000000000..b7105c7a2029 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedGetterFromJava.test @@ -0,0 +1,43 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + getValue(); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + companion object { + val value = "foobar"; + @JvmStatic get() { + } + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.getValue; + +public class Foo { + public void main() + { + getValue(); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedSetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedSetterFromJava.test new file mode 100644 index 000000000000..5d05eb024667 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinCompanionStaticPropertyOverloadedSetterFromJava.test @@ -0,0 +1,44 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + companion object { + var variable: String; + @JvmStatic set(value) { + field = value + } + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.setVariable; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinPropertyAsFieldFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinPropertyAsFieldFromJava.test new file mode 100644 index 000000000000..a7c6e4910a44 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinPropertyAsFieldFromJava.test @@ -0,0 +1,45 @@ +// FILE: bar/Foo.before.java +// "Static import constant 'foo.Bar.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Rename reference +// ACTION: Create field 'foobar' +// ACTION: Create parameter 'foobar' +// ACTION: Create local variable 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + foobar + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + @JvmField var foobar = "foobar" +} + +// FILE: bar/Foo.after.java +// "Static import constant 'foo.Bar.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Rename reference +// ACTION: Create field 'foobar' +// ACTION: Create parameter 'foobar' +// ACTION: Create local variable 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.foobar; + +public class Foo { + public void main() + { + foobar + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticFunctionFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticFunctionFromJava.test new file mode 100644 index 000000000000..457f472e2f8a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticFunctionFromJava.test @@ -0,0 +1,40 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + foobar(); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + @JvmStatic fun foobar() { + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.foobar'" "true" +// ERROR: Unresolved reference: foobar +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.foobar; + +public class Foo { + public void main() + { + foobar(); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultGetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultGetterFromJava.test new file mode 100644 index 000000000000..2b69d5749588 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultGetterFromJava.test @@ -0,0 +1,39 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + getValue(); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + @JvmStatic val value = "foobar"; +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.getValue; + +public class Foo { + public void main() + { + getValue(); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultSetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultSetterFromJava.test new file mode 100644 index 000000000000..22a052154a25 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyDefaultSetterFromJava.test @@ -0,0 +1,39 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + @JvmStatic var variable: String; +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.setVariable; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedGetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedGetterFromJava.test new file mode 100644 index 000000000000..e587153e8fb2 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedGetterFromJava.test @@ -0,0 +1,41 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + getValue(); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + val value = "foobar"; + @JvmStatic get() { + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.getValue'" "true" +// ERROR: Unresolved reference: getValue +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.getValue; + +public class Foo { + public void main() + { + getValue(); + } +} + + diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedSetterFromJava.test b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedSetterFromJava.test new file mode 100644 index 000000000000..0cf9278165aa --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/importKotlinStaticPropertyOverloadedSetterFromJava.test @@ -0,0 +1,42 @@ +// FILE: bar/Foo.before.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + + +// FILE: foo/Bar.dependency.kt +package foo + +object Bar { + var variable: String; + @JvmStatic set(value) { + field = value + } +} + +// FILE: bar/Foo.after.java +// "Static import method 'foo.Bar.setVariable'" "true" +// ERROR: Unresolved reference: setVariable +// ACTION: Create method 'foobar' +// WITH_RUNTIME +package bar; + +import static foo.Bar.setVariable; + +public class Foo { + public void main() + { + setVariable("foobar"); + } +} + +