diff --git a/json/gen/com/intellij/json/psi/JsonStringLiteral.java b/json/gen/com/intellij/json/psi/JsonStringLiteral.java index 2e3d5221289c..260976c915ad 100644 --- a/json/gen/com/intellij/json/psi/JsonStringLiteral.java +++ b/json/gen/com/intellij/json/psi/JsonStringLiteral.java @@ -15,4 +15,6 @@ public interface JsonStringLiteral extends JsonLiteral { @NotNull String getValue(); + boolean isPropertyName(); + } diff --git a/json/gen/com/intellij/json/psi/impl/JsonStringLiteralImpl.java b/json/gen/com/intellij/json/psi/impl/JsonStringLiteralImpl.java index 823428e6430c..365409b9f54c 100644 --- a/json/gen/com/intellij/json/psi/impl/JsonStringLiteralImpl.java +++ b/json/gen/com/intellij/json/psi/impl/JsonStringLiteralImpl.java @@ -37,4 +37,8 @@ public class JsonStringLiteralImpl extends JsonStringLiteralMixin implements Jso return JsonPsiImplUtils.getValue(this); } + public boolean isPropertyName() { + return JsonPsiImplUtils.isPropertyName(this); + } + } diff --git a/json/json.bnf b/json/json.bnf index 701015ec6aa5..8036cf33d746 100644 --- a/json/json.bnf +++ b/json/json.bnf @@ -108,6 +108,7 @@ string_literal ::= SINGLE_QUOTED_STRING | DOUBLE_QUOTED_STRING { methods=[ getTextFragments getValue + isPropertyName SINGLE_QUOTED_STRING="" DOUBLE_QUOTED_STRING="" ] diff --git a/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java b/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java index ae1adb0f3ed4..126e3f7d2bcb 100644 --- a/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java +++ b/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java @@ -218,6 +218,11 @@ public class JsonPsiImplUtils { return StringUtil.unescapeStringCharacters(JsonPsiUtil.stripQuotes(literal.getText())); } + public static boolean isPropertyName(@NotNull JsonStringLiteral literal) { + final PsiElement parent = literal.getParent(); + return parent instanceof JsonProperty && ((JsonProperty)parent).getNameElement() == literal; + } + public static boolean getValue(@NotNull JsonBooleanLiteral literal) { return literal.textMatches("true"); } diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonPropertyName2SchemaDefinitionReferenceProvider.java b/json/src/com/jetbrains/jsonSchema/impl/JsonPropertyName2SchemaDefinitionReferenceProvider.java deleted file mode 100644 index 383259765b7f..000000000000 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonPropertyName2SchemaDefinitionReferenceProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2000-2018 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 com.jetbrains.jsonSchema.impl; - -import com.intellij.json.psi.JsonProperty; -import com.intellij.json.psi.JsonStringLiteral; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.ElementManipulators; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; -import com.intellij.psi.PsiReferenceProvider; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.ProcessingContext; -import com.jetbrains.jsonSchema.ide.JsonSchemaService; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * @author Irina.Chernushina on 4/15/2016. - */ -public class JsonPropertyName2SchemaDefinitionReferenceProvider extends PsiReferenceProvider { - @NotNull - @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { - return new PsiReference[] {new JsonPropertyName2SchemaRefReference((JsonStringLiteral)element)}; - } - - private static class JsonPropertyName2SchemaRefReference extends JsonSchemaBaseReference { - JsonPropertyName2SchemaRefReference(JsonStringLiteral element) { - super(element, ElementManipulators.getValueTextRange(element)); - } - - @Nullable - @Override - public PsiElement resolveInner() { - final JsonSchemaService service = JsonSchemaService.Impl.get(myElement.getProject()); - final VirtualFile file = myElement.getContainingFile().getVirtualFile(); - if (file == null || !service.isApplicableToFile(file)) return null; - final List steps = JsonOriginalPsiWalker.INSTANCE.findPosition(getElement(), true); - if (steps == null) return null; - final JsonSchemaObject schemaObject = service.getSchemaObject(file); - if (schemaObject != null) { - final JsonProperty parentProperty = PsiTreeUtil.getParentOfType(myElement, JsonProperty.class); - return new JsonSchemaResolver(schemaObject, true, steps) - .findNavigationTarget(false, parentProperty == null ? null : parentProperty.getValue(), - JsonSchemaService.isSchemaFile(myElement.getContainingFile())); - } - return null; - } - } -} diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaGotoDeclarationHandler.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaGotoDeclarationHandler.java new file mode 100644 index 000000000000..072bd5f56511 --- /dev/null +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaGotoDeclarationHandler.java @@ -0,0 +1,48 @@ +// Copyright 2000-2018 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 com.jetbrains.jsonSchema.impl; + +import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler; +import com.intellij.json.JsonElementTypes; +import com.intellij.json.psi.JsonProperty; +import com.intellij.json.psi.JsonStringLiteral; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; +import com.jetbrains.jsonSchema.ide.JsonSchemaService; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class JsonSchemaGotoDeclarationHandler implements GotoDeclarationHandler { + @Nullable + @Override + public PsiElement[] getGotoDeclarationTargets(@Nullable PsiElement sourceElement, int offset, Editor editor) { + final IElementType elementType = PsiUtilCore.getElementType(sourceElement); + if (elementType != JsonElementTypes.DOUBLE_QUOTED_STRING && elementType != JsonElementTypes.SINGLE_QUOTED_STRING) return null; + final JsonStringLiteral literal = PsiTreeUtil.getParentOfType(sourceElement, JsonStringLiteral.class); + if (literal == null) return null; + final PsiElement parent = literal.getParent(); + if (parent instanceof JsonProperty && ((JsonProperty)parent).getNameElement() == literal) { + final JsonSchemaService service = JsonSchemaService.Impl.get(literal.getProject()); + final PsiFile containingFile = literal.getContainingFile(); + final VirtualFile file = containingFile.getVirtualFile(); + if (file == null || !service.isApplicableToFile(file)) return null; + final List steps = JsonOriginalPsiWalker.INSTANCE.findPosition(literal, true); + if (steps == null) return null; + final JsonSchemaObject schemaObject = service.getSchemaObject(file); + if (schemaObject != null) { + final PsiElement target = new JsonSchemaResolver(schemaObject, false, steps) + .findNavigationTarget(false, ((JsonProperty)parent).getValue(), + JsonSchemaService.isSchemaFile(containingFile)); + if (target != null) { + return new PsiElement[] {target}; + } + } + } + return null; + } +} diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReferenceContributor.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReferenceContributor.java index 9e3d65569f95..d9f6a3256e6a 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReferenceContributor.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReferenceContributor.java @@ -36,13 +36,11 @@ import org.jetbrains.annotations.Nullable; */ public class JsonSchemaReferenceContributor extends PsiReferenceContributor { public static final PsiElementPattern.Capture REF_PATTERN = createPropertyValuePattern("$ref"); - public static final PsiElementPattern.Capture PROPERTY_NAME_PATTERN = createPropertyNamePattern(); public static final PsiElementPattern.Capture REQUIRED_PROP_PATTERN = createRequiredPropPattern(); @Override public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { registrar.registerReferenceProvider(REF_PATTERN, new JsonSchemaRefReferenceProvider()); - registrar.registerReferenceProvider(PROPERTY_NAME_PATTERN, new JsonPropertyName2SchemaDefinitionReferenceProvider()); registrar.registerReferenceProvider(REQUIRED_PROP_PATTERN, new JsonRequiredPropsReferenceProvider()); } @@ -70,24 +68,6 @@ public class JsonSchemaReferenceContributor extends PsiReferenceContributor { })); } - private static PsiElementPattern.Capture createPropertyNamePattern() { - return PlatformPatterns.psiElement(JsonStringLiteral.class).and(new FilterPattern(new ElementFilter() { - @Override - public boolean isAcceptable(Object element, @Nullable PsiElement context) { - if (element instanceof JsonStringLiteral) { - final PsiElement parent = ((JsonStringLiteral)element).getParent(); - return parent instanceof JsonProperty && ((JsonProperty)parent).getNameElement() == element; - } - return false; - } - - @Override - public boolean isClassAcceptable(Class hintClass) { - return true; - } - })); - } - private static PsiElementPattern.Capture createRequiredPropPattern() { return PlatformPatterns.psiElement(JsonStringLiteral.class).and(new FilterPattern(new ElementFilter() { @Override diff --git a/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaCrossReferencesTest.java b/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaCrossReferencesTest.java index 8e8fc41bb6f6..ff6083cb7c82 100644 --- a/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaCrossReferencesTest.java +++ b/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaCrossReferencesTest.java @@ -3,6 +3,7 @@ package com.jetbrains.jsonSchema; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction; import com.intellij.json.JsonFileType; import com.intellij.json.psi.*; import com.intellij.openapi.application.ApplicationManager; @@ -26,7 +27,6 @@ import com.jetbrains.jsonSchema.extension.JsonSchemaProjectSelfProviderFactory; import com.jetbrains.jsonSchema.ide.JsonSchemaService; import com.jetbrains.jsonSchema.impl.JsonSchemaComplianceInspection; import com.jetbrains.jsonSchema.impl.JsonSchemaObject; -import com.jetbrains.jsonSchema.impl.JsonSchemaReferenceContributor; import com.jetbrains.jsonSchema.impl.JsonSchemaVersion; import com.jetbrains.jsonSchema.schemaFile.TestJsonSchemaMappingsProjectConfiguration; import org.jetbrains.annotations.NotNull; @@ -196,7 +196,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { skeleton(new Callback() { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); + int offset = getCaretOffset(); final PsiReference referenceAt = myFile.findReferenceAt(offset); Assert.assertNotNull(referenceAt); final PsiElement resolve = referenceAt.resolve(); @@ -256,7 +256,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); + int offset = getCaretOffset(); final PsiReference referenceAt = myFile.findReferenceAt(offset); Assert.assertNotNull(referenceAt); final PsiElement resolve = referenceAt.resolve(); @@ -291,20 +291,8 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); - PsiElement element = myFile.findElementAt(offset); - boolean found = false; - while (element.getTextRange().contains(offset)) { - if (JsonSchemaReferenceContributor.PROPERTY_NAME_PATTERN.accepts(element)) { - found = true; - break; - } - element = element.getParent(); - } - Assert.assertTrue(found); - final PsiReference referenceAt = myFile.findReferenceAt(offset); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); + int offset = getCaretOffset(); + final PsiElement resolve = GotoDeclarationAction.findTargetElement(getProject(), myEditor, offset); Assert.assertNotNull(resolve); Assert.assertEquals("basePropertiesSchema.json", resolve.getContainingFile().getName()); Assert.assertEquals("\"baseEnum\"", resolve.getText()); @@ -330,7 +318,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); + int offset = getCaretOffset(); final PsiReference referenceAt = myFile.findReferenceAt(offset); Assert.assertNotNull(referenceAt); final PsiElement resolve = referenceAt.resolve(); @@ -361,7 +349,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); + int offset = getCaretOffset(); final PsiReference referenceAt = myFile.findReferenceAt(offset); Assert.assertNotNull(referenceAt); final PsiElement resolve = referenceAt.resolve(); @@ -391,9 +379,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { final String text = myFile.getText(); final int indexOf = text.indexOf("dependencies"); assertTrue(indexOf > 0); - final PsiReference referenceAt = myFile.findReferenceAt(indexOf); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); + final PsiElement resolve = GotoDeclarationAction.findTargetElement(getProject(), myEditor, indexOf); Assert.assertNotNull(resolve); Assert.assertEquals("packageJsonSchema.json", resolve.getContainingFile().getName()); Assert.assertEquals("\"dependencies\"", resolve.getText()); @@ -418,10 +404,8 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); - final PsiReference referenceAt = myFile.findReferenceAt(offset); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); + int offset = getCaretOffset(); + final PsiElement resolve = GotoDeclarationAction.findTargetElement(getProject(), myEditor, offset); Assert.assertNotNull(resolve); Assert.assertEquals("nestedDefinitionsSchema.json", resolve.getContainingFile().getName()); Assert.assertEquals("\"definitions\"", resolve.getText()); @@ -448,10 +432,8 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); - final PsiReference referenceAt = myFile.findReferenceAt(offset); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); + int offset = getCaretOffset(); + final PsiElement resolve = GotoDeclarationAction.findTargetElement(getProject(), myEditor, offset); Assert.assertNotNull(resolve); Assert.assertEquals("nestedAllOfOneOfDefinitionsSchema.json", resolve.getContainingFile().getName()); Assert.assertEquals("\"begriff\"", resolve.getText()); @@ -478,10 +460,8 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); - final PsiReference referenceAt = myFile.findReferenceAt(offset); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); + int offset = getCaretOffset(); + final PsiElement resolve = GotoDeclarationAction.findTargetElement(getProject(), myEditor, offset); Assert.assertNotNull(resolve); Assert.assertEquals("baseSchema.json", resolve.getContainingFile().getName()); Assert.assertEquals("\"findMe\"", resolve.getText()); @@ -556,7 +536,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); + int offset = getCaretOffset(); final PsiReference referenceAt = myFile.findReferenceAt(offset); Assert.assertNotNull(referenceAt); final PsiElement resolve = referenceAt.resolve(); @@ -618,10 +598,8 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); - final PsiReference referenceAt = myFile.findReferenceAt(offset); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); + int offset = getCaretOffset(); + final PsiElement resolve = GotoDeclarationAction.findTargetElement(getProject(), myEditor, offset); Assert.assertNotNull(resolve); Assert.assertEquals("\"properties\"", resolve.getText()); final PsiElement parent = resolve.getParent(); @@ -699,23 +677,19 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { " }\n" + " }\n" + " }"; - checkNavigationTo(midia, "midia", JsonSchemaObject.DEFINITIONS); + checkNavigationTo(midia, "midia", getCaretOffset(), JsonSchemaObject.DEFINITIONS, true); } }); } - private void checkNavigationTo(@NotNull String resolvedText, @NotNull String name, @NotNull String base) { - int offset = myEditor.getCaretModel().getPrimaryCaret().getOffset(); - final PsiElement element = myFile.findElementAt(offset); - Assert.assertNotNull(element); - - checkNavigationTo(resolvedText, name, offset, base); + private int getCaretOffset() { + return myEditor.getCaretModel().getPrimaryCaret().getOffset(); } - private void checkNavigationTo(@NotNull String resolvedText, @NotNull String name, int offset, @NotNull String base) { - final PsiReference referenceAt = myFile.findReferenceAt(offset); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); + private void checkNavigationTo(@NotNull String resolvedText, @NotNull String name, int offset, @NotNull String base, boolean isReference) { + final PsiElement resolve = isReference + ? myFile.findReferenceAt(offset).resolve() + : GotoDeclarationAction.findTargetElement(getProject(), myEditor, offset); Assert.assertNotNull(resolve); Assert.assertEquals(resolvedText, resolve.getText()); final PsiElement parent = resolve.getParent(); @@ -744,7 +718,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { public void doCheck() { checkNavigationTo("{\n" + " \"$ref\": \"#/definitions/one\"\n" + - " }", "all", JsonSchemaObject.DEFINITIONS); + " }", "all", getCaretOffset(), JsonSchemaObject.DEFINITIONS, true); } }); } @@ -766,7 +740,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - checkNavigationTo("\"bbb\"", "bbb", JsonSchemaObject.PROPERTIES); + checkNavigationTo("\"bbb\"", "bbb", getCaretOffset(), JsonSchemaObject.PROPERTIES, false); } }); } @@ -803,7 +777,8 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { " \"type\": \"string\"\n" + " }\n" + " }\n" + - " }", "cycle.schema", literal.getTextRange().getEndOffset() - 1, JsonSchemaObject.DEFINITIONS)); + " }", "cycle.schema", literal.getTextRange().getEndOffset() - 1, + JsonSchemaObject.DEFINITIONS, true)); } }); } @@ -827,7 +802,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { @Override public void doCheck() { - checkNavigationTo("\"id\"", "id", JsonSchemaObject.PROPERTIES); + checkNavigationTo("\"id\"", "id", getCaretOffset(), JsonSchemaObject.PROPERTIES, false); } }); } @@ -902,10 +877,7 @@ public class JsonSchemaCrossReferencesTest extends JsonSchemaHeavyAbstractTest { } private void checkNavigationToSchemaVariant(@NotNull String name, int offset, @NotNull String parentPropertyName) { - final PsiReference referenceAt = myFile.findReferenceAt(offset); - Assert.assertNotNull(referenceAt); - final PsiElement resolve = referenceAt.resolve(); - Assert.assertNotNull(resolve); + final PsiElement resolve = GotoDeclarationAction.findTargetElement(getProject(), myEditor, offset); Assert.assertEquals("\"" + name + "\"", resolve.getText()); final PsiElement parent = resolve.getParent(); Assert.assertTrue(parent instanceof JsonProperty); diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml index 4255fbb9accd..9575d30dea16 100644 --- a/platform/platform-resources/src/META-INF/JsonPlugin.xml +++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml @@ -102,6 +102,7 @@ +