Switch to 183 platform

This commit is contained in:
Vyacheslav Gerasimov
2018-12-06 20:16:58 +03:00
parent 5aa0b7d2aa
commit d84c5b1608
70 changed files with 698 additions and 698 deletions
@@ -22,12 +22,16 @@ import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.resolveCandidates
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
@@ -52,4 +56,11 @@ class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService {
override fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings {
return element.languageVersionSettings
}
override fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor> {
val resolutionFacade = ktElement.getResolutionFacade()
val bindingContext = ktElement.analyze()
val call = ktElement.getCall(bindingContext) ?: return emptySequence()
return call.resolveCandidates(bindingContext, resolutionFacade).map { it.candidateDescriptor }.asSequence()
}
}
@@ -22,16 +22,12 @@ import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.resolveCandidates
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
@@ -56,11 +52,4 @@ class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService {
override fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings {
return element.languageVersionSettings
}
override fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor> {
val resolutionFacade = ktElement.getResolutionFacade()
val bindingContext = ktElement.analyze()
val call = ktElement.getCall(bindingContext) ?: return emptySequence()
return call.resolveCandidates(bindingContext, resolutionFacade).map { it.candidateDescriptor }.asSequence()
}
}
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.lexer.KtTokens
@@ -49,6 +50,7 @@ interface KotlinUastResolveProviderService {
fun getTypeMapper(element: KtElement): KotlinTypeMapper?
fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings
fun isJvmElement(psiElement: PsiElement): Boolean
fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor>
}
var PsiElement.destructuringDeclarationInitializer: Boolean? by UserDataProperty(Key.create("kotlin.uast.destructuringDeclarationInitializer"))
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.lexer.KtTokens
@@ -50,7 +49,6 @@ interface KotlinUastResolveProviderService {
fun getTypeMapper(element: KtElement): KotlinTypeMapper?
fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings
fun isJvmElement(psiElement: PsiElement): Boolean
fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor>
}
var PsiElement.destructuringDeclarationInitializer: Boolean? by UserDataProperty(Key.create("kotlin.uast.destructuringDeclarationInitializer"))
@@ -3,6 +3,7 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.asJava.toLightAnnotation
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
@@ -22,11 +23,12 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
import org.jetbrains.uast.kotlin.internal.multiResolveResults
abstract class KotlinUAnnotationBase<T : KtCallElement>(
final override val sourcePsi: T,
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UAnnotationEx, UAnchorOwner {
) : KotlinAbstractUElement(givenParent), UAnnotationEx, UAnchorOwner, UMultiResolvable {
abstract override val javaPsi: PsiAnnotation?
@@ -100,6 +102,8 @@ abstract class KotlinUAnnotationBase<T : KtCallElement>(
}
return superParent
}
override fun multiResolve(): Iterable<ResolveResult> = sourcePsi.multiResolveResults().asIterable()
}
class KotlinUAnnotation(
@@ -3,7 +3,6 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.asJava.toLightAnnotation
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
@@ -23,12 +22,11 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
import org.jetbrains.uast.kotlin.internal.multiResolveResults
abstract class KotlinUAnnotationBase<T : KtCallElement>(
final override val sourcePsi: T,
givenParent: UElement?
) : KotlinAbstractUElement(givenParent), UAnnotationEx, UAnchorOwner, UMultiResolvable {
) : KotlinAbstractUElement(givenParent), UAnnotationEx, UAnchorOwner {
abstract override val javaPsi: PsiAnnotation?
@@ -102,8 +100,6 @@ abstract class KotlinUAnnotationBase<T : KtCallElement>(
}
return superParent
}
override fun multiResolve(): Iterable<ResolveResult> = sourcePsi.multiResolveResults().asIterable()
}
class KotlinUAnnotation(
@@ -17,16 +17,19 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
import org.jetbrains.uast.UCallableReferenceExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
class KotlinUCallableReferenceExpression(
override val psi: KtCallableReferenceExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), UCallableReferenceExpression, KotlinUElementWithType {
) : KotlinAbstractUExpression(givenParent), UCallableReferenceExpression, UMultiResolvable, KotlinUElementWithType {
override val qualifierExpression: UExpression?
get() {
if (qualifierType != null) return null
@@ -46,4 +49,7 @@ class KotlinUCallableReferenceExpression(
get() = (resolve() as? PsiNamedElement)?.name
override fun resolve() = psi.callableReference.resolveCallToDeclaration(this)
override fun multiResolve(): Iterable<ResolveResult> = getResolveResultVariants(psi.callableReference)
}
@@ -17,19 +17,16 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
import org.jetbrains.uast.UCallableReferenceExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
class KotlinUCallableReferenceExpression(
override val psi: KtCallableReferenceExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), UCallableReferenceExpression, UMultiResolvable, KotlinUElementWithType {
) : KotlinAbstractUExpression(givenParent), UCallableReferenceExpression, KotlinUElementWithType {
override val qualifierExpression: UExpression?
get() {
if (qualifierType != null) return null
@@ -49,7 +46,4 @@ class KotlinUCallableReferenceExpression(
get() = (resolve() as? PsiNamedElement)?.name
override fun resolve() = psi.callableReference.resolveCallToDeclaration(this)
override fun multiResolve(): Iterable<ResolveResult> = getResolveResultVariants(psi.callableReference)
}
@@ -16,10 +16,13 @@
package org.jetbrains.uast.kotlin
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.PsiType
import com.intellij.psi.util.PsiTypesUtil
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -30,16 +33,20 @@ import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.uast.*
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
import org.jetbrains.uast.kotlin.internal.TypedResolveResult
import org.jetbrains.uast.kotlin.internal.getReferenceVariants
import org.jetbrains.uast.kotlin.internal.multiResolveResults
import org.jetbrains.uast.visitor.UastVisitor
class KotlinUFunctionCallExpression(
override val psi: KtCallElement,
givenParent: UElement?,
private val _resolvedCall: ResolvedCall<*>?
) : KotlinAbstractUExpression(givenParent), UCallExpressionEx, KotlinUElementWithType {
) : KotlinAbstractUExpression(givenParent), UCallExpressionEx, KotlinUElementWithType, UMultiResolvable {
constructor(psi: KtCallElement, uastParent: UElement?) : this(psi, uastParent, null)
@@ -80,12 +87,37 @@ class KotlinUFunctionCallExpression(
override val valueArguments by lz { psi.valueArguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this) } }
override fun getArgumentForParameter(i: Int): UExpression? {
val resolvedCall = resolvedCall ?: return null
val actualParamIndex = if (resolvedCall.extensionReceiver == null) i else i - 1
if (actualParamIndex == -1) return receiver
return getArgumentExpressionByIndex(actualParamIndex, resolvedCall, this)
val resolvedCall = resolvedCall
if (resolvedCall != null) {
val actualParamIndex = if (resolvedCall.extensionReceiver == null) i else i - 1
if (actualParamIndex == -1) return receiver
return getArgumentExpressionByIndex(actualParamIndex, resolvedCall, this)
}
val argument = valueArguments.getOrNull(i) ?: return null
val argumentType = argument.getExpressionType()
for (resolveResult in multiResolve()) {
val psiMethod = resolveResult.element as? PsiMethod ?: continue
val psiParameter = psiMethod.parameterList.parameters.getOrNull(i) ?: continue
if (argumentType == null || psiParameter.type.isAssignableFrom(argumentType))
return argument
}
return null
}
override fun getExpressionType(): PsiType? {
super<KotlinUElementWithType>.getExpressionType()?.let { return it }
for (resolveResult in multiResolve()) {
val psiMethod = resolveResult.element
when {
psiMethod.isConstructor ->
psiMethod.containingClass?.let { return PsiTypesUtil.getClassType(it) }
else ->
psiMethod.returnType?.let { return it }
}
}
return null
}
override val typeArgumentCount: Int
get() = psi.typeArguments.size
@@ -131,6 +163,30 @@ class KotlinUFunctionCallExpression(
}
private val multiResolved by lazy(fun(): Iterable<TypedResolveResult<PsiMethod>> {
val contextElement = psi
if (!Registry.`is`("kotlin.uast.multiresolve.enabled", true)) {
val calleeExpression = contextElement.calleeExpression ?: return emptyList()
return calleeExpression.multiResolveResults()
.mapNotNull { it.element.safeAs<PsiMethod>()?.let { TypedResolveResult(it) } }
.asIterable()
}
val calleeExpression = contextElement.calleeExpression as? KtReferenceExpression ?: return emptyList()
val methodName = methodName ?: calleeExpression.text ?: return emptyList()
val variants = getReferenceVariants(calleeExpression, methodName)
return variants.flatMap {
when (val source = it.toSource()) {
is KtClass -> source.toLightClass()?.constructors?.asSequence().orEmpty()
else -> resolveSource(psi, it, source)?.let { sequenceOf(it) }.orEmpty()
}
}.map { TypedResolveResult(it) }.asIterable()
})
override fun multiResolve(): Iterable<TypedResolveResult<PsiMethod>> = multiResolved
override fun resolve(): PsiMethod? {
val descriptor = resolvedCall?.resultingDescriptor ?: return null
val source = descriptor.toSource()
@@ -16,13 +16,10 @@
package org.jetbrains.uast.kotlin
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.PsiType
import com.intellij.psi.util.PsiTypesUtil
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -33,20 +30,16 @@ import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.uast.*
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
import org.jetbrains.uast.kotlin.internal.TypedResolveResult
import org.jetbrains.uast.kotlin.internal.getReferenceVariants
import org.jetbrains.uast.kotlin.internal.multiResolveResults
import org.jetbrains.uast.visitor.UastVisitor
class KotlinUFunctionCallExpression(
override val psi: KtCallElement,
givenParent: UElement?,
private val _resolvedCall: ResolvedCall<*>?
) : KotlinAbstractUExpression(givenParent), UCallExpressionEx, KotlinUElementWithType, UMultiResolvable {
) : KotlinAbstractUExpression(givenParent), UCallExpressionEx, KotlinUElementWithType {
constructor(psi: KtCallElement, uastParent: UElement?) : this(psi, uastParent, null)
@@ -87,37 +80,12 @@ class KotlinUFunctionCallExpression(
override val valueArguments by lz { psi.valueArguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this) } }
override fun getArgumentForParameter(i: Int): UExpression? {
val resolvedCall = resolvedCall
if (resolvedCall != null) {
val actualParamIndex = if (resolvedCall.extensionReceiver == null) i else i - 1
if (actualParamIndex == -1) return receiver
return getArgumentExpressionByIndex(actualParamIndex, resolvedCall, this)
}
val argument = valueArguments.getOrNull(i) ?: return null
val argumentType = argument.getExpressionType()
for (resolveResult in multiResolve()) {
val psiMethod = resolveResult.element as? PsiMethod ?: continue
val psiParameter = psiMethod.parameterList.parameters.getOrNull(i) ?: continue
if (argumentType == null || psiParameter.type.isAssignableFrom(argumentType))
return argument
}
return null
val resolvedCall = resolvedCall ?: return null
val actualParamIndex = if (resolvedCall.extensionReceiver == null) i else i - 1
if (actualParamIndex == -1) return receiver
return getArgumentExpressionByIndex(actualParamIndex, resolvedCall, this)
}
override fun getExpressionType(): PsiType? {
super<KotlinUElementWithType>.getExpressionType()?.let { return it }
for (resolveResult in multiResolve()) {
val psiMethod = resolveResult.element
when {
psiMethod.isConstructor ->
psiMethod.containingClass?.let { return PsiTypesUtil.getClassType(it) }
else ->
psiMethod.returnType?.let { return it }
}
}
return null
}
override val typeArgumentCount: Int
get() = psi.typeArguments.size
@@ -163,30 +131,6 @@ class KotlinUFunctionCallExpression(
}
private val multiResolved by lazy(fun(): Iterable<TypedResolveResult<PsiMethod>> {
val contextElement = psi
if (!Registry.`is`("kotlin.uast.multiresolve.enabled", true)) {
val calleeExpression = contextElement.calleeExpression ?: return emptyList()
return calleeExpression.multiResolveResults()
.mapNotNull { it.element.safeAs<PsiMethod>()?.let { TypedResolveResult(it) } }
.asIterable()
}
val calleeExpression = contextElement.calleeExpression as? KtReferenceExpression ?: return emptyList()
val methodName = methodName ?: calleeExpression.text ?: return emptyList()
val variants = getReferenceVariants(calleeExpression, methodName)
return variants.flatMap {
when (val source = it.toSource()) {
is KtClass -> source.toLightClass()?.constructors?.asSequence().orEmpty()
else -> resolveSource(psi, it, source)?.let { sequenceOf(it) }.orEmpty()
}
}.map { TypedResolveResult(it) }.asIterable()
})
override fun multiResolve(): Iterable<TypedResolveResult<PsiMethod>> = multiResolved
override fun resolve(): PsiMethod? {
val descriptor = resolvedCall?.resultingDescriptor ?: return null
val source = descriptor.toSource()
@@ -17,14 +17,17 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
class KotlinUSafeQualifiedExpression(
override val psi: KtSafeQualifiedExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), UQualifiedReferenceExpression,
) : KotlinAbstractUExpression(givenParent), UQualifiedReferenceExpression, UMultiResolvable,
KotlinUElementWithType, KotlinEvaluatableUElement {
override val receiver by lz { KotlinConverter.convertOrEmpty(psi.receiverExpression, this) }
override val selector by lz { KotlinConverter.convertOrEmpty(psi.selectorExpression, this) }
@@ -34,4 +37,5 @@ class KotlinUSafeQualifiedExpression(
get() = (resolve() as? PsiNamedElement)?.name
override fun resolve() = psi.selectorExpression?.resolveCallToDeclaration(this)
override fun multiResolve(): Iterable<ResolveResult> = getResolveResultVariants(psi.selectorExpression)
}
@@ -17,17 +17,14 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
class KotlinUSafeQualifiedExpression(
override val psi: KtSafeQualifiedExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), UQualifiedReferenceExpression, UMultiResolvable,
) : KotlinAbstractUExpression(givenParent), UQualifiedReferenceExpression,
KotlinUElementWithType, KotlinEvaluatableUElement {
override val receiver by lz { KotlinConverter.convertOrEmpty(psi.receiverExpression, this) }
override val selector by lz { KotlinConverter.convertOrEmpty(psi.selectorExpression, this) }
@@ -37,5 +34,4 @@ class KotlinUSafeQualifiedExpression(
get() = (resolve() as? PsiNamedElement)?.name
override fun resolve() = psi.selectorExpression?.resolveCallToDeclaration(this)
override fun multiResolve(): Iterable<ResolveResult> = getResolveResultVariants(psi.selectorExpression)
}
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.container.ComponentProvider
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtElement
@@ -40,6 +41,9 @@ class CliKotlinUastResolveProviderService : KotlinUastResolveProviderService {
override fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings {
return element.project.analysisCompletedHandler?.getLanguageVersionSettings() ?: LanguageVersionSettingsImpl.DEFAULT
}
override fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor> =
emptySequence() // Not supported
}
class UastAnalysisHandlerExtension : AnalysisHandlerExtension {
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.container.ComponentProvider
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtElement
@@ -41,9 +40,6 @@ class CliKotlinUastResolveProviderService : KotlinUastResolveProviderService {
override fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings {
return element.project.analysisCompletedHandler?.getLanguageVersionSettings() ?: LanguageVersionSettingsImpl.DEFAULT
}
override fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor> =
emptySequence() // Not supported
}
class UastAnalysisHandlerExtension : AnalysisHandlerExtension {
@@ -5,10 +5,55 @@
package org.jetbrains.uast.kotlin.internal
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPolyVariantReference
import com.intellij.psi.PsiSubstitutor
import com.intellij.psi.ResolveResult
import com.intellij.psi.infos.CandidateInfo
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.UResolvable
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
import org.jetbrains.uast.kotlin.getMaybeLightElement
import org.jetbrains.uast.kotlin.toSource
//Dummy holder until idea 183
interface DelegatedMultiResolve : UResolvable
internal fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor> =
ServiceManager.getService(ktElement.project, KotlinUastResolveProviderService::class.java).getReferenceVariants(ktElement, nameHint)
internal fun UElement.getResolveResultVariants(ktExpression: KtExpression?): Iterable<ResolveResult> {
ktExpression ?: return emptyList()
if (!Registry.`is`("kotlin.uast.multiresolve.enabled", true)) return ktExpression.multiResolveResults().asIterable()
val referenceVariants = getReferenceVariants(ktExpression, ktExpression.name ?: ktExpression.text)
fun asCandidateInfo(descriptor: DeclarationDescriptor): CandidateInfo? =
descriptor.toSource()?.getMaybeLightElement(this)?.let { CandidateInfo(it, PsiSubstitutor.EMPTY) }
return referenceVariants.mapNotNull(::asCandidateInfo).asIterable()
}
internal fun KtElement.multiResolveResults(): Sequence<ResolveResult> =
references.asSequence().flatMap { ref ->
when (ref) {
is PsiPolyVariantReference -> ref.multiResolve(false).asSequence()
else -> (ref.resolve()?.let { sequenceOf(CandidateInfo(it, PsiSubstitutor.EMPTY)) }).orEmpty()
}
}
interface DelegatedMultiResolve : UMultiResolvable, UResolvable {
override fun multiResolve(): Iterable<ResolveResult> = listOfNotNull(resolve()?.let { CandidateInfo(it, PsiSubstitutor.EMPTY) })
}
class TypedResolveResult<T : PsiElement>(element: T) : CandidateInfo(element, PsiSubstitutor.EMPTY) {
@Suppress("UNCHECKED_CAST")
override fun getElement(): T = super.getElement() as T
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.uast.kotlin.internal
import org.jetbrains.uast.UResolvable
//Dummy holder until idea 183
interface DelegatedMultiResolve : UResolvable
@@ -1,59 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.uast.kotlin.internal
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPolyVariantReference
import com.intellij.psi.PsiSubstitutor
import com.intellij.psi.ResolveResult
import com.intellij.psi.infos.CandidateInfo
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.UResolvable
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
import org.jetbrains.uast.kotlin.getMaybeLightElement
import org.jetbrains.uast.kotlin.toSource
internal fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence<DeclarationDescriptor> =
ServiceManager.getService(ktElement.project, KotlinUastResolveProviderService::class.java).getReferenceVariants(ktElement, nameHint)
internal fun UElement.getResolveResultVariants(ktExpression: KtExpression?): Iterable<ResolveResult> {
ktExpression ?: return emptyList()
if (!Registry.`is`("kotlin.uast.multiresolve.enabled", true)) return ktExpression.multiResolveResults().asIterable()
val referenceVariants = getReferenceVariants(ktExpression, ktExpression.name ?: ktExpression.text)
fun asCandidateInfo(descriptor: DeclarationDescriptor): CandidateInfo? =
descriptor.toSource()?.getMaybeLightElement(this)?.let { CandidateInfo(it, PsiSubstitutor.EMPTY) }
return referenceVariants.mapNotNull(::asCandidateInfo).asIterable()
}
internal fun KtElement.multiResolveResults(): Sequence<ResolveResult> =
references.asSequence().flatMap { ref ->
when (ref) {
is PsiPolyVariantReference -> ref.multiResolve(false).asSequence()
else -> (ref.resolve()?.let { sequenceOf(CandidateInfo(it, PsiSubstitutor.EMPTY)) }).orEmpty()
}
}
interface DelegatedMultiResolve : UMultiResolvable, UResolvable {
override fun multiResolve(): Iterable<ResolveResult> = listOfNotNull(resolve()?.let { CandidateInfo(it, PsiSubstitutor.EMPTY) })
}
class TypedResolveResult<T : PsiElement>(element: T) : CandidateInfo(element, PsiSubstitutor.EMPTY) {
@Suppress("UNCHECKED_CAST")
override fun getElement(): T = super.getElement() as T
}
@@ -5,19 +5,32 @@
package org.jetbrains.uast.test.kotlin
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiClassType
import com.intellij.psi.PsiType
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.getContainingUMethod
import org.jetbrains.uast.kotlin.KotlinUFunctionCallExpression
import org.jetbrains.uast.test.env.findElementByText
import org.jetbrains.uast.test.env.findElementByTextFromPsi
import org.jetbrains.uast.test.env.findUElementByTextFromPsi
import org.jetbrains.uast.toUElement
class KotlinUastResolveApiTest : KotlinLightCodeInsightFixtureTestCase() {
override fun getProjectDescriptor(): LightProjectDescriptor =
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
override fun setUp() {
super.setUp()
Registry.get("kotlin.uast.multiresolve.enabled").setValue(true, testRootDisposable)
}
fun testResolveStringFromUast() {
val file = myFixture.addFileToProject(
"s.kt", """fun foo(){
@@ -31,4 +44,250 @@ class KotlinUastResolveApiTest : KotlinLightCodeInsightFixtureTestCase() {
TestCase.assertNotNull((refs.receiver.getExpressionType() as PsiClassType).resolve())
}
fun testMultiResolve() {
val file = myFixture.configureByText(
"s.kt", """
fun foo(): Int = TODO()
fun foo(a: Int): Int = TODO()
fun foo(a: Int, b: Int): Int = TODO()
fun main(args: Array<String>) {
foo(1<caret>
}"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall =
main.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"fun foo(): Int = TODO()",
"fun foo(a: Int): Int = TODO()",
"fun foo(a: Int, b: Int): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("1")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveJava() {
val file = myFixture.configureByText(
"s.kt", """
fun main(args: Array<String>) {
System.out.print(""
}
"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall = main.findElementByText<UElement>("print").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"public void print(char c) { /* compiled code */ }",
"public void print(int i) { /* compiled code */ }",
"public void print(long l) { /* compiled code */ }",
"public void print(float f) { /* compiled code */ }",
"public void print(double d) { /* compiled code */ }",
"public void print(char[] s) { /* compiled code */ }",
"public void print(java.lang.String s) { /* compiled code */ }",
"public void print(java.lang.Object obj) { /* compiled code */ }"
)
TestCase.assertEquals(PsiType.VOID, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("\"\"")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveJavaAmbiguous() {
myFixture.addClass(
"""
public class JavaClass {
public void setParameter(String name, int value){}
public void setParameter(String name, double value){}
public void setParameter(String name, String value){}
}
"""
)
val file = myFixture.configureByText(
"s.kt", """
fun main(args: Array<String>) {
JavaClass().setParameter(""
}
"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall = main.findElementByText<UElement>("setParameter").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"public void setParameter(String name, int value){}",
"public void setParameter(String name, double value){}",
"public void setParameter(String name, String value){}"
)
TestCase.assertEquals(PsiType.VOID, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("\"\"")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveInClass() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass {
fun foo(): Int = TODO()
fun foo(a: Int): Int = TODO()
fun foo(a: Int, b: Int): Int = TODO()
}
fun foo(string: String) = TODO()
fun main(args: Array<String>) {
MyClass().foo(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"fun foo(): Int = TODO()",
"fun foo(a: Int): Int = TODO()",
"fun foo(a: Int, b: Int): Int = TODO()"
)
assertDoesntContain(resolvedDeclarationsStrings, "fun foo(string: String) = TODO()")
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
fun testMultiConstructorResolve() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass(int: Int) {
constructor(int: Int, int1: Int) : this(int + int1)
fun foo(): Int = TODO()
}
fun MyClass(string: String): MyClass = MyClass(1)
fun main(args: Array<String>) {
MyClass(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("MyClass").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"(int: Int)",
"constructor(int: Int, int1: Int) : this(int + int1)",
"fun MyClass(string: String): MyClass = MyClass(1)"
)
assertDoesntContain(resolvedDeclarationsStrings, "fun foo(): Int = TODO()")
TestCase.assertEquals(PsiType.getTypeByName("MyClass", project, file.resolveScope), functionCall.getExpressionType())
}
fun testMultiInvokableObjectResolve() {
val file = myFixture.configureByText(
"s.kt", """
object Foo {
operator fun invoke(i: Int): Int = TODO()
operator fun invoke(i1: Int, i2: Int): Int = TODO()
operator fun invoke(i1: Int, i2: Int, i3: Int): Int = TODO()
}
fun main(args: Array<String>) {
Foo(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("Foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"operator fun invoke(i: Int): Int = TODO()",
"operator fun invoke(i1: Int, i2: Int): Int = TODO()",
"operator fun invoke(i1: Int, i2: Int, i3: Int): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
fun testMultiResolveJvmOverloads() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass {
@JvmOverloads
fun foo(i1: Int = 1, i2: Int = 2): Int = TODO()
}
fun main(args: Array<String>) {
MyClass().foo(
}"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"@JvmOverloads\n fun foo(i1: Int = 1, i2: Int = 2): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.uast.test.kotlin
import com.intellij.psi.PsiClassType
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.test.env.findUElementByTextFromPsi
class KotlinUastResolveApiTest : KotlinLightCodeInsightFixtureTestCase() {
override fun getProjectDescriptor(): LightProjectDescriptor =
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
fun testResolveStringFromUast() {
val file = myFixture.addFileToProject(
"s.kt", """fun foo(){
val s = "abc"
s.toUpperCase()
}
""${'"'}"""
)
val refs = file.findUElementByTextFromPsi<UQualifiedReferenceExpression>("s.toUpperCase()")
TestCase.assertNotNull((refs.receiver.getExpressionType() as PsiClassType).resolve())
}
}
@@ -1,293 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.uast.test.kotlin
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiClassType
import com.intellij.psi.PsiType
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.getContainingUMethod
import org.jetbrains.uast.kotlin.KotlinUFunctionCallExpression
import org.jetbrains.uast.test.env.findElementByText
import org.jetbrains.uast.test.env.findElementByTextFromPsi
import org.jetbrains.uast.test.env.findUElementByTextFromPsi
import org.jetbrains.uast.toUElement
class KotlinUastResolveApiTest : KotlinLightCodeInsightFixtureTestCase() {
override fun getProjectDescriptor(): LightProjectDescriptor =
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
override fun setUp() {
super.setUp()
Registry.get("kotlin.uast.multiresolve.enabled").setValue(true, testRootDisposable)
}
fun testResolveStringFromUast() {
val file = myFixture.addFileToProject(
"s.kt", """fun foo(){
val s = "abc"
s.toUpperCase()
}
""${'"'}"""
)
val refs = file.findUElementByTextFromPsi<UQualifiedReferenceExpression>("s.toUpperCase()")
TestCase.assertNotNull((refs.receiver.getExpressionType() as PsiClassType).resolve())
}
fun testMultiResolve() {
val file = myFixture.configureByText(
"s.kt", """
fun foo(): Int = TODO()
fun foo(a: Int): Int = TODO()
fun foo(a: Int, b: Int): Int = TODO()
fun main(args: Array<String>) {
foo(1<caret>
}"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall =
main.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"fun foo(): Int = TODO()",
"fun foo(a: Int): Int = TODO()",
"fun foo(a: Int, b: Int): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("1")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveJava() {
val file = myFixture.configureByText(
"s.kt", """
fun main(args: Array<String>) {
System.out.print(""
}
"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall = main.findElementByText<UElement>("print").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"public void print(char c) { /* compiled code */ }",
"public void print(int i) { /* compiled code */ }",
"public void print(long l) { /* compiled code */ }",
"public void print(float f) { /* compiled code */ }",
"public void print(double d) { /* compiled code */ }",
"public void print(char[] s) { /* compiled code */ }",
"public void print(java.lang.String s) { /* compiled code */ }",
"public void print(java.lang.Object obj) { /* compiled code */ }"
)
TestCase.assertEquals(PsiType.VOID, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("\"\"")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveJavaAmbiguous() {
myFixture.addClass(
"""
public class JavaClass {
public void setParameter(String name, int value){}
public void setParameter(String name, double value){}
public void setParameter(String name, String value){}
}
"""
)
val file = myFixture.configureByText(
"s.kt", """
fun main(args: Array<String>) {
JavaClass().setParameter(""
}
"""
)
val main = file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
val functionCall = main.findElementByText<UElement>("setParameter").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"public void setParameter(String name, int value){}",
"public void setParameter(String name, double value){}",
"public void setParameter(String name, String value){}"
)
TestCase.assertEquals(PsiType.VOID, functionCall.getExpressionType())
val firstArgument = main.findElementByText<UElement>("\"\"")
val firstParameter = functionCall.getArgumentForParameter(0)
TestCase.assertEquals(firstArgument, firstParameter)
}
fun testMultiResolveInClass() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass {
fun foo(): Int = TODO()
fun foo(a: Int): Int = TODO()
fun foo(a: Int, b: Int): Int = TODO()
}
fun foo(string: String) = TODO()
fun main(args: Array<String>) {
MyClass().foo(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"fun foo(): Int = TODO()",
"fun foo(a: Int): Int = TODO()",
"fun foo(a: Int, b: Int): Int = TODO()"
)
assertDoesntContain(resolvedDeclarationsStrings, "fun foo(string: String) = TODO()")
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
fun testMultiConstructorResolve() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass(int: Int) {
constructor(int: Int, int1: Int) : this(int + int1)
fun foo(): Int = TODO()
}
fun MyClass(string: String): MyClass = MyClass(1)
fun main(args: Array<String>) {
MyClass(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("MyClass").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"(int: Int)",
"constructor(int: Int, int1: Int) : this(int + int1)",
"fun MyClass(string: String): MyClass = MyClass(1)"
)
assertDoesntContain(resolvedDeclarationsStrings, "fun foo(): Int = TODO()")
TestCase.assertEquals(PsiType.getTypeByName("MyClass", project, file.resolveScope), functionCall.getExpressionType())
}
fun testMultiInvokableObjectResolve() {
val file = myFixture.configureByText(
"s.kt", """
object Foo {
operator fun invoke(i: Int): Int = TODO()
operator fun invoke(i1: Int, i2: Int): Int = TODO()
operator fun invoke(i1: Int, i2: Int, i3: Int): Int = TODO()
}
fun main(args: Array<String>) {
Foo(
}
"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("Foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"operator fun invoke(i: Int): Int = TODO()",
"operator fun invoke(i1: Int, i2: Int): Int = TODO()",
"operator fun invoke(i1: Int, i2: Int, i3: Int): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
fun testMultiResolveJvmOverloads() {
val file = myFixture.configureByText(
"s.kt", """
class MyClass {
@JvmOverloads
fun foo(i1: Int = 1, i2: Int = 2): Int = TODO()
}
fun main(args: Array<String>) {
MyClass().foo(
}"""
)
val functionCall =
file.toUElement()!!.findElementByTextFromPsi<UElement>("main").getContainingUMethod()!!
.findElementByText<UElement>("foo").uastParent as KotlinUFunctionCallExpression
val resolvedDeclaration = functionCall.multiResolve()
val resolvedDeclarationsStrings = resolvedDeclaration.map { it.element.text ?: "<null>" }
assertContainsElements(
resolvedDeclarationsStrings,
"@JvmOverloads\n fun foo(i1: Int = 1, i2: Int = 2): Int = TODO()"
)
TestCase.assertEquals(PsiType.INT, functionCall.getExpressionType())
}
}