mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
WEB-29954 Support JSON schema v7
This commit is contained in:
+12
-5
@@ -16,15 +16,17 @@ import java.util.List;
|
||||
* @author Irina.Chernushina on 2/24/2016.
|
||||
*/
|
||||
public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderFactory {
|
||||
public static final int TOTAL_PROVIDERS = 2;
|
||||
public static final String SCHEMA_JSON_FILE_NAME = "schema.json";
|
||||
public static final String SCHEMA06_JSON_FILE_NAME = "schema06.json";
|
||||
public static final int TOTAL_PROVIDERS = 3;
|
||||
private static final String SCHEMA_JSON_FILE_NAME = "schema.json";
|
||||
private static final String SCHEMA06_JSON_FILE_NAME = "schema06.json";
|
||||
private static final String SCHEMA07_JSON_FILE_NAME = "schema07.json";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JsonSchemaFileProvider> getProviders(@NotNull final Project project) {
|
||||
return ContainerUtil.list(new MyJsonSchemaFileProvider(project, SCHEMA_JSON_FILE_NAME),
|
||||
new MyJsonSchemaFileProvider(project, SCHEMA06_JSON_FILE_NAME));
|
||||
new MyJsonSchemaFileProvider(project, SCHEMA06_JSON_FILE_NAME),
|
||||
new MyJsonSchemaFileProvider(project, SCHEMA07_JSON_FILE_NAME));
|
||||
}
|
||||
|
||||
public static class MyJsonSchemaFileProvider implements JsonSchemaFileProvider {
|
||||
@@ -38,6 +40,9 @@ public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderF
|
||||
public boolean isSchemaV6() {
|
||||
return SCHEMA06_JSON_FILE_NAME.equals(myFileName);
|
||||
}
|
||||
public boolean isSchemaV7() {
|
||||
return SCHEMA07_JSON_FILE_NAME.equals(myFileName);
|
||||
}
|
||||
|
||||
private MyJsonSchemaFileProvider(@NotNull final Project project, @NotNull String fileName) {
|
||||
myProject = project;
|
||||
@@ -55,6 +60,8 @@ public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderF
|
||||
return isSchemaV4();
|
||||
case SCHEMA_6:
|
||||
return isSchemaV6();
|
||||
case SCHEMA_7:
|
||||
return isSchemaV7();
|
||||
}
|
||||
|
||||
throw new NotImplementedError("Unknown schema version: " + schemaVersion);
|
||||
@@ -62,7 +69,7 @@ public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderF
|
||||
|
||||
@Override
|
||||
public JsonSchemaVersion getSchemaVersion() {
|
||||
return isSchemaV4() ? JsonSchemaVersion.SCHEMA_4 : JsonSchemaVersion.SCHEMA_6;
|
||||
return isSchemaV4() ? JsonSchemaVersion.SCHEMA_4 : isSchemaV7() ? JsonSchemaVersion.SCHEMA_7 : JsonSchemaVersion.SCHEMA_6;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -25,7 +25,7 @@ public class JsonCachedValues {
|
||||
@Nullable
|
||||
public static JsonSchemaObject getSchemaObject(@NotNull VirtualFile schemaFile, @NotNull Project project) {
|
||||
JsonFileResolver.startFetchingHttpFileIfNeeded(schemaFile);
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(schemaFile);
|
||||
final PsiFile psiFile = resolveFile(schemaFile, project);
|
||||
if (!(psiFile instanceof JsonFile)) return null;
|
||||
|
||||
return CachedValueProviderOnPsiFile.getOrCompute(psiFile, JsonCachedValues::computeSchemaObject, JSON_OBJECT_CACHE_KEY);
|
||||
@@ -55,11 +55,17 @@ public class JsonCachedValues {
|
||||
@Nullable
|
||||
public static String getSchemaUrlFromSchemaProperty(@NotNull VirtualFile file,
|
||||
@NotNull Project project) {
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
PsiFile psiFile = resolveFile(file, project);
|
||||
return !(psiFile instanceof JsonFile) ? null : CachedValueProviderOnPsiFile
|
||||
.getOrCompute(psiFile, JsonCachedValues::fetchSchemaUrl, SCHEMA_URL_KEY);
|
||||
}
|
||||
|
||||
private static PsiFile resolveFile(@NotNull VirtualFile file,
|
||||
@NotNull Project project) {
|
||||
if (!file.isValid()) return null;
|
||||
return PsiManager.getInstance(project).findFile(file);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String fetchSchemaUrl(@Nullable PsiFile f) {
|
||||
if (!(f instanceof JsonFile)) return null;
|
||||
@@ -78,7 +84,7 @@ public class JsonCachedValues {
|
||||
public static String getSchemaId(@NotNull final VirtualFile schemaFile,
|
||||
@NotNull final Project project) {
|
||||
if (!schemaFile.isValid()) return null;
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(schemaFile);
|
||||
final PsiFile psiFile = resolveFile(schemaFile, project);
|
||||
if (!(psiFile instanceof JsonFile)) return null;
|
||||
return CachedValueProviderOnPsiFile.getOrCompute(psiFile, JsonCachedValues::getSchemaId, SCHEMA_ID_CACHE_KEY);
|
||||
}
|
||||
@@ -110,7 +116,7 @@ public class JsonCachedValues {
|
||||
public static List<Pair<Collection<String>, String>> getSchemaCatalog(@NotNull final VirtualFile catalog,
|
||||
@NotNull final Project project) {
|
||||
if (!catalog.isValid()) return null;
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(catalog);
|
||||
final PsiFile psiFile = resolveFile(catalog, project);
|
||||
if (!(psiFile instanceof JsonFile)) return null;
|
||||
return CachedValueProviderOnPsiFile.getOrCompute(psiFile, JsonCachedValues::computeSchemaCatalog, SCHEMA_CATALOG_CACHE_KEY);
|
||||
}
|
||||
|
||||
@@ -190,6 +190,33 @@ class JsonSchemaAnnotatorChecker {
|
||||
final JsonSchemaAnnotatorChecker checker = checkByMatchResult(value, result);
|
||||
if (checker == null || checker.isCorrect()) error("Validates against 'not' schema", value.getDelegate());
|
||||
}
|
||||
|
||||
if (schema.getIf() != null) {
|
||||
MatchResult result = new JsonSchemaResolver(schema.getIf()).detailedResolve();
|
||||
if (result.mySchemas.isEmpty() && result.myExcludingSchemas.isEmpty()) return;
|
||||
|
||||
final JsonSchemaAnnotatorChecker checker = checkByMatchResult(value, result);
|
||||
if (checker != null) {
|
||||
if (checker.isCorrect()) {
|
||||
JsonSchemaObject then = schema.getThen();
|
||||
if (then == null) {
|
||||
error("Validates against 'if' branch but no 'then' branch is present", value.getDelegate());
|
||||
}
|
||||
else {
|
||||
checkObjectBySchemaRecordErrors(then, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
JsonSchemaObject schemaElse = schema.getElse();
|
||||
if (schemaElse == null) {
|
||||
error("Validates counter 'if' branch but no 'else' branch is present", value.getDelegate());
|
||||
}
|
||||
else {
|
||||
checkObjectBySchemaRecordErrors(schemaElse, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkObjectBySchemaRecordErrors(@NotNull JsonSchemaObject schema, @NotNull JsonValueAdapter object) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.jsonSchema.extension.JsonLikePsiWalker;
|
||||
import com.jetbrains.jsonSchema.extension.JsonSchemaFileProvider;
|
||||
import com.jetbrains.jsonSchema.extension.SchemaType;
|
||||
import com.jetbrains.jsonSchema.extension.adapters.JsonObjectValueAdapter;
|
||||
import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter;
|
||||
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -142,9 +143,8 @@ public class JsonSchemaCompletionContributor extends CompletionContributor {
|
||||
final JsonPropertyAdapter adapter = myWalker.getParentPropertyAdapter(myOriginalPosition);
|
||||
|
||||
final Map<String, JsonSchemaObject> schemaProperties = schema.getProperties();
|
||||
schemaProperties.keySet().stream()
|
||||
.filter(name -> !properties.contains(name) || adapter != null && name.equals(adapter.getName()))
|
||||
.forEach(name -> addPropertyVariant(name, schemaProperties.get(name), hasValue, insertComma));
|
||||
addAllPropertyVariants(insertComma, hasValue, properties, adapter, schemaProperties);
|
||||
addIfThenElsePropertyNameVariants(schema, insertComma, hasValue, properties, adapter);
|
||||
}
|
||||
else {
|
||||
suggestValues(schema);
|
||||
@@ -156,6 +156,46 @@ public class JsonSchemaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
|
||||
private void addIfThenElsePropertyNameVariants(@NotNull JsonSchemaObject schema,
|
||||
boolean insertComma,
|
||||
boolean hasValue,
|
||||
@NotNull Collection<String> properties,
|
||||
@Nullable JsonPropertyAdapter adapter) {
|
||||
if (schema.getIf() == null) return;
|
||||
|
||||
JsonLikePsiWalker walker = JsonLikePsiWalker.getWalker(myPosition, schema);
|
||||
JsonPropertyAdapter propertyAdapter = walker == null ? null : walker.getParentPropertyAdapter(myPosition);
|
||||
if (propertyAdapter == null) return;
|
||||
|
||||
JsonObjectValueAdapter object = propertyAdapter.getParentObject();
|
||||
if (object == null) return;
|
||||
|
||||
JsonSchemaAnnotatorChecker checker = new JsonSchemaAnnotatorChecker();
|
||||
checker.checkByScheme(object, schema.getIf());
|
||||
if (checker.isCorrect()) {
|
||||
JsonSchemaObject then = schema.getThen();
|
||||
if (then != null) {
|
||||
addAllPropertyVariants(insertComma, hasValue, properties, adapter, then.getProperties());
|
||||
}
|
||||
}
|
||||
else {
|
||||
JsonSchemaObject schemaElse = schema.getElse();
|
||||
if (schemaElse != null) {
|
||||
addAllPropertyVariants(insertComma, hasValue, properties, adapter, schemaElse.getProperties());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addAllPropertyVariants(boolean insertComma,
|
||||
boolean hasValue,
|
||||
Collection<String> properties,
|
||||
JsonPropertyAdapter adapter,
|
||||
Map<String, JsonSchemaObject> schemaProperties) {
|
||||
schemaProperties.keySet().stream()
|
||||
.filter(name -> !properties.contains(name) || adapter != null && name.equals(adapter.getName()))
|
||||
.forEach(name -> addPropertyVariant(name, schemaProperties.get(name), hasValue, insertComma));
|
||||
}
|
||||
|
||||
private void suggestValues(JsonSchemaObject schema) {
|
||||
suggestValuesForSchemaVariants(schema.getAnyOf());
|
||||
suggestValuesForSchemaVariants(schema.getOneOf());
|
||||
|
||||
@@ -89,6 +89,9 @@ public class JsonSchemaObject {
|
||||
@Nullable private List<JsonSchemaObject> myAnyOf;
|
||||
@Nullable private List<JsonSchemaObject> myOneOf;
|
||||
@Nullable private JsonSchemaObject myNot;
|
||||
@Nullable private JsonSchemaObject myIf;
|
||||
@Nullable private JsonSchemaObject myThen;
|
||||
@Nullable private JsonSchemaObject myElse;
|
||||
private boolean myShouldValidateAgainstJSType;
|
||||
|
||||
public JsonSchemaObject(@NotNull JsonObject object) {
|
||||
@@ -152,6 +155,9 @@ public class JsonSchemaObject {
|
||||
myAnyOf = copyList(myAnyOf, other.myAnyOf);
|
||||
myOneOf = copyList(myOneOf, other.myOneOf);
|
||||
if (other.myNot != null) myNot = other.myNot;
|
||||
if (other.myIf != null) myIf = other.myIf;
|
||||
if (other.myThen != null) myThen = other.myThen;
|
||||
if (other.myElse != null) myElse = other.myElse;
|
||||
myShouldValidateAgainstJSType |= other.myShouldValidateAgainstJSType;
|
||||
}
|
||||
|
||||
@@ -500,6 +506,33 @@ public class JsonSchemaObject {
|
||||
myNot = not;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JsonSchemaObject getIf() {
|
||||
return myIf;
|
||||
}
|
||||
|
||||
public void setIf(@Nullable JsonSchemaObject anIf) {
|
||||
myIf = anIf;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JsonSchemaObject getThen() {
|
||||
return myThen;
|
||||
}
|
||||
|
||||
public void setThen(@Nullable JsonSchemaObject then) {
|
||||
myThen = then;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JsonSchemaObject getElse() {
|
||||
return myElse;
|
||||
}
|
||||
|
||||
public void setElse(@Nullable JsonSchemaObject anElse) {
|
||||
myElse = anElse;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<JsonSchemaType> getTypeVariants() {
|
||||
return myTypeVariants;
|
||||
|
||||
@@ -190,10 +190,43 @@ public class JsonSchemaReader {
|
||||
READERS_MAP.put("anyOf", createContainer((object, members) -> object.setAnyOf(members)));
|
||||
READERS_MAP.put("oneOf", createContainer((object, members) -> object.setOneOf(members)));
|
||||
READERS_MAP.put("not", createNot());
|
||||
READERS_MAP.put("if", createIf());
|
||||
READERS_MAP.put("then", createThen());
|
||||
READERS_MAP.put("else", createElse());
|
||||
READERS_MAP.put("instanceof", ((element, object, queue) -> object.shouldValidateAgainstJSType()));
|
||||
READERS_MAP.put("typeof", ((element, object, queue) -> object.shouldValidateAgainstJSType()));
|
||||
}
|
||||
|
||||
private static MyReader createIf() {
|
||||
return (element, object, queue) -> {
|
||||
if (element instanceof JsonObject) {
|
||||
final JsonSchemaObject ifSchema = new JsonSchemaObject((JsonObject)element);
|
||||
queue.add(ifSchema);
|
||||
object.setIf(ifSchema);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static MyReader createThen() {
|
||||
return (element, object, queue) -> {
|
||||
if (element instanceof JsonObject) {
|
||||
final JsonSchemaObject ifSchema = new JsonSchemaObject((JsonObject)element);
|
||||
queue.add(ifSchema);
|
||||
object.setThen(ifSchema);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static MyReader createElse() {
|
||||
return (element, object, queue) -> {
|
||||
if (element instanceof JsonObject) {
|
||||
final JsonSchemaObject ifSchema = new JsonSchemaObject((JsonObject)element);
|
||||
queue.add(ifSchema);
|
||||
object.setElse(ifSchema);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static MyReader createNot() {
|
||||
return (element, object, queue) -> {
|
||||
if (element instanceof JsonObject) {
|
||||
|
||||
@@ -369,7 +369,8 @@ public class JsonSchemaVariantsTreeBuilder {
|
||||
}
|
||||
|
||||
private static boolean interestingSchema(@NotNull JsonSchemaObject schema) {
|
||||
return schema.getAnyOf() != null || schema.getOneOf() != null || schema.getAllOf() != null || schema.getRef() != null;
|
||||
return schema.getAnyOf() != null || schema.getOneOf() != null || schema.getAllOf() != null || schema.getRef() != null
|
||||
|| schema.getIf() != null;
|
||||
}
|
||||
|
||||
public static class Step {
|
||||
@@ -450,8 +451,31 @@ public class JsonSchemaVariantsTreeBuilder {
|
||||
if (schema != null) {
|
||||
return Pair.create(ThreeState.UNSURE, schema);
|
||||
}
|
||||
if (parent.getAdditionalPropertiesSchema() != null && acceptAdditionalPropertiesSchemas) {
|
||||
return Pair.create(ThreeState.UNSURE, parent.getAdditionalPropertiesSchema());
|
||||
if (acceptAdditionalPropertiesSchemas) {
|
||||
if (parent.getAdditionalPropertiesSchema() != null) {
|
||||
return Pair.create(ThreeState.UNSURE, parent.getAdditionalPropertiesSchema());
|
||||
}
|
||||
|
||||
// resolve inside V7 if-then-else conditionals
|
||||
if (parent.getIf() != null) {
|
||||
JsonSchemaObject childObject;
|
||||
|
||||
// NOTE: do not resolve inside 'if' itself - it is just a condition, but not an actual validation!
|
||||
// only 'then' and 'else' branches provide actual validation sources, but not the 'if' branch
|
||||
|
||||
if (parent.getThen() != null) {
|
||||
childObject = parent.getThen().getProperties().get(myName);
|
||||
if (childObject != null) {
|
||||
return Pair.create(ThreeState.UNSURE, childObject);
|
||||
}
|
||||
}
|
||||
if (parent.getElse() != null) {
|
||||
childObject = parent.getElse().getProperties().get(myName);
|
||||
if (childObject != null) {
|
||||
return Pair.create(ThreeState.UNSURE, childObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Boolean.FALSE.equals(parent.getAdditionalPropertiesAllowed())) {
|
||||
return Pair.create(ThreeState.NO, null);
|
||||
|
||||
@@ -7,12 +7,15 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public enum JsonSchemaVersion {
|
||||
SCHEMA_4,
|
||||
SCHEMA_6;
|
||||
SCHEMA_6,
|
||||
SCHEMA_7;
|
||||
|
||||
private static final String ourSchemaV4Schema = "http://json-schema.org/draft-04/schema#";
|
||||
private static final String ourSchemaV4SchemaTrim = "http://json-schema.org/draft-04/schema";
|
||||
private static final String ourSchemaV6Schema = "http://json-schema.org/draft-06/schema#";
|
||||
private static final String ourSchemaV6SchemaTrim = "http://json-schema.org/draft-06/schema";
|
||||
private static final String ourSchemaV7Schema = "http://json-schema.org/draft-07/schema#";
|
||||
private static final String ourSchemaV7SchemaTrim = "http://json-schema.org/draft-07/schema";
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -21,6 +24,8 @@ public enum JsonSchemaVersion {
|
||||
return "JSON Schema Version 4";
|
||||
case SCHEMA_6:
|
||||
return "JSON Schema Version 6";
|
||||
case SCHEMA_7:
|
||||
return "JSON Schema Version 7";
|
||||
}
|
||||
|
||||
throw new NotImplementedError("Unknown version: " + this);
|
||||
@@ -36,12 +41,15 @@ public enum JsonSchemaVersion {
|
||||
case ourSchemaV6Schema:
|
||||
case ourSchemaV6SchemaTrim:
|
||||
return SCHEMA_6;
|
||||
case ourSchemaV7Schema:
|
||||
case ourSchemaV7SchemaTrim:
|
||||
return SCHEMA_7;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isSchemaSchemaId(@Nullable String id) {
|
||||
return ourSchemaV4Schema.equals(id) || ourSchemaV6Schema.equals(id);
|
||||
return ourSchemaV4Schema.equals(id) || ourSchemaV6Schema.equals(id) || ourSchemaV7Schema.equals(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Core schema meta-schema",
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#" }
|
||||
},
|
||||
"nonNegativeInteger": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"nonNegativeIntegerDefault0": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/definitions/nonNegativeInteger" },
|
||||
{ "default": 0 }
|
||||
]
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": [
|
||||
"array",
|
||||
"boolean",
|
||||
"integer",
|
||||
"null",
|
||||
"number",
|
||||
"object",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"stringArray": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"uniqueItems": true,
|
||||
"default": []
|
||||
}
|
||||
},
|
||||
"type": ["object", "boolean"],
|
||||
"properties": {
|
||||
"$id": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"$ref": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"$comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": true,
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"examples": {
|
||||
"type": "array",
|
||||
"items": true
|
||||
},
|
||||
"multipleOf": {
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
|
||||
"minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"format": "regex"
|
||||
},
|
||||
"additionalItems": { "$ref": "#" },
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/schemaArray" }
|
||||
],
|
||||
"default": true
|
||||
},
|
||||
"maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
|
||||
"minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
|
||||
"uniqueItems": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"contains": { "$ref": "#" },
|
||||
"maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
|
||||
"minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
|
||||
"required": { "$ref": "#/definitions/stringArray" },
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"definitions": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"default": {}
|
||||
},
|
||||
"patternProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#" },
|
||||
"propertyNames": { "format": "regex" },
|
||||
"default": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#" },
|
||||
{ "$ref": "#/definitions/stringArray" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"propertyNames": { "$ref": "#" },
|
||||
"const": true,
|
||||
"enum": {
|
||||
"type": "array",
|
||||
"items": true,
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{ "$ref": "#/definitions/simpleTypes" },
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/simpleTypes" },
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": { "type": "string" },
|
||||
"contentMediaType": { "type": "string" },
|
||||
"contentEncoding": { "type": "string" },
|
||||
"if": {"$ref": "#"},
|
||||
"then": {"$ref": "#"},
|
||||
"else": {"$ref": "#"},
|
||||
"allOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"anyOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"oneOf": { "$ref": "#/definitions/schemaArray" },
|
||||
"not": { "$ref": "#" }
|
||||
},
|
||||
"default": true
|
||||
}
|
||||
@@ -704,6 +704,44 @@ public class JsonSchemaHighlightingTest extends DaemonAnalyzerTestCase {
|
||||
doTest(schema, "{\"prop\": \"foo\"}");
|
||||
}
|
||||
|
||||
public void testIfThenElseV7() throws Exception {
|
||||
@Language("JSON") String schema = "{\n" +
|
||||
" \"if\": {\n" +
|
||||
" \"properties\": {\n" +
|
||||
" \"a\": {\n" +
|
||||
" \"type\": \"string\"\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"required\": [\"a\"]\n" +
|
||||
" },\n" +
|
||||
" \"then\": {\n" +
|
||||
" \"properties\": {\n" +
|
||||
" \"b\": {\n" +
|
||||
" \"type\": \"number\"\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"required\": [\"b\"]\n" +
|
||||
" },\n" +
|
||||
" \"else\": {\n" +
|
||||
" \"properties\": {\n" +
|
||||
" \"c\": {\n" +
|
||||
" \"type\": \"boolean\"\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"required\": [\"c\"]\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
doTest(schema, "<warning>{}</warning>");
|
||||
doTest(schema, "{\"c\": <warning>5</warning>}");
|
||||
doTest(schema, "{\"c\": true}");
|
||||
doTest(schema, "<warning>{\"a\": 5, \"b\": 5}</warning>");
|
||||
doTest(schema, "{\"a\": 5, \"c\": <warning>5</warning>}");
|
||||
doTest(schema, "{\"a\": 5, \"c\": true}");
|
||||
doTest(schema, "<warning>{\"a\": \"a\", \"c\": true}</warning>");
|
||||
doTest(schema, "{\"a\": \"a\", \"b\": <warning>true</warning>}");
|
||||
doTest(schema, "{\"a\": \"a\", \"b\": 5}");
|
||||
}
|
||||
|
||||
public void testNestedOneOf() throws Exception {
|
||||
@Language("JSON") String schema = "{\"type\":\"object\",\n" +
|
||||
" \"oneOf\": [\n" +
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.jetbrains.jsonSchema.impl
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
import com.jetbrains.jsonSchema.JsonSchemaHighlightingTest
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Assert
|
||||
|
||||
/**
|
||||
@@ -284,4 +285,71 @@ class JsonBySchemaCompletionTest : JsonBySchemaCompletionBaseTest() {
|
||||
vararg variants: String) {
|
||||
testBySchema(schema, text, ".json", *variants)
|
||||
}
|
||||
|
||||
private val ifThenElseSchema: String
|
||||
get() {
|
||||
@Suppress("UnnecessaryVariable")
|
||||
@Language("JSON") val schema = """{
|
||||
"if": {
|
||||
"properties": {
|
||||
"a": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["a"]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"b": {
|
||||
"type": "number",
|
||||
"description": "Target b description"
|
||||
}
|
||||
},
|
||||
"required": ["b"]
|
||||
},
|
||||
"else": {
|
||||
"properties": {
|
||||
"c": {
|
||||
"type": "boolean",
|
||||
"description": "Target c description"
|
||||
}
|
||||
},
|
||||
"required": ["c"]
|
||||
}
|
||||
}"""
|
||||
return schema
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testIfThenElseV7EmptyPropName() {
|
||||
testImpl(ifThenElseSchema, "{<caret>}", "\"c\"")
|
||||
Assert.assertEquals(1, myItems.size.toLong())
|
||||
val presentation = LookupElementPresentation()
|
||||
myItems[0].renderElement(presentation)
|
||||
Assert.assertEquals("Target c description", presentation.typeText)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testIfThenElseV7ThenPropName() {
|
||||
testImpl(ifThenElseSchema, """{"a": "a", <caret>}""", "\"b\"")
|
||||
Assert.assertEquals(1, myItems.size.toLong())
|
||||
val presentation = LookupElementPresentation()
|
||||
myItems[0].renderElement(presentation)
|
||||
Assert.assertEquals("Target b description", presentation.typeText)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testIfThenElseV7ElsePropName() {
|
||||
testImpl(ifThenElseSchema, """{"a": 5, <caret>}""", "\"c\"")
|
||||
Assert.assertEquals(1, myItems.size.toLong())
|
||||
val presentation = LookupElementPresentation()
|
||||
myItems[0].renderElement(presentation)
|
||||
Assert.assertEquals("Target c description", presentation.typeText)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun testIfThenElseV7ElsePropValue() {
|
||||
testImpl(ifThenElseSchema, """{"a": 5, "c": <caret>}""", "false", "true")
|
||||
Assert.assertEquals(2, myItems.size.toLong())
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -219,6 +219,9 @@ class CommunityLibraryLicenses {
|
||||
new LibraryLicense(name: "JSON Schema (schema06.json)", attachedTo: "intellij.json", version: "draft-06", license: "Simplified BSD License",
|
||||
licenseUrl: "https://opensource.org/licenses/BSD-2-Clause",
|
||||
url: "http://json-schema.org/draft-06/schema#"),
|
||||
new LibraryLicense(name: "JSON Schema (schema07.json)", attachedTo: "intellij.json", version: "draft-07", license: "Simplified BSD License",
|
||||
licenseUrl: "https://opensource.org/licenses/BSD-2-Clause",
|
||||
url: "http://json-schema.org/draft-07/schema#"),
|
||||
new LibraryLicense(name: "jsoup", libraryName: "jsoup", version: "1.10.3", license: "MIT",
|
||||
url: "http://jsoup.org", licenseUrl: "http://jsoup.org/license"),
|
||||
new LibraryLicense(name: "jsr305", libraryName: "jsr305", version: "snapshot", license: "BSD", url: "http://code.google.com/p/jsr-305/",
|
||||
|
||||
Reference in New Issue
Block a user