Support @JvmOverloads annotation in ultra-light classes

This commit is contained in:
Denis Zharkov
2018-11-19 17:52:43 +03:00
parent 41997769e3
commit 28f20a97f8
3 changed files with 57 additions and 10 deletions
@@ -41,10 +41,7 @@ import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
import org.jetbrains.kotlin.resolve.jvm.annotations.STRICTFP_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.TRANSIENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
@@ -240,7 +237,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
for (declaration in this.classOrObject.declarations.filterNot { isHiddenByDeprecation(it) }) {
if (declaration.hasModifier(PRIVATE_KEYWORD) && isInterface) continue
when (declaration) {
is KtNamedFunction -> result.add(asJavaMethod(declaration, false))
is KtNamedFunction -> result.addAll(asJavaMethods(declaration, false))
is KtProperty -> result.addAll(propertyAccessors(declaration, declaration.isVar, false))
}
}
@@ -253,7 +250,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
this.classOrObject.companionObjects.firstOrNull()?.let { companion ->
for (declaration in companion.declarations.filterNot { isHiddenByDeprecation(it) }) {
when (declaration) {
is KtNamedFunction -> if (isJvmStatic(declaration)) result.add(asJavaMethod(declaration, true))
is KtNamedFunction -> if (isJvmStatic(declaration)) result.addAll(asJavaMethods(declaration, true))
is KtProperty -> result.addAll(propertyAccessors(declaration, declaration.isVar, true))
}
}
@@ -268,7 +265,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
result.add(defaultConstructor())
}
for (constructor in constructors.filterNot { isHiddenByDeprecation(it) }) {
result.add(asJavaMethod(constructor, false))
result.addAll(asJavaMethods(constructor, false))
}
val primary = classOrObject.primaryConstructor
if (primary != null && shouldGenerateNoArgOverload(primary)) {
@@ -314,7 +311,22 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
override fun getOwnMethods(): List<KtLightMethod> = if (tooComplex) super.getOwnMethods() else _ownMethods
private fun asJavaMethod(ktFunction: KtFunction, forceStatic: Boolean): KtLightMethod {
private fun asJavaMethods(ktFunction: KtFunction, forceStatic: Boolean): Collection<KtLightMethod> {
val basicMethod = asJavaMethod(ktFunction, forceStatic)
if (!ktFunction.hasAnnotation(JVM_OVERLOADS_FQ_NAME)) return listOf(basicMethod)
val result = mutableListOf<KtLightMethod>()
val numberOfDefaultParameters = ktFunction.valueParameters.count(KtParameter::hasDefaultValue)
for (numberOfDefaultParametersToAdd in 0 until numberOfDefaultParameters) {
result.add(asJavaMethod(ktFunction, forceStatic, numberOfDefaultParametersToAdd))
}
result.add(basicMethod)
return result
}
private fun asJavaMethod(ktFunction: KtFunction, forceStatic: Boolean, numberOfDefaultParametersToAdd: Int = -1): KtLightMethod {
val isConstructor = ktFunction is KtConstructor<*>
val name =
if (isConstructor)
@@ -324,7 +336,21 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
val method = lightMethod(name.orEmpty(), ktFunction, forceStatic)
val wrapper = KtUltraLightMethod(method, ktFunction, support, this)
addReceiverParameter(ktFunction, wrapper)
var remainingNumberOfDefaultParametersToAdd =
if (numberOfDefaultParametersToAdd >= 0)
numberOfDefaultParametersToAdd
else
// Just to avoid computing the actual number of default parameters, we use an upper bound
ktFunction.valueParameters.size
for (parameter in ktFunction.valueParameters) {
if (parameter.hasDefaultValue()) {
if (remainingNumberOfDefaultParametersToAdd == 0) continue
remainingNumberOfDefaultParametersToAdd--
}
method.addParameter(KtUltraLightParameter(parameter.name.orEmpty(), parameter, support, wrapper, null, ktFunction))
}
val returnType: PsiType? by lazyPub {
+20 -2
View File
@@ -1,6 +1,24 @@
/** should load cls */
class C @JvmOverloads constructor(
val type: String?,
val p1: Boolean = false,
val p2: String = type
)
) {
@JvmOverloads
fun foo(x: Int = 1, y: Double, z: String = "") {}
@JvmOverloads
fun bar(x: Int = 1, y: Double = 1.3, z: String = "") {}
@JvmOverloads
fun baz(x: Int = 1, y: Double = 1.3, z: String) {}
@JvmOverloads
fun foobar(x: Int, y: Double = 1.3, z: String = "") {}
@JvmOverloads
fun foobarbaz(x: Int, y: Double = 1.3, z: String) {}
companion object {
@JvmOverloads
fun foo123(x: Int = 1, y: Double, z: String = "") {}
@JvmStatic
@JvmOverloads
fun fooStatic(x: Int = 1, y: Double, z: String = "") {}
}
}
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -57,6 +58,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException
import java.util.concurrent.ConcurrentMap
@@ -116,6 +118,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
if (name == JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME.shortName()) return false
if (name == JVM_WILDCARD_ANNOTATION_FQ_NAME.shortName()) return false
if (name == JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME.shortName()) return false
if (name == JVM_OVERLOADS_FQ_NAME.shortName()) return false
return true
}