IDEA-217138 Properly replace name element, add completion from property names schema, add highlighting in YAML

GitOrigin-RevId: fa54e8c1c6b66cd840ade5102431e78e74d8a666
This commit is contained in:
Anton Lobov
2019-07-02 06:52:16 +03:00
committed by intellij-monorepo-bot
parent ce0c6d2f27
commit 69d390a5e7
5 changed files with 110 additions and 2 deletions
@@ -186,6 +186,7 @@ public class JsonSchemaCompletionContributor extends CompletionContributor {
final Map<String, JsonSchemaObject> schemaProperties = schema.getProperties();
addAllPropertyVariants(insertComma, hasValue, properties, adapter, schemaProperties, knownNames);
addIfThenElsePropertyNameVariants(schema, insertComma, hasValue, properties, adapter, knownNames);
addPropertyNameSchemaVariants(schema);
}
if (isName != ThreeState.YES) {
@@ -198,6 +199,19 @@ public class JsonSchemaCompletionContributor extends CompletionContributor {
}
}
private void addPropertyNameSchemaVariants(@NotNull JsonSchemaObject schema) {
JsonSchemaObject propertyNamesSchema = schema.getPropertyNamesSchema();
if (propertyNamesSchema == null) return;
List<Object> anEnum = propertyNamesSchema.getEnum();
if (anEnum == null) return;
for (Object o : anEnum) {
if (!(o instanceof String)) continue;
String key = ((String)o);
key = !shouldWrapInQuotes(key, false) ? key : StringUtil.wrapWithDoubleQuote(key);
myVariants.add(LookupElementBuilder.create(StringUtil.unquoteString(key)));
}
}
private void addIfThenElsePropertyNameVariants(@NotNull JsonSchemaObject schema,
boolean insertComma,
boolean hasValue,
@@ -8,6 +8,8 @@ import com.intellij.codeInspection.BatchQuickFix;
import com.intellij.codeInspection.CommonProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.json.psi.JsonElementGenerator;
import com.intellij.json.psi.JsonProperty;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -61,7 +63,14 @@ public class SuggestEnumValuesFix implements LocalQuickFix, BatchQuickFix<Common
prevPrev = prev.getPrevSibling();
}
boolean shouldAddWhitespace = myQuickFixAdapter.fixWhitespaceBefore(initialElement, element);
WriteAction.run(() -> element.delete());
PsiElement parent = element.getParent();
boolean isJsonPropName = parent instanceof JsonProperty && ((JsonProperty)parent).getNameElement() == element;
if (isJsonPropName) {
WriteAction.run(() -> element.replace(new JsonElementGenerator(project).createStringLiteral("")));
}
else {
WriteAction.run(() -> element.delete());
}
EditorEx editor = EditorUtil.getEditorEx(fileEditor);
assert editor != null;
// this is a workaround for buggy formatters such as in YAML - it removes the whitespace after ':' when deleting the value
@@ -73,6 +82,9 @@ public class SuggestEnumValuesFix implements LocalQuickFix, BatchQuickFix<Common
editor.getCaretModel().moveToOffset(offset + 1);
});
}
if (isJsonPropName) {
editor.getCaretModel().moveToOffset(((JsonProperty)parent).getNameElement().getTextOffset() + 1);
}
CodeCompletionHandlerBase.createHandler(CompletionType.BASIC).invokeCompletion(project, editor);
}
@@ -34,7 +34,10 @@ public class YamlPropertyAdapter implements JsonPropertyAdapter {
@Nullable
@Override
public JsonValueAdapter getNameValueAdapter() {
return null; // todo: we need a separate adapter for names; but currently names schema is rarely used, let's just skip validation
if (!(myProperty instanceof YAMLKeyValue)) return null;
PsiElement key = ((YAMLKeyValue)myProperty).getKey();
if (key == null) return null;
return new YamlPropertyKeyAdapter(key);
}
@NotNull
@@ -0,0 +1,65 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.schema;
import com.intellij.psi.PsiElement;
import com.jetbrains.jsonSchema.extension.adapters.JsonArrayValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonObjectValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class YamlPropertyKeyAdapter implements JsonValueAdapter {
private final PsiElement myDelegate;
public YamlPropertyKeyAdapter(PsiElement delegate) {
myDelegate = delegate;
}
@Override
public boolean isObject() {
return false;
}
@Override
public boolean isArray() {
return false;
}
@Override
public boolean isStringLiteral() {
return true;
}
@Override
public boolean isNumberLiteral() {
return false;
}
@Override
public boolean isBooleanLiteral() {
return false;
}
@Override
public boolean isNull() {
return false;
}
@NotNull
@Override
public PsiElement getDelegate() {
return myDelegate;
}
@Nullable
@Override
public JsonObjectValueAdapter getAsObject() {
return null;
}
@Nullable
@Override
public JsonArrayValueAdapter getAsArray() {
return null;
}
}
@@ -910,4 +910,18 @@ public class YamlByJsonSchemaHighlightingTest extends JsonSchemaHighlightingTest
" }\n" +
" }}", "<weak_warning descr=\"Key 'myPropertyXxx' is deprecated: Baz\">myPropertyXxx</weak_warning>: a");
}
public void testPropertyNameSchema() throws Exception {
doTest("{\n" +
" \"type\": \"object\",\n" +
" \"patternProperties\": {\n" +
" \".*\": {\n" +
" \"type\": \"boolean\"\n" +
" }\n" +
" },\n" +
" \"propertyNames\": {\n" +
" \"enum\": [\"a\", \"b\"]\n" +
" }\n" +
"}", "<warning>r</warning>: true");
}
}