mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-19061 Integrate the Rearranger-plugin into core-IDEA
Basic 'code arrangement' infrastructure is defined
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testSources" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
@@ -12,6 +13,8 @@
|
||||
<orderEntry type="library" exported="" name="NanoXML" level="project" />
|
||||
<orderEntry type="module" module-name="indexing-api" exported="" />
|
||||
<orderEntry type="module" module-name="projectModel-api" exported="" />
|
||||
<orderEntry type="library" name="JUnit4" level="project" />
|
||||
<orderEntry type="library" name="Groovy" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -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<ArrangementRule> myArrangementRules = new ArrayList<ArrangementRule>();
|
||||
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
|
||||
|
||||
+20
-5
@@ -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.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* 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
|
||||
@@ -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.
|
||||
* <p/>
|
||||
* Example: we can define a rule like 'private final non-static fields' or 'public static methods' etc.
|
||||
* <p/>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
+59
@@ -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.
|
||||
* <p/>
|
||||
* 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)}.
|
||||
* <p/>
|
||||
* <b>Note:</b> it's save to return <code>null</code> if current rearranger doesn't use custom rules (rules over those
|
||||
* located at the <code>'lang-api'</code>/<code>'lang-impl'</code> modules).
|
||||
*
|
||||
* @param element serialized rule
|
||||
* @return rule de-serialized from the given element;
|
||||
* <code>null</code> 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)}.
|
||||
* <p/>
|
||||
* <b>Note:</b> it's save to return <code>null</code> if current rearranger doesn't use custom rules (rules over those
|
||||
* located at the <code>'lang-api'</code>/<code>'lang-impl'</code> modules).
|
||||
*
|
||||
* @param rule rule to serialize
|
||||
* @return serialized rule;
|
||||
* <code>null</code> as an indication that no custom serialization logic for the given rule
|
||||
* is provided by the current rearranger
|
||||
*/
|
||||
@Nullable
|
||||
Element serialize(ArrangementRule rule);
|
||||
}
|
||||
+144
@@ -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<ArrangementRule> readExternal(@NotNull Element element, @NotNull Language language) {
|
||||
final List<ArrangementRule> result = new ArrayList<ArrangementRule>();
|
||||
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<ArrangementRule> 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<ArrangementRuleSerializer> mySerializers = new ArrayList<ArrangementRuleSerializer>();
|
||||
|
||||
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
|
||||
}
|
||||
+82
@@ -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;
|
||||
}
|
||||
}
|
||||
+28
@@ -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();
|
||||
}
|
||||
@@ -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.
|
||||
* <p/>
|
||||
* Implementations of this interface are expected to be thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/16/12 3:23 PM
|
||||
* @param <E> entry type
|
||||
*/
|
||||
public interface Rearranger<E extends ArrangementEntry> {
|
||||
|
||||
LanguageExtension<Rearranger<?>> EXTENSION = new LanguageExtension<Rearranger<?>>("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<E> parse(@NotNull PsiElement root, @NotNull TextRange range);
|
||||
}
|
||||
+7
-5
@@ -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.
|
||||
* <p/>
|
||||
* 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();
|
||||
}
|
||||
+10
-7
@@ -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}.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* 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 <code>true</code> if given entry is matched by the current rule; <code>false</code> otherwise
|
||||
*/
|
||||
boolean isMatched(@NotNull RearrangerEntry entry);
|
||||
boolean isMatched(@NotNull ArrangementEntry entry);
|
||||
}
|
||||
+4
-4
@@ -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.
|
||||
* <p/>
|
||||
* 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
|
||||
}
|
||||
+2
-2
@@ -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,
|
||||
+68
@@ -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);
|
||||
}
|
||||
}
|
||||
+80
@@ -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}.
|
||||
* <p/>
|
||||
* <b>Note:</b> type-unaware entry will not be matched by the current rule.
|
||||
* <p/>
|
||||
* Thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/17/12 11:19 AM
|
||||
*/
|
||||
public class ByTypeArrangementEntryMatcher implements ArrangementEntryMatcher {
|
||||
|
||||
@NotNull private final Set<ArrangementEntryType> myTypes = EnumSet.noneOf(ArrangementEntryType.class);
|
||||
|
||||
public ByTypeArrangementEntryMatcher(@NotNull ArrangementEntryType... interestedTypes) {
|
||||
this(Arrays.asList(interestedTypes));
|
||||
}
|
||||
|
||||
public ByTypeArrangementEntryMatcher(@NotNull Collection<ArrangementEntryType> 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<ArrangementEntryType> 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);
|
||||
}
|
||||
}
|
||||
+91
@@ -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<ArrangementEntryMatcher> myMatchers = new HashSet<ArrangementEntryMatcher>();
|
||||
@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<ArrangementEntryMatcher> 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}
|
||||
}
|
||||
+29
@@ -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();
|
||||
}
|
||||
+4
-5
@@ -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
|
||||
}
|
||||
+61
@@ -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.
|
||||
* <p/>
|
||||
* Implementations of this interface are expected to be thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/19/12 12:31 PM
|
||||
*/
|
||||
public interface ArrangementEntryMatcherSerializer<T extends ArrangementEntryMatcher> {
|
||||
|
||||
/**
|
||||
* @return class of the target matcher that can be processed by the current serializer
|
||||
*/
|
||||
@NotNull
|
||||
Class<T> getMatcherClass();
|
||||
|
||||
/**
|
||||
* @return allowed element names of the serialized matcher. Are expected to be unique between
|
||||
* {@link ArrangementEntryMatcherSerializer} implementations
|
||||
*/
|
||||
@NotNull
|
||||
Set<ArrangementEntryMatcherSerializationTag> 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;
|
||||
}
|
||||
+54
@@ -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<ByNameArrangementEntryMatcher> {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Class<ByNameArrangementEntryMatcher> getMatcherClass() {
|
||||
return ByNameArrangementEntryMatcher.class;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<ArrangementEntryMatcherSerializationTag> 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());
|
||||
}
|
||||
}
|
||||
+81
@@ -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<ByTypeArrangementEntryMatcher> {
|
||||
|
||||
private static final String SEPARATOR = "|";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Class<ByTypeArrangementEntryMatcher> getMatcherClass() {
|
||||
return ByTypeArrangementEntryMatcher.class;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<ArrangementEntryMatcherSerializationTag> 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<ArrangementEntryType> types = EnumSet.noneOf(ArrangementEntryType.class);
|
||||
for (String s : text.split("\\" + SEPARATOR)) {
|
||||
types.add(ArrangementEntryType.valueOf(s));
|
||||
}
|
||||
return new ByTypeArrangementEntryMatcher(types);
|
||||
}
|
||||
}
|
||||
+153
@@ -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<ArrangementEntryMatcherSerializer<?>> mySerializers
|
||||
= new ClassMap<ArrangementEntryMatcherSerializer<?>>();
|
||||
|
||||
@NotNull private final Map<String /* element name */, ArrangementEntryMatcherSerializer<?>> myDeserializers =
|
||||
new HashMap<String, ArrangementEntryMatcherSerializer<?>>();
|
||||
|
||||
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 <T extends ArrangementEntryMatcher> Element serialize(@NotNull T matcher) {
|
||||
ArrangementEntryMatcherSerializer<T> serializer = (ArrangementEntryMatcherSerializer<T>)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 extends ArrangementEntryMatcher> T deserialize(@NotNull Element matcherElement) {
|
||||
ArrangementEntryMatcherSerializer<T> serializer = (ArrangementEntryMatcherSerializer<T>)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<CompositeArrangementEntryMatcher> {
|
||||
@NotNull
|
||||
@Override
|
||||
public Class<CompositeArrangementEntryMatcher> getMatcherClass() {
|
||||
return CompositeArrangementEntryMatcher.class;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<ArrangementEntryMatcherSerializationTag> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -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
|
||||
}
|
||||
+44
@@ -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}.
|
||||
* <p/>
|
||||
* Implementations of this interface are expected to provide correct {@link #equals(Object)} & {@link #hashCode()} implementations.
|
||||
* <p/>
|
||||
* 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);
|
||||
}
|
||||
+63
@@ -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<ArrangementEntry> weights = new TObjectIntHashMap<ArrangementEntry>();
|
||||
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<ArrangementEntry> {
|
||||
|
||||
@NotNull
|
||||
private final TObjectIntHashMap<ArrangementEntry> myFallbackWeights;
|
||||
|
||||
MyComparator(@NotNull TObjectIntHashMap<ArrangementEntry> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p/>
|
||||
* Implementations of this interface are expected to be thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/16/12 3:23 PM
|
||||
* @param <E> entry type
|
||||
* @param <R> rule type
|
||||
*/
|
||||
public interface RearrangerFacade<E extends RearrangerEntry> {
|
||||
|
||||
ExtensionPointName<RearrangerFacade> 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<E> 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<E> entries, @NotNull RearrangerRule rule);
|
||||
}
|
||||
-64
@@ -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<RearrangerRule> myRules = new ArrayList<RearrangerRule>();
|
||||
@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}
|
||||
}
|
||||
-61
@@ -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;
|
||||
}
|
||||
}
|
||||
-53
@@ -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}.
|
||||
* <p/>
|
||||
* <b>Note:</b> type-unaware entry will not be matched by the current rule.
|
||||
* <p/>
|
||||
* Thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 7/17/12 11:19 AM
|
||||
*/
|
||||
public class RearrangerTypeRule implements RearrangerRule {
|
||||
|
||||
private final Set<RearrangerEntryType> 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;
|
||||
}
|
||||
}
|
||||
+73
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user