diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/ModifierAwareRearrangerEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/ModifierAwareRearrangerEntry.java new file mode 100644 index 000000000000..3519a5c481a3 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/ModifierAwareRearrangerEntry.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.rearranger; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Denis Zhdanov + * @since 7/17/12 8:57 PM + */ +public interface ModifierAwareRearrangerEntry extends RearrangerEntry { + + @NotNull + RearrangerModifier getModifier(); +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntry.java new file mode 100644 index 000000000000..ddfff7b0d3e4 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntry.java @@ -0,0 +1,54 @@ +package com.intellij.psi.codeStyle.rearranger; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +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. + *

+ * The entries can be organised into hierarchies where every sub-hierarchy is independent + * (see {@link #getParent()}, {@link #getChildren()}). + *

+ * Implementations of this interface are not obliged to be thread-safe. + * + * @author Denis Zhdanov + * @since 7/16/12 3:31 PM + */ +public interface RearrangerEntry { + + /** + * @return parent entry, e.g. it would be a class entry for a method entry + * @see #getChildren() + */ + @Nullable + RearrangerEntry getParent(); + + /** + * Entries can be organised into hierarchies, that means that only siblings position can be changed during the rearrangement. + *

+ * Example: there are two classes at file and every class has two methods. Rearranger should not swap positions of methods + * from the different classes here. + * + * @return current entry's children. Empty collection if there are no children + * @see #getParent() + */ + @NotNull + Collection getChildren(); + + /** + * @return start offset of the current entry (inclusive) within the target document. Rearranger engine uses this information + * to move rearranged entries + */ + int getStartOffset(); + + /** + * @return end offset of the current entry (exclusive) within the target document. Rearranger engine uses this information + * to move rearranged entries + */ + int getEndOffset(); +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntryType.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntryType.java new file mode 100644 index 000000000000..61236b2a4dd7 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerEntryType.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.codeStyle.rearranger; + +import com.intellij.psi.codeStyle.rearranger.RearrangerEntry; + +/** + * Enumerates all possible {@link RearrangerEntry 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 { + + CLASS, FIELD, METHOD +} 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 new file mode 100644 index 000000000000..d60d2d39ce55 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerFacade.java @@ -0,0 +1,42 @@ +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/RearrangerModifier.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerModifier.java new file mode 100644 index 000000000000..5bd519c8c0ef --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerModifier.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.rearranger; + +/** + * @author Denis Zhdanov + * @since 7/17/12 8:54 PM + */ +public enum RearrangerModifier { + + //region Visibility + PUBLIC, PROTECTED, PRIVATE, PACKAGE_PRIVATE, + //endregion + + STATIC, FINAL +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerRule.java new file mode 100644 index 000000000000..a81360fd10c0 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/RearrangerRule.java @@ -0,0 +1,41 @@ +/* + * 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; + +import org.jetbrains.annotations.NotNull; + +/** + * Identifies a strategy which can be used for grouping {@link RearrangerEntry entries}. + *

+ * Example: we can define a rule like 'private final non-static fields' or 'public static methods' etc. + *

+ * Implementations of this interface are expected to be thread-safe. + * + * @author Denis Zhdanov + * @since 7/17/12 11:07 AM + */ +public interface RearrangerRule { + + /** + * 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); +} diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/TypeAwareRearrangerEntry.java b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/TypeAwareRearrangerEntry.java new file mode 100644 index 000000000000..9a77f37053f5 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/TypeAwareRearrangerEntry.java @@ -0,0 +1,32 @@ +/* + * 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; + +import org.jetbrains.annotations.NotNull; + +/** + * Stands for the {@link RearrangerEntry} 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 { + + @NotNull + RearrangerEntryType getType(); +} 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 new file mode 100644 index 000000000000..0bc59ca9833e --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerCompositeRule.java @@ -0,0 +1,64 @@ +/* + * 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 new file mode 100644 index 000000000000..b1d63954c258 --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerRuleUtil.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.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 new file mode 100644 index 000000000000..c7a71377925e --- /dev/null +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/rearranger/rule/RearrangerTypeRule.java @@ -0,0 +1,53 @@ +/* + * 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; + } +}