mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
WEB-31865: add an intention action to sort properties
GitOrigin-RevId: e58db1b1395a3c6de03bcac5638987e0c8cb3ed2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f5b4c70b34
commit
7bbb655cd3
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"a": 9,
|
||||
"f": false,
|
||||
"x": 5,
|
||||
"z": true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"x": 5,
|
||||
"a": 9,
|
||||
"z": true,
|
||||
"f": false
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention sorts JSON object properties alphabetically.
|
||||
</body>
|
||||
</html>
|
||||
@@ -64,4 +64,6 @@ json.schema.ref.no.property=Property ''{0}'' not found
|
||||
|
||||
settings.json.schema.add.mapping=Add mapping
|
||||
settings.json.schema.edit.mapping=Edit mapping
|
||||
settings.json.schema.remove.mapping=Remove mapping
|
||||
settings.json.schema.remove.mapping=Remove mapping
|
||||
|
||||
json.intention.sort.properties=Sort properties alphabetically
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright 2000-2019 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.intellij.json.intentions;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction;
|
||||
import com.intellij.json.JsonBundle;
|
||||
import com.intellij.json.psi.JsonObject;
|
||||
import com.intellij.json.psi.JsonProperty;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JsonSortPropertiesIntention implements IntentionAction, LowPriorityAction {
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return JsonBundle.message("json.intention.sort.properties");
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return JsonBundle.message("json.intention.sort.properties");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
PsiElement parent = findParentObject(editor, file);
|
||||
return parent instanceof JsonObject && !isSorted((JsonObject)parent);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement findParentObject(@NotNull Editor editor, @NotNull PsiFile file) {
|
||||
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
JsonProperty property = PsiTreeUtil.getParentOfType(element, JsonProperty.class);
|
||||
return property == null ? null : property.getParent();
|
||||
}
|
||||
|
||||
private static boolean isSorted(@NotNull JsonObject parent) {
|
||||
List<JsonProperty> list = parent.getPropertyList();
|
||||
if (list.size() <= 1) return true;
|
||||
List<String> names = ContainerUtil.map(list, p -> p.getName());
|
||||
return ContainerUtil.equalsIdentity(ContainerUtil.sorted(names), names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
PsiElement parentObject = findParentObject(editor, file);
|
||||
assert parentObject instanceof JsonObject;
|
||||
// cycle-sort performs the minimal amount of modifications, and we want to patch the tree as little as possible
|
||||
cycleSortProperties(((JsonObject)parentObject).getPropertyList());
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
|
||||
codeStyleManager.reformat(parentObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void cycleSortProperties(@NotNull List<JsonProperty> properties) {
|
||||
int size = properties.size();
|
||||
for (int cycleStart = 0; cycleStart < size; cycleStart++) {
|
||||
JsonProperty item = properties.get(cycleStart);
|
||||
int pos = advance(properties, size, cycleStart, item);
|
||||
if (pos == -1) continue;
|
||||
if (pos != cycleStart) {
|
||||
exchange(properties, pos, cycleStart);
|
||||
}
|
||||
while (pos != cycleStart) {
|
||||
pos = advance(properties, size, cycleStart, properties.get(cycleStart));
|
||||
if (pos == -1) break;
|
||||
if (pos != cycleStart) {
|
||||
exchange(properties, pos, cycleStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int advance(@NotNull List<JsonProperty> properties, int size, int cycleStart, JsonProperty item) {
|
||||
int pos = cycleStart;
|
||||
String itemName = item.getName();
|
||||
for (int i = cycleStart + 1; i < size; i++) {
|
||||
if (properties.get(i).getName().compareTo(itemName) < 0) pos++;
|
||||
}
|
||||
if (pos == cycleStart) return -1;
|
||||
while (item == properties.get(pos)) pos++;
|
||||
return pos;
|
||||
}
|
||||
|
||||
private static void exchange(@NotNull List<JsonProperty> properties, int pos, int item) {
|
||||
JsonProperty propertyAtPos = properties.get(pos);
|
||||
JsonProperty itemProperty = properties.get(item);
|
||||
properties.set(pos, (JsonProperty)propertyAtPos.getParent().addBefore(itemProperty, propertyAtPos));
|
||||
properties.set(item, (JsonProperty)itemProperty.getParent().addBefore(propertyAtPos, itemProperty));
|
||||
propertyAtPos.delete();
|
||||
itemProperty.delete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2000-2019 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.intellij.json;
|
||||
|
||||
public class JsonIntentionActionTest extends JsonTestCase {
|
||||
|
||||
private void doTest(@SuppressWarnings("SameParameterValue") String intentionKey) {
|
||||
myFixture.testHighlighting("/intention/" + getTestName(false) + ".json");
|
||||
myFixture.launchAction(myFixture.getAvailableIntention(JsonBundle.message(intentionKey)));
|
||||
myFixture.checkResultByFile("/intention/" + getTestName(false) + "_after.json");
|
||||
}
|
||||
|
||||
public void testSortProperties() {
|
||||
doTest("json.intention.sort.properties");
|
||||
}
|
||||
}
|
||||
3
json/tests/testData/intention/SortProperties.json
Normal file
3
json/tests/testData/intention/SortProperties.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"MAP<caret>BLKLOT": "0001001", "BLKLOT": "0001001", "BLOCK_NUM": "0001", "LOT_NUM": "001", "FROM_ST": "0", "TO_ST": "0", "STREET": "UNKNOWN", "ST_TYPE": null, "ODD_EVEN": "E"
|
||||
}
|
||||
11
json/tests/testData/intention/SortProperties_after.json
Normal file
11
json/tests/testData/intention/SortProperties_after.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"BLKLOT": "0001001",
|
||||
"BLOCK_NUM": "0001",
|
||||
"FROM_ST": "0",
|
||||
"LOT_NUM": "001",
|
||||
"MAPBLKLOT": "0001001",
|
||||
"ODD_EVEN": "E",
|
||||
"STREET": "UNKNOWN",
|
||||
"ST_TYPE": null,
|
||||
"TO_ST": "0"
|
||||
}
|
||||
@@ -111,6 +111,10 @@
|
||||
<gotoDeclarationHandler implementation="com.jetbrains.jsonSchema.impl.JsonSchemaGotoDeclarationHandler"/>
|
||||
<copyPastePostProcessor implementation="com.intellij.json.editor.JsonCopyPastePostProcessor"/>
|
||||
<highlightVisitor implementation="com.intellij.json.highlighting.JsonRainbowVisitor"/>
|
||||
<intentionAction>
|
||||
<className>com.intellij.json.intentions.JsonSortPropertiesIntention</className>
|
||||
<category>JSON</category>
|
||||
</intentionAction>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="JavaScript">
|
||||
<JsonSchema.ProviderFactory implementation="com.jetbrains.jsonSchema.extension.JsonSchemaUserDefinedProviderFactory"/>
|
||||
|
||||
Reference in New Issue
Block a user