mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
WEB-33880 JSON Schemas: false positive 'Validates to more than one variant' warning
This commit is contained in:
@@ -540,7 +540,7 @@ class JsonSchemaAnnotatorChecker {
|
||||
if (type != null) {
|
||||
list.add(type);
|
||||
} else {
|
||||
final List<JsonSchemaType> variants = schema.getTypeVariants();
|
||||
final Set<JsonSchemaType> variants = schema.getTypeVariants();
|
||||
if (variants != null) {
|
||||
list.addAll(variants);
|
||||
}
|
||||
@@ -575,7 +575,7 @@ class JsonSchemaAnnotatorChecker {
|
||||
}
|
||||
}
|
||||
if (schema.getTypeVariants() != null) {
|
||||
List<JsonSchemaType> matchTypes = schema.getTypeVariants();
|
||||
Set<JsonSchemaType> matchTypes = schema.getTypeVariants();
|
||||
if (matchTypes.contains(input)) {
|
||||
return input;
|
||||
}
|
||||
@@ -583,7 +583,7 @@ class JsonSchemaAnnotatorChecker {
|
||||
return input;
|
||||
}
|
||||
//nothing matches, lets return one of the list so that other heuristics does not match
|
||||
return matchTypes.get(0);
|
||||
return matchTypes.iterator().next();
|
||||
}
|
||||
if (!schema.getProperties().isEmpty() && JsonSchemaType._object.equals(input)) return JsonSchemaType._object;
|
||||
return null;
|
||||
|
||||
@@ -10,14 +10,12 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -50,7 +48,7 @@ public class JsonSchemaObject {
|
||||
@Nullable private Object myDefault;
|
||||
@Nullable private String myRef;
|
||||
@Nullable private String myFormat;
|
||||
@Nullable private List<JsonSchemaType> myTypeVariants;
|
||||
@Nullable private Set<JsonSchemaType> myTypeVariants;
|
||||
@Nullable private Number myMultipleOf;
|
||||
@Nullable private Number myMaximum;
|
||||
private boolean myExclusiveMaximum;
|
||||
@@ -123,7 +121,7 @@ public class JsonSchemaObject {
|
||||
if (other.myDefault != null) myDefault = other.myDefault;
|
||||
if (other.myRef != null) myRef = other.myRef;
|
||||
if (other.myFormat != null) myFormat = other.myFormat;
|
||||
myTypeVariants = copyList(myTypeVariants, other.myTypeVariants);
|
||||
myTypeVariants = copySet(myTypeVariants, other.myTypeVariants);
|
||||
if (other.myMultipleOf != null) myMultipleOf = other.myMultipleOf;
|
||||
if (other.myMaximum != null) myMaximum = other.myMaximum;
|
||||
if (other.myExclusiveMaximumNumber != null) myExclusiveMaximumNumber = other.myExclusiveMaximumNumber;
|
||||
@@ -186,7 +184,16 @@ public class JsonSchemaObject {
|
||||
@Nullable
|
||||
private static <T> List<T> copyList(@Nullable List<T> target, @Nullable List<T> source) {
|
||||
if (source == null || source.isEmpty()) return target;
|
||||
if (target == null) target = new ArrayList<>();
|
||||
if (target == null) target = ContainerUtil.newArrayListWithCapacity(source.size());
|
||||
target.addAll(source);
|
||||
return target;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T> Set<T> copySet(@Nullable Set<T> target, @Nullable Set<T> source) {
|
||||
if (source == null || source.isEmpty()) return target;
|
||||
if (target != null && source.containsAll(target)) return target;
|
||||
if (target == null) target = ContainerUtil.newHashSet(source.size());
|
||||
target.addAll(source);
|
||||
return target;
|
||||
}
|
||||
@@ -194,7 +201,7 @@ public class JsonSchemaObject {
|
||||
@Nullable
|
||||
private static <K, V> Map<K, V> copyMap(@Nullable Map<K, V> target, @Nullable Map<K, V> source) {
|
||||
if (source == null || source.isEmpty()) return target;
|
||||
if (target == null) target = new HashMap<>();
|
||||
if (target == null) target = ContainerUtilRt.newHashMap(source.size());
|
||||
target.putAll(source);
|
||||
return target;
|
||||
}
|
||||
@@ -548,11 +555,11 @@ public class JsonSchemaObject {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<JsonSchemaType> getTypeVariants() {
|
||||
public Set<JsonSchemaType> getTypeVariants() {
|
||||
return myTypeVariants;
|
||||
}
|
||||
|
||||
public void setTypeVariants(@Nullable List<JsonSchemaType> typeVariants) {
|
||||
public void setTypeVariants(@Nullable Set<JsonSchemaType> typeVariants) {
|
||||
myTypeVariants = typeVariants;
|
||||
}
|
||||
|
||||
@@ -782,7 +789,7 @@ public class JsonSchemaObject {
|
||||
JsonSchemaType type = getType();
|
||||
if (type != null) return type.getDescription();
|
||||
|
||||
List<JsonSchemaType> possibleTypes = getTypeVariants();
|
||||
Set<JsonSchemaType> possibleTypes = getTypeVariants();
|
||||
|
||||
String description = getTypesDescription(shortDesc, possibleTypes);
|
||||
if (description != null) return description;
|
||||
@@ -796,9 +803,9 @@ public class JsonSchemaObject {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static String getTypesDescription(boolean shortDesc, @Nullable List<JsonSchemaType> possibleTypes) {
|
||||
static String getTypesDescription(boolean shortDesc, @Nullable Collection<JsonSchemaType> possibleTypes) {
|
||||
if (possibleTypes == null || possibleTypes.size() == 0) return null;
|
||||
if (possibleTypes.size() == 1) return possibleTypes.get(0).getDescription();
|
||||
if (possibleTypes.size() == 1) return possibleTypes.iterator().next().getDescription();
|
||||
if (possibleTypes.contains(JsonSchemaType._any)) return JsonSchemaType._any.getDescription();
|
||||
|
||||
Stream<String> typeDescriptions = possibleTypes.stream().map(t -> t.getDescription()).distinct().sorted();
|
||||
|
||||
@@ -270,9 +270,9 @@ public class JsonSchemaReader {
|
||||
final JsonSchemaType type = parseType(StringUtil.unquoteString(element.getText()));
|
||||
if (type != null) object.setType(type);
|
||||
} else if (element instanceof JsonArray) {
|
||||
final List<JsonSchemaType> typeList = ((JsonArray)element).getValueList().stream()
|
||||
final Set<JsonSchemaType> typeList = ((JsonArray)element).getValueList().stream()
|
||||
.filter(notEmptyString()).map(el -> parseType(StringUtil.unquoteString(el.getText())))
|
||||
.filter(el -> el != null).collect(Collectors.toList());
|
||||
.filter(el -> el != null).collect(Collectors.toSet());
|
||||
if (!typeList.isEmpty()) object.setTypeVariants(typeList);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -866,6 +866,16 @@ public class JsonSchemaHighlightingTest extends JsonSchemaHighlightingTestBase {
|
||||
"] ");
|
||||
}
|
||||
|
||||
public void testComplexOneOfSchema() throws Exception {
|
||||
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/complexOneOfSchema.json"));
|
||||
doTest(schemaText, "{\n" +
|
||||
" \"indentation\": \"tab\"\n" +
|
||||
" }");
|
||||
doTest(schemaText, "{\n" +
|
||||
" \"indentation\": <warning>\"ttab\"</warning>\n" +
|
||||
" }");
|
||||
}
|
||||
|
||||
public void testEnumCasing() throws Exception {
|
||||
@Language("JSON") String schema = "{\n" +
|
||||
" \"type\": \"object\",\n" +
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"properties": {
|
||||
"indentation": {
|
||||
"description": "Specify indentation",
|
||||
"type": [
|
||||
"null",
|
||||
"integer",
|
||||
"string",
|
||||
"array"
|
||||
],
|
||||
"oneOf": [
|
||||
{
|
||||
"type": [
|
||||
"null",
|
||||
"integer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"tab",
|
||||
[]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string",
|
||||
"object"
|
||||
],
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"tab",
|
||||
{}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/coreRule"
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"indentInsideParens": {
|
||||
"description": "If `true`, the closing brace of a block (rule or at-rule) will be expected at the same indentation level as the block's inner nodes",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"twice",
|
||||
"once-at-root-twice-in-block"
|
||||
]
|
||||
},
|
||||
"except": {
|
||||
"description": "Do not indent for these things",
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"block",
|
||||
"param",
|
||||
"value"
|
||||
]
|
||||
}
|
||||
},
|
||||
"ignore": {
|
||||
"description": "Ignore the indentation inside parentheses",
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"inside-parens",
|
||||
"param",
|
||||
"value"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user