Return Kotlin fields and methods through KotlinShortNameCache

#KT-12205 Fixed
This commit is contained in:
Simon Ogorodnik
2016-08-30 19:49:10 +03:00
committed by Dmitry Jemerov
parent b06bdcef75
commit 18feb8f622
28 changed files with 1156 additions and 57 deletions
@@ -16,14 +16,12 @@
package org.jetbrains.kotlin.asJava
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.psi.*
import com.intellij.psi.impl.java.stubs.PsiClassStub
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.PsiFileStub
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.SmartList
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
@@ -31,6 +29,7 @@ import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues
object LightClassUtil {
@@ -53,9 +52,11 @@ object LightClassUtil {
fun getLightClassAccessorMethods(accessor: KtPropertyAccessor): List<PsiMethod> {
val property = accessor.getNonStrictParentOfType<KtProperty>() ?: return emptyList()
val wrappers = getPsiMethodWrappers(property, true)
return wrappers.filter { wrapper -> (accessor.isGetter && !JvmAbi.isSetterName(wrapper.name)) ||
(accessor.isSetter && JvmAbi.isSetterName(wrapper.name)) }
val wrappers = getPsiMethodWrappers(property)
return wrappers.filter { wrapper ->
(accessor.isGetter && !JvmAbi.isSetterName(wrapper.name)) ||
(accessor.isSetter && JvmAbi.isSetterName(wrapper.name))
}.toList()
}
fun getLightFieldForCompanionObject(companionObject: KtClassOrObject): PsiField? {
@@ -120,36 +121,16 @@ object LightClassUtil {
}
fun getLightClassMethods(function: KtFunction): List<PsiMethod> {
return getPsiMethodWrappers(function, true)
return getPsiMethodWrappers(function).toList()
}
private fun getPsiMethodWrapper(declaration: KtDeclaration): PsiMethod? {
return getPsiMethodWrappers(declaration, false).firstOrNull()
return getPsiMethodWrappers(declaration).firstOrNull()
}
private fun getPsiMethodWrappers(declaration: KtDeclaration, collectAll: Boolean): List<PsiMethod> {
val psiClass = getWrappingClass(declaration) ?: return emptyList()
val methods = SmartList<PsiMethod>()
for (method in psiClass.methods.asList()) {
try {
if (method is KtLightMethod && method.kotlinOrigin === declaration) {
methods.add(method)
if (!collectAll) {
return methods
}
}
}
catch (e: ProcessCanceledException) {
throw e
}
catch (e: Throwable) {
throw IllegalStateException(
"Error while wrapping declaration " + declaration.name + "Context\n:" + method, e)
}
}
return methods
private fun getPsiMethodWrappers(declaration: KtDeclaration): Sequence<PsiMethod> {
return getWrappingClasses(declaration).flatMap { it.methods.asSequence() }
.filter { method -> method is KtLightMethod && method.kotlinOrigin === declaration }
}
private fun getWrappingClass(declaration: KtDeclaration): PsiClass? {
@@ -185,6 +166,15 @@ object LightClassUtil {
return null
}
private fun getWrappingClasses(declaration: KtDeclaration): Sequence<PsiClass> {
val wrapperClass = getWrappingClass(declaration) ?: return emptySequence()
val wrapperClassOrigin = (wrapperClass as KtLightClass).kotlinOrigin
if (wrapperClassOrigin is KtObjectDeclaration && wrapperClassOrigin.isCompanion()) {
return sequenceOfLazyValues({ wrapperClass }, { wrapperClass.parent as PsiClass })
}
return sequenceOf(wrapperClass)
}
fun canGenerateLightClass(declaration: KtDeclaration): Boolean {
//noinspection unchecked
return PsiTreeUtil.getParentOfType(declaration, KtFunction::class.java, KtProperty::class.java) == null
@@ -197,7 +187,7 @@ object LightClassUtil {
var setterWrapper = specialSetter
val additionalAccessors = arrayListOf<PsiMethod>()
for (wrapper in getPsiMethodWrappers(ktDeclaration, true)) {
for (wrapper in getPsiMethodWrappers(ktDeclaration)) {
if (wrapper !is KtLightMethod) continue
if (wrapper.isSetter) {
@@ -209,7 +199,7 @@ object LightClassUtil {
}
}
else {
if (getterWrapper == null || getterWrapper == specialGetter) {
if (getterWrapper == null || getterWrapper === specialGetter) {
getterWrapper = wrapper
}
else {
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiField
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.impl.PsiVariableEx
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
@@ -31,4 +32,6 @@ interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiNamedElemen
interface KtLightDeclaration<out T: KtDeclaration, out D: PsiElement>: KtLightElement<T, D>
interface KtLightField : PsiField, KtLightDeclaration<KtDeclaration, PsiField>, PsiVariableEx
interface KtLightField : PsiField, KtLightDeclaration<KtDeclaration, PsiField>, PsiVariableEx {
val lightMemberOrigin: LightMemberOrigin?
}
@@ -16,6 +16,9 @@
package org.jetbrains.kotlin.asJava.elements
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.navigation.NavigationItem
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.impl.PsiVariableEx
@@ -30,10 +33,11 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import java.lang.UnsupportedOperationException
// Copied from com.intellij.psi.impl.light.LightField
sealed class KtLightFieldImpl(
private val lightMemberOrigin: LightMemberOrigin?,
override val lightMemberOrigin: LightMemberOrigin?,
override val clsDelegate: PsiField,
private val containingClass: KtLightClass
) : LightElement(clsDelegate.manager, KotlinLanguage.INSTANCE), KtLightField {
@@ -44,6 +48,8 @@ sealed class KtLightFieldImpl(
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
override fun getPresentation(): ItemPresentation? = (kotlinOrigin ?: this).let { ItemPresentationProviders.getItemPresentation(it) }
override fun getName() = clsDelegate.name
override fun getNameIdentifier() = lightIdentifier
@@ -92,6 +98,20 @@ sealed class KtLightFieldImpl(
override fun toString(): String = "${this.javaClass.simpleName}:$name"
override fun equals(other: Any?): Boolean =
other is KtLightField &&
name == other.name &&
lightMemberOrigin == other.lightMemberOrigin &&
containingClass == other.containingClass &&
clsDelegate == other.clsDelegate
override fun hashCode(): Int {
var result = lightMemberOrigin?.hashCode() ?: 0
result = 31 * result + clsDelegate.hashCode()
result = 31 * result + containingClass.hashCode()
return result
}
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
override fun getNavigationElement() = kotlinOrigin ?: super.getNavigationElement()
@@ -111,6 +131,7 @@ sealed class KtLightFieldImpl(
override fun copy() = Factory.create(lightMemberOrigin?.copy(), clsDelegate, containingClass)
class KtLightEnumConstant(
origin: LightMemberOrigin?,
override val clsDelegate: PsiEnumConstant,
@@ -182,4 +182,8 @@ fun accessorNameByPropertyName(name: String, accessor: KtLightMethod): String? {
JvmAbi.isSetterName(methodName) -> JvmAbi.setterName(name)
else -> null
}
}
fun getAccessorNamesCandidatesByPropertyName(name: String): List<String> {
return listOf(JvmAbi.setterName(name), JvmAbi.getterName(name))
}
@@ -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<PsiMethod>
= emptyArray()
override fun getMethodsByName(name: String, scope: GlobalSearchScope): Array<PsiMethod> {
return getMethodSequenceByName(name, scope).toList().toTypedArray()
}
override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiMethod>
= emptyArray()
fun getMethodSequenceByName(name: String, scope: GlobalSearchScope): Sequence<PsiMethod> {
val propertiesIndex = KotlinPropertyShortNameIndex.getInstance()
val functionIndex = KotlinFunctionShortNameIndex.getInstance()
override fun getFieldsByNameIfNotMoreThan(s: String, scope: GlobalSearchScope, i: Int): Array<PsiField>
= 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<PsiMethod> {
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<PsiField> {
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<PsiMethod>): Boolean
= ContainerUtil.process(getMethodsByName(name, scope), processor)
override fun getAllMethodNames(): Array<String>
= emptyArray()
override fun getAllMethodNames(): Array<String> {
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<String>) {
set.addAll(allMethodNames)
}
override fun getFieldsByName(name: String, scope: GlobalSearchScope): Array<PsiField>
= emptyArray()
fun getFieldSequenceByName(name: String, scope: GlobalSearchScope): Sequence<PsiField> {
return KotlinPropertyShortNameIndex.getInstance().get(name, project, scope).asSequence()
.map { LightClassUtil.getLightClassBackingField(it) }
.filterNotNull()
}
override fun getAllFieldNames(): Array<String>
= emptyArray()
override fun getFieldsByName(name: String, scope: GlobalSearchScope): Array<PsiField> {
return getFieldSequenceByName(name, scope).toList().toTypedArray()
}
override fun getAllFieldNames(): Array<String> {
return KotlinPropertyShortNameIndex.getInstance().getAllKeys(project).toTypedArray()
}
override fun getAllFieldNames(set: HashSet<String>) {
set.addAll(allFieldNames)
}
}
@@ -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<CallableDescriptor> {
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<String>()
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<String>()
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
@@ -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<NavigationItem>()
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)
+22
View File
@@ -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 = ""
}
+16
View File
@@ -0,0 +1,16 @@
object B1 {
@JvmField
val foobar = ""
fun method1(){}
fun methodInBoth(){}
}
object B2 {
val barfoo = ""
fun method2(){}
fun methodInBoth(){}
}
@@ -0,0 +1,7 @@
class C1 {
}
object O1 {
}
@@ -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) {
}
}
}
@@ -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 = ""
}
}
@@ -0,0 +1,17 @@
@JvmField
var topLevelVar = ""
object B1 {
@JvmField
var objectVar = ""
}
class C1 {
@JvmField
var classVar = ""
companion object {
@JvmField
var companionVar = ""
}
}
@@ -0,0 +1,27 @@
fun topLevelFunction(){
}
object B1 {
@JvmStatic
fun staticMethodOfObject() {
}
fun nonStaticMethodOfObject() {
}
}
class C1 {
fun methodOfClass() {
}
companion object {
@JvmStatic
fun staticMethodOfCompanion() {
}
fun nonStaticMethodOfCompanion() {
}
}
}
@@ -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<caret>
}
}
// 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<caret>
}
}
@@ -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<caret>();
}
}
// 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<caret>();
}
}
@@ -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<caret>();
}
}
// 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<caret>();
}
}
@@ -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<caret>("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<caret>("foobar");
}
}
@@ -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<caret>();
}
}
// 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<caret>();
}
}
@@ -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<caret>("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<caret>("foobar");
}
}
@@ -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<caret>
}
}
// 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<caret>
}
}
@@ -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<caret>();
}
}
// 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<caret>();
}
}
@@ -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<caret>();
}
}
// 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<caret>();
}
}
@@ -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<caret>("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<caret>("foobar");
}
}
@@ -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<caret>();
}
}
// 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<caret>();
}
}
@@ -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<caret>("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<caret>("foobar");
}
}
@@ -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<PsiMethod>)
= a.map { "${(it as KtLightMethod).clsDelegate.getKotlinFqName()} static=${it.hasModifierProperty(PsiModifier.STATIC)}" }.joinToString("\n")
fun accessorArrayDebugToString(a: Array<PsiMethod>)
= 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<PsiMethod>, 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<String, String> {
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<PsiMethod>, 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<PsiField>, 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<PsiField>)
= 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() + "/"
}
}
@@ -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");