Add Kotlin DeprecationLevel into the REPL completion

This commit is contained in:
Ilya Muradyan
2021-05-05 02:49:30 +03:00
committed by TeamCityServer
parent 6bc4e124fb
commit e9af2849ef
4 changed files with 57 additions and 7 deletions
@@ -19,7 +19,8 @@ data class SourceCodeCompletionVariant(
val text: String,
val displayText: String,
val tail: String,
val icon: String
val icon: String,
val deprecationLevel: DeprecationLevel? = null,
)
interface ReplAnalyzerResultKeys
@@ -127,6 +127,39 @@ class ReplCompletionAndErrorsAnalysisTest : TestCase() {
}
}
@Test
fun testDeprecatedCompletion() = test {
run {
doCompile
code = """
@Deprecated("deprecated")
class Clazz1
@Deprecated("deprecated", level=DeprecationLevel.ERROR)
class Clazz2
""".trimIndent()
}
run {
doComplete
code = """
@Deprecated("deprecated1", level=DeprecationLevel.WA)
class Clazz3
@Deprecated("deprecated1", level=kotlin.annotation.AnnotationRetention.SOURCE)
class Clazz4
Claz
""".trimIndent()
cursor = code.length
expect {
addCompletion("Clazz3", "Clazz3", " (Line_2_simplescript)", "class", DeprecationLevel.WARNING)
addCompletion("Clazz4", "Clazz4", " (Line_2_simplescript)", "class", DeprecationLevel.WARNING)
addCompletion("Clazz1", "Clazz1", " (Line_1_simplescript)", "class", DeprecationLevel.WARNING)
addCompletion("Clazz2", "Clazz2", " (Line_1_simplescript)", "class", DeprecationLevel.ERROR)
}
}
}
@Test
fun testExtensionMethods() = test {
run {
@@ -72,8 +72,8 @@ class TestConf {
class Expected(private val run: Run) {
val completions = ExpectedList<SourceCodeCompletionVariant>(run::doComplete)
fun addCompletion(text: String, displayText: String, tail: String, icon: String) {
completions.add(SourceCodeCompletionVariant(text, displayText, tail, icon))
fun addCompletion(text: String, displayText: String, tail: String, icon: String, deprecationLevel: DeprecationLevel? = null) {
completions.add(SourceCodeCompletionVariant(text, displayText, tail, icon, deprecationLevel))
}
val errors = ExpectedList<ScriptDiagnostic>(run::doErrorCheck)
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.lexer.KtKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -27,16 +29,20 @@ import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope.Companion.ALL_NAME_FILTER
import org.jetbrains.kotlin.scripting.ide_services.compiler.completion
import org.jetbrains.kotlin.scripting.ide_services.compiler.filterOutShadowedDescriptors
import org.jetbrains.kotlin.scripting.ide_services.compiler.nameFilter
import org.jetbrains.kotlin.scripting.resolve.classId
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.asFlexibleType
import org.jetbrains.kotlin.types.isFlexible
import java.io.File
import java.lang.IllegalArgumentException
import java.util.*
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.SourceCodeCompletionVariant
@@ -252,14 +258,23 @@ private class KJvmReplCompleter(
.let {
if (isSortNeeded) it.sortedBy { descTriple -> descTriple.third } else it
}
.forEach {
val descriptor = it.first
val (rawName, presentableText, tailText, completionText) = it.second
.forEach { resultTriple ->
val descriptor = resultTriple.first
val (rawName, presentableText, tailText, completionText) = resultTriple.second
if (nameFilter(rawName, prefix)) {
val fullName: String =
formatName(
presentableText
)
val deprecationLevel = descriptor.annotations
.findAnnotation(FqName("kotlin.Deprecated"))
?.let { annotationDescriptor ->
val valuePair = annotationDescriptor.argumentValue("level")?.value as? Pair<*, *>
val valueClass = (valuePair?.first as? ClassId)?.takeIf { DeprecationLevel::class.classId == it }
val valueName = (valuePair?.second as? Name)?.identifier
if (valueClass == null || valueName == null) return@let DeprecationLevel.WARNING
DeprecationLevel.valueOf(valueName)
}
yield(
SourceCodeCompletionVariant(
completionText,
@@ -267,7 +282,8 @@ private class KJvmReplCompleter(
tailText,
getIconFromDescriptor(
descriptor
)
),
deprecationLevel,
)
)
}