191: Uast: making KotlinUObjectLiteralExpression provide a proper referenceNameElement (KT-30534)
This commit is contained in:
@@ -121,9 +121,7 @@ class KotlinUAnnotation(
|
||||
override val uastAnchor by lazy {
|
||||
KotlinUIdentifier(
|
||||
javaPsi?.nameReferenceElement,
|
||||
annotationEntry.typeReference?.typeElement?.let {
|
||||
(it as? KtUserType)?.referenceExpression?.getReferencedNameElement() ?: it.navigationElement
|
||||
},
|
||||
annotationEntry.typeReference?.nameElement,
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
+1
-3
@@ -117,9 +117,7 @@ class KotlinUAnnotation(
|
||||
override val uastAnchor by lazy {
|
||||
KotlinUIdentifier(
|
||||
javaPsi?.nameReferenceElement,
|
||||
annotationEntry.typeReference?.typeElement?.let {
|
||||
(it as? KtUserType)?.referenceExpression?.getReferencedNameElement() ?: it.navigationElement
|
||||
},
|
||||
annotationEntry.typeReference?.nameElement,
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
|
||||
|
||||
class KotlinUObjectLiteralExpression(
|
||||
override val psi: KtObjectLiteralExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), UObjectLiteralExpression, UCallExpressionEx, DelegatedMultiResolve, KotlinUElementWithType {
|
||||
|
||||
override val declaration: UClass by lz {
|
||||
psi.objectDeclaration.toLightClass()
|
||||
?.let { getLanguagePlugin().convert<UClass>(it, this) }
|
||||
?: KotlinInvalidUClass("<invalid object code>", psi, this)
|
||||
}
|
||||
|
||||
override fun getExpressionType() = psi.objectDeclaration.toPsiType()
|
||||
|
||||
private val superClassConstructorCall by lz {
|
||||
psi.objectDeclaration.superTypeListEntries.firstOrNull { it is KtSuperTypeCallEntry } as? KtSuperTypeCallEntry
|
||||
}
|
||||
|
||||
override val classReference: UReferenceExpression? by lz { superClassConstructorCall?.let { ObjectLiteralClassReference(it, this) } }
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = superClassConstructorCall?.valueArguments?.size ?: 0
|
||||
|
||||
override val valueArguments by lz {
|
||||
val psi = superClassConstructorCall ?: return@lz emptyList<UExpression>()
|
||||
psi.valueArguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this) }
|
||||
}
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = superClassConstructorCall?.typeArguments?.size ?: 0
|
||||
|
||||
override val typeArguments by lz {
|
||||
val psi = superClassConstructorCall ?: return@lz emptyList<PsiType>()
|
||||
psi.typeArguments.map { it.typeReference.toPsiType(this, boxed = true) }
|
||||
}
|
||||
|
||||
override fun resolve() = superClassConstructorCall?.resolveCallToDeclaration() as? PsiMethod
|
||||
|
||||
override fun getArgumentForParameter(i: Int): UExpression? =
|
||||
superClassConstructorCall?.let { it.getResolvedCall(it.analyze()) }?.let { getArgumentExpressionByIndex(i, it, this) }
|
||||
|
||||
private class ObjectLiteralClassReference(
|
||||
override val psi: KtSuperTypeCallEntry,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUElement(givenParent), USimpleNameReferenceExpression {
|
||||
|
||||
override val javaPsi = null
|
||||
override val sourcePsi = psi
|
||||
|
||||
override fun resolve() = (psi.resolveCallToDeclaration() as? PsiMethod)?.containingClass
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = identifier
|
||||
|
||||
override val identifier: String
|
||||
get() = psi.name ?: referenceNameElement.sourcePsi?.text ?: "<error>"
|
||||
|
||||
override val referenceNameElement: UElement
|
||||
get() = KotlinUIdentifier(psi.typeReference?.nameElement, this)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -326,6 +326,11 @@ internal fun KtExpression.getExpectedType(): KotlinType? = analyze()[BindingCont
|
||||
|
||||
internal fun KtTypeReference.getType(): KotlinType? = analyze()[BindingContext.TYPE, this]
|
||||
|
||||
internal val KtTypeReference.nameElement: PsiElement?
|
||||
get() = this.typeElement?.let {
|
||||
(it as? KtUserType)?.referenceExpression?.getReferencedNameElement() ?: it.navigationElement
|
||||
}
|
||||
|
||||
internal fun KotlinType.getFunctionalInterfaceType(source: UElement, element: KtElement): PsiType? =
|
||||
takeIf { it.isInterface() && !it.isBuiltinFunctionalTypeOrSubtype }?.toPsiType(source, element, false)
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ runnable2 -> USimpleNameReferenceExpression (identifier = runnable2) from KtName
|
||||
run -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression
|
||||
Runnable -> USimpleNameReferenceExpression (identifier = Runnable) from KtNameReferenceExpression
|
||||
Closeable -> USimpleNameReferenceExpression (identifier = Closeable) from KtNameReferenceExpression
|
||||
InputStream -> USimpleNameReferenceExpression (identifier = InputStream) from KtObjectLiteralExpression
|
||||
InputStream -> UObjectLiteralExpression from KtNameReferenceExpression
|
||||
Runnable -> USimpleNameReferenceExpression (identifier = Runnable) from KtNameReferenceExpression
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
A -> UClass (name = A)
|
||||
str -> UParameter (name = str)
|
||||
String -> USimpleNameReferenceExpression (identifier = String)
|
||||
constructor -> UAnnotationMethod (name = A)
|
||||
i -> UParameter (name = i)
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int)
|
||||
this -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
i -> USimpleNameReferenceExpression (identifier = i)
|
||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
foo -> UAnnotationMethod (name = foo)
|
||||
a -> UParameter (name = a)
|
||||
Long -> USimpleNameReferenceExpression (identifier = Long)
|
||||
B -> UClass (name = B)
|
||||
param -> UParameter (name = param)
|
||||
String -> USimpleNameReferenceExpression (identifier = String)
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
param -> USimpleNameReferenceExpression (identifier = param)
|
||||
C -> UClass (name = C)
|
||||
A -> USimpleNameReferenceExpression (identifier = A)
|
||||
constructor -> UAnnotationMethod (name = C)
|
||||
p -> UParameter (name = p)
|
||||
String -> USimpleNameReferenceExpression (identifier = String)
|
||||
super -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
p -> USimpleNameReferenceExpression (identifier = p)
|
||||
constructor -> UAnnotationMethod (name = C)
|
||||
i -> UParameter (name = i)
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int)
|
||||
super -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
i -> USimpleNameReferenceExpression (identifier = i)
|
||||
println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0))
|
||||
foo -> UAnnotationMethod (name = foo)
|
||||
a -> UParameter (name = a)
|
||||
Long -> USimpleNameReferenceExpression (identifier = Long)
|
||||
super -> USimpleNameReferenceExpression (identifier = super)
|
||||
foo -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
a -> USimpleNameReferenceExpression (identifier = a)
|
||||
O -> UClass (name = O)
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
anon -> UField (name = anon)
|
||||
object -> UClass (name = null)
|
||||
A -> UObjectLiteralExpression
|
||||
bar -> UAnnotationMethod (name = bar)
|
||||
cons -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))
|
||||
object -> UClass (name = null)
|
||||
A -> UObjectLiteralExpression
|
||||
innerObject -> UClass (name = innerObject)
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
InnerClass -> UClass (name = InnerClass)
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1))
|
||||
cons -> UAnnotationMethod (name = cons)
|
||||
a -> UParameter (name = a)
|
||||
A -> USimpleNameReferenceExpression (identifier = A)
|
||||
@@ -0,0 +1,28 @@
|
||||
String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression
|
||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtDotQualifiedExpression
|
||||
i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression
|
||||
toString -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression
|
||||
Long -> USimpleNameReferenceExpression (identifier = Long) from KtNameReferenceExpression
|
||||
String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) from KtNameReferenceExpression
|
||||
param -> USimpleNameReferenceExpression (identifier = param) from KtNameReferenceExpression
|
||||
A -> USimpleNameReferenceExpression (identifier = A) from KtNameReferenceExpression
|
||||
String -> USimpleNameReferenceExpression (identifier = String) from KtNameReferenceExpression
|
||||
p -> USimpleNameReferenceExpression (identifier = p) from KtNameReferenceExpression
|
||||
Int -> USimpleNameReferenceExpression (identifier = Int) from KtNameReferenceExpression
|
||||
i -> USimpleNameReferenceExpression (identifier = i) from KtNameReferenceExpression
|
||||
println -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) from KtNameReferenceExpression
|
||||
Long -> USimpleNameReferenceExpression (identifier = Long) from KtNameReferenceExpression
|
||||
foo -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtDotQualifiedExpression
|
||||
foo -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression
|
||||
a -> USimpleNameReferenceExpression (identifier = a) from KtNameReferenceExpression
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) from KtNameReferenceExpression
|
||||
A -> USimpleNameReferenceExpression (identifier = A) from KtObjectLiteralExpression
|
||||
A -> UObjectLiteralExpression from KtNameReferenceExpression
|
||||
cons -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) from KtNameReferenceExpression
|
||||
A -> USimpleNameReferenceExpression (identifier = A) from KtObjectLiteralExpression
|
||||
A -> UObjectLiteralExpression from KtNameReferenceExpression
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) from KtNameReferenceExpression
|
||||
A -> UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) from KtNameReferenceExpression
|
||||
A -> USimpleNameReferenceExpression (identifier = A) from KtNameReferenceExpression
|
||||
@@ -1,13 +1,12 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.UFile
|
||||
import org.jetbrains.uast.UReferenceExpression
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.test.common.UElementToParentMap
|
||||
import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase
|
||||
import org.jetbrains.uast.test.env.assertEqualsToFile
|
||||
import org.jetbrains.uast.toUElementOfType
|
||||
import java.io.File
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
|
||||
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
||||
@@ -23,6 +22,15 @@ abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), Identif
|
||||
}
|
||||
}
|
||||
|
||||
fun UFile.asRefNames() = object : UElementToParentMap({ it.toUElementOfType<UReferenceExpression>()?.referenceNameElement }) {
|
||||
private fun refNameRetriever(psiElement: PsiElement): UElement? =
|
||||
when (val uElement = psiElement.toUElementOfExpectedTypes(UCallExpression::class.java, UReferenceExpression::class.java)) {
|
||||
is UReferenceExpression -> uElement.referenceNameElement
|
||||
is UCallExpression -> uElement.classReference?.referenceNameElement
|
||||
else -> null
|
||||
}?.also {
|
||||
assertNotNull(it.sourcePsi, "referenceNameElement should have physical source, origin = $psiElement")
|
||||
}
|
||||
|
||||
fun UFile.asRefNames() = object : UElementToParentMap(::refNameRetriever) {
|
||||
override fun renderSource(element: PsiElement): String = element.javaClass.simpleName
|
||||
}.visitUFileAndGetResult(this)
|
||||
@@ -24,4 +24,7 @@ class KotlinUastIdentifiersTest : AbstractKotlinIdentifiersTest() {
|
||||
@Test
|
||||
fun testAnonymous() = doTest("Anonymous")
|
||||
|
||||
@Test
|
||||
fun testSuperCalls() = doTest("SuperCalls")
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user