Switch to 183 platform
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
-11
@@ -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"))
|
||||
|
||||
-2
@@ -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(
|
||||
|
||||
+1
-5
@@ -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(
|
||||
+7
-1
@@ -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)
|
||||
|
||||
}
|
||||
+1
-7
@@ -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)
|
||||
|
||||
}
|
||||
+61
-5
@@ -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()
|
||||
|
||||
+5
-61
@@ -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()
|
||||
+5
-1
@@ -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)
|
||||
}
|
||||
+1
-5
@@ -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)
|
||||
}
|
||||
+4
@@ -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 {
|
||||
|
||||
-4
@@ -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 {
|
||||
+47
-2
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -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
|
||||
|
||||
|
||||
-59
@@ -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())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user