mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
[json schema] AMPER-932 Don't suggest duplicate enum values if parent array assumes unique items
GitOrigin-RevId: a0e471c3d086ea2a4234501f75bbe4792b15a3d1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
45b39c3607
commit
1f409fad17
@@ -34,6 +34,7 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement
|
|||||||
import com.intellij.psi.injection.Injectable
|
import com.intellij.psi.injection.Injectable
|
||||||
import com.intellij.psi.util.PsiUtilCore
|
import com.intellij.psi.util.PsiUtilCore
|
||||||
import com.intellij.psi.util.endOffset
|
import com.intellij.psi.util.endOffset
|
||||||
|
import com.intellij.psi.util.parents
|
||||||
import com.intellij.ui.IconManager.Companion.getInstance
|
import com.intellij.ui.IconManager.Companion.getInstance
|
||||||
import com.intellij.ui.PlatformIcons
|
import com.intellij.ui.PlatformIcons
|
||||||
import com.intellij.util.ObjectUtils
|
import com.intellij.util.ObjectUtils
|
||||||
@@ -209,11 +210,12 @@ class JsonSchemaCompletionContributor : CompletionContributor() {
|
|||||||
val metadata = schema.enumMetadata
|
val metadata = schema.enumMetadata
|
||||||
val isEnumOrderSensitive = schema.readChildNodeValue(X_INTELLIJ_ENUM_ORDER_SENSITIVE).toBoolean()
|
val isEnumOrderSensitive = schema.readChildNodeValue(X_INTELLIJ_ENUM_ORDER_SENSITIVE).toBoolean()
|
||||||
val anEnum = schema.enum
|
val anEnum = schema.enum
|
||||||
|
val filtered = filteredByDefault + getEnumItemsToSkip()
|
||||||
for (i in anEnum!!.indices) {
|
for (i in anEnum!!.indices) {
|
||||||
val o = anEnum[i]
|
val o = anEnum[i]
|
||||||
if (insideStringLiteral && o !is String) continue
|
if (insideStringLiteral && o !is String) continue
|
||||||
val variant = o.toString()
|
val variant = o.toString()
|
||||||
if (!filtered.contains(variant)) {
|
if (!filtered.contains(variant) && !filtered.contains(StringUtil.unquoteString(variant))) {
|
||||||
val valueMetadata = metadata?.get(StringUtil.unquoteString(variant))
|
val valueMetadata = metadata?.get(StringUtil.unquoteString(variant))
|
||||||
val description = valueMetadata?.get("description")
|
val description = valueMetadata?.get("description")
|
||||||
val deprecated = valueMetadata?.get("deprecationMessage")
|
val deprecated = valueMetadata?.get("deprecationMessage")
|
||||||
@@ -243,6 +245,19 @@ class JsonSchemaCompletionContributor : CompletionContributor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getEnumItemsToSkip(): Set<String> {
|
||||||
|
// if the parent is an array, and it assumes unique items, we don't suggest the same enum items again
|
||||||
|
val position = psiWalker?.findPosition(psiWalker.findElementToCheck(completionPsiElement), false)
|
||||||
|
val containerSchema = position?.trimTail(1)?.let { JsonSchemaResolver(myProject, rootSchema, it, null) }?.resolve()?.singleOrNull()
|
||||||
|
return if (psiWalker != null && containerSchema?.isUniqueItems == true) {
|
||||||
|
val parentArray = completionPsiElement.parents(false).firstNotNullOfOrNull {
|
||||||
|
psiWalker.createValueAdapter(it)?.asArray
|
||||||
|
}
|
||||||
|
parentArray?.elements.orEmpty().map { StringUtil.unquoteString(it.delegate.text) }.toSet()
|
||||||
|
}
|
||||||
|
else emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
fun suggestSpecialValues(type: JsonSchemaType?) {
|
fun suggestSpecialValues(type: JsonSchemaType?) {
|
||||||
if (!JsonSchemaVersion.isSchemaSchemaId(rootSchema.id) || type != JsonSchemaType._string) return
|
if (!JsonSchemaVersion.isSchemaSchemaId(rootSchema.id) || type != JsonSchemaType._string) return
|
||||||
val propertyAdapter = psiWalker!!.getParentPropertyAdapter(originalPosition) ?: return
|
val propertyAdapter = psiWalker!!.getParentPropertyAdapter(originalPosition) ?: return
|
||||||
@@ -528,7 +543,7 @@ class JsonSchemaCompletionContributor : CompletionContributor() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// some schemas provide an empty array or an empty object in enum values...
|
// some schemas provide an empty array or an empty object in enum values...
|
||||||
private val filtered = setOf("[]", "{}", "[ ]", "{ }")
|
private val filteredByDefault = setOf("[]", "{}", "[ ]", "{ }")
|
||||||
private val commonAbbreviations = listOf("e.g.", "i.e.")
|
private val commonAbbreviations = listOf("e.g.", "i.e.")
|
||||||
|
|
||||||
private fun findFirstSentence(sentence: String): String {
|
private fun findFirstSentence(sentence: String): String {
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ class JsonBySchemaCompletionTest : JsonBySchemaCompletionBaseTest() {
|
|||||||
"""{"prop": <caret>}""", "\"prima\"", "\"primus\"", "\"proto\"")
|
"""{"prop": <caret>}""", "\"prima\"", "\"primus\"", "\"proto\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testEnumInArrayOfUniqueItems() {
|
||||||
|
// don't suggest the same enum elements again if the parent array assumes unique items
|
||||||
|
testImpl("""{"properties": {"prop": { "type": "array", "items": {"enum": ["prima", "proto", "primus"]}, "uniqueItems": true}}}""",
|
||||||
|
"""{"prop": ["prima", <caret>]}""", "\"primus\"", "\"proto\"")
|
||||||
|
}
|
||||||
|
|
||||||
fun testTopLevelAnyOfValues() {
|
fun testTopLevelAnyOfValues() {
|
||||||
testImpl("""{"properties": {"prop": {"anyOf": [{"enum": ["prima", "proto", "primus"]},""" + "{\"type\": \"boolean\"}]}}}",
|
testImpl("""{"properties": {"prop": {"anyOf": [{"enum": ["prima", "proto", "primus"]},""" + "{\"type\": \"boolean\"}]}}}",
|
||||||
"""{"prop": <caret>}""", "\"prima\"", "\"primus\"", "\"proto\"", "false", "true")
|
"""{"prop": <caret>}""", "\"prima\"", "\"primus\"", "\"proto\"", "false", "true")
|
||||||
|
|||||||
Reference in New Issue
Block a user