mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
[http-client + yaml + json] IJ-CR-112452 Review fixes
- Made intention preview available - Merged subsequent read actions - Made isAvailable work very fast - Tried to set the same id to all commands to achieve single redo for the entire request, but that didn't work out yet GitOrigin-RevId: 54f4a3458bb05d1a03729483a95b269fbf2875e0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
17e3852cca
commit
9c49b47de2
@@ -42,9 +42,7 @@ public interface JsonSchemaService {
|
||||
Collection<VirtualFile> getSchemaFilesForFile(@NotNull VirtualFile file);
|
||||
|
||||
@Nullable
|
||||
default VirtualFile getDynamicSchemaForFile(@NotNull PsiFile psiFile) {
|
||||
return null;
|
||||
}
|
||||
VirtualFile getDynamicSchemaForFile(@NotNull PsiFile psiFile);
|
||||
void registerRemoteUpdateCallback(@NotNull Runnable callback);
|
||||
void unregisterRemoteUpdateCallback(@NotNull Runnable callback);
|
||||
void registerResetAction(Runnable action);
|
||||
|
||||
@@ -260,6 +260,11 @@ public final class JsonCachedValues {
|
||||
return value == JsonSchemaObject.NULL_OBJ ? null : value;
|
||||
}
|
||||
|
||||
public static boolean hasComputedSchemaObjectForFile(@NotNull PsiFile file) {
|
||||
CachedValue<JsonSchemaObject> data = CompletionUtil.getOriginalOrSelf(file).getUserData(OBJECT_FOR_FILE_KEY);
|
||||
return data != null && data.hasUpToDateValue();
|
||||
}
|
||||
|
||||
private static @NotNull Pair<PsiFile, JsonSchemaObject> getSchemaFile(@NotNull PsiFile originalFile,
|
||||
@NotNull JsonSchemaService service) {
|
||||
VirtualFile virtualFile = originalFile.getVirtualFile();
|
||||
|
||||
@@ -116,44 +116,44 @@ public class AddMissingPropertyFix implements LocalQuickFix, BatchQuickFix {
|
||||
if (node == null) return null;
|
||||
PsiElement element = node instanceof PsiFile ? node.getFirstChild() : node;
|
||||
Ref<PsiElement> newElementRef = Ref.create(null);
|
||||
WriteAction.run(() -> { performFixInner(hadComma, element, newElementRef); });
|
||||
return newElementRef.get();
|
||||
}
|
||||
|
||||
WriteAction.run(() -> {
|
||||
boolean isSingle = myData.myMissingPropertyIssues.size() == 1;
|
||||
PsiElement processedElement = element;
|
||||
List<JsonValidationError.MissingPropertyIssueData> reverseOrder
|
||||
= ContainerUtil.reverse(new ArrayList<>(myData.myMissingPropertyIssues));
|
||||
for (JsonValidationError.MissingPropertyIssueData issue: reverseOrder) {
|
||||
Object defaultValueObject = issue.defaultValue;
|
||||
String defaultValue = formatDefaultValue(defaultValueObject, element.getLanguage());
|
||||
PsiElement property = myQuickFixAdapter.createProperty(issue.propertyName, defaultValue == null
|
||||
? myQuickFixAdapter
|
||||
.getDefaultValueFromType(issue.propertyType)
|
||||
: defaultValue, element);
|
||||
PsiElement newElement;
|
||||
if (processedElement instanceof LeafPsiElement) {
|
||||
newElement = myQuickFixAdapter.adjustPropertyAnchor((LeafPsiElement)processedElement).addBefore(property, null);
|
||||
public void performFixInner(@NotNull Ref<Boolean> hadComma, PsiElement element, Ref<PsiElement> newElementRef) {
|
||||
boolean isSingle = myData.myMissingPropertyIssues.size() == 1;
|
||||
PsiElement processedElement = element;
|
||||
List<JsonValidationError.MissingPropertyIssueData> reverseOrder
|
||||
= ContainerUtil.reverse(new ArrayList<>(myData.myMissingPropertyIssues));
|
||||
for (JsonValidationError.MissingPropertyIssueData issue: reverseOrder) {
|
||||
Object defaultValueObject = issue.defaultValue;
|
||||
String defaultValue = formatDefaultValue(defaultValueObject, element.getLanguage());
|
||||
PsiElement property = myQuickFixAdapter.createProperty(issue.propertyName, defaultValue == null
|
||||
? myQuickFixAdapter
|
||||
.getDefaultValueFromType(issue.propertyType)
|
||||
: defaultValue, element);
|
||||
PsiElement newElement;
|
||||
if (processedElement instanceof LeafPsiElement) {
|
||||
newElement = myQuickFixAdapter.adjustPropertyAnchor((LeafPsiElement)processedElement).addBefore(property, null);
|
||||
}
|
||||
else {
|
||||
if (processedElement == element) {
|
||||
newElement = processedElement.addBefore(property, processedElement.getLastChild());
|
||||
}
|
||||
else {
|
||||
if (processedElement == element) {
|
||||
newElement = processedElement.addBefore(property, processedElement.getLastChild());
|
||||
}
|
||||
else {
|
||||
newElement = processedElement.getParent().addBefore(property, processedElement);
|
||||
}
|
||||
}
|
||||
PsiElement adjusted = myQuickFixAdapter.adjustNewProperty(newElement);
|
||||
hadComma.set(myQuickFixAdapter.ensureComma(adjusted, PsiTreeUtil.skipWhitespacesAndCommentsForward(newElement)));
|
||||
if (!hadComma.get()) {
|
||||
hadComma.set(processedElement == element && myQuickFixAdapter.ensureComma(PsiTreeUtil.skipWhitespacesAndCommentsBackward(newElement), adjusted));
|
||||
}
|
||||
processedElement = adjusted;
|
||||
if (isSingle) {
|
||||
newElementRef.set(adjusted);
|
||||
newElement = processedElement.getParent().addBefore(property, processedElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return newElementRef.get();
|
||||
PsiElement adjusted = myQuickFixAdapter.adjustNewProperty(newElement);
|
||||
hadComma.set(myQuickFixAdapter.ensureComma(adjusted, PsiTreeUtil.skipWhitespacesAndCommentsForward(newElement)));
|
||||
if (!hadComma.get()) {
|
||||
hadComma.set(processedElement == element && myQuickFixAdapter.ensureComma(PsiTreeUtil.skipWhitespacesAndCommentsBackward(newElement), adjusted));
|
||||
}
|
||||
processedElement = adjusted;
|
||||
if (isSingle) {
|
||||
newElementRef.set(adjusted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.jetbrains.jsonSchema.impl.fixes
|
||||
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.json.JsonBundle
|
||||
import com.intellij.json.psi.JsonObject
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
@@ -14,6 +15,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.util.parentOfType
|
||||
import com.jetbrains.jsonSchema.extension.JsonLikeSyntaxAdapter
|
||||
import com.jetbrains.jsonSchema.impl.JsonCachedValues
|
||||
import com.jetbrains.jsonSchema.impl.JsonOriginalPsiWalker
|
||||
|
||||
open class AddOptionalPropertiesIntention : IntentionAction {
|
||||
@@ -31,8 +33,7 @@ open class AddOptionalPropertiesIntention : IntentionAction {
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
|
||||
val containingObject = findContainingObjectNode(editor, file) ?: return false
|
||||
val missingProperties = collectMissingPropertiesFromSchema(containingObject, containingObject.project)
|
||||
return missingProperties != null && !missingProperties.hasOnlyRequiredPropertiesMissing
|
||||
return JsonCachedValues.hasComputedSchemaObjectForFile(containingObject.containingFile)
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor, file: PsiFile) {
|
||||
@@ -55,4 +56,14 @@ open class AddOptionalPropertiesIntention : IntentionAction {
|
||||
protected open fun getSyntaxAdapter(project: Project): JsonLikeSyntaxAdapter {
|
||||
return JsonOriginalPsiWalker.INSTANCE.getSyntaxAdapter(project)
|
||||
}
|
||||
|
||||
override fun generatePreview(project: Project, editor: Editor, file: PsiFile): IntentionPreviewInfo {
|
||||
val containingObject = findContainingObjectNode(editor, file) ?: return IntentionPreviewInfo.EMPTY
|
||||
val missingProperties = collectMissingPropertiesFromSchema(containingObject, containingObject.project)
|
||||
?.missingKnownProperties ?: return IntentionPreviewInfo.EMPTY
|
||||
AddMissingPropertyFix(missingProperties, getSyntaxAdapter(project))
|
||||
.performFixInner(Ref.create(), containingObject, Ref.create())
|
||||
ReformatCodeProcessor(containingObject.containingFile, false).run()
|
||||
return IntentionPreviewInfo.DIFF
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ package com.jetbrains.jsonSchema.intentions
|
||||
|
||||
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler
|
||||
import com.intellij.json.JsonTestCase
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.jetbrains.jsonSchema.JsonSchemaHighlightingTestBase.registerJsonSchema
|
||||
import com.jetbrains.jsonSchema.ide.JsonSchemaService
|
||||
import com.jetbrains.jsonSchema.impl.fixes.AddOptionalPropertiesIntention
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.junit.Assert
|
||||
@@ -55,12 +57,23 @@ class AddOptionalPropertiesIntentionTest : JsonTestCase() {
|
||||
""".trimIndent(),
|
||||
"json"
|
||||
) { true }
|
||||
myFixture.configureByText("test.json", before)
|
||||
val json = myFixture.configureByText("test.json", before)
|
||||
|
||||
ensureSchemaIsCached(json)
|
||||
val intention = myFixture.getAvailableIntention(AddOptionalPropertiesIntention().text)!!
|
||||
ShowIntentionActionsHandler.chooseActionAndInvoke(myFixture.file, myFixture.editor, intention, intention.text)
|
||||
|
||||
ensureSchemaIsCached(json)
|
||||
val previewText = myFixture.getIntentionPreviewText(intention)
|
||||
Assert.assertEquals(after, previewText)
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
// Since intention now relies on CachedValue API, we have to make sure that no dependencies were updated before intention#isAvailable call
|
||||
private fun ensureSchemaIsCached(json: PsiFile) {
|
||||
Assert.assertNotNull(JsonSchemaService.Impl.get(myFixture.project).getSchemaObject(json))
|
||||
}
|
||||
|
||||
fun `test insert properties in empty object`() {
|
||||
doTest(
|
||||
"""
|
||||
@@ -116,24 +129,6 @@ class AddOptionalPropertiesIntentionTest : JsonTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun `test intention unavailable if all properties are present`() {
|
||||
registerJsonSchema(myFixture, """
|
||||
{
|
||||
"properties": {
|
||||
"a" : {}
|
||||
}
|
||||
}
|
||||
""".trimIndent(), "json") { true }
|
||||
myFixture.configureByText("test.json", """
|
||||
{
|
||||
"a": 123
|
||||
<caret>
|
||||
}
|
||||
""".trimIndent())
|
||||
Assert.assertNull(myFixture.getAvailableIntention (AddOptionalPropertiesIntention().text))
|
||||
}
|
||||
|
||||
fun `test add example from schema as default value`() {
|
||||
doTest(
|
||||
"""
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
package org.jetbrains.yaml.intention
|
||||
|
||||
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import com.jetbrains.jsonSchema.JsonSchemaHighlightingTestBase
|
||||
import com.jetbrains.jsonSchema.ide.JsonSchemaService
|
||||
import com.jetbrains.jsonSchema.impl.fixes.AddOptionalPropertiesIntention
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.yaml.intentions.YAMLAddOptionalPropertiesIntention
|
||||
@@ -58,12 +60,22 @@ class YAMLAddOptionalPropertiesIntentionTest : BasePlatformTestCase() {
|
||||
) { true }
|
||||
}
|
||||
|
||||
private fun ensureSchemaIsCached(json: PsiFile) {
|
||||
Assert.assertNotNull(JsonSchemaService.Impl.get(myFixture.project).getSchemaObject(json))
|
||||
}
|
||||
|
||||
private fun doTest(@Language("yaml") before: String, @Language("yaml") after: String) {
|
||||
addSchema()
|
||||
|
||||
myFixture.configureByText("test.yaml", before)
|
||||
val yaml = myFixture.configureByText("test.yaml", before)
|
||||
Assert.assertNotNull(JsonSchemaService.Impl.get(myFixture.project).getSchemaObject(yaml))
|
||||
ensureSchemaIsCached(yaml)
|
||||
val intention = myFixture.findSingleIntention(YAMLAddOptionalPropertiesIntention().text)
|
||||
ShowIntentionActionsHandler.chooseActionAndInvoke(myFixture.file, myFixture.editor, intention, intention.text)
|
||||
|
||||
ensureSchemaIsCached(yaml)
|
||||
val previewText = myFixture.getIntentionPreviewText(intention)
|
||||
Assert.assertEquals(after, previewText)
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user