Uast: support for Kotlin array literals
This commit is contained in:
@@ -323,8 +323,20 @@ internal object KotlinConverter {
|
|||||||
}
|
}
|
||||||
is KtImportDirective -> el<UImportStatement>(build(::KotlinUImportStatement))
|
is KtImportDirective -> el<UImportStatement>(build(::KotlinUImportStatement))
|
||||||
else -> {
|
else -> {
|
||||||
if (element is LeafPsiElement && element.elementType == KtTokens.IDENTIFIER) {
|
if (element is LeafPsiElement) {
|
||||||
|
if (element.elementType == KtTokens.IDENTIFIER)
|
||||||
el<UIdentifier>(build(::UIdentifier))
|
el<UIdentifier>(build(::UIdentifier))
|
||||||
|
else if (element.elementType == KtTokens.LBRACKET && element.parent is KtCollectionLiteralExpression)
|
||||||
|
el<UIdentifier> {
|
||||||
|
UIdentifier(
|
||||||
|
element,
|
||||||
|
KotlinUCollectionLiteralExpression(
|
||||||
|
element.parent as KtCollectionLiteralExpression,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else null
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@@ -395,6 +407,7 @@ internal object KotlinConverter {
|
|||||||
is KtSafeQualifiedExpression -> expr<UQualifiedReferenceExpression>(build(::KotlinUSafeQualifiedExpression))
|
is KtSafeQualifiedExpression -> expr<UQualifiedReferenceExpression>(build(::KotlinUSafeQualifiedExpression))
|
||||||
is KtSimpleNameExpression -> expr<USimpleNameReferenceExpression>(build(::KotlinUSimpleReferenceExpression))
|
is KtSimpleNameExpression -> expr<USimpleNameReferenceExpression>(build(::KotlinUSimpleReferenceExpression))
|
||||||
is KtCallExpression -> expr<UCallExpression>(build(::KotlinUFunctionCallExpression))
|
is KtCallExpression -> expr<UCallExpression>(build(::KotlinUFunctionCallExpression))
|
||||||
|
is KtCollectionLiteralExpression -> expr<UCallExpression>(build(::KotlinUCollectionLiteralExpression))
|
||||||
is KtBinaryExpression -> {
|
is KtBinaryExpression -> {
|
||||||
if (expression.operationToken == KtTokens.ELVIS) {
|
if (expression.operationToken == KtTokens.ELVIS) {
|
||||||
expr<UExpressionList>(build(::createElvisExpression))
|
expr<UExpressionList>(build(::createElvisExpression))
|
||||||
|
|||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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), UCallExpression, 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
|
||||||
|
|
||||||
|
}
|
||||||
+9
-1
@@ -3,6 +3,8 @@ annotation class IntRange(val from: Long, val to: Long)
|
|||||||
|
|
||||||
annotation class RequiresPermission(val anyOf: IntArray)
|
annotation class RequiresPermission(val anyOf: IntArray)
|
||||||
|
|
||||||
|
annotation class RequiresStrPermission(val strs: Array<String>)
|
||||||
|
|
||||||
annotation class WithDefaultValue(val value: Int = 42)
|
annotation class WithDefaultValue(val value: Int = 42)
|
||||||
|
|
||||||
annotation class SuppressLint(vararg val value: String)
|
annotation class SuppressLint(vararg val value: String)
|
||||||
@@ -15,4 +17,10 @@ fun foo(): Int = 5
|
|||||||
|
|
||||||
@IntRange(0, 100)
|
@IntRange(0, 100)
|
||||||
@SuppressLint("Lorem", "Ipsum", "Dolor")
|
@SuppressLint("Lorem", "Ipsum", "Dolor")
|
||||||
fun bar() = Unit
|
fun bar() = Unit
|
||||||
|
|
||||||
|
@RequiresPermission(anyOf = [1, 2, 3])
|
||||||
|
fun fooWithArrLiteral(): Int = 5
|
||||||
|
|
||||||
|
@RequiresStrPermission(strs = ["a", "b", "c"])
|
||||||
|
fun fooWithStrArrLiteral(): Int = 3
|
||||||
@@ -32,11 +32,31 @@ UFile (package = )
|
|||||||
ULiteralExpression (value = "Ipsum")
|
ULiteralExpression (value = "Ipsum")
|
||||||
ULiteralExpression (value = "Dolor")
|
ULiteralExpression (value = "Dolor")
|
||||||
USimpleNameReferenceExpression (identifier = Unit)
|
USimpleNameReferenceExpression (identifier = Unit)
|
||||||
|
UAnnotationMethod (name = fooWithArrLiteral)
|
||||||
|
UAnnotation (fqName = RequiresPermission)
|
||||||
|
UNamedExpression (name = anyOf)
|
||||||
|
UCallExpression (kind = UastCallKind(name='array_initializer'), argCount = 3))
|
||||||
|
UIdentifier (Identifier ([))
|
||||||
|
ULiteralExpression (value = 1)
|
||||||
|
ULiteralExpression (value = 2)
|
||||||
|
ULiteralExpression (value = 3)
|
||||||
|
ULiteralExpression (value = 5)
|
||||||
|
UAnnotationMethod (name = fooWithStrArrLiteral)
|
||||||
|
UAnnotation (fqName = RequiresStrPermission)
|
||||||
|
UNamedExpression (name = strs)
|
||||||
|
UCallExpression (kind = UastCallKind(name='array_initializer'), argCount = 3))
|
||||||
|
UIdentifier (Identifier ([))
|
||||||
|
ULiteralExpression (value = "a")
|
||||||
|
ULiteralExpression (value = "b")
|
||||||
|
ULiteralExpression (value = "c")
|
||||||
|
ULiteralExpression (value = 3)
|
||||||
UClass (name = IntRange)
|
UClass (name = IntRange)
|
||||||
UAnnotationMethod (name = from)
|
UAnnotationMethod (name = from)
|
||||||
UAnnotationMethod (name = to)
|
UAnnotationMethod (name = to)
|
||||||
UClass (name = RequiresPermission)
|
UClass (name = RequiresPermission)
|
||||||
UAnnotationMethod (name = anyOf)
|
UAnnotationMethod (name = anyOf)
|
||||||
|
UClass (name = RequiresStrPermission)
|
||||||
|
UAnnotationMethod (name = strs)
|
||||||
UClass (name = WithDefaultValue)
|
UClass (name = WithDefaultValue)
|
||||||
UAnnotationMethod (name = value)
|
UAnnotationMethod (name = value)
|
||||||
ULiteralExpression (value = 42)
|
ULiteralExpression (value = 42)
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ public final class AnnotationParametersKt {
|
|||||||
@IntRange(from = 0, to = 100)
|
@IntRange(from = 0, to = 100)
|
||||||
@SuppressLint(value = <noref>("Lorem", "Ipsum", "Dolor"))
|
@SuppressLint(value = <noref>("Lorem", "Ipsum", "Dolor"))
|
||||||
public static final fun bar() : void = Unit
|
public static final fun bar() : void = Unit
|
||||||
|
@RequiresPermission(anyOf = collectionLiteral[1, 2, 3])
|
||||||
|
public static final fun fooWithArrLiteral() : int = 5
|
||||||
|
@RequiresStrPermission(strs = collectionLiteral["a", "b", "c"])
|
||||||
|
public static final fun fooWithStrArrLiteral() : int = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract annotation IntRange {
|
public abstract annotation IntRange {
|
||||||
@@ -18,6 +22,10 @@ public abstract annotation RequiresPermission {
|
|||||||
public abstract fun anyOf() : int[] = UastEmptyExpression
|
public abstract fun anyOf() : int[] = UastEmptyExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract annotation RequiresStrPermission {
|
||||||
|
public abstract fun strs() : java.lang.String[] = UastEmptyExpression
|
||||||
|
}
|
||||||
|
|
||||||
public abstract annotation WithDefaultValue {
|
public abstract annotation WithDefaultValue {
|
||||||
public abstract fun value() : int = UastEmptyExpression
|
public abstract fun value() : int = UastEmptyExpression
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.jetbrains.uast.test.kotlin
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiRecursiveElementVisitor
|
import com.intellij.psi.PsiRecursiveElementVisitor
|
||||||
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||||
@@ -108,7 +109,9 @@ abstract class AbstractKotlinRenderLogTest : AbstractKotlinUastTest(), RenderLog
|
|||||||
|
|
||||||
jvmDeclaration.sourcePsi?.let {
|
jvmDeclaration.sourcePsi?.let {
|
||||||
assertTrue("sourcePsi should be physical but ${it.javaClass} found for [${it.text}] " +
|
assertTrue("sourcePsi should be physical but ${it.javaClass} found for [${it.text}] " +
|
||||||
"for ${jvmDeclaration.javaClass}->${jvmDeclaration.uastParent?.javaClass}", it is KtElement)
|
"for ${jvmDeclaration.javaClass}->${jvmDeclaration.uastParent?.javaClass}",
|
||||||
|
it is KtElement || it is LeafPsiElement
|
||||||
|
)
|
||||||
}
|
}
|
||||||
jvmDeclaration.javaPsi?.let {
|
jvmDeclaration.javaPsi?.let {
|
||||||
assertTrue("javaPsi should be light but ${it.javaClass} found for [${it.text}] " +
|
assertTrue("javaPsi should be light but ${it.javaClass} found for [${it.text}] " +
|
||||||
|
|||||||
@@ -257,6 +257,24 @@ class KotlinUastApiTest : AbstractKotlinUastTest() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testLiteralArraysTypes() {
|
||||||
|
doTest("AnnotationParameters") { _, file ->
|
||||||
|
file.findElementByTextFromPsi<UCallExpression>("intArrayOf(1, 2, 3)").let { field ->
|
||||||
|
Assert.assertEquals("PsiType:int[]", field.returnType.toString())
|
||||||
|
}
|
||||||
|
file.findElementByTextFromPsi<UCallExpression>("[1, 2, 3]").let { field ->
|
||||||
|
Assert.assertEquals("PsiType:int[]", field.returnType.toString())
|
||||||
|
Assert.assertEquals("PsiType:int", field.typeArguments.single().toString())
|
||||||
|
}
|
||||||
|
file.findElementByTextFromPsi<UCallExpression>("[\"a\", \"b\", \"c\"]").let { field ->
|
||||||
|
Assert.assertEquals("PsiType:String[]", field.returnType.toString())
|
||||||
|
Assert.assertEquals("PsiType:String", field.typeArguments.single().toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T, R> Iterable<T>.assertedFind(value: R, transform: (T) -> R): T = find { transform(it) == value } ?: throw AssertionError("'$value' not found, only ${this.joinToString { transform(it).toString() }}")
|
fun <T, R> Iterable<T>.assertedFind(value: R, transform: (T) -> R): T = find { transform(it) == value } ?: throw AssertionError("'$value' not found, only ${this.joinToString { transform(it).toString() }}")
|
||||||
|
|||||||
Reference in New Issue
Block a user