UAST: Fix getContainingFile, should return KtFile instead of FakeFileForLightClass
#KT-20170 Fixed
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
open class FakeFileForLightClass(
|
open class FakeFileForLightClass(
|
||||||
protected val ktFile: KtFile,
|
val ktFile: KtFile,
|
||||||
private val lightClass: () -> KtLightClass,
|
private val lightClass: () -> KtLightClass,
|
||||||
private val stub: () -> PsiClassHolderFileStub<*>,
|
private val stub: () -> PsiClassHolderFileStub<*>,
|
||||||
private val packageFqName: FqName = ktFile.packageFqName
|
private val packageFqName: FqName = ktFile.packageFqName
|
||||||
|
|||||||
@@ -39,15 +39,15 @@ open class KotlinUClass private constructor(
|
|||||||
|
|
||||||
override fun getOriginalElement(): PsiElement? = super.getOriginalElement()
|
override fun getOriginalElement(): PsiElement? = super.getOriginalElement()
|
||||||
|
|
||||||
override fun getNameIdentifier() = UastLightIdentifier(psi, ktClass)
|
override fun getNameIdentifier(): PsiIdentifier? = UastLightIdentifier(psi, ktClass)
|
||||||
|
|
||||||
override fun getContainingFile(): PsiFile? = ktClass?.containingFile ?: psi.containingFile
|
override fun getContainingFile(): PsiFile? = unwrapFakeFileForLightClass(psi.containingFile)
|
||||||
|
|
||||||
override val annotations: List<UAnnotation>
|
override val annotations: List<UAnnotation>
|
||||||
get() = ktClass?.annotationEntries?.map { KotlinUAnnotation(it, this) } ?: emptyList()
|
get() = ktClass?.annotationEntries?.map { KotlinUAnnotation(it, this) } ?: emptyList()
|
||||||
|
|
||||||
override val uastAnchor: UElement
|
override val uastAnchor: UElement
|
||||||
get() = UIdentifier(psi.nameIdentifier, this)
|
get() = UIdentifier(nameIdentifier, this)
|
||||||
|
|
||||||
override fun getInnerClasses(): Array<UClass> {
|
override fun getInnerClasses(): Array<UClass> {
|
||||||
// filter DefaultImpls to avoid processing same methods from original interface multiple times
|
// filter DefaultImpls to avoid processing same methods from original interface multiple times
|
||||||
@@ -123,6 +123,8 @@ class KotlinUAnonymousClass(
|
|||||||
override fun getInitializers(): Array<UClassInitializer> = super<AbstractJavaUClass>.getInitializers()
|
override fun getInitializers(): Array<UClassInitializer> = super<AbstractJavaUClass>.getInitializers()
|
||||||
override fun getInnerClasses(): Array<UClass> = super<AbstractJavaUClass>.getInnerClasses()
|
override fun getInnerClasses(): Array<UClass> = super<AbstractJavaUClass>.getInnerClasses()
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(psi.containingFile)
|
||||||
|
|
||||||
override val uastAnchor: UElement?
|
override val uastAnchor: UElement?
|
||||||
get() {
|
get() {
|
||||||
val ktClassOrObject = (psi.originalElement as? KtLightClass)?.kotlinOrigin as? KtObjectDeclaration ?: return null
|
val ktClassOrObject = (psi.originalElement as? KtLightClass)?.kotlinOrigin as? KtObjectDeclaration ?: return null
|
||||||
@@ -134,6 +136,12 @@ class KotlinScriptUClass(
|
|||||||
psi: KtLightClassForScript,
|
psi: KtLightClassForScript,
|
||||||
override val uastParent: UElement?
|
override val uastParent: UElement?
|
||||||
) : AbstractJavaUClass(), PsiClass by psi {
|
) : AbstractJavaUClass(), PsiClass by psi {
|
||||||
|
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(psi.containingFile)
|
||||||
|
|
||||||
|
override fun getNameIdentifier(): PsiIdentifier? = UastLightIdentifier(psi, psi.kotlinOrigin)
|
||||||
|
|
||||||
|
override val uastAnchor: UElement
|
||||||
|
get() = UIdentifier(nameIdentifier, this)
|
||||||
|
|
||||||
override val psi = unwrap<UClass, KtLightClassForScript>(psi)
|
override val psi = unwrap<UClass, KtLightClassForScript>(psi)
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ open class KotlinUMethod(
|
|||||||
|
|
||||||
private val kotlinOrigin = (psi.originalElement as KtLightElement<*, *>).kotlinOrigin
|
private val kotlinOrigin = (psi.originalElement as KtLightElement<*, *>).kotlinOrigin
|
||||||
|
|
||||||
override fun getContainingFile(): PsiFile? = kotlinOrigin?.containingFile ?: psi.containingFile
|
override fun getContainingFile(): PsiFile? = unwrapFakeFileForLightClass(psi.containingFile)
|
||||||
|
|
||||||
override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
|
override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ open class KotlinUMethod(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val uastAnchor: UElement
|
override val uastAnchor: UElement
|
||||||
get() = UIdentifier((psi.originalElement as? PsiNameIdentifierOwner)?.nameIdentifier ?: psi.nameIdentifier, this)
|
get() = UIdentifier(nameIdentifier, this)
|
||||||
|
|
||||||
|
|
||||||
override val uastBody by lz {
|
override val uastBody by lz {
|
||||||
|
|||||||
@@ -69,12 +69,14 @@ abstract class AbstractKotlinUVariable : PsiVariable, UVariable, KotlinUElementW
|
|||||||
return UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
|
return UastLightIdentifier(psi, kotlinOrigin as KtNamedDeclaration?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(psi.containingFile)
|
||||||
|
|
||||||
override val annotations: List<UAnnotation> by lz { psi.annotations.map { JavaUAnnotation(it, this) } }
|
override val annotations: List<UAnnotation> by lz { psi.annotations.map { JavaUAnnotation(it, this) } }
|
||||||
|
|
||||||
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
|
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
|
||||||
|
|
||||||
override val uastAnchor: UElement?
|
override val uastAnchor: UElement?
|
||||||
get() = UIdentifier(psi.nameIdentifier, this)
|
get() = UIdentifier(nameIdentifier, this)
|
||||||
|
|
||||||
override fun equals(other: Any?) = other is AbstractKotlinUVariable && psi == other.psi
|
override fun equals(other: Any?) = other is AbstractKotlinUVariable && psi == other.psi
|
||||||
|
|
||||||
@@ -91,8 +93,6 @@ class KotlinUVariable(
|
|||||||
|
|
||||||
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
|
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
|
||||||
|
|
||||||
override fun getContainingFile(): PsiFile? = (psi as? KtLightElement<*, *>)?.kotlinOrigin?.containingFile ?: psi.containingFile
|
|
||||||
|
|
||||||
override fun getInitializer(): PsiExpression? {
|
override fun getInitializer(): PsiExpression? {
|
||||||
return super<AbstractKotlinUVariable>.getInitializer()
|
return super<AbstractKotlinUVariable>.getInitializer()
|
||||||
}
|
}
|
||||||
@@ -104,6 +104,10 @@ class KotlinUVariable(
|
|||||||
override fun getNameIdentifier(): PsiIdentifier {
|
override fun getNameIdentifier(): PsiIdentifier {
|
||||||
return super.getNameIdentifier()
|
return super.getNameIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile {
|
||||||
|
return super.getContainingFile()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class KotlinUParameter(
|
open class KotlinUParameter(
|
||||||
@@ -124,6 +128,10 @@ open class KotlinUParameter(
|
|||||||
override fun getNameIdentifier(): PsiIdentifier {
|
override fun getNameIdentifier(): PsiIdentifier {
|
||||||
return super.getNameIdentifier()
|
return super.getNameIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile {
|
||||||
|
return super.getContainingFile()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class KotlinUField(
|
open class KotlinUField(
|
||||||
@@ -145,12 +153,14 @@ open class KotlinUField(
|
|||||||
return super.getNameIdentifier()
|
return super.getNameIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile {
|
||||||
|
return super.getContainingFile()
|
||||||
|
}
|
||||||
|
|
||||||
override fun isPhysical(): Boolean {
|
override fun isPhysical(): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getContainingFile(): PsiFile? = (psi as? KtLightElement<*, *>)?.kotlinOrigin?.containingFile ?: psi.containingFile
|
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitField(this)) return
|
if (visitor.visitField(this)) return
|
||||||
annotations.acceptList(visitor)
|
annotations.acceptList(visitor)
|
||||||
@@ -179,6 +189,10 @@ open class KotlinULocalVariable(
|
|||||||
return super.getNameIdentifier()
|
return super.getNameIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile {
|
||||||
|
return super.getContainingFile()
|
||||||
|
}
|
||||||
|
|
||||||
override fun accept(visitor: UastVisitor) {
|
override fun accept(visitor: UastVisitor) {
|
||||||
if (visitor.visitLocalVariable(this)) return
|
if (visitor.visitLocalVariable(this)) return
|
||||||
annotations.acceptList(visitor)
|
annotations.acceptList(visitor)
|
||||||
@@ -201,36 +215,40 @@ open class KotlinUEnumConstant(
|
|||||||
psi: PsiEnumConstant,
|
psi: PsiEnumConstant,
|
||||||
override val uastParent: UElement?
|
override val uastParent: UElement?
|
||||||
) : AbstractKotlinUVariable(), UEnumConstant, PsiEnumConstant by psi {
|
) : AbstractKotlinUVariable(), UEnumConstant, PsiEnumConstant by psi {
|
||||||
override val initializingClass: UClass? by lz { getLanguagePlugin().convertOpt<UClass>(psi.initializingClass, this) }
|
|
||||||
|
|
||||||
override val psi = unwrap<UEnumConstant, PsiEnumConstant>(psi)
|
override fun getContainingFile(): PsiFile {
|
||||||
|
return super.getContainingFile()
|
||||||
override fun getInitializer(): PsiExpression? {
|
|
||||||
return super<AbstractKotlinUVariable>.getInitializer()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOriginalElement(): PsiElement? {
|
|
||||||
return super<AbstractKotlinUVariable>.getOriginalElement()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNameIdentifier(): PsiIdentifier {
|
override fun getNameIdentifier(): PsiIdentifier {
|
||||||
return super.getNameIdentifier()
|
return super.getNameIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val initializingClass: UClass? by lz { getLanguagePlugin().convertOpt<UClass>(psi.initializingClass, this) }
|
||||||
|
|
||||||
|
override val psi = unwrap<UEnumConstant, PsiEnumConstant>(psi)
|
||||||
|
|
||||||
override val kind: UastCallKind
|
override val kind: UastCallKind
|
||||||
get() = UastCallKind.CONSTRUCTOR_CALL
|
get() = UastCallKind.CONSTRUCTOR_CALL
|
||||||
|
|
||||||
override val receiver: UExpression?
|
override val receiver: UExpression?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
override val receiverType: PsiType?
|
override val receiverType: PsiType?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
override val methodIdentifier: UIdentifier?
|
override val methodIdentifier: UIdentifier?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
override val classReference: UReferenceExpression?
|
override val classReference: UReferenceExpression?
|
||||||
get() = KotlinEnumConstantClassReference(psi, this)
|
get() = KotlinEnumConstantClassReference(psi, this)
|
||||||
|
|
||||||
override val typeArgumentCount: Int
|
override val typeArgumentCount: Int
|
||||||
get() = 0
|
get() = 0
|
||||||
|
|
||||||
override val typeArguments: List<PsiType>
|
override val typeArguments: List<PsiType>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
override val valueArgumentCount: Int
|
override val valueArgumentCount: Int
|
||||||
get() = psi.argumentList?.expressions?.size ?: 0
|
get() = psi.argumentList?.expressions?.size ?: 0
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -20,11 +20,9 @@ import com.intellij.psi.PsiFile
|
|||||||
import com.intellij.psi.PsiNameIdentifierOwner
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
|
import org.jetbrains.uast.kotlin.unwrapFakeFileForLightClass
|
||||||
|
|
||||||
class UastLightIdentifier(lightOwner: PsiNameIdentifierOwner, ktDeclaration: KtNamedDeclaration?)
|
class UastLightIdentifier(lightOwner: PsiNameIdentifierOwner, ktDeclaration: KtNamedDeclaration?)
|
||||||
: KtLightIdentifier(lightOwner, ktDeclaration) {
|
: KtLightIdentifier(lightOwner, ktDeclaration) {
|
||||||
|
override fun getContainingFile(): PsiFile = unwrapFakeFileForLightClass(super.getContainingFile())
|
||||||
override fun getContainingFile(): PsiFile {
|
|
||||||
return origin?.containingFile ?: super.getContainingFile()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.ServiceManager
|
|||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiPrimitiveType
|
import com.intellij.psi.PsiPrimitiveType
|
||||||
import com.intellij.psi.PsiType
|
import com.intellij.psi.PsiType
|
||||||
import com.intellij.psi.impl.cache.TypeInfo
|
import com.intellij.psi.impl.cache.TypeInfo
|
||||||
@@ -28,6 +29,7 @@ import com.intellij.psi.impl.compiled.SignatureParsing
|
|||||||
import com.intellij.psi.impl.compiled.StubBuildingVisitor
|
import com.intellij.psi.impl.compiled.StubBuildingVisitor
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.PsiTypesUtil
|
import com.intellij.psi.util.PsiTypesUtil
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightElements
|
import org.jetbrains.kotlin.asJava.toLightElements
|
||||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
|
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
|
||||||
@@ -36,7 +38,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -198,3 +199,5 @@ internal fun KotlinULambdaExpression.getFunctionalInterfaceType(): PsiType? {
|
|||||||
else -> psi.getExpectedType()?.getFunctionalInterfaceType(this, psi)
|
else -> psi.getExpectedType()?.getFunctionalInterfaceType(this, psi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun unwrapFakeFileForLightClass(file: PsiFile): PsiFile = (file as? FakeFileForLightClass)?.ktFile ?: file
|
||||||
|
|||||||
@@ -1,9 +1,39 @@
|
|||||||
package org.jetbrains.uast.test.kotlin
|
package org.jetbrains.uast.test.kotlin
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||||
|
import org.jetbrains.uast.UDeclaration
|
||||||
|
import org.jetbrains.uast.UElement
|
||||||
|
import org.jetbrains.uast.UFile
|
||||||
|
import org.jetbrains.uast.UIdentifier
|
||||||
import org.jetbrains.uast.test.common.RenderLogTestBase
|
import org.jetbrains.uast.test.common.RenderLogTestBase
|
||||||
|
import org.jetbrains.uast.visitor.UastVisitor
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractKotlinRenderLogTest : AbstractKotlinUastTest(), RenderLogTestBase {
|
abstract class AbstractKotlinRenderLogTest : AbstractKotlinUastTest(), RenderLogTestBase {
|
||||||
override fun getTestFile(testName: String, ext: String) =
|
override fun getTestFile(testName: String, ext: String) =
|
||||||
File(File(TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
File(File(TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
||||||
|
|
||||||
|
override fun check(testName: String, file: UFile) {
|
||||||
|
super.check(testName, file)
|
||||||
|
file.checkContainingFileForAllElements()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun UFile.checkContainingFileForAllElements() {
|
||||||
|
accept(object : UastVisitor {
|
||||||
|
override fun visitElement(node: UElement): Boolean {
|
||||||
|
if (node is PsiElement) {
|
||||||
|
node.containingFile.assertedCast<KtFile> { "containingFile should be KtFile for ${node.asLogString()}" }
|
||||||
|
}
|
||||||
|
|
||||||
|
val anchorPsi = (node as? UDeclaration)?.uastAnchor?.psi
|
||||||
|
if (anchorPsi != null) {
|
||||||
|
anchorPsi.containingFile.assertedCast<KtFile> { "uastAnchor.containingFile should be KtFile for ${node.asLogString()}" }
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user