181: Uast: more implementations of UCallExpressionEx
This commit is contained in:
committed by
xiexed
parent
bd50ad87ba
commit
83573ed517
+4
-1
@@ -380,7 +380,7 @@ class KotlinUEnumConstant(
|
||||
psi: PsiEnumConstant,
|
||||
override val sourcePsi: KtElement?,
|
||||
givenParent: UElement?
|
||||
) : AbstractKotlinUVariable(givenParent), UEnumConstant, PsiEnumConstant by psi {
|
||||
) : AbstractKotlinUVariable(givenParent), UEnumConstant, UCallExpressionEx, PsiEnumConstant by psi {
|
||||
|
||||
override val initializingClass: UClass? by lz {
|
||||
(psi.initializingClass as? KtLightClass)?.let { initializingClass ->
|
||||
@@ -458,4 +458,7 @@ class KotlinUEnumConstant(
|
||||
override val identifier: String
|
||||
get() = psi.containingClass?.name ?: "<error>"
|
||||
}
|
||||
|
||||
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-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.expressions
|
||||
|
||||
import com.intellij.psi.PsiArrayType
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.KotlinAbstractUExpression
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter
|
||||
import org.jetbrains.uast.kotlin.KotlinUElementWithType
|
||||
|
||||
class KotlinUCollectionLiteralExpression(
|
||||
override val sourcePsi: KtCollectionLiteralExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), UCallExpressionEx, KotlinUElementWithType {
|
||||
|
||||
override val classReference: UReferenceExpression? get() = null
|
||||
|
||||
override val kind: UastCallKind = UastCallKind.NESTED_ARRAY_INITIALIZER
|
||||
|
||||
override val methodIdentifier: UIdentifier? by lazy { UIdentifier(sourcePsi.leftBracket, this) }
|
||||
|
||||
override val methodName: String? get() = null
|
||||
|
||||
override val receiver: UExpression? get() = null
|
||||
|
||||
override val receiverType: PsiType? get() = null
|
||||
|
||||
override val returnType: PsiType? get() = getExpressionType()
|
||||
|
||||
override val typeArgumentCount: Int get() = typeArguments.size
|
||||
|
||||
override val typeArguments: List<PsiType> get() = listOfNotNull((returnType as? PsiArrayType)?.componentType)
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = sourcePsi.getInnerExpressions().size
|
||||
|
||||
override val valueArguments by lazy {
|
||||
sourcePsi.getInnerExpressions().map { KotlinConverter.convertOrEmpty(it, this) }
|
||||
}
|
||||
|
||||
override fun asRenderString(): String = "collectionLiteral[" + valueArguments.joinToString { it.asRenderString() } + "]"
|
||||
|
||||
override fun resolve(): PsiMethod? = null
|
||||
|
||||
override val psi: PsiElement get() = sourcePsi
|
||||
|
||||
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)
|
||||
|
||||
}
|
||||
+26
-16
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -97,24 +98,9 @@ class KotlinUFunctionCallExpression(
|
||||
val resolvedCall = resolvedCall ?: return null
|
||||
val actualParamIndex = if (resolvedCall.extensionReceiver == null) i else i - 1
|
||||
if (actualParamIndex == -1) return receiver
|
||||
val (parameter, resolvedArgument) = resolvedCall.valueArguments.entries.find { it.key.index == actualParamIndex } ?: return null
|
||||
val arguments = resolvedArgument.arguments
|
||||
if (arguments.isEmpty()) return null
|
||||
if (arguments.size == 1) {
|
||||
val argument = arguments.single()
|
||||
val expression = argument.getArgumentExpression()
|
||||
if (parameter.varargElementType != null && argument.getSpreadElement() == null) {
|
||||
return createVarargsHolder(arguments, this)
|
||||
}
|
||||
return KotlinConverter.convertOrEmpty(expression, this)
|
||||
}
|
||||
return createVarargsHolder(arguments, this)
|
||||
return getArgumentExpressionByIndex(actualParamIndex, resolvedCall, this)
|
||||
}
|
||||
|
||||
private fun createVarargsHolder(arguments: List<ValueArgument>, parent: UElement?): KotlinUExpressionList =
|
||||
KotlinUExpressionList(null, UastSpecialExpressionKind.VARARGS, parent).apply {
|
||||
expressions = arguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), parent) }
|
||||
}
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = psi.typeArguments.size
|
||||
@@ -171,3 +157,27 @@ class KotlinUFunctionCallExpression(
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun getArgumentExpressionByIndex(
|
||||
actualParamIndex: Int,
|
||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||
parent: UElement
|
||||
): UExpression? {
|
||||
val (parameter, resolvedArgument) = resolvedCall.valueArguments.entries.find { it.key.index == actualParamIndex } ?: return null
|
||||
val arguments = resolvedArgument.arguments
|
||||
if (arguments.isEmpty()) return null
|
||||
if (arguments.size == 1) {
|
||||
val argument = arguments.single()
|
||||
val expression = argument.getArgumentExpression()
|
||||
if (parameter.varargElementType != null && argument.getSpreadElement() == null) {
|
||||
return createVarargsHolder(arguments, parent)
|
||||
}
|
||||
return KotlinConverter.convertOrEmpty(expression, parent)
|
||||
}
|
||||
return createVarargsHolder(arguments, parent)
|
||||
}
|
||||
|
||||
private fun createVarargsHolder(arguments: List<ValueArgument>, parent: UElement?): KotlinUExpressionList =
|
||||
KotlinUExpressionList(null, UastSpecialExpressionKind.VARARGS, parent).apply {
|
||||
expressions = arguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), parent) }
|
||||
}
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.openapi.diagnostic.Attachment
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.impl.light.LightPsiClassBuilder
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
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.*
|
||||
|
||||
class KotlinUObjectLiteralExpression(
|
||||
override val psi: KtObjectLiteralExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), UObjectLiteralExpression, UCallExpressionEx, KotlinUElementWithType {
|
||||
|
||||
override val declaration: UClass by lz {
|
||||
val lightClass: KtLightClass? = psi.objectDeclaration.toLightClass()
|
||||
if (lightClass != null) {
|
||||
getLanguagePlugin().convert<UClass>(lightClass, this)
|
||||
}
|
||||
else {
|
||||
logger.error(
|
||||
"Failed to create light class for object declaration",
|
||||
Attachment(psi.containingFile.virtualFile?.path ?: "<no path>", psi.containingFile.text))
|
||||
|
||||
getLanguagePlugin().convert(LightPsiClassBuilder(psi, "<unnamed>"), 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(this) 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(this) as? PsiMethod)?.containingClass
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = emptyList()
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = identifier
|
||||
|
||||
override val identifier: String
|
||||
get() = psi.name ?: "<error>"
|
||||
}
|
||||
|
||||
companion object {
|
||||
val logger by lz { Logger.getInstance(KotlinUObjectLiteralExpression::class.java) }
|
||||
}
|
||||
}
|
||||
@@ -25,4 +25,11 @@ class A {
|
||||
|
||||
fun String.with2Receivers(a: Int, b: Float) {}
|
||||
|
||||
}
|
||||
|
||||
open class Parent(a: String, b: Int)
|
||||
|
||||
fun objectLiteral() {
|
||||
|
||||
object : Parent(b = 1, a = "foo")
|
||||
}
|
||||
@@ -138,6 +138,13 @@ UFile (package = )
|
||||
USimpleNameReferenceExpression (identifier = with2Receivers)
|
||||
ULiteralExpression (value = 8)
|
||||
ULiteralExpression (value = 7.0)
|
||||
UAnnotationMethod (name = objectLiteral)
|
||||
UBlockExpression
|
||||
UObjectLiteralExpression
|
||||
ULiteralExpression (value = 1)
|
||||
ULiteralExpression (value = "foo")
|
||||
UClass (name = null)
|
||||
UAnnotationMethod (name = ParametersDisorderKt$objectLiteral$1)
|
||||
UClass (name = A)
|
||||
UAnnotationMethod (name = with2Receivers)
|
||||
UParameter (name = $receiver)
|
||||
@@ -148,3 +155,9 @@ UFile (package = )
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UBlockExpression
|
||||
UAnnotationMethod (name = A)
|
||||
UClass (name = Parent)
|
||||
UAnnotationMethod (name = Parent)
|
||||
UParameter (name = a)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
UParameter (name = b)
|
||||
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
|
||||
|
||||
@@ -19,6 +19,10 @@ public final class ParametersDisorderKt {
|
||||
"def".with2Receivers(8, 7.0)
|
||||
})
|
||||
}
|
||||
public static final fun objectLiteral() : void {
|
||||
anonymous object : Parent(b = 1, a = "foo")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public final class A {
|
||||
@@ -26,3 +30,7 @@ public final class A {
|
||||
}
|
||||
public fun A() = UastEmptyExpression
|
||||
}
|
||||
|
||||
public class Parent {
|
||||
public fun Parent(@org.jetbrains.annotations.NotNull a: java.lang.String, @org.jetbrains.annotations.NotNull b: int) = UastEmptyExpression
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.intellij.testFramework.UsefulTestCase
|
||||
import org.jetbrains.kotlin.asJava.toLightAnnotation
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getValueParameterList
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.uast.*
|
||||
@@ -338,6 +337,7 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
|
||||
)
|
||||
assertArguments(listOf("\"%i %i %i\"", "\"\".chunked(2).toTypedArray()"), "format(\"%i %i %i\", *\"\".chunked(2).toTypedArray())")
|
||||
assertArguments(listOf("\"def\"", "8", "7.0"), "with2Receivers(8, 7.0F)")
|
||||
assertArguments(listOf("\"foo\"", "1"), "object : Parent(b = 1, a = \"foo\")\n")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user