Kotlin Uast, Refactoring: Extract toSource() function

This commit is contained in:
Yan Zhulanow
2016-03-15 20:33:37 +03:00
parent ed1e1c6a2b
commit 5c07e6de9d
6 changed files with 37 additions and 21 deletions
@@ -18,12 +18,9 @@ package org.jetbrains.kotlin.uast
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.psi.KtTypeParameter
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.uast.KotlinPsiElementStub
import org.jetbrains.kotlin.uast.orAnonymous
import org.jetbrains.uast.*
import org.jetbrains.uast.psi.PsiElementBacked
@@ -34,7 +31,7 @@ class KotlinParameterUTypeReference(
override fun resolve(context: UastContext): UClass? {
val descriptor = psi.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE_PARAMETER, psi]
?.typeConstructor?.declarationDescriptor as? ClassDescriptor ?: return null
return context.convert(DescriptorToSourceUtilsIde.getAnyDeclaration(psi.project, descriptor)) as? UClass
return context.convert(descriptor.toSource(psi)) as? UClass
}
override val nameElement: UElement?
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.uast
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isBooleanOrNullableBoolean
@@ -38,7 +37,7 @@ class KotlinUType(
override fun resolve(context: UastContext): UClass? {
val descriptor = type.constructor.declarationDescriptor ?: return null
val sourceElement = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null
val sourceElement = descriptor.toSource(project) ?: return null
return context.convert(sourceElement) as? UClass
}
@@ -19,11 +19,8 @@ package org.jetbrains.kotlin.uast
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
import org.jetbrains.kotlin.psi.KtConstructor
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.uast.*
@@ -43,7 +40,7 @@ abstract class KotlinAbstractUFunction : UFunction, PsiElementBacked {
val bindingContext = psi.analyze(BodyResolveMode.PARTIAL)
val clazz = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, psi] as? FunctionDescriptor ?: return emptyList()
return clazz.overriddenDescriptors.map {
context.convert(DescriptorToSourceUtilsIde.getAnyDeclaration(psi.getProject(), it)) as? UFunction
context.convert(it.toSource(psi)) as? UFunction
}.filterNotNull()
}
@@ -20,9 +20,9 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.uast.*
import org.jetbrains.uast.psi.PsiElementBacked
@@ -64,8 +64,16 @@ class KotlinUFunctionCallExpression(
}
override fun resolve(context: UastContext): UFunction? {
val resultingDescriptor = resolveCall()?.resultingDescriptor ?: return null
val source = DescriptorToSourceUtilsIde.getAnyDeclaration(psi.project, resultingDescriptor) ?: return null
val resolvedCall = resolveCall()
val descriptor = resolvedCall?.resultingDescriptor ?: return null
val source = descriptor.toSource(psi) ?: return null
if (descriptor is ConstructorDescriptor && descriptor.isPrimary
&& source is KtClassOrObject && source.getPrimaryConstructor() == null
&& source.getSecondaryConstructors().isEmpty()) {
return (context.convert(source) as? UClass)?.constructors?.firstOrNull()
}
return context.convert(source) as? UFunction
}
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.uast
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -50,7 +49,7 @@ class KotlinClassViaConstructorUSimpleReferenceExpression(
val resolvedCall = psi.getResolvedCall(psi.analyze(BodyResolveMode.PARTIAL))
val resultingDescriptor = resolvedCall?.resultingDescriptor as? ConstructorDescriptor ?: return null
val clazz = resultingDescriptor.containingDeclaration
val source = DescriptorToSourceUtilsIde.getAnyDeclaration(psi.project, clazz) ?: return null
val source = clazz.toSource(psi) ?: return null
return context.convert(source) as? UClass
}
}
@@ -17,6 +17,9 @@
package org.jetbrains.kotlin.uast
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.lexer.KtTokens
@@ -41,7 +44,11 @@ internal fun KtDeclaration.getVisibility() = when (visibilityModifierType()) {
internal fun KtModifierListOwner.hasModifier(modifier: UastModifier): Boolean {
if (modifier == UastModifier.STATIC) {
return this is KtObjectDeclaration || !hasModifier(KtTokens.INNER_KEYWORD)
// Object literals can't be static
if (this is KtObjectDeclaration && this.isObjectLiteral()) {
return false
}
return !hasModifier(KtTokens.INNER_KEYWORD)
}
if (modifier == UastModifier.FINAL) {
@@ -61,7 +68,7 @@ internal fun <T> runReadAction(action: () -> T): T {
internal fun KtElement?.resolveCallToUDeclaration(context: UastContext): UDeclaration? {
if (this == null) return null
val resolvedCall = this.getResolvedCall(analyze(BodyResolveMode.PARTIAL)) ?: return null
val source = DescriptorToSourceUtilsIde.getAnyDeclaration(project, resolvedCall.resultingDescriptor) ?: return null
val source = (resolvedCall.resultingDescriptor).toSource(project) ?: return null
return context.convert(source) as? UDeclaration
}
@@ -69,7 +76,7 @@ internal fun KtElement?.resolveElementToUDeclaration(context: UastContext): UDec
if (this == null) return null
val bindingContext = analyze(BodyResolveMode.PARTIAL)
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, this] ?: return null
val source = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null
val source = descriptor.toSource(project) ?: return null
return context.convert(source) as? UDeclaration
}
@@ -80,4 +87,13 @@ internal inline fun String?.orAnonymous(kind: String = ""): String {
internal fun KtAnnotated.getUastAnnotations(parent: UElement) = annotationEntries.map { KotlinUAnnotation(it, parent) }
internal fun <T> singletonListOrEmpty(element: T?) = if (element != null) listOf(element) else emptyList<T>()
internal fun <T> singletonListOrEmpty(element: T?) = if (element != null) listOf(element) else emptyList<T>()
@Suppress("NOTHING_TO_INLINE")
internal inline fun DeclarationDescriptor.toSource(element: PsiElement) = toSource(element.project)
internal fun DeclarationDescriptor.toSource(project: Project) = try {
DescriptorToSourceUtilsIde.getAnyDeclaration(project, this)
} catch (e: Exception) {
null
}