From 5265c3f291b2e79563df8c19d2b9c362f187271a Mon Sep 17 00:00:00 2001 From: Anton Lobov Date: Tue, 20 Nov 2018 14:28:35 +0100 Subject: [PATCH] IDEA-CR-40081 fix caching top-level values for JSON 1) cache null values 2) better handle json-based file types --- .../jsonSchema/impl/JsonCachedValues.java | 20 +++++++--------- .../impl/JsonSchemaFileValuesIndex.java | 24 ++++++------------- .../impl/JsonSchemaFileValuesIndexTest.java | 18 ++++++++++---- .../referencingGlobalSchema.json | 4 ++-- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonCachedValues.java b/json/src/com/jetbrains/jsonSchema/impl/JsonCachedValues.java index 1f83e1d7e817..40773ae4a1b4 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonCachedValues.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonCachedValues.java @@ -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 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; } diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaFileValuesIndex.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaFileValuesIndex.java index d2bce7eb318d..e48273585b2a 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaFileValuesIndex.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaFileValuesIndex.java @@ -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 { public static final ID 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 getValueExternalizer() { - return new DataExternalizer() { - @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 file.getFileType() instanceof JsonFileType; } @Override @@ -106,7 +93,7 @@ public class JsonSchemaFileValuesIndex extends FileBasedIndexExtension 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 map = ContainerUtil.newHashMap(); @@ -151,6 +138,9 @@ public class JsonSchemaFileValuesIndex extends FileBasedIndexExtension 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 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 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 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 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 map) { + map.values().forEach(JsonSchemaFileValuesIndexTest::assertCacheNull); + } } diff --git a/json/tests/testData/jsonSchema/crossReferences/referencingGlobalSchema.json b/json/tests/testData/jsonSchema/crossReferences/referencingGlobalSchema.json index 612d7e8a0109..dd2b1e1a8104 100644 --- a/json/tests/testData/jsonSchema/crossReferences/referencingGlobalSchema.json +++ b/json/tests/testData/jsonSchema/crossReferences/referencingGlobalSchema.json @@ -1,7 +1,7 @@ { "properties": { "smth": { - "$ref" : "http://json-schema.org/draft-04/schema#/properties/enum" + "$ref" : "http://json-schema.org/draft-04/schema#/properties/enum" } } -} \ No newline at end of file +}