IDEA-CR-40081 fix caching top-level values for JSON

1) cache null values
2) better handle json-based file types
This commit is contained in:
Anton Lobov
2018-11-20 14:29:56 +01:00
parent 939ac38ebd
commit 5265c3f291
4 changed files with 31 additions and 35 deletions
@@ -71,7 +71,8 @@ public class JsonCachedValues {
@Nullable
static String fetchSchemaUrl(@Nullable PsiFile psiFile) {
if (!(psiFile instanceof JsonFile)) return null;
return JsonSchemaFileValuesIndex.readTopLevelProps(psiFile.getFileType(), psiFile.getText()).get(URL_CACHE_KEY);
final String url = JsonSchemaFileValuesIndex.readTopLevelProps(psiFile.getFileType(), psiFile.getText()).get(URL_CACHE_KEY);
return url == null || JsonSchemaFileValuesIndex.NULL.equals(url) ? null : url;
}
static final String ID_CACHE_KEY = "JsonSchemaIdCache";
@@ -81,14 +82,10 @@ public class JsonCachedValues {
public static String getSchemaId(@NotNull final VirtualFile schemaFile,
@NotNull final Project project) {
String value = JsonSchemaFileValuesIndex.getCachedValue(project, schemaFile, ID_CACHE_KEY);
if (value != null) {
return JsonSchemaFileValuesIndex.NULL.equals(value) ? null : JsonSchemaService.normalizeId(value);
}
value = JsonSchemaFileValuesIndex.getCachedValue(project, schemaFile, OBSOLETE_ID_CACHE_KEY);
if (value != null) {
return JsonSchemaFileValuesIndex.NULL.equals(value) ? null : JsonSchemaService.normalizeId(value);
}
if (value != null && !JsonSchemaFileValuesIndex.NULL.equals(value)) return JsonSchemaService.normalizeId(value);
String obsoleteValue = JsonSchemaFileValuesIndex.getCachedValue(project, schemaFile, OBSOLETE_ID_CACHE_KEY);
if (obsoleteValue != null && !JsonSchemaFileValuesIndex.NULL.equals(obsoleteValue)) return JsonSchemaService.normalizeId(obsoleteValue);
if (JsonSchemaFileValuesIndex.NULL.equals(value) || JsonSchemaFileValuesIndex.NULL.equals(obsoleteValue)) return null;
final String result = computeForFile(schemaFile, project, JsonCachedValues::fetchSchemaId, SCHEMA_ID_CACHE_KEY);
return result == null ? null : JsonSchemaService.normalizeId(result);
@@ -128,8 +125,9 @@ public class JsonCachedValues {
if (!(psiFile instanceof JsonFile)) return null;
final Map<String, String> props = JsonSchemaFileValuesIndex.readTopLevelProps(psiFile.getFileType(), psiFile.getText());
final String id = props.get(ID_CACHE_KEY);
if (id != null) return id;
return props.get(OBSOLETE_ID_CACHE_KEY);
if (id != null && !JsonSchemaFileValuesIndex.NULL.equals(id)) return id;
final String obsoleteId = props.get(OBSOLETE_ID_CACHE_KEY);
return obsoleteId == null || JsonSchemaFileValuesIndex.NULL.equals(obsoleteId) ? null : obsoleteId;
}
@@ -22,16 +22,13 @@ import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JsonSchemaFileValuesIndex extends FileBasedIndexExtension<String, String> {
public static final ID<String, String> INDEX_ID = ID.create("json.file.root.values");
private static final int VERSION = 1;
private static final int VERSION = 5;
public static final String NULL = "$NULL$";
@NotNull
@@ -64,17 +61,7 @@ public class JsonSchemaFileValuesIndex extends FileBasedIndexExtension<String, S
@NotNull
@Override
public DataExternalizer<String> getValueExternalizer() {
return new DataExternalizer<String>() {
@Override
public void save(@NotNull DataOutput out, String value) throws IOException {
out.writeUTF(value);
}
@Override
public String read(@NotNull DataInput in) throws IOException {
return in.readUTF();
}
};
return EnumeratorStringDescriptor.INSTANCE;
}
@Override
@@ -85,7 +72,7 @@ public class JsonSchemaFileValuesIndex extends FileBasedIndexExtension<String, S
@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(JsonFileType.INSTANCE, Json5FileType.INSTANCE);
return file -> file.getFileType() instanceof JsonFileType;
}
@Override
@@ -106,7 +93,7 @@ public class JsonSchemaFileValuesIndex extends FileBasedIndexExtension<String, S
@NotNull
static Map<String, String> readTopLevelProps(@NotNull FileType fileType, @NotNull CharSequence content) {
if (fileType != JsonFileType.INSTANCE && fileType != Json5FileType.INSTANCE) return ContainerUtil.newHashMap();
if (!(fileType instanceof JsonFileType)) return ContainerUtil.newHashMap();
Lexer lexer = fileType == Json5FileType.INSTANCE ? new Json5Lexer() : new JsonLexer();
final HashMap<String, String> map = ContainerUtil.newHashMap();
@@ -151,6 +138,9 @@ public class JsonSchemaFileValuesIndex extends FileBasedIndexExtension<String, S
}
lexer.advance();
}
if (!map.containsKey(JsonCachedValues.ID_CACHE_KEY)) map.put(JsonCachedValues.ID_CACHE_KEY, NULL);
if (!map.containsKey(JsonCachedValues.OBSOLETE_ID_CACHE_KEY)) map.put(JsonCachedValues.OBSOLETE_ID_CACHE_KEY, NULL);
if (!map.containsKey(JsonCachedValues.URL_CACHE_KEY)) map.put(JsonCachedValues.URL_CACHE_KEY, NULL);
return map;
}
@@ -28,33 +28,33 @@ public class JsonSchemaFileValuesIndexTest extends JsonTestCase {
public void testEmpty() {
final VirtualFile file = myFixture.configureByFile("indexing/empty.json").getVirtualFile();
Map<String, String> map = new JsonSchemaFileValuesIndex().getIndexer().map(FileContentImpl.createByFile(file));
assertTrue(map.isEmpty());
assertAllCacheNulls(map);
}
public void testSimple() {
final VirtualFile file = myFixture.configureByFile("indexing/empty.json").getVirtualFile();
Map<String, String> map = new JsonSchemaFileValuesIndex().getIndexer().map(FileContentImpl.createByFile(file));
assertTrue(map.isEmpty());
assertAllCacheNulls(map);
}
public void testValid() {
final VirtualFile file = myFixture.configureByFile("indexing/valid.json").getVirtualFile();
Map<String, String> map = new JsonSchemaFileValuesIndex().getIndexer().map(FileContentImpl.createByFile(file));
assertEquals("the-id", map.get(ID_CACHE_KEY));
assertNull(map.get(URL_CACHE_KEY));
assertCacheNull(map.get(URL_CACHE_KEY));
}
public void testValid2() {
final VirtualFile file = myFixture.configureByFile("indexing/valid2.json5").getVirtualFile();
Map<String, String> map = new JsonSchemaFileValuesIndex().getIndexer().map(FileContentImpl.createByFile(file));
assertEquals("the-schema", map.get(URL_CACHE_KEY));
assertNull(map.get(ID_CACHE_KEY));
assertCacheNull(map.get(ID_CACHE_KEY));
}
public void testInvalid() {
final VirtualFile file = myFixture.configureByFile("indexing/invalid.json").getVirtualFile();
Map<String, String> map = new JsonSchemaFileValuesIndex().getIndexer().map(FileContentImpl.createByFile(file));
assertTrue(map.isEmpty());
assertAllCacheNulls(map);
}
public void testStopsOnAllFound() {
@@ -64,4 +64,12 @@ public class JsonSchemaFileValuesIndexTest extends JsonTestCase {
assertEquals("the-id", map.get(ID_CACHE_KEY));
assertEquals("the-obsolete-id", map.get(OBSOLETE_ID_CACHE_KEY));
}
private static void assertCacheNull(String value) {
assertEquals(JsonSchemaFileValuesIndex.NULL, value);
}
private static void assertAllCacheNulls(Map<String, String> map) {
map.values().forEach(JsonSchemaFileValuesIndexTest::assertCacheNull);
}
}
@@ -1,7 +1,7 @@
{
"properties": {
"smth": {
"$ref" : "http://json-schema.org/draft-04/schema#/properties/enum<caret>"
"$ref" : "http://json-schema.org/draft-04/schema#/properties/enu<caret>m"
}
}
}
}