IDEA-19061 Integrate the Rearranger-plugin into core-IDE

1. Making arrangement blank lines aware;
2. Refactoring;
This commit is contained in:
Denis.Zhdanov
2012-08-31 09:32:48 +04:00
parent e65b55b2da
commit a6c8c31272
9 changed files with 372 additions and 101 deletions
@@ -36,6 +36,7 @@ public class JavaElementArrangementEntry extends DefaultArrangementEntry
private final Set<ArrangementModifier> myModifiers = EnumSet.noneOf(ArrangementModifier.class);
@NotNull private final Set<ArrangementEntryType> myTypes;
@NotNull private final ArrangementEntryType myType;
@Nullable private final String myName;
public JavaElementArrangementEntry(@Nullable ArrangementEntry parent,
@@ -55,6 +56,7 @@ public class JavaElementArrangementEntry extends DefaultArrangementEntry
boolean canBeArranged)
{
super(parent, startOffset, endOffset, canBeArranged);
myType = type;
myTypes = EnumSet.of(type);
myName = name;
}
@@ -81,6 +83,11 @@ public class JavaElementArrangementEntry extends DefaultArrangementEntry
return myTypes;
}
@NotNull
public ArrangementEntryType getType() {
return myType;
}
@Override
public String toString() {
return String.format(
@@ -15,10 +15,13 @@
*/
package com.intellij.psi.codeStyle.arrangement;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
@@ -123,6 +126,36 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
return result;
}
@Override
public int getBlankLines(@NotNull CodeStyleSettings settings,
@Nullable JavaElementArrangementEntry parent,
@Nullable JavaElementArrangementEntry previous,
@NotNull JavaElementArrangementEntry target)
{
if (previous == null) {
return 0;
}
CommonCodeStyleSettings commonSettings = settings.getCommonSettings(JavaLanguage.INSTANCE);
switch (target.getType()) {
case FIELD:
if (parent != null && parent.getType() == INTERFACE) {
return commonSettings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE;
}
else {
return commonSettings.BLANK_LINES_AROUND_FIELD;
}
case METHOD:
if (parent != null && parent.getType() == INTERFACE) {
return commonSettings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE;
}
else {
return commonSettings.BLANK_LINES_AROUND_METHOD;
}
default: return 0;
}
}
@Override
public boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementMatchCondition current) {
return SUPPORTED_TYPES.contains(type);
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.codeStyle.arrangement
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.lang.java.JavaLanguage
/**
* @author Denis Zhdanov
* @since 8/30/12 12:15 PM
*/
abstract class AbstractJavaRearrangerTest extends AbstractRearrangerTest {
AbstractJavaRearrangerTest() {
fileType = JavaFileType.INSTANCE
language = JavaLanguage.INSTANCE
}
}
@@ -0,0 +1,83 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.codeStyle.arrangement
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType.*
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.PUBLIC
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.STATIC
/**
* @author Denis Zhdanov
* @since 8/30/12 12:14 PM
*/
public class JavaRearrangerBlankLinesTest extends AbstractJavaRearrangerTest {
void testPreserveRelativeBlankLines() {
commonSettings.BLANK_LINES_AROUND_FIELD = 1
commonSettings.BLANK_LINES_AROUND_METHOD = 2
commonSettings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE = 2
commonSettings.BLANK_LINES_AROUND_METHOD_IN_INTERFACE = 3
doTest(
'''\
class Test {
private void method1() {}
public void method2() {}
private int i;
public int j;
public static int k;
}
interface MyInterface {
void test1();
void test2();
int i = 0;
int j = 0;
}''',
'''\
interface MyInterface {
int i = 0;
int j = 0;
void test1();
void test2();
}
class Test {
public static int k;
public int j;
private int i;
public void method2() {}
private void method1() {}
}''',
[rule(INTERFACE),
rule(CLASS),
rule(FIELD, STATIC),
rule(FIELD, PUBLIC),
rule(FIELD),
rule(METHOD, PUBLIC),
rule(METHOD)]
)
}
}
@@ -15,22 +15,13 @@
*/
package com.intellij.psi.codeStyle.arrangement
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.lang.java.JavaLanguage
import static com.intellij.psi.codeStyle.arrangement.ArrangementUtil.and
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType.*
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.*
/**
* @author Denis Zhdanov
* @since 8/28/12 6:42 PM
*/
class JavaRearrangerByTypeAndModifierTest extends AbstractRearrangerTest {
JavaRearrangerByTypeAndModifierTest() {
fileType = JavaFileType.INSTANCE
language = JavaLanguage.INSTANCE
}
class JavaRearrangerByTypeAndModifierTest extends AbstractJavaRearrangerTest {
void testComplex() {
doTest(
@@ -62,17 +53,17 @@ class Test {
public class PublicInner {}
protected static class ProtectedStaticInner {}
}''',
[rule(and(atom(FIELD), atom(PUBLIC), atom(STATIC))),
rule(and(atom(FIELD), atom(PUBLIC))),
rule(and(atom(FIELD), atom(VOLATILE))),
rule(and(atom(FIELD), atom(PRIVATE))),
rule(and(atom(METHOD), atom(ABSTRACT))),
rule(and(atom(METHOD), atom(PUBLIC))),
rule(atom(METHOD)),
rule(atom(INTERFACE)),
rule(atom(ENUM)),
rule(and(atom(CLASS), atom(PUBLIC))),
rule(atom(CLASS))]
[rule(FIELD, PUBLIC, STATIC),
rule(FIELD, PUBLIC),
rule(FIELD, VOLATILE),
rule(FIELD, PRIVATE),
rule(METHOD, ABSTRACT),
rule(METHOD, PUBLIC),
rule(METHOD),
rule(INTERFACE),
rule(ENUM),
rule(CLASS, PUBLIC),
rule(CLASS)]
)
}
}
@@ -15,19 +15,12 @@
*/
package com.intellij.psi.codeStyle.arrangement
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.lang.java.JavaLanguage
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType.*
/**
* @author Denis Zhdanov
* @since 7/20/12 2:45 PM
*/
class JavaRearrangerByTypeTest extends AbstractRearrangerTest {
JavaRearrangerByTypeTest() {
fileType = JavaFileType.INSTANCE
language = JavaLanguage.INSTANCE
}
class JavaRearrangerByTypeTest extends AbstractJavaRearrangerTest {
void testFieldsBeforeMethods() {
doTest(
@@ -53,7 +46,7 @@ class Test2 {
public void test() {
}
}''',
[rule(atom(ArrangementEntryType.FIELD))]
[rule(FIELD)]
)
}
@@ -97,7 +90,7 @@ class Test {
return null;
}
}''',
[rule(atom(ArrangementEntryType.FIELD))]
[rule(FIELD)]
)
}
@@ -135,7 +128,7 @@ class Test {
});
}
}''',
[rule(atom(ArrangementEntryType.FIELD))]
[rule(FIELD)]
)
}
@@ -153,9 +146,9 @@ class Test {
enum E { ONE, TWO }
class Inner {}
}''',
[rule(atom(ArrangementEntryType.INTERFACE)),
rule(atom(ArrangementEntryType.ENUM)),
rule(atom(ArrangementEntryType.CLASS))]
[rule(INTERFACE),
rule(ENUM),
rule(CLASS)]
)
}
@@ -193,7 +186,7 @@ class Test {
});
}
}''',
[rule(atom(ArrangementEntryType.FIELD))]
[rule(FIELD)]
)
}
}
@@ -19,7 +19,9 @@ import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -46,4 +48,15 @@ public interface Rearranger<E extends ArrangementEntry> {
*/
@NotNull
Collection<E> parse(@NotNull PsiElement root, @NotNull Document document, @NotNull Collection<TextRange> ranges);
/**
* Allows to answer how many blank lines should be inserted before the target arrangement entry which position is changed.
*
* @param settings code style settings to use (it's assumed that returned result is derived from 'blank lines' code style settings)
* @param parent target entry's parent (if available)
* @param previous previous entry (if available)
* @param target target entry which blank lines number the caller is interested in
* @return number of blank lines to insert before the target entry
*/
int getBlankLines(@NotNull CodeStyleSettings settings, @Nullable E parent, @Nullable E previous, @NotNull E target);
}
@@ -18,9 +18,10 @@ package com.intellij.psi.codeStyle.arrangement.engine;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -30,7 +31,11 @@ import com.intellij.psi.codeStyle.arrangement.Rearranger;
import com.intellij.psi.codeStyle.arrangement.StdArrangementRule;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
import com.intellij.util.containers.Stack;
import com.intellij.util.text.CharArrayUtil;
import gnu.trove.TIntArrayList;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -53,13 +58,12 @@ public class ArrangementEngine {
return;
}
Rearranger<?> rearranger = Rearranger.EXTENSION.forLanguage(file.getLanguage());
final Rearranger<?> rearranger = Rearranger.EXTENSION.forLanguage(file.getLanguage());
if (rearranger == null) {
return;
}
CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(file.getProject()).getCurrentSettings();
final Ref<List<? extends ArrangementRule>> rulesRef = new Ref<List<? extends ArrangementRule>>();
final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(file.getProject()).getCurrentSettings();
List<? extends ArrangementRule> arrangementRules = settings.getCommonSettings(file.getLanguage()).getArrangementRules();
if (arrangementRules.isEmpty() && rearranger instanceof ArrangementStandardSettingsAware) {
List<StdArrangementRule> defaultRules = ((ArrangementStandardSettingsAware)rearranger).getDefaultRules();
@@ -70,11 +74,7 @@ public class ArrangementEngine {
if (arrangementRules.isEmpty()) {
return;
}
else {
rulesRef.set(arrangementRules);
}
final Collection<? extends ArrangementEntry> entriesToProcess = rearranger.parse(file, document, ranges);
final DocumentEx documentEx;
if (document instanceof DocumentEx && !((DocumentEx)document).isInBulkUpdate()) {
documentEx = (DocumentEx)document;
@@ -83,6 +83,8 @@ public class ArrangementEngine {
documentEx = null;
}
final Context<? extends ArrangementEntry> context = Context.from(rearranger, document, file, ranges, arrangementRules, settings);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -90,7 +92,7 @@ public class ArrangementEngine {
documentEx.setInBulkUpdate(true);
}
try {
doArrange(document, rulesRef.get(), entriesToProcess);
doArrange(context);
}
finally {
if (documentEx != null) {
@@ -101,10 +103,8 @@ public class ArrangementEngine {
});
}
private static void doArrange(@NotNull final Document document,
@NotNull List<? extends ArrangementRule> arrangementRules,
@NotNull Collection<? extends ArrangementEntry> entriesToProcess)
{
@SuppressWarnings("unchecked")
private static <E extends ArrangementEntry> void doArrange(Context<E> context) {
// The general idea is to process entries bottom-up where every processed group belongs to the same parent. We may not bother
// with entries text ranges then. We use a list and a stack for achieving that than.
//
@@ -115,8 +115,9 @@ public class ArrangementEngine {
//
// --------------------------
// Stage 1:
// list: Entry1 Entry2
// stack: [0, 0, 2]
// list: Entry1 Entry2 <-- entries to process
// stack: [0, 0, 2] <-- holds current iteration info at the following format:
// (start entry index at the auxiliary list (inclusive); current index; end index (exclusive))
// --------------------------
// Stage 2:
// list: Entry1 Entry2 Entry11 Entry12
@@ -161,17 +162,17 @@ public class ArrangementEngine {
// stack: [0, 2, 2]
// --------------------------
// arrange 'Entry1 Entry2'
List<ArrangementEntry> entries = new ArrayList<ArrangementEntry>();
Stack<StackEntry> stack = new Stack<StackEntry>();
entries.addAll(entriesToProcess);
stack.push(new StackEntry(0, entriesToProcess.size()));
entries.addAll(context.entries);
stack.push(new StackEntry(0, context.entries.size()));
while (!stack.isEmpty()) {
StackEntry stackEntry = stack.peek();
if (stackEntry.current >= stackEntry.end) {
List<ArrangementEntry> subEntries = entries.subList(stackEntry.start, stackEntry.end);
List<E> subEntries = (List<E>)entries.subList(stackEntry.start, stackEntry.end);
if (subEntries.size() > 1) {
doArrange(arrangementRules, subEntries, document);
doArrange(subEntries, context);
}
subEntries.clear();
stack.pop();
@@ -187,15 +188,15 @@ public class ArrangementEngine {
}
}
private static void doArrange(@NotNull List<? extends ArrangementRule> rules,
@NotNull List<? extends ArrangementEntry> entries,
@NotNull Document document)
@SuppressWarnings("unchecked")
private static <E extends ArrangementEntry> void doArrange(@NotNull List<E> entries,
@NotNull Context<E> context)
{
List<ArrangementEntry> arranged = new ArrayList<ArrangementEntry>();
Set<ArrangementEntry> unprocessed = new LinkedHashSet<ArrangementEntry>(entries);
List<E> arranged = new ArrayList<E>();
Set<E> unprocessed = new LinkedHashSet<E>(entries);
for (ArrangementRule rule : rules) {
for (ArrangementEntry entry : entries) {
for (ArrangementRule rule : context.rules) {
for (E entry : entries) {
if (entry.canBeMatched() && unprocessed.contains(entry) && rule.getMatcher().isMatched(entry)) {
arranged.add(entry);
unprocessed.remove(entry);
@@ -203,35 +204,152 @@ public class ArrangementEngine {
}
}
arranged.addAll(unprocessed);
if (arranged.equals(entries)) {
return;
}
context.prepare(arranged);
// We apply changes from the last position to the first position in order not to bother with offsets shifts.
ArrangementEntry parent = entries.get(0).getParent();
final String initial;
final int shift;
if (parent == null) {
initial = document.getCharsSequence().toString();
shift = 0;
}
else {
initial = document.getCharsSequence().subSequence(parent.getStartOffset(), parent.getEndOffset()).toString();
shift = parent.getStartOffset();
}
for (int i = arranged.size() - 1; i >= 0; i--) {
ArrangementEntry arrangedEntry = arranged.get(i);
ArrangementEntry initialEntry = entries.get(i);
if (!arrangedEntry.equals(initialEntry)) {
String text = initial.substring(arrangedEntry.getStartOffset() - shift, arrangedEntry.getEndOffset() - shift);
document.replaceString(initialEntry.getStartOffset(), initialEntry.getEndOffset(), text);
E arrangedEntry = arranged.get(i);
E initialEntry = entries.get(i);
context.replace(initialEntry, arrangedEntry, (E)arrangedEntry.getParent(), i > 0 ? arranged.get(i - 1) : null);
}
}
private static class Context<E extends ArrangementEntry> {
@NotNull public final Rearranger<E> rearranger;
@NotNull public final Collection<E> entries;
@NotNull public final Document document;
@NotNull public final List<? extends ArrangementRule> rules;
@NotNull public final CodeStyleSettings mySettings;
/** Holds information on how many symbols was added to the initial entry text during the processing. */
@NotNull private final TObjectIntHashMap<ArrangementEntry> myExtraSizes = new TObjectIntHashMap<ArrangementEntry>();
@NotNull private String myParentText;
private int myParentShift;
private Context(@NotNull Rearranger<E> rearranger,
@NotNull Collection<E> entries,
@NotNull Document document,
@NotNull List<? extends ArrangementRule> rules,
@NotNull CodeStyleSettings settings)
{
this.rearranger = rearranger;
this.entries = entries;
this.document = document;
this.rules = rules;
mySettings = settings;
}
public static <T extends ArrangementEntry> Context<T> from(@NotNull Rearranger<T> rearranger,
@NotNull Document document,
@NotNull PsiElement root,
@NotNull Collection<TextRange> ranges,
@NotNull List<? extends ArrangementRule> rules,
@NotNull CodeStyleSettings settings)
{
Collection<T> entries = rearranger.parse(root, document, ranges);
return new Context<T>(rearranger, entries, document, rules, settings);
}
public void prepare(@NotNull List<E> arrangedEntries) {
if (arrangedEntries.isEmpty()) {
return;
}
E parent = arrangedEntries.get(0);
if (parent == null) {
myParentText = document.getText();
myParentShift = 0;
}
else {
int endOffset = parent.getEndOffset();
if (myExtraSizes.containsKey(parent)) {
endOffset += myExtraSizes.get(parent);
}
myParentText = document.getCharsSequence().subSequence(parent.getStartOffset(), endOffset).toString();
myParentShift = parent.getStartOffset();
}
}
/**
* Replaces given 'old entry' by the given 'new entry'.
*
* @param oldEntry entry which range should be replaced by the given 'new entry'
* @param newEntry entry which text should replace given 'old entry' range
* @param parent parent entry for the given entries
* @param previous previous entry for the 'new entry' (if any)
*/
@SuppressWarnings("AssignmentToForLoopParameter")
public void replace(@NotNull E oldEntry, @NotNull E newEntry, @Nullable E parent, @Nullable E previous) {
// Calculate blank lines before the arrangement.
int blankLinesBefore = 0;
TIntArrayList lineFeedOffsets = new TIntArrayList();
int oldStartLine = document.getLineNumber(oldEntry.getStartOffset());
if (oldStartLine > 0) {
int lastLineFeed = document.getLineStartOffset(oldStartLine) - 1;
lineFeedOffsets.add(lastLineFeed);
for (int i = lastLineFeed - 1 - myParentShift; i >= 0; i--) {
i = CharArrayUtil.shiftBackward(myParentText, i, " \t");
if (myParentText.charAt(i) == '\n') {
blankLinesBefore++;
lineFeedOffsets.add(i + myParentShift);
}
else {
break;
}
}
}
int desiredBlankLinesNumber = rearranger.getBlankLines(mySettings, parent, previous, newEntry);
if (desiredBlankLinesNumber == blankLinesBefore && newEntry.equals(oldEntry)) {
return;
}
String newEntryText = myParentText.substring(newEntry.getStartOffset() - myParentShift, newEntry.getEndOffset() - myParentShift);
int lineFeedsDiff = desiredBlankLinesNumber - blankLinesBefore;
if (lineFeedsDiff == 0) {
document.replaceString(oldEntry.getStartOffset(), oldEntry.getEndOffset(), newEntryText);
return;
}
int oldEndOffset = oldEntry.getEndOffset();
if (myExtraSizes.containsKey(oldEntry)) {
oldEndOffset += myExtraSizes.get(oldEntry);
}
if (lineFeedsDiff > 0) {
StringBuilder buffer = new StringBuilder(StringUtil.repeat("\n", lineFeedsDiff));
buffer.append(newEntryText);
document.replaceString(oldEntry.getStartOffset(), oldEndOffset, buffer);
for (ArrangementEntry entry = newEntry; entry != null; entry = entry.getParent()) {
if (myExtraSizes.containsKey(entry)) {
myExtraSizes.put(entry, myExtraSizes.get(entry) + lineFeedsDiff);
}
else {
myExtraSizes.put(entry, lineFeedsDiff);
}
}
}
else if (desiredBlankLinesNumber == blankLinesBefore) {
document.replaceString(oldEntry.getStartOffset(), oldEndOffset, newEntryText);
}
else {
// Cut exceeding blank lines.
int blankLinesToCut = blankLinesBefore - desiredBlankLinesNumber;
int replacementStartOffset = lineFeedOffsets.get(lineFeedOffsets.size() - blankLinesToCut);
document.replaceString(replacementStartOffset, oldEndOffset, newEntryText);
}
for (ArrangementEntry entry = newEntry; entry != null; entry = entry.getParent()) {
if (myExtraSizes.containsKey(entry)) {
myExtraSizes.put(entry, myExtraSizes.get(entry) + lineFeedsDiff);
}
else {
myExtraSizes.put(entry, lineFeedsDiff);
}
}
}
}
private static class StackEntry {
public int start;
public int current;
public int end;
@@ -21,13 +21,11 @@ import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.util.TextRange
import com.intellij.psi.codeStyle.CodeStyleSettings
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
import org.jetbrains.annotations.NotNull
/**
@@ -51,23 +49,27 @@ abstract class AbstractRearrangerTest extends LightPlatformCodeInsightFixtureTes
super.tearDown()
}
protected StdArrangementRule rule(@NotNull ArrangementMatchCondition condition) {
@NotNull
protected CommonCodeStyleSettings getCommonSettings() {
CodeStyleSettingsManager.getInstance(myFixture.project).currentSettings.getCommonSettings(language)
}
@NotNull
protected StdArrangementRule rule(@NotNull Object ... conditions) {
def condition
if (conditions.length == 1) {
condition = atom(conditions[0])
}
else {
condition = ArrangementUtil.and(conditions.collect { atom(it) } as ArrangementMatchCondition[])
}
new StdArrangementRule(new StdArrangementEntryMatcher(condition))
}
@NotNull
protected ArrangementAtomMatchCondition atom(@NotNull Object condition) {
def type;
if (condition in ArrangementEntryType) {
type = ArrangementSettingType.TYPE;
}
else if (condition in ArrangementModifier) {
type = ArrangementSettingType.MODIFIER
}
else {
throw new IllegalArgumentException("Unexpected condition of type '${condition.class}': $condition")
}
new ArrangementAtomMatchCondition(type, condition)
new ArrangementAtomMatchCondition(ArrangementUtil.parseType(condition), condition)
}
protected void doTest(@NotNull String initial,