IDEA-CR-36618: don't use completion provider in spellchecking; restore broken spellchecking for files with schemas

refixes WEB-31037
This commit is contained in:
Anton Lobov
2018-09-04 11:29:26 +02:00
parent 02c33dd3a6
commit 543e21c812
5 changed files with 85 additions and 12 deletions
@@ -3,6 +3,7 @@ package com.intellij.json;
import com.intellij.json.psi.JsonStringLiteral;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiUtilCore;
@@ -10,11 +11,16 @@ import com.intellij.spellchecker.inspections.PlainTextSplitter;
import com.intellij.spellchecker.tokenizer.SpellcheckingStrategy;
import com.intellij.spellchecker.tokenizer.TokenConsumer;
import com.intellij.spellchecker.tokenizer.Tokenizer;
import com.intellij.util.ThreeState;
import com.jetbrains.jsonSchema.extension.JsonLikePsiWalker;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.JsonSchemaCompletionContributor;
import com.jetbrains.jsonSchema.impl.JsonOriginalPsiWalker;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.JsonSchemaResolver;
import com.jetbrains.jsonSchema.impl.JsonSchemaVariantsTreeBuilder;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
/**
@@ -42,22 +48,39 @@ public class JsonSpellcheckerStrategy extends SpellcheckingStrategy {
}
};
private static boolean matchesNameFromSchema(@NotNull JsonStringLiteral element) {
final VirtualFile file = PsiUtilCore.getVirtualFile(element);
if (file == null) return false;
final JsonSchemaService service = JsonSchemaService.Impl.get(element.getProject());
if (!service.isApplicableToFile(file)) return false;
final JsonSchemaObject rootSchema = service.getSchemaObject(file);
if (rootSchema == null) return false;
String value = element.getValue();
if (StringUtil.isEmpty(value)) return false;
JsonOriginalPsiWalker walker = JsonLikePsiWalker.JSON_ORIGINAL_PSI_WALKER;
final PsiElement checkable = walker.goUpToCheckable(element);
if (checkable == null) return false;
final ThreeState isName = walker.isName(checkable);
final List<JsonSchemaVariantsTreeBuilder.Step> position = walker.findPosition(checkable, isName == ThreeState.NO);
if (position == null || position.isEmpty() && isName == ThreeState.NO) return false;
final Collection<JsonSchemaObject> schemas = new JsonSchemaResolver(rootSchema, false, position).resolve();
if (schemas.isEmpty()) return false;
return schemas.stream().anyMatch(s -> s.getProperties().keySet().contains(value)
|| s.getMatchingPatternPropertySchema(value) != null);
}
@NotNull
@Override
public Tokenizer getTokenizer(PsiElement element) {
if (element instanceof JsonStringLiteral) {
final VirtualFile file = PsiUtilCore.getVirtualFile(element);
if (file == null) return ourStringLiteralTokenizer;
final JsonSchemaService service = JsonSchemaService.Impl.get(element.getProject());
if (!service.isApplicableToFile(file)) return ourStringLiteralTokenizer;
final JsonSchemaObject rootSchema = service.getSchemaObject(file);
if (rootSchema == null) return ourStringLiteralTokenizer;
if (JsonSchemaCompletionContributor.getCompletionVariants(rootSchema, element, element) != null) {
return EMPTY_TOKENIZER;
}
return matchesNameFromSchema((JsonStringLiteral)element)
? EMPTY_TOKENIZER
: ourStringLiteralTokenizer;
}
return super.getTokenizer(element);
}
@@ -40,6 +40,7 @@ import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.util.*;
@@ -94,6 +95,7 @@ public class JsonSchemaCompletionContributor extends CompletionContributor {
}
}
@TestOnly
public static List<LookupElement> getCompletionVariants(@NotNull final JsonSchemaObject schema,
@NotNull final PsiElement position, @NotNull final PsiElement originalPosition) {
final List<LookupElement> result = new ArrayList<>();
@@ -1,7 +1,18 @@
package com.intellij.json;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.extensions.AreaPicoContainer;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.spellchecker.inspections.SpellCheckingInspection;
import com.intellij.util.containers.Predicate;
import com.jetbrains.jsonSchema.JsonSchemaTestProvider;
import com.jetbrains.jsonSchema.JsonSchemaTestServiceImpl;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
/**
* @author Mikhail Golubev
@@ -22,6 +33,29 @@ public class JsonSpellcheckerTest extends JsonTestCase {
doTest();
}
protected Predicate<VirtualFile> getAvailabilityPredicate() {
return file -> file.getFileType() instanceof LanguageFileType && ((LanguageFileType)file.getFileType()).getLanguage().isKindOf(
JsonLanguage.INSTANCE);
}
public void testWithSchema() {
PsiFile[] files = myFixture.configureByFiles(getTestName(false) + ".json", "Schema.json");
JsonSchemaTestServiceImpl.setProvider(new JsonSchemaTestProvider(files[1].getVirtualFile(),
getAvailabilityPredicate()));
AreaPicoContainer container = Extensions.getArea(getProject()).getPicoContainer();
String key = JsonSchemaService.class.getName();
container.unregisterComponent(key);
container.registerComponentImplementation(key, JsonSchemaTestServiceImpl.class);
Disposer.register(getTestRootDisposable(), new Disposable() {
@Override
public void dispose() {
JsonSchemaTestServiceImpl.setProvider(null);
}
});
myFixture.enableInspections(SpellCheckingInspection.class);
myFixture.checkHighlighting(true, false, true);
}
// WEB-31894 EA-117068
public void testAfterModificationOfStringLiteralWithEscaping() {
myFixture.configureByFile(getTestName(false) + ".json");
@@ -0,0 +1,8 @@
{
"properties": {
"qwertyuiop": {}
},
"patternProperties": {
"^boo.*moo$": {}
}
}
@@ -0,0 +1,6 @@
{
"$schema": "./Schema.json",
"qwertyuiop": "a",
"booxxxxmoo": "a",
"<TYPO>qwertyzop</TYPO>": "b"
}