KT-56843 [SLC] Support unsafe property initializers
This commit is contained in:
committed by
Space Team
parent
6b62499c85
commit
85b5a4521e
+24
-2
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.light.classes.symbol.fields
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.hasAnnotation
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.*
|
||||
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
|
||||
@@ -173,9 +173,31 @@ internal class SymbolLightFieldForProperty private constructor(
|
||||
}
|
||||
|
||||
private val _initializer by lazyPub {
|
||||
_initializerValue?.createPsiExpression(this)
|
||||
_initializerValue?.createPsiExpression(this) ?: withPropertySymbol { propertySymbol ->
|
||||
if (propertySymbol !is KtKotlinPropertySymbol) return@withPropertySymbol null
|
||||
(kotlinOrigin as? KtProperty)?.initializer?.evaluateAsAnnotationValue()
|
||||
?.let(::toPsiExpression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toPsiExpression(value: KtAnnotationValue): PsiExpression? =
|
||||
project.withElementFactorySafe {
|
||||
when (value) {
|
||||
is KtConstantAnnotationValue ->
|
||||
value.constantValue.createPsiExpression(this@SymbolLightFieldForProperty)
|
||||
is KtEnumEntryAnnotationValue ->
|
||||
value.callableId?.let { createExpressionFromText(it.asSingleFqName().asString(), this@SymbolLightFieldForProperty) }
|
||||
is KtArrayAnnotationValue ->
|
||||
createExpressionFromText(
|
||||
value.values
|
||||
.map { toPsiExpression(it)?.text ?: return@withElementFactorySafe null }
|
||||
.joinToString(", ", "{", "}"),
|
||||
this@SymbolLightFieldForProperty
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun getInitializer(): PsiExpression? = _initializer
|
||||
|
||||
private val _constantValue by lazyPub {
|
||||
|
||||
+35
-25
@@ -151,17 +151,20 @@ internal fun KtType.isClassTypeWithClassId(classId: ClassId): Boolean {
|
||||
return this.classId == classId
|
||||
}
|
||||
|
||||
private fun escapeString(str: String): String = buildString {
|
||||
str.forEach { char ->
|
||||
val escaped = when (char) {
|
||||
'\n' -> "\\n"
|
||||
'\r' -> "\\r"
|
||||
'\t' -> "\\t"
|
||||
'\"' -> "\\\""
|
||||
'\\' -> "\\\\"
|
||||
else -> "$char"
|
||||
private fun escapeString(s: String): String = buildString {
|
||||
s.forEach {
|
||||
when (it) {
|
||||
'\n' -> append("\\n")
|
||||
'\r' -> append("\\r")
|
||||
'\t' -> append("\\t")
|
||||
'"' -> append("\\\"")
|
||||
'\\' -> append("\\\\")
|
||||
else -> if (it.code in 32..128) {
|
||||
append(it)
|
||||
} else {
|
||||
append("\\u%04X".format(it.code))
|
||||
}
|
||||
}
|
||||
append(escaped)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,11 +183,11 @@ internal fun KtAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiA
|
||||
)
|
||||
|
||||
is KtConstantAnnotationValue -> {
|
||||
this.constantValue.createPsiExpression(parent)?.let {
|
||||
if (it is PsiLiteral)
|
||||
SymbolPsiLiteral(sourcePsi, parent, it)
|
||||
else
|
||||
SymbolPsiExpression(sourcePsi, parent, it)
|
||||
constantValue.createPsiExpression(parent)?.let {
|
||||
when (it) {
|
||||
is PsiLiteral -> SymbolPsiLiteral(sourcePsi, parent, it)
|
||||
else -> SymbolPsiExpression(sourcePsi, parent, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,23 +223,30 @@ private fun KtKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement):
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtConstantValue.asStringForPsiLiteral(): String = when (val value = value) {
|
||||
is Char -> "'$value'"
|
||||
is String -> "\"${escapeString(value)}\""
|
||||
is Long -> "${value}L"
|
||||
is Float -> "${value}f"
|
||||
null -> "null"
|
||||
else -> value.toString()
|
||||
}
|
||||
private fun KtConstantValue.asStringForPsiExpression(): String =
|
||||
when (val value = value) {
|
||||
Double.NEGATIVE_INFINITY -> "-1.0 / 0.0"
|
||||
Double.NaN -> "0.0 / 0.0"
|
||||
Double.POSITIVE_INFINITY -> "1.0 / 0.0"
|
||||
Float.NEGATIVE_INFINITY -> "-1.0F / 0.0F"
|
||||
Float.NaN -> "0.0F / 0.0F"
|
||||
Float.POSITIVE_INFINITY -> "1.0F / 0.0F"
|
||||
'\'' -> "'\\''"
|
||||
is Char -> "'${escapeString(value.toString())}'"
|
||||
is String -> "\"${escapeString(value)}\""
|
||||
is Long -> "${value}L"
|
||||
is Float -> "${value}f"
|
||||
else -> value.toString()
|
||||
}
|
||||
|
||||
internal fun KtConstantValue.createPsiExpression(parent: PsiElement): PsiExpression? {
|
||||
val asString = asStringForPsiLiteral()
|
||||
val asString = asStringForPsiExpression()
|
||||
return parent.project.withElementFactorySafe {
|
||||
createExpressionFromText(asString, parent)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T> Project.withElementFactorySafe(crossinline action: PsiElementFactory.() -> T): T? {
|
||||
internal inline fun <T> Project.withElementFactorySafe(crossinline action: PsiElementFactory.() -> T): T? {
|
||||
val instance = PsiElementFactory.getInstance(this)
|
||||
return try {
|
||||
instance.action()
|
||||
|
||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesByFqNameForLibraryTestGenerated extends AbstractS
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsAnnotationArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvalidJavaIdentifierAsPropertyInitializer.kt")
|
||||
public void testInvalidJavaIdentifierAsPropertyInitializer() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("JavaBetween.kt")
|
||||
public void testJavaBetween() throws Exception {
|
||||
|
||||
+6
@@ -318,6 +318,12 @@ public class SymbolLightClassesByPsiForLibraryTestGenerated extends AbstractSymb
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unresolvedWithAliasedImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsafePropertyInitializers.kt")
|
||||
public void testUnsafePropertyInitializers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unsafePropertyInitializers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassInSignature.kt")
|
||||
public void testValueClassInSignature() throws Exception {
|
||||
|
||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesEqualityByFqNameForLibraryTestGenerated extends A
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsAnnotationArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvalidJavaIdentifierAsPropertyInitializer.kt")
|
||||
public void testInvalidJavaIdentifierAsPropertyInitializer() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("JavaBetween.kt")
|
||||
public void testJavaBetween() throws Exception {
|
||||
|
||||
+6
@@ -318,6 +318,12 @@ public class SymbolLightClassesEqualityByPsiForLibraryTestGenerated extends Abst
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unresolvedWithAliasedImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsafePropertyInitializers.kt")
|
||||
public void testUnsafePropertyInitializers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unsafePropertyInitializers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassInSignature.kt")
|
||||
public void testValueClassInSignature() throws Exception {
|
||||
|
||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesParentingByFqNameForLibraryTestGenerated extends
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsAnnotationArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvalidJavaIdentifierAsPropertyInitializer.kt")
|
||||
public void testInvalidJavaIdentifierAsPropertyInitializer() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("JavaBetween.kt")
|
||||
public void testJavaBetween() throws Exception {
|
||||
|
||||
+6
@@ -318,6 +318,12 @@ public class SymbolLightClassesParentingByPsiForLibraryTestGenerated extends Abs
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unresolvedWithAliasedImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsafePropertyInitializers.kt")
|
||||
public void testUnsafePropertyInitializers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unsafePropertyInitializers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassInSignature.kt")
|
||||
public void testValueClassInSignature() throws Exception {
|
||||
|
||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsAnnotationArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvalidJavaIdentifierAsPropertyInitializer.kt")
|
||||
public void testInvalidJavaIdentifierAsPropertyInitializer() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("JavaBetween.kt")
|
||||
public void testJavaBetween() throws Exception {
|
||||
|
||||
+6
@@ -318,6 +318,12 @@ public class SymbolLightClassesByPsiForSourceTestGenerated extends AbstractSymbo
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unresolvedWithAliasedImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsafePropertyInitializers.kt")
|
||||
public void testUnsafePropertyInitializers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unsafePropertyInitializers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassInSignature.kt")
|
||||
public void testValueClassInSignature() throws Exception {
|
||||
|
||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesEqualityByFqNameForSourceTestGenerated extends Ab
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsAnnotationArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvalidJavaIdentifierAsPropertyInitializer.kt")
|
||||
public void testInvalidJavaIdentifierAsPropertyInitializer() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("JavaBetween.kt")
|
||||
public void testJavaBetween() throws Exception {
|
||||
|
||||
+6
@@ -318,6 +318,12 @@ public class SymbolLightClassesEqualityByPsiForSourceTestGenerated extends Abstr
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unresolvedWithAliasedImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsafePropertyInitializers.kt")
|
||||
public void testUnsafePropertyInitializers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unsafePropertyInitializers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassInSignature.kt")
|
||||
public void testValueClassInSignature() throws Exception {
|
||||
|
||||
+6
@@ -192,6 +192,12 @@ public class SymbolLightClassesParentingByFqNameForSourceTestGenerated extends A
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsAnnotationArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvalidJavaIdentifierAsPropertyInitializer.kt")
|
||||
public void testInvalidJavaIdentifierAsPropertyInitializer() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/InvalidJavaIdentifierAsPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("JavaBetween.kt")
|
||||
public void testJavaBetween() throws Exception {
|
||||
|
||||
+6
@@ -318,6 +318,12 @@ public class SymbolLightClassesParentingByPsiForSourceTestGenerated extends Abst
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unresolvedWithAliasedImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsafePropertyInitializers.kt")
|
||||
public void testUnsafePropertyInitializers() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/lightClassByPsi/unsafePropertyInitializers.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassInSignature.kt")
|
||||
public void testValueClassInSignature() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user