diff --git a/platform/lang-api/lang-api.iml b/platform/lang-api/lang-api.iml
index 0c89574778c7..c11c72642e4c 100644
--- a/platform/lang-api/lang-api.iml
+++ b/platform/lang-api/lang-api.iml
@@ -4,6 +4,7 @@
+
@@ -12,6 +13,8 @@
+
+
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
index d5f3e7143669..15bf90ccec1f 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * 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.
@@ -19,6 +19,8 @@ import com.intellij.lang.Language;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.*;
+import com.intellij.psi.codeStyle.arrangement.ArrangementRule;
+import com.intellij.psi.codeStyle.arrangement.ArrangementRuleUtil;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import org.intellij.lang.annotations.MagicConstant;
@@ -28,6 +30,8 @@ import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
/**
@@ -37,11 +41,14 @@ import java.util.Set;
* @author Rustam Vishnyakov
*/
public class CommonCodeStyleSettings {
-
- private Language myLanguage;
+
+ @NotNull private static final String ARRANGEMENT_ELEMENT_NAME = "arrangementRules";
+
+ @NotNull private final List myArrangementRules = new ArrayList();
+ private Language myLanguage;
private CodeStyleSettings myRootSettings;
- private IndentOptions myIndentOptions;
- private FileType myFileType;
+ private IndentOptions myIndentOptions;
+ private FileType myFileType;
private final static String INDENT_OPTIONS_TAG = "indentOptions";
@@ -193,6 +200,10 @@ public class CommonCodeStyleSettings {
myIndentOptions.deserialize(indentOptionsElement);
}
}
+ Element arrangementRulesContainer = element.getChild(ARRANGEMENT_ELEMENT_NAME);
+ if (arrangementRulesContainer != null) {
+ myArrangementRules.addAll(ArrangementRuleUtil.readExternal(arrangementRulesContainer, myLanguage));
+ }
}
public void writeExternal(Element element) throws WriteExternalException {
@@ -210,6 +221,14 @@ public class CommonCodeStyleSettings {
element.addContent(indentOptionsElement);
}
}
+
+ if (!myArrangementRules.isEmpty()) {
+ Element container = new Element(ARRANGEMENT_ELEMENT_NAME);
+ ArrangementRuleUtil.writeExternal(container, myArrangementRules, myLanguage);
+ if (!container.getChildren().isEmpty()) {
+ element.addContent(container);
+ }
+ }
}
@Nullable
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntry.java
similarity index 67%
rename from platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntry.java
rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntry.java
index ddfff7b0d3e4..f29ed7d103a2 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntry.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementEntry.java
@@ -1,4 +1,19 @@
-package com.intellij.psi.codeStyle.rearranger;
+/*
+ * 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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -9,7 +24,7 @@ import java.util.Collection;
* Represents a processing unit during 'rearrangement' operation. I.e. entry's position can be changed during the processing.
*
* Example: we can provide a grouping rule for class methods (e.g. getters and setters). Every such method will be represented by
- * a {@link RearrangerEntry} then.
+ * a {@link ArrangementEntry} then.
*
* The entries can be organised into hierarchies where every sub-hierarchy is independent
* (see {@link #getParent()}, {@link #getChildren()}).
@@ -19,14 +34,14 @@ import java.util.Collection;
* @author Denis Zhdanov
* @since 7/16/12 3:31 PM
*/
-public interface RearrangerEntry {
+public interface ArrangementEntry {
/**
* @return parent entry, e.g. it would be a class entry for a method entry
* @see #getChildren()
*/
@Nullable
- RearrangerEntry getParent();
+ ArrangementEntry getParent();
/**
* Entries can be organised into hierarchies, that means that only siblings position can be changed during the rearrangement.
@@ -38,7 +53,7 @@ public interface RearrangerEntry {
* @see #getParent()
*/
@NotNull
- Collection extends RearrangerEntry> getChildren();
+ Collection extends ArrangementEntry> getChildren();
/**
* @return start offset of the current entry (inclusive) within the target document. Rearranger engine uses this information
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRule.java
new file mode 100644
index 000000000000..8145784a27c1
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRule.java
@@ -0,0 +1,76 @@
+/*
+ * 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.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
+import com.intellij.psi.codeStyle.arrangement.sort.ArrangementEntrySortType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Container for the strategies to be used during file entries arrangement.
+ *
+ * Example: we can define a rule like 'private final non-static fields' or 'public static methods' etc.
+ *
+ * Not thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 7/17/12 11:07 AM
+ */
+public class ArrangementRule {
+
+ @NotNull private final ArrangementEntryMatcher myMatcher;
+ @NotNull private final ArrangementEntrySortType mySortType;
+
+ public ArrangementRule(@NotNull ArrangementEntryMatcher matcher) {
+ this(matcher, ArrangementEntrySortType.NO_SORT);
+ }
+
+ public ArrangementRule(@NotNull ArrangementEntryMatcher matcher, @NotNull ArrangementEntrySortType type) {
+ myMatcher = matcher;
+ mySortType = type;
+ }
+
+ @NotNull
+ public ArrangementEntryMatcher getMatcher() {
+ return myMatcher;
+ }
+
+ @NotNull
+ public ArrangementEntrySortType getSorter() {
+ return mySortType;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myMatcher.hashCode();
+ result = 31 * result + mySortType.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ArrangementRule that = (ArrangementRule)o;
+ return mySortType == that.mySortType && myMatcher.equals(that.myMatcher);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("matcher: %s, sort type: %s", myMatcher, mySortType);
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleSerializer.java
new file mode 100644
index 000000000000..c568dde2f4f1
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleSerializer.java
@@ -0,0 +1,59 @@
+/*
+ * 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 org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Identifies a strategy that can tweak default {@link ArrangementRule arrangement rules} (de)serialization mechanism.
+ *
+ * Implementations of this interface are expected to be thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 7/18/12 10:30 AM
+ */
+public interface ArrangementRuleSerializer {
+
+ /**
+ * Allows to provide custom rule deserialization logic. This method is expected to be consistent with {@link #serialize(ArrangementRule)}.
+ *
+ * Note: it's save to return null if current rearranger doesn't use custom rules (rules over those
+ * located at the 'lang-api'/'lang-impl' modules).
+ *
+ * @param element serialized rule
+ * @return rule de-serialized from the given element;
+ * null as an indication that current rearranger doesn't provide custom serialization logic
+ * for the target rule serialized at the given element, i.e. default deserialization algorithm should be used for it
+ */
+ @Nullable
+ ArrangementRule deserialize(@NotNull Element element);
+
+ /**
+ * Allows to provide custom rule serialization logic. This method is expected to be consistent with {@link #deserialize(Element)}.
+ *
+ * Note: it's save to return null if current rearranger doesn't use custom rules (rules over those
+ * located at the 'lang-api'/'lang-impl' modules).
+ *
+ * @param rule rule to serialize
+ * @return serialized rule;
+ * null as an indication that no custom serialization logic for the given rule
+ * is provided by the current rearranger
+ */
+ @Nullable
+ Element serialize(ArrangementRule rule);
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleUtil.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleUtil.java
new file mode 100644
index 000000000000..9d9c21da3533
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/ArrangementRuleUtil.java
@@ -0,0 +1,144 @@
+/*
+ * 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.lang.Language;
+import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
+import com.intellij.psi.codeStyle.arrangement.match.CompositeArrangementEntryMatcher;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/17/12 11:24 AM
+ */
+public class ArrangementRuleUtil {
+
+ private ArrangementRuleUtil() {
+ }
+
+ //region Serialization
+
+ @NotNull
+ public static List readExternal(@NotNull Element element, @NotNull Language language) {
+ final List result = new ArrayList();
+ ArrangementRuleSerializer serializer = getSerializer(language);
+ for (Object child : element.getChildren()) {
+ ArrangementRule rule = serializer.deserialize((Element)child);
+ if (rule != null) {
+ result.add(rule);
+ }
+ }
+ return result;
+ }
+
+ public static void writeExternal(@NotNull Element element, @NotNull List rules, @NotNull Language language) {
+ if (rules.isEmpty()) {
+ return;
+ }
+
+ ArrangementRuleSerializer serializer = getSerializer(language);
+ for (ArrangementRule rule : rules) {
+ Element e = serializer.serialize(rule);
+ if (e != null) {
+ element.addContent(e);
+ }
+ }
+ }
+
+ private static ArrangementRuleSerializer getSerializer(@NotNull Language language) {
+ Rearranger> rearranger = Rearranger.EXTENSION.forLanguage(language);
+ if (rearranger instanceof ArrangementRuleSerializer) {
+ return new CompositeArrangementRuleSerializer((ArrangementRuleSerializer)rearranger, DefaultArrangementRuleSerializer.INSTANCE);
+ }
+ return DefaultArrangementRuleSerializer.INSTANCE;
+ }
+
+ private static class CompositeArrangementRuleSerializer implements ArrangementRuleSerializer {
+
+ @NotNull private final List mySerializers = new ArrayList();
+
+ CompositeArrangementRuleSerializer(@NotNull ArrangementRuleSerializer ... serializers) {
+ mySerializers.addAll(Arrays.asList(serializers));
+ }
+
+ @Nullable
+ @Override
+ public ArrangementRule deserialize(@NotNull Element element) {
+ for (ArrangementRuleSerializer serializer : mySerializers) {
+ ArrangementRule rule = serializer.deserialize(element);
+ if (rule != null) {
+ return rule;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Element serialize(ArrangementRule rule) {
+ for (ArrangementRuleSerializer serializer : mySerializers) {
+ Element element = serializer.serialize(rule);
+ if (element != null) {
+ return element;
+ }
+ }
+ return null;
+ }
+ }
+ //endregion
+
+ //region Matchers composition
+ @NotNull
+ public static ArrangementEntryMatcher or(@NotNull ArrangementEntryMatcher... matchers) {
+ return combine(CompositeArrangementEntryMatcher.Operator.OR, matchers);
+ }
+
+ @NotNull
+ public static ArrangementEntryMatcher and(@NotNull ArrangementEntryMatcher... matchers) {
+ return combine(CompositeArrangementEntryMatcher.Operator.AND, matchers);
+ }
+
+ @NotNull
+ private static ArrangementEntryMatcher combine(@NotNull CompositeArrangementEntryMatcher.Operator operator,
+ @NotNull ArrangementEntryMatcher... matchers)
+ {
+ CompositeArrangementEntryMatcher composite = null;
+ for (ArrangementEntryMatcher matcher : matchers) {
+ if (matcher instanceof CompositeArrangementEntryMatcher && ((CompositeArrangementEntryMatcher)(matcher)).getOperator() == operator) {
+ composite = (CompositeArrangementEntryMatcher)matcher;
+ break;
+ }
+ }
+
+ if (composite == null) {
+ return new CompositeArrangementEntryMatcher(operator, matchers);
+ }
+
+ for (ArrangementEntryMatcher matcher : matchers) {
+ if (matcher != composite) {
+ composite.addMatcher(matcher);
+ }
+ }
+ return composite;
+ }
+ //endregion
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementRuleSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementRuleSerializer.java
new file mode 100644
index 000000000000..c7702fff35e4
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/DefaultArrangementRuleSerializer.java
@@ -0,0 +1,82 @@
+/*
+ * 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.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
+import com.intellij.psi.codeStyle.arrangement.match.serialization.DefaultArrangementEntryMatcherSerializer;
+import com.intellij.psi.codeStyle.arrangement.sort.ArrangementEntrySortType;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+/**
+ * @author Denis Zhdanov
+ * @since 7/18/12 10:37 AM
+ */
+public class DefaultArrangementRuleSerializer implements ArrangementRuleSerializer {
+
+ public static final ArrangementRuleSerializer INSTANCE = new DefaultArrangementRuleSerializer();
+
+ @NotNull @NonNls private static final String RULE_ELEMENT_NAME = "rule";
+ @NotNull @NonNls private static final String MATCHER_ELEMENT_NAME = "match";
+ @NotNull @NonNls private static final String SORT_TYPE_ELEMENT_NAME = "sort";
+
+ @NotNull private final DefaultArrangementEntryMatcherSerializer myMatcherSerializer = new DefaultArrangementEntryMatcherSerializer();
+
+
+ @Nullable
+ @Override
+ public ArrangementRule deserialize(@NotNull Element element) {
+ Element matcherElement = element.getChild(MATCHER_ELEMENT_NAME);
+ if (matcherElement == null) {
+ return null;
+ }
+
+ ArrangementEntryMatcher matcher = null;
+ for (Object o : matcherElement.getChildren()) {
+ matcher = myMatcherSerializer.deserialize((Element)o);
+ if (matcher != null) {
+ break;
+ }
+ }
+
+ if (matcher == null) {
+ return null;
+ }
+
+ Element sortElement = element.getChild(SORT_TYPE_ELEMENT_NAME);
+ ArrangementEntrySortType sortType = ArrangementEntrySortType.NO_SORT;
+ if (sortElement != null) {
+ sortType = ArrangementEntrySortType.valueOf(sortElement.getText());
+ }
+
+ return new ArrangementRule(matcher, sortType);
+ }
+
+ @Nullable
+ @Override
+ public Element serialize(@NotNull ArrangementRule rule) {
+ Element matcherElement = myMatcherSerializer.serialize(rule.getMatcher());
+ if (matcherElement == null) {
+ return null;
+ }
+
+ Element result = new Element(RULE_ELEMENT_NAME);
+ result.addContent(new Element(MATCHER_ELEMENT_NAME).addContent(matcherElement));
+ result.addContent(new Element(SORT_TYPE_ELEMENT_NAME).setText(rule.getSorter().toString()));
+ return result;
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/NameAwareArrangementEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/NameAwareArrangementEntry.java
new file mode 100644
index 000000000000..91ac3c203360
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/NameAwareArrangementEntry.java
@@ -0,0 +1,28 @@
+/*
+ * 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 org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/19/12 6:13 PM
+ */
+public interface NameAwareArrangementEntry extends ArrangementEntry {
+
+ @Nullable
+ String getName();
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java
new file mode 100644
index 000000000000..b8eb681b3704
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/Rearranger.java
@@ -0,0 +1,47 @@
+/*
+ * 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.lang.LanguageExtension;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+/**
+ * Encapsulates language-specific rearrangement logic.
+ *
+ * Implementations of this interface are expected to be thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 7/16/12 3:23 PM
+ * @param entry type
+ */
+public interface Rearranger {
+
+ LanguageExtension> EXTENSION = new LanguageExtension>("com.intellij.rearranger.facade");
+
+ /**
+ * Allows to build rearranger-interested data for the given element.
+ *
+ * @param root root element which children should be parsed for the rearrangement
+ * @param range target offsets range to use for filtering given root's children
+ * @return given root's children that are subject for further rearrangement
+ */
+ @NotNull
+ Collection parse(@NotNull PsiElement root, @NotNull TextRange range);
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/TypeAwareRearrangerEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/TypeAwareArrangementEntry.java
similarity index 68%
rename from platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/TypeAwareRearrangerEntry.java
rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/TypeAwareArrangementEntry.java
index 9a77f37053f5..14ddd6d3f682 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/TypeAwareRearrangerEntry.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/TypeAwareArrangementEntry.java
@@ -13,20 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.psi.codeStyle.rearranger;
+package com.intellij.psi.codeStyle.arrangement;
+import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
- * Stands for the {@link RearrangerEntry} which provides information about its type.
+ * Stands for the {@link ArrangementEntry} which provides information about its type.
*
* Implementations of this interface are not obliged to be thread-safe.
*
* @author Denis Zhdanov
* @since 7/17/12 11:17 AM
*/
-public interface TypeAwareRearrangerEntry extends RearrangerEntry {
+public interface TypeAwareArrangementEntry extends ArrangementEntry {
- @NotNull
- RearrangerEntryType getType();
+ @Nullable
+ ArrangementEntryType getType();
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementEntryMatcher.java
similarity index 65%
rename from platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerRule.java
rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementEntryMatcher.java
index a81360fd10c0..93a92b321561 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerRule.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementEntryMatcher.java
@@ -13,29 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.psi.codeStyle.rearranger;
+package com.intellij.psi.codeStyle.arrangement.match;
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
+import com.intellij.psi.codeStyle.arrangement.ArrangementRule;
import org.jetbrains.annotations.NotNull;
/**
- * Identifies a strategy which can be used for grouping {@link RearrangerEntry entries}.
+ * Defines a contract for strategy that determines if an {@link ArrangementRule arrangement rule} matches particular
+ * {@link ArrangementEntry arrangement entry}.
*
- * Example: we can define a rule like 'private final non-static fields' or 'public static methods' etc.
+ * Implementations of this interface are expected to provide correct {@link #equals(Object)} & {@link #hashCode()} implementations.
*
* Implementations of this interface are expected to be thread-safe.
*
* @author Denis Zhdanov
- * @since 7/17/12 11:07 AM
+ * @since 7/18/12 12:02 PM
*/
-public interface RearrangerRule {
+public interface ArrangementEntryMatcher {
/**
* Allows to check if given entry is matched by the current rule.
*
* Example: entry like 'public final field' should be matched by a 'final fields' rule but not matched by a 'private fields' rule.
- *
+ *
* @param entry entry to check
* @return true if given entry is matched by the current rule; false otherwise
*/
- boolean isMatched(@NotNull RearrangerEntry entry);
+ boolean isMatched(@NotNull ArrangementEntry entry);
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntryType.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementEntryType.java
similarity index 78%
rename from platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntryType.java
rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementEntryType.java
index 61236b2a4dd7..0ba54c75a6be 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntryType.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementEntryType.java
@@ -13,19 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.psi.codeStyle.rearranger;
+package com.intellij.psi.codeStyle.arrangement.match;
-import com.intellij.psi.codeStyle.rearranger.RearrangerEntry;
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
/**
- * Enumerates all possible {@link RearrangerEntry entry} types.
+ * Enumerates all possible {@link ArrangementEntry entry} types.
*
* This enum is expected to be populated every time new entry type is introduced.
*
* @author Denis Zhdanov
* @since 7/17/12 11:14 AM
*/
-public enum RearrangerEntryType {
+public enum ArrangementEntryType {
CLASS, FIELD, METHOD
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerModifier.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementModifier.java
similarity index 89%
rename from platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerModifier.java
rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementModifier.java
index 5bd519c8c0ef..3876c43806c3 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerModifier.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementModifier.java
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.psi.codeStyle.rearranger;
+package com.intellij.psi.codeStyle.arrangement.match;
/**
* @author Denis Zhdanov
* @since 7/17/12 8:54 PM
*/
-public enum RearrangerModifier {
+public enum ArrangementModifier {
//region Visibility
PUBLIC, PROTECTED, PRIVATE, PACKAGE_PRIVATE,
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByNameArrangementEntryMatcher.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByNameArrangementEntryMatcher.java
new file mode 100644
index 000000000000..251c3c91f8dc
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByNameArrangementEntryMatcher.java
@@ -0,0 +1,68 @@
+/*
+ * 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.match;
+
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
+import com.intellij.psi.codeStyle.arrangement.NameAwareArrangementEntry;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/19/12 6:36 PM
+ */
+public class ByNameArrangementEntryMatcher implements ArrangementEntryMatcher {
+
+ @NotNull private final String myPattern;
+
+ public ByNameArrangementEntryMatcher(@NotNull String pattern) {
+ myPattern = pattern;
+ }
+
+ @Override
+ public boolean isMatched(@NotNull ArrangementEntry entry) {
+ if (entry instanceof NameAwareArrangementEntry) {
+ String name = ((NameAwareArrangementEntry)entry).getName();
+ if (name != null) {
+ return name.matches(myPattern);
+ }
+ }
+ return false;
+ }
+
+ @NotNull
+ public String getPattern() {
+ return myPattern;
+ }
+
+ @Override
+ public int hashCode() {
+ return myPattern.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ByNameArrangementEntryMatcher that = (ByNameArrangementEntryMatcher)o;
+ return myPattern.equals(that.myPattern);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("with name like '%s'", myPattern);
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByTypeArrangementEntryMatcher.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByTypeArrangementEntryMatcher.java
new file mode 100644
index 000000000000..f28bfdb107e2
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ByTypeArrangementEntryMatcher.java
@@ -0,0 +1,80 @@
+/*
+ * 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.match;
+
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
+import com.intellij.psi.codeStyle.arrangement.TypeAwareArrangementEntry;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * Filters {@link ArrangementEntry entries} by {@link TypeAwareArrangementEntry#getType() their types}.
+ *
+ * Note: type-unaware entry will not be matched by the current rule.
+ *
+ * Thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 7/17/12 11:19 AM
+ */
+public class ByTypeArrangementEntryMatcher implements ArrangementEntryMatcher {
+
+ @NotNull private final Set myTypes = EnumSet.noneOf(ArrangementEntryType.class);
+
+ public ByTypeArrangementEntryMatcher(@NotNull ArrangementEntryType... interestedTypes) {
+ this(Arrays.asList(interestedTypes));
+ }
+
+ public ByTypeArrangementEntryMatcher(@NotNull Collection interestedTypes) {
+ myTypes.addAll(interestedTypes);
+ }
+
+ @Override
+ public boolean isMatched(@NotNull ArrangementEntry entry) {
+ if (entry instanceof TypeAwareArrangementEntry) {
+ return myTypes.contains(((TypeAwareArrangementEntry)(entry)).getType());
+ }
+ return false;
+ }
+
+ @NotNull
+ public Set getTypes() {
+ return myTypes;
+ }
+
+ @Override
+ public int hashCode() {
+ return myTypes.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ByTypeArrangementEntryMatcher that = (ByTypeArrangementEntryMatcher)o;
+ return myTypes.equals(that.myTypes);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("of type '%s'", myTypes);
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/CompositeArrangementEntryMatcher.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/CompositeArrangementEntryMatcher.java
new file mode 100644
index 000000000000..528941a25817
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/CompositeArrangementEntryMatcher.java
@@ -0,0 +1,91 @@
+/*
+ * 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.match;
+
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/17/12 11:26 AM
+ */
+public class CompositeArrangementEntryMatcher implements ArrangementEntryMatcher {
+
+ @NotNull private final Set myMatchers = new HashSet();
+ @NotNull private final Operator myOperator;
+
+ public CompositeArrangementEntryMatcher(@NotNull Operator operator, @NotNull ArrangementEntryMatcher... matchers) {
+ myOperator = operator;
+ myMatchers.addAll(Arrays.asList(matchers));
+ }
+
+ @Override
+ public boolean isMatched(@NotNull ArrangementEntry entry) {
+ for (ArrangementEntryMatcher matcher : myMatchers) {
+ boolean matched = matcher.isMatched(entry);
+ if (matched && myOperator == Operator.OR) {
+ return true;
+ }
+ else if (!matched && myOperator == Operator.AND) {
+ return false;
+ }
+ }
+ return myOperator == Operator.AND;
+ }
+
+ @NotNull
+ public Operator getOperator() {
+ return myOperator;
+ }
+
+ @NotNull
+ public Collection getMatchers() {
+ return myMatchers;
+ }
+
+ public void addMatcher(@NotNull ArrangementEntryMatcher rule) {
+ myMatchers.add(rule);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myMatchers.hashCode();
+ result = 31 * result + myOperator.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CompositeArrangementEntryMatcher matcher = (CompositeArrangementEntryMatcher)o;
+
+ if (!myMatchers.equals(matcher.myMatchers)) return false;
+ if (myOperator != matcher.myOperator) return false;
+
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s of those: %s", myOperator == Operator.AND ? "all" : "any", myMatchers);
+ }
+
+ public enum Operator {AND, OR}
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ModifierAwareArrangementEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ModifierAwareArrangementEntry.java
new file mode 100644
index 000000000000..10acb1bbd263
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ModifierAwareArrangementEntry.java
@@ -0,0 +1,29 @@
+/*
+ * 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.match;
+
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/17/12 8:57 PM
+ */
+public interface ModifierAwareArrangementEntry extends ArrangementEntry {
+
+ @NotNull
+ ArrangementModifier getModifier();
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/ModifierAwareRearrangerEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ArrangementEntryMatcherSerializationTag.java
similarity index 78%
rename from platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/ModifierAwareRearrangerEntry.java
rename to platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ArrangementEntryMatcherSerializationTag.java
index 3519a5c481a3..94e99d524764 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/ModifierAwareRearrangerEntry.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ArrangementEntryMatcherSerializationTag.java
@@ -13,16 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.psi.codeStyle.rearranger;
+package com.intellij.psi.codeStyle.arrangement.match.serialization;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
- * @since 7/17/12 8:57 PM
+ * @since 7/19/12 12:45 PM
*/
-public interface ModifierAwareRearrangerEntry extends RearrangerEntry {
+public enum ArrangementEntryMatcherSerializationTag {
- @NotNull
- RearrangerModifier getModifier();
+ TYPE, MODIFIER, OR, AND, NAME
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ArrangementEntryMatcherSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ArrangementEntryMatcherSerializer.java
new file mode 100644
index 000000000000..428b31da45b8
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ArrangementEntryMatcherSerializer.java
@@ -0,0 +1,61 @@
+/*
+ * 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.match.serialization;
+
+import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * Strategy that knows how to serialize {@link ArrangementEntryMatcher} objects of particular class.
+ *
+ * Implementations of this interface are expected to be thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 7/19/12 12:31 PM
+ */
+public interface ArrangementEntryMatcherSerializer {
+
+ /**
+ * @return class of the target matcher that can be processed by the current serializer
+ */
+ @NotNull
+ Class getMatcherClass();
+
+ /**
+ * @return allowed element names of the serialized matcher. Are expected to be unique between
+ * {@link ArrangementEntryMatcherSerializer} implementations
+ */
+ @NotNull
+ Set getTags();
+
+ @NotNull
+ Element serialize(@NotNull T matcher);
+
+ /**
+ * Allows to deserialize target matcher object serialized previously via {@link #serialize(ArrangementEntryMatcher)}
+ *
+ * @param element serialized representation of the target matcher
+ * @return de-serialized matcher instance
+ * @throws IllegalArgumentException if current strategy doesn't know how to deserialize target matcher from the given
+ * element (the exception must not be thrown if given element's name is in
+ * {@link #getTags() target element names})
+ */
+ @NotNull
+ T deserialize(@NotNull Element element) throws IllegalArgumentException;
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ByNameArrangementEntryMatcherSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ByNameArrangementEntryMatcherSerializer.java
new file mode 100644
index 000000000000..66bf247fef16
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ByNameArrangementEntryMatcherSerializer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.match.serialization;
+
+import com.intellij.psi.codeStyle.arrangement.match.ByNameArrangementEntryMatcher;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/19/12 6:40 PM
+ */
+public class ByNameArrangementEntryMatcherSerializer implements ArrangementEntryMatcherSerializer {
+
+ @NotNull
+ @Override
+ public Class getMatcherClass() {
+ return ByNameArrangementEntryMatcher.class;
+ }
+
+ @NotNull
+ @Override
+ public Set getTags() {
+ return EnumSet.of(ArrangementEntryMatcherSerializationTag.NAME);
+ }
+
+ @NotNull
+ @Override
+ public Element serialize(@NotNull ByNameArrangementEntryMatcher matcher) {
+ return new Element(ArrangementEntryMatcherSerializationTag.NAME.toString()).setText(matcher.getPattern());
+ }
+
+ @NotNull
+ @Override
+ public ByNameArrangementEntryMatcher deserialize(@NotNull Element element) throws IllegalArgumentException {
+ return new ByNameArrangementEntryMatcher(element.getText());
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ByTypeArrangementEntryMatcherSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ByTypeArrangementEntryMatcherSerializer.java
new file mode 100644
index 000000000000..948f97c13fa9
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/ByTypeArrangementEntryMatcherSerializer.java
@@ -0,0 +1,81 @@
+/*
+ * 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.match.serialization;
+
+import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
+import com.intellij.psi.codeStyle.arrangement.match.ByTypeArrangementEntryMatcher;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/19/12 12:44 PM
+ */
+public class ByTypeArrangementEntryMatcherSerializer implements ArrangementEntryMatcherSerializer {
+
+ private static final String SEPARATOR = "|";
+
+ @NotNull
+ @Override
+ public Class getMatcherClass() {
+ return ByTypeArrangementEntryMatcher.class;
+ }
+
+ @NotNull
+ @Override
+ public Set getTags() {
+ return EnumSet.of(ArrangementEntryMatcherSerializationTag.TYPE);
+ }
+
+ @NotNull
+ @Override
+ public Element serialize(@NotNull ByTypeArrangementEntryMatcher matcher) {
+ StringBuilder buffer = new StringBuilder();
+ for (ArrangementEntryType type : matcher.getTypes()) {
+ buffer.append(type).append(SEPARATOR);
+ }
+ if (buffer.length() > 0) {
+ buffer.setLength(buffer.length() - 1);
+ }
+ return new Element(ArrangementEntryMatcherSerializationTag.TYPE.toString()).setText(buffer.toString());
+ }
+
+ @NotNull
+ @Override
+ public ByTypeArrangementEntryMatcher deserialize(@NotNull Element element) throws IllegalArgumentException {
+ if (!ArrangementEntryMatcherSerializationTag.TYPE.toString().equals(element.getName())) {
+ throw new IllegalArgumentException(String.format(
+ "Can't deserialize matcher of class %s from an element with name '%s'. Expected name: '%s'",
+ getMatcherClass(), element.getName(), ArrangementEntryMatcherSerializationTag.TYPE.toString()));
+ }
+
+ String text = element.getText();
+ if (text == null) {
+ throw new IllegalArgumentException(String.format(
+ "Can't deserialize matcher of class %s. Reason: no information about target type(s) is found", getMatcherClass()
+ ));
+ }
+
+ Set types = EnumSet.noneOf(ArrangementEntryType.class);
+ for (String s : text.split("\\" + SEPARATOR)) {
+ types.add(ArrangementEntryType.valueOf(s));
+ }
+ return new ByTypeArrangementEntryMatcher(types);
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/DefaultArrangementEntryMatcherSerializer.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/DefaultArrangementEntryMatcherSerializer.java
new file mode 100644
index 000000000000..2d340d0efe0f
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/serialization/DefaultArrangementEntryMatcherSerializer.java
@@ -0,0 +1,153 @@
+/*
+ * 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.match.serialization;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
+import com.intellij.psi.codeStyle.arrangement.match.CompositeArrangementEntryMatcher;
+import com.intellij.util.containers.ClassMap;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/19/12 1:00 PM
+ */
+public class DefaultArrangementEntryMatcherSerializer {
+
+ private static final Logger LOG = Logger.getInstance("#" + DefaultArrangementEntryMatcherSerializer.class.getName());
+
+ @NotNull private final ClassMap> mySerializers
+ = new ClassMap>();
+
+ @NotNull private final Map> myDeserializers =
+ new HashMap>();
+
+ public DefaultArrangementEntryMatcherSerializer() {
+ register(new ByTypeArrangementEntryMatcherSerializer());
+ register(new ByNameArrangementEntryMatcherSerializer());
+ register(new CompositeSerializer());
+ }
+
+ private void register(@NotNull ArrangementEntryMatcherSerializer> serializer) {
+ mySerializers.put(serializer.getMatcherClass(), serializer);
+ for (ArrangementEntryMatcherSerializationTag tag : serializer.getTags()) {
+ ArrangementEntryMatcherSerializer> old = myDeserializers.put(tag.toString(), serializer);
+ assert old == null : String.format("Multiple serializers are registered for the tag %s: %s and %s", tag.toString(), old, serializer);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Nullable
+ public Element serialize(@NotNull T matcher) {
+ ArrangementEntryMatcherSerializer serializer = (ArrangementEntryMatcherSerializer)mySerializers.get(matcher.getClass());
+ if (serializer != null) {
+ return serializer.serialize(matcher);
+ }
+ StringBuilder buffer = new StringBuilder();
+ for (ArrangementEntryMatcherSerializer> s : mySerializers.values()) {
+ buffer.append(s.getMatcherClass()).append(", ");
+ }
+ if (buffer.length() > 0) {
+ buffer.setLength(buffer.length() - 2);
+ }
+ LOG.warn(String.format(
+ "Can't serialize arrangement entry matcher of class '%s'. Reason: no corresponding serializer is registered."
+ + "Available serializers can handle the following matchers: '%s'", matcher.getClass(), buffer.toString()
+ ));
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Nullable
+ public T deserialize(@NotNull Element matcherElement) {
+ ArrangementEntryMatcherSerializer serializer = (ArrangementEntryMatcherSerializer)myDeserializers.get(matcherElement.getName());
+ if (serializer != null) {
+ return serializer.deserialize(matcherElement);
+ }
+ StringBuilder buffer = new StringBuilder();
+ for (String s : myDeserializers.keySet()) {
+ buffer.append(s).append(", ");
+ }
+ if (buffer.length() > 0) {
+ buffer.setLength(buffer.length() - 2);
+ }
+ LOG.warn(String.format(
+ "Can't deserialize an arrangement entry matcher from matchElement with name '%s'. Reason: only the following elements are supported: %s",
+ matcherElement.getName(), buffer
+ ));
+ return null;
+ }
+
+ private class CompositeSerializer implements ArrangementEntryMatcherSerializer {
+ @NotNull
+ @Override
+ public Class getMatcherClass() {
+ return CompositeArrangementEntryMatcher.class;
+ }
+
+ @NotNull
+ @Override
+ public Set getTags() {
+ return EnumSet.of(ArrangementEntryMatcherSerializationTag.AND, ArrangementEntryMatcherSerializationTag.OR);
+ }
+
+ @NotNull
+ @Override
+ public Element serialize(@NotNull CompositeArrangementEntryMatcher matcher) {
+ ArrangementEntryMatcherSerializationTag tag = matcher.getOperator() == CompositeArrangementEntryMatcher.Operator.AND
+ ? ArrangementEntryMatcherSerializationTag.AND
+ : ArrangementEntryMatcherSerializationTag.OR;
+ Element result = new Element(tag.toString());
+ for (ArrangementEntryMatcher childMatcher : matcher.getMatchers()) {
+ Element element = DefaultArrangementEntryMatcherSerializer.this.serialize(childMatcher);
+ if (element != null) {
+ result.addContent(element);
+ }
+ }
+ return result;
+ }
+
+ @NotNull
+ @Override
+ public CompositeArrangementEntryMatcher deserialize(@NotNull Element element) throws IllegalArgumentException {
+ CompositeArrangementEntryMatcher.Operator operator = ArrangementEntryMatcherSerializationTag.OR.toString().equals(element.getName())
+ ? CompositeArrangementEntryMatcher.Operator.OR
+ : CompositeArrangementEntryMatcher.Operator.AND;
+
+ CompositeArrangementEntryMatcher result = null;
+ for (Object o : element.getChildren()) {
+ ArrangementEntryMatcher matcher = DefaultArrangementEntryMatcherSerializer.this.deserialize((Element)o);
+ if (matcher == null) {
+ continue;
+ }
+ if (result == null) {
+ result = new CompositeArrangementEntryMatcher(operator, matcher);
+ }
+ else {
+ result.addMatcher(matcher);
+ }
+ }
+ if (result == null) {
+ throw new IllegalArgumentException(String.format("Can't deserialize a matcher from element '%s'", element));
+ }
+ return result;
+ }
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ArrangementEntrySortType.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ArrangementEntrySortType.java
new file mode 100644
index 000000000000..ee0f0c5e0eb7
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ArrangementEntrySortType.java
@@ -0,0 +1,25 @@
+/*
+ * 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.sort;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/19/12 6:24 PM
+ */
+public enum ArrangementEntrySortType {
+
+ NO_SORT, BY_NAME
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ArrangementEntrySorter.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ArrangementEntrySorter.java
new file mode 100644
index 000000000000..3a887db09759
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ArrangementEntrySorter.java
@@ -0,0 +1,44 @@
+/*
+ * 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.sort;
+
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
+import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * Defines a contract for a strategy that knows how to sort {@link ArrangementEntry arrangement entries}
+ * {@link ArrangementEntryMatcher#isMatched(ArrangementEntry) matched} against the same rule using particular
+ * {@link ArrangementEntrySortType sort type}.
+ *
+ * Implementations of this interface are expected to provide correct {@link #equals(Object)} & {@link #hashCode()} implementations.
+ *
+ * Implementations of this interface are expected to be thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 7/18/12 12:41 PM
+ */
+public interface ArrangementEntrySorter {
+
+ /**
+ * Asks to sort given entries matched against the current rule. Given list defines a default order to be used.
+ *
+ * @param entries entries matched against the current rule
+ */
+ void sort(@NotNull List extends ArrangementEntry> entries);
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ByNameArrangementEntrySorter.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ByNameArrangementEntrySorter.java
new file mode 100644
index 000000000000..d9a0360c9eab
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/sort/ByNameArrangementEntrySorter.java
@@ -0,0 +1,63 @@
+/*
+ * 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.sort;
+
+import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
+import com.intellij.psi.codeStyle.arrangement.NameAwareArrangementEntry;
+import gnu.trove.TObjectIntHashMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * @author Denis Zhdanov
+ * @since 7/19/12 6:17 PM
+ */
+public class ByNameArrangementEntrySorter implements ArrangementEntrySorter {
+
+ @Override
+ public void sort(@NotNull List extends ArrangementEntry> entries) {
+ TObjectIntHashMap weights = new TObjectIntHashMap();
+ for (int i = 0; i < entries.size(); i++) {
+ weights.put(entries.get(i), i);
+ }
+ Collections.sort(entries, new MyComparator(weights));
+ }
+
+ private static class MyComparator implements Comparator {
+
+ @NotNull
+ private final TObjectIntHashMap myFallbackWeights;
+
+ MyComparator(@NotNull TObjectIntHashMap weights) {
+ myFallbackWeights = weights;
+ }
+
+ @Override
+ public int compare(ArrangementEntry o1, ArrangementEntry o2) {
+ if (o1 instanceof NameAwareArrangementEntry && o2 instanceof NameAwareArrangementEntry) {
+ String name1 = ((NameAwareArrangementEntry)o1).getName();
+ String name2 = ((NameAwareArrangementEntry)o1).getName();
+ if (name1 != null && name2 != null) {
+ return name1.compareTo(name2);
+ }
+ }
+ return myFallbackWeights.get(o1) - myFallbackWeights.get(o2);
+ }
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerFacade.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerFacade.java
deleted file mode 100644
index d60d2d39ce55..000000000000
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerFacade.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.intellij.psi.codeStyle.rearranger;
-
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Encapsulates language-specific rearrangement logic.
- *
- * Implementations of this interface are expected to be thread-safe.
- *
- * @author Denis Zhdanov
- * @since 7/16/12 3:23 PM
- * @param entry type
- * @param rule type
- */
-public interface RearrangerFacade {
-
- ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.rearranger.facade");
-
- /**
- * Allows to build rearranger-interested data for the given element.
- *
- * @param root root element which children should be parsed for the rearrangement
- * @param range target offsets range to use for filtering given root's children
- * @return given root's children that are subject for further rearrangement
- */
- @NotNull
- Collection parse(@NotNull PsiElement root, @NotNull TextRange range);
-
- /**
- * Asks to sort given entries matched against the given rule. Given list defines a default order to be used.
- *
- * @param entries entries matched against the given rule
- * @param rule target rule
- */
- void sort(@NotNull List entries, @NotNull RearrangerRule rule);
-}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerCompositeRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerCompositeRule.java
deleted file mode 100644
index 0bc59ca9833e..000000000000
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerCompositeRule.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.rearranger.rule;
-
-import com.intellij.psi.codeStyle.rearranger.RearrangerEntry;
-import com.intellij.psi.codeStyle.rearranger.RearrangerRule;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * @author Denis Zhdanov
- * @since 7/17/12 11:26 AM
- */
-public class RearrangerCompositeRule implements RearrangerRule {
-
- @NotNull private final List myRules = new ArrayList();
- @NotNull private final Operator myOperator;
-
- public RearrangerCompositeRule(@NotNull Operator operator, @NotNull RearrangerRule ... rules) {
- myOperator = operator;
- myRules.addAll(Arrays.asList(rules));
- }
-
- @Override
- public boolean isMatched(@NotNull RearrangerEntry entry) {
- for (RearrangerRule rule : myRules) {
- boolean matched = rule.isMatched(entry);
- if (matched && myOperator == Operator.OR) {
- return true;
- }
- else if (!matched && myOperator == Operator.AND) {
- return false;
- }
- }
- return myOperator == Operator.AND;
- }
-
- @NotNull
- public Operator getOperator() {
- return myOperator;
- }
-
- public void addRule(@NotNull RearrangerRule rule) {
- myRules.add(rule);
- }
-
- public enum Operator {AND, OR}
-}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerRuleUtil.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerRuleUtil.java
deleted file mode 100644
index b1d63954c258..000000000000
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerRuleUtil.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.rearranger.rule;
-
-import com.intellij.psi.codeStyle.rearranger.RearrangerRule;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author Denis Zhdanov
- * @since 7/17/12 11:24 AM
- */
-public class RearrangerRuleUtil {
-
- private RearrangerRuleUtil() {
- }
-
- @NotNull
- public static RearrangerRule or(@NotNull RearrangerRule ... rules) {
- return combine(RearrangerCompositeRule.Operator.OR, rules);
- }
-
- @NotNull
- public static RearrangerRule and(@NotNull RearrangerRule ... rules) {
- return combine(RearrangerCompositeRule.Operator.AND, rules);
- }
-
- @NotNull
- private static RearrangerRule combine(@NotNull RearrangerCompositeRule.Operator operator, @NotNull RearrangerRule... rules) {
- RearrangerCompositeRule composite = null;
- for (RearrangerRule rule : rules) {
- if (rule instanceof RearrangerCompositeRule && ((RearrangerCompositeRule)(rule)).getOperator() == operator) {
- composite = (RearrangerCompositeRule)rule;
- break;
- }
- }
-
- if (composite == null) {
- return new RearrangerCompositeRule(operator, rules);
- }
-
- for (RearrangerRule rule : rules) {
- if (rule != composite) {
- composite.addRule(rule);
- }
- }
- return composite;
- }
-}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerTypeRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerTypeRule.java
deleted file mode 100644
index c7a71377925e..000000000000
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerTypeRule.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.rearranger.rule;
-
-import com.intellij.psi.codeStyle.rearranger.RearrangerEntry;
-import com.intellij.psi.codeStyle.rearranger.RearrangerEntryType;
-import com.intellij.psi.codeStyle.rearranger.RearrangerRule;
-import com.intellij.psi.codeStyle.rearranger.TypeAwareRearrangerEntry;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * Filters {@link RearrangerEntry entries} by {@link TypeAwareRearrangerEntry#getType() their types}.
- *
- * Note: type-unaware entry will not be matched by the current rule.
- *
- * Thread-safe.
- *
- * @author Denis Zhdanov
- * @since 7/17/12 11:19 AM
- */
-public class RearrangerTypeRule implements RearrangerRule {
-
- private final Set myTypes = EnumSet.noneOf(RearrangerEntryType.class);
-
- public RearrangerTypeRule(@NotNull RearrangerEntryType ... interestedTypes) {
- myTypes.addAll(Arrays.asList(interestedTypes));
- }
-
- @Override
- public boolean isMatched(@NotNull RearrangerEntry entry) {
- if (entry instanceof TypeAwareRearrangerEntry) {
- return myTypes.contains(((TypeAwareRearrangerEntry)(entry)).getType());
- }
- return false;
- }
-}
diff --git a/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementRuleSerializerTest.java b/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementRuleSerializerTest.java
new file mode 100644
index 000000000000..37948f38fa31
--- /dev/null
+++ b/platform/lang-api/testSources/com/intellij/psi/codeStyle/arrangement/match/DefaultArrangementRuleSerializerTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.match;
+
+import com.intellij.psi.codeStyle.arrangement.ArrangementRule;
+import com.intellij.psi.codeStyle.arrangement.ArrangementRuleSerializer;
+import com.intellij.psi.codeStyle.arrangement.ArrangementRuleUtil;
+import com.intellij.psi.codeStyle.arrangement.DefaultArrangementRuleSerializer;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Denis Zhdanov
+ * @since 07/18/2012
+ */
+public class DefaultArrangementRuleSerializerTest {
+
+ private ArrangementRuleSerializer mySerializer;
+
+ @Before
+ public void setUp() {
+ mySerializer = DefaultArrangementRuleSerializer.INSTANCE;
+ }
+
+ @Test
+ public void simpleMatchers() {
+ doTest(new ByTypeArrangementEntryMatcher(ArrangementEntryType.CLASS));
+ doTest(new ByTypeArrangementEntryMatcher(ArrangementEntryType.values()));
+ }
+
+ @Test
+ public void compositeMatchers() {
+ doTest(ArrangementRuleUtil.or(
+ new ByTypeArrangementEntryMatcher(ArrangementEntryType.FIELD),
+ new ByTypeArrangementEntryMatcher(ArrangementEntryType.METHOD))
+ );
+
+ doTest(ArrangementRuleUtil.and(
+ ArrangementRuleUtil.or(
+ new ByTypeArrangementEntryMatcher(ArrangementEntryType.METHOD),
+ new ByNameArrangementEntryMatcher("get*")
+ )
+ ));
+ }
+
+ private void doTest(@NotNull ArrangementEntryMatcher matcher) {
+ doTest(new ArrangementRule(matcher));
+ }
+
+ private void doTest(@NotNull ArrangementRule rule) {
+ Element element = mySerializer.serialize(rule);
+ assertNotNull(String.format("Can't serialize rule '%s'", rule), element);
+ assertEquals(rule, mySerializer.deserialize(element));
+ }
+}