IDEA-95117 Arrangement Allow to specify 'condition' sequences

This commit is contained in:
Svetlana.Zemlyanskay
2014-10-08 14:28:30 +04:00
parent 9816a243ba
commit fceb2d5cc9
31 changed files with 1523 additions and 24 deletions
@@ -30,6 +30,10 @@ public class ArrangementConstants {
@NonNls public static final String ACTION_GROUP_MATCHING_RULES_CONTROL_TOOLBAR = "Arrangement.Rule.Match.Control.ToolBar";
@NonNls public static final String MATCHING_RULES_CONTROL_TOOLBAR_PLACE = "Arrangement.Rule.Match.Control.ToolBar.Place";
@NonNls public static final String MATCHING_RULES_CONTROL_PLACE = "Arrangement.Rule.Match.Control.Place";
@NonNls public static final String ALIAS_RULE_CONTEXT_MENU = "Arrangement.Alias.Rule.Context.Menu";
@NonNls public static final String ALIAS_RULE_CONTROL_TOOLBAR = "Arrangement.Alias.Rule.ToolBar";
@NonNls public static final String ALIAS_RULE_CONTROL_TOOLBAR_PLACE = "Arrangement.Alias.Rule.ToolBar.Place";
@NonNls public static final String ALIAS_RULE_CONTROL_PLACE = "Arrangement.Alias.Rule.Control.Place";
@NonNls public static final String MATCHING_RULE_ADD = "Arrangement.Rule.Add";
@NonNls public static final String MATCHING_RULE_REMOVE = "Arrangement.Rule.Remove";
@@ -39,6 +43,12 @@ public class ArrangementConstants {
@NonNls public static final String GROUPING_RULE_MOVE_UP = "Arrangement.Rule.Group.Condition.Move.Up";
@NonNls public static final String GROUPING_RULE_MOVE_DOWN = "Arrangement.Rule.Group.Condition.Move.Down";
@NonNls public static final String MATCHING_ALIAS_RULE_ADD = "Arrangement.Alias.Rule.Add";
@NonNls public static final String MATCHING_ALIAS_RULE_REMOVE = "Arrangement.Alias.Rule.Remove";
@NonNls public static final String MATCHING_ALIAS_RULE_EDIT = "Arrangement.Alias.Rule.Edit";
@NonNls public static final String MATCHING_ALIAS_RULE_MOVE_UP = "Arrangement.Alias.Rule.Match.Condition.Move.Up";
@NonNls public static final String MATCHING_ALIAS_RULE_MOVE_DOWN = "Arrangement.Alias.Rule.Match.Condition.Move.Down";
public static final int HORIZONTAL_PADDING = 8;
public static final int VERTICAL_PADDING = 4;
public static final int HORIZONTAL_GAP = 5;
@@ -51,6 +61,7 @@ public class ArrangementConstants {
public static final int TEXT_UPDATE_DELAY_MILLIS = 1000;
public static final boolean LOG_RULE_MODIFICATION = Boolean.parseBoolean(System.getProperty("log.arrangement.rule.modification"));
public static final boolean LOG_ALIAS_RULE_MODIFICATION = Boolean.parseBoolean(System.getProperty("log.arrangement.rule.sequence.modification"));
private ArrangementConstants() {
}
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2014 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.ArrangementSectionRule;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementRuleAlias;
import java.util.List;
import java.util.Set;
/**
* Arrangement settings that can be extended by aliasing sequence of rules to one token,
* e.g. alias: 'visibility' -> {'public', 'protected', 'private'}
*
* @author Svetlana.Zemlyanskaya
*/
public interface ArrangementExtendableSettings extends ArrangementSettings {
Set<ArrangementRuleAlias> getRuleAliases();
/**
* Use this method to get all rules with replaced custom aliases
*/
List<ArrangementSectionRule> getExtendedSectionRules();
}
@@ -314,4 +314,20 @@ public class ArrangementUtil {
return matchRules;
}
//endregion
//region Arrangement Custom Tokens
public static List<ArrangementSectionRule> getExtendedSectionRules(@NotNull ArrangementSettings settings) {
return settings instanceof ArrangementExtendableSettings ?
((ArrangementExtendableSettings)settings).getExtendedSectionRules() : settings.getSections();
}
@NotNull
public static ArrangementSettingsToken createRuleAliasToken(@NotNull String id, @NotNull String name) {
return StdArrangementSettingsToken.token(id, name, StdArrangementTokenType.ALIAS);
}
public static boolean isAliasedCondition(@NotNull ArrangementAtomMatchCondition condition) {
return StdArrangementTokenType.ALIAS.is(condition.getType());
}
//endregion
}
@@ -21,6 +21,7 @@ import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
import com.intellij.psi.codeStyle.arrangement.match.*;
import com.intellij.psi.codeStyle.arrangement.std.*;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -29,6 +30,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* {@link ArrangementSettingsSerializer} which knows how to handle {@link StdArrangementSettings built-in arrangement tokens}
@@ -43,6 +45,10 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
@NotNull @NonNls private static final String GROUPS_ELEMENT_NAME = "groups";
@NotNull @NonNls private static final String GROUP_ELEMENT_NAME = "group";
@NotNull @NonNls private static final String RULES_ELEMENT_NAME = "rules";
@NotNull @NonNls private static final String TOKENS_ELEMENT_NAME = "tokens";
@NotNull @NonNls private static final String TOKEN_ELEMENT_NAME = "token";
@NotNull @NonNls private static final String TOKEN_ID = "id";
@NotNull @NonNls private static final String TOKEN_NAME = "name";
@NotNull @NonNls private static final String SECTION_ELEMENT_NAME = "section";
@NotNull @NonNls private static final String SECTION_START_ATTRIBUTE = "start_comment";
@NotNull @NonNls private static final String SECTION_END_ATTRIBUTE = "end_comment";
@@ -60,8 +66,8 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
}
public DefaultArrangementSettingsSerializer(@NotNull Mixin mixin, @NotNull StdArrangementSettings defaultSettings) {
myMixin = mixin;
myMatcherSerializer = new DefaultArrangementEntryMatcherSerializer(mixin);
myMixin = new MutableMixin(mixin);
myMatcherSerializer = new DefaultArrangementEntryMatcherSerializer(myMixin);
myDefaultSettings = defaultSettings;
}
@@ -72,6 +78,32 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
}
StdArrangementSettings settings = (StdArrangementSettings)s;
if (settings instanceof ArrangementExtendableSettings && myDefaultSettings instanceof ArrangementExtendableSettings) {
final Set<ArrangementRuleAlias> tokensDefinition =
((ArrangementExtendableSettings)settings).getRuleAliases();
final boolean isDefault = tokensDefinition.equals(((ArrangementExtendableSettings)myDefaultSettings).getRuleAliases());
if (!isDefault) {
final Element tokensElement = new Element(TOKENS_ELEMENT_NAME);
if (tokensDefinition.isEmpty()) {
tokensElement.addContent(new Element("no_tokens"));
}
for (ArrangementRuleAlias definition : tokensDefinition) {
final Element tokenElement = new Element(TOKEN_ELEMENT_NAME);
final ArrangementSettingsToken token = definition.getAliasToken();
tokenElement.setAttribute(TOKEN_ID, token.getId());
tokenElement.setAttribute(TOKEN_NAME, token.getRepresentationValue());
final Element rulesElement = new Element(RULES_ELEMENT_NAME);
for (StdArrangementMatchRule rule : definition.getDefinitionRules()) {
rulesElement.addContent(serialize(rule));
}
tokenElement.addContent(rulesElement);
tokensElement.addContent(tokenElement);
}
holder.addContent(tokensElement);
}
}
List<ArrangementGroupingRule> groupings = settings.getGroupings();
final boolean isDefaultGroupings = groupings.equals(myDefaultSettings.getGroupings());
if (!isDefaultGroupings) {
@@ -99,6 +131,7 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
@Nullable
@Override
public ArrangementSettings deserialize(@NotNull Element element) {
final Set<ArrangementRuleAlias> tokensDefinition = deserializeTokensDefinition(element, myDefaultSettings);
final List<ArrangementGroupingRule> groupingRules = deserializeGropings(element, myDefaultSettings);
final Element rulesElement = element.getChild(RULES_ELEMENT_NAME);
final List<ArrangementSectionRule> sectionRules = ContainerUtil.newArrayList();
@@ -106,14 +139,45 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
sectionRules.addAll(myDefaultSettings.getSections());
}
else {
sectionRules.addAll(deserializeSectionRules(rulesElement));
sectionRules.addAll(deserializeSectionRules(rulesElement, tokensDefinition));
if (sectionRules.isEmpty()) {
// for backward compatibility
final List<StdArrangementMatchRule> rules = deserializeRules(rulesElement);
final List<StdArrangementMatchRule> rules = deserializeRules(rulesElement, tokensDefinition);
return StdArrangementSettings.createByMatchRules(groupingRules, rules);
}
}
return new StdArrangementSettings(groupingRules, sectionRules);
if (tokensDefinition == null) {
return new StdArrangementSettings(groupingRules, sectionRules);
}
return new StdArrangementExtendableSettings(groupingRules, sectionRules, tokensDefinition);
}
@Nullable
private Set<ArrangementRuleAlias> deserializeTokensDefinition(@NotNull Element element, @NotNull ArrangementSettings defaultSettings) {
if (!(defaultSettings instanceof ArrangementExtendableSettings)) {
return null;
}
final Element tokensRoot = element.getChild(TOKENS_ELEMENT_NAME);
if (tokensRoot == null || tokensRoot.getChildren().size() == 0) {
// no tag for tokens exists -> get from default
return ((ArrangementExtendableSettings)myDefaultSettings).getRuleAliases();
}
final Set<ArrangementRuleAlias> tokenDefinitions =
new THashSet<ArrangementRuleAlias>();
final List<Element> tokens = tokensRoot.getChildren(TOKEN_ELEMENT_NAME);
for (Element token : tokens) {
final Attribute id = token.getAttribute(TOKEN_ID);
final Attribute name = token.getAttribute(TOKEN_NAME);
assert id != null && name != null : "Can not find id for token: " + token;
final Element rules = token.getChild(RULES_ELEMENT_NAME);
final ArrangementSettingsToken addToken = ArrangementUtil.createRuleAliasToken(id.getValue(), name.getValue());
final List<StdArrangementMatchRule> tokenRules = deserializeRules(rules, null);
tokenDefinitions.add(new ArrangementRuleAlias(addToken, tokenRules));
}
return tokenDefinitions;
}
@NotNull
@@ -154,11 +218,12 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
}
@NotNull
private List<ArrangementSectionRule> deserializeSectionRules(@NotNull Element rulesElement) {
private List<ArrangementSectionRule> deserializeSectionRules(@NotNull Element rulesElement,
@Nullable Set<ArrangementRuleAlias> tokens) {
final List<ArrangementSectionRule> sectionRules = new ArrayList<ArrangementSectionRule>();
for (Object o : rulesElement.getChildren(SECTION_ELEMENT_NAME)) {
final Element sectionElement = (Element)o;
final List<StdArrangementMatchRule> rules = deserializeRules(sectionElement);
final List<StdArrangementMatchRule> rules = deserializeRules(sectionElement, tokens);
final Attribute start = sectionElement.getAttribute(SECTION_START_ATTRIBUTE);
final String startComment = start != null ? start.getValue().trim() : null;
final Attribute end = sectionElement.getAttribute(SECTION_END_ATTRIBUTE);
@@ -169,7 +234,10 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
}
@NotNull
private List<StdArrangementMatchRule> deserializeRules(@NotNull Element element) {
private List<StdArrangementMatchRule> deserializeRules(@NotNull Element element, @Nullable final Set<ArrangementRuleAlias> aliases) {
if (aliases != null && myMixin instanceof MutableMixin) {
((MutableMixin)myMixin).setMyRuleAliases(aliases);
}
final List<StdArrangementMatchRule> rules = new ArrayList<StdArrangementMatchRule>();
for (Object o : element.getChildren(RULE_ELEMENT_NAME)) {
Element ruleElement = (Element)o;
@@ -247,6 +315,35 @@ public class DefaultArrangementSettingsSerializer implements ArrangementSettings
}
}
return sectionElement;
}
public static class MutableMixin implements Mixin {
private Mixin myDelegate;
private Set<ArrangementRuleAlias> myRuleAliases;
public MutableMixin(Mixin delegate) {
myDelegate = delegate;
}
public void setMyRuleAliases(Set<ArrangementRuleAlias> aliases) {
myRuleAliases = aliases;
}
@Nullable
@Override
public ArrangementSettingsToken deserializeToken(@NotNull String id) {
final ArrangementSettingsToken token = myDelegate.deserializeToken(id);
if (token != null || myRuleAliases == null) {
return token;
}
for (ArrangementRuleAlias alias : myRuleAliases) {
if (StringUtil.equals(alias.getAliasToken().getId(), id)) {
return alias.getAliasToken();
}
}
return null;
}
}
public interface Mixin {
@@ -0,0 +1,89 @@
/*
* Copyright 2000-2014 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.std;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* Extension for {@link ArrangementStandardSettingsManager} for managing matching rules with custom aliases
*
* @author Svetlana.Zemlyanskaya
*/
public class ArrangementExtendableSettingsManager extends ArrangementStandardSettingsManager {
@NotNull private Collection<ArrangementRuleAlias> myRuleAliases;
@NotNull private CompositeArrangementSettingsToken myRuleAliasToken;
@NotNull private Set<ArrangementSettingsToken> myRuleAliasMutex;
public ArrangementExtendableSettingsManager(@NotNull ArrangementStandardSettingsAware delegate,
@NotNull ArrangementColorsProvider colorsProvider,
@NotNull Collection<ArrangementRuleAlias> aliases) {
super(delegate, colorsProvider);
final Set<ArrangementSettingsToken> tokensSet = ContainerUtil.newHashSet();
for (ArrangementRuleAlias token : aliases) {
tokensSet.add(token.getAliasToken());
}
myRuleAliases = aliases;
myRuleAliasToken = createAliasTokenRepresentation(tokensSet);
myRuleAliasMutex = tokensSet;
}
@NotNull
private static CompositeArrangementSettingsToken createAliasTokenRepresentation(@NotNull Collection<ArrangementSettingsToken> tokens) {
return new CompositeArrangementSettingsToken(StdArrangementTokens.General.ALIAS, tokens);
}
@NotNull
public Collection<ArrangementRuleAlias> getRuleAliases() {
return myRuleAliases;
}
@Nullable
public List<CompositeArrangementSettingsToken> getSupportedMatchingTokens() {
final List<CompositeArrangementSettingsToken> tokens = super.getSupportedMatchingTokens();
if (tokens == null) {
return null;
}
final List<CompositeArrangementSettingsToken> allTokens = ContainerUtil.newArrayList(tokens);
allTokens.add(myRuleAliasToken);
return allTokens;
}
public boolean isEnabled(@NotNull ArrangementSettingsToken token, @Nullable ArrangementMatchCondition current) {
if (myRuleAliasMutex.contains(token)) {
return true;
}
return super.isEnabled(token, current);
}
@NotNull
public Collection<Set<ArrangementSettingsToken>> getMutexes() {
final List<Set<ArrangementSettingsToken>> allMutexes = ContainerUtil.newArrayList(super.getMutexes());
allMutexes.add(myRuleAliasMutex);
return allMutexes;
}
}
@@ -0,0 +1,91 @@
/*
* Copyright 2000-2014 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.std;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author Svetlana.Zemlyanskaya
*/
public class ArrangementRuleAlias implements Cloneable {
/**
* Token to be used in matching rules ui
*/
private ArrangementSettingsToken myAliasToken;
/**
* All usages of alias token will be replaced by this sequence of rules
*/
private List<StdArrangementMatchRule> myDefinitionRules;
public ArrangementRuleAlias() {
}
public ArrangementRuleAlias(@NotNull ArrangementSettingsToken aliasToken,
@NotNull List<StdArrangementMatchRule> definitionRules) {
myAliasToken = aliasToken;
myDefinitionRules = definitionRules;
}
public ArrangementSettingsToken getAliasToken() {
return myAliasToken;
}
public void setAliasToken(@NotNull ArrangementSettingsToken aliasToken) {
myAliasToken = aliasToken;
}
public List<StdArrangementMatchRule> getDefinitionRules() {
return myDefinitionRules;
}
public void setDefinitionRules(List<StdArrangementMatchRule> definitionRules) {
myDefinitionRules = definitionRules;
}
@Override
protected ArrangementRuleAlias clone() {
final List<StdArrangementMatchRule> newValue = new ArrayList<StdArrangementMatchRule>(myDefinitionRules.size());
for (StdArrangementMatchRule rule : myDefinitionRules) {
newValue.add(rule.clone());
}
return new ArrangementRuleAlias(myAliasToken, newValue);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ArrangementRuleAlias token = (ArrangementRuleAlias)o;
if (myAliasToken != null ? !myAliasToken.equals(token.myAliasToken) : token.myAliasToken != null) return false;
if (myDefinitionRules != null ? !myDefinitionRules.equals(token.myDefinitionRules) : token.myDefinitionRules != null) return false;
return true;
}
@Override
public int hashCode() {
int result = myAliasToken != null ? myAliasToken.hashCode() : 0;
result = 31 * result + (myDefinitionRules != null ? myDefinitionRules.hashCode() : 0);
return result;
}
}
@@ -89,6 +89,11 @@ public class ArrangementStandardSettingsManager {
}
}
@NotNull
public ArrangementStandardSettingsAware getDelegate() {
return myDelegate;
}
private void parseWidths(@NotNull Collection<CompositeArrangementSettingsToken> compositeTokens,
@NotNull SimpleColoredComponent renderer)
{
@@ -0,0 +1,190 @@
/*
* Copyright 2000-2014 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.std;
import com.intellij.psi.codeStyle.arrangement.ArrangementExtendableSettings;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementSectionRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchConditionVisitor;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author Svetlana.Zemlyanskaya
*/
public class StdArrangementExtendableSettings extends StdArrangementSettings implements ArrangementExtendableSettings {
@NotNull private final Set<ArrangementRuleAlias> myRulesAliases = new THashSet<ArrangementRuleAlias>();
// cached values
@NotNull private final List<ArrangementSectionRule> myExtendedSectionRules = new ArrayList<ArrangementSectionRule>();
public StdArrangementExtendableSettings() {
super();
}
public StdArrangementExtendableSettings(@NotNull List<ArrangementGroupingRule> groupingRules,
@NotNull List<ArrangementSectionRule> sectionRules,
@NotNull Collection<ArrangementRuleAlias> rulesAliases) {
super(groupingRules, sectionRules);
myRulesAliases.addAll(rulesAliases);
}
@Override
public Set<ArrangementRuleAlias> getRuleAliases() {
return myRulesAliases;
}
private Set<ArrangementRuleAlias> cloneTokenDefinitions() {
final Set<ArrangementRuleAlias> definitions = new THashSet<ArrangementRuleAlias>();
for (ArrangementRuleAlias definition : myRulesAliases) {
definitions.add(definition.clone());
}
return definitions;
}
@Override
public List<ArrangementSectionRule> getExtendedSectionRules() {
if (myExtendedSectionRules.isEmpty()) {
final Map<String, ArrangementRuleAlias> tokenIdToDefinition = new THashMap<String, ArrangementRuleAlias>(myRulesAliases.size());
for (ArrangementRuleAlias alias : myRulesAliases) {
final String id = alias.getAliasToken().getId();
tokenIdToDefinition.put(id, alias);
}
final List<ArrangementSectionRule> sections = getSections();
for (ArrangementSectionRule section : sections) {
final List<StdArrangementMatchRule> extendedRules = new ArrayList<StdArrangementMatchRule>();
for (StdArrangementMatchRule rule : section.getMatchRules()) {
appendExpandedRules(rule, extendedRules, tokenIdToDefinition);
}
myExtendedSectionRules.add(ArrangementSectionRule.create(section.getStartComment(), section.getEndComment(), extendedRules));
}
}
return myExtendedSectionRules;
}
public void appendExpandedRules(@NotNull final StdArrangementMatchRule rule,
@NotNull final List<StdArrangementMatchRule> rules,
@NotNull final Map<String, ArrangementRuleAlias> tokenIdToDefinition) {
final List<StdArrangementMatchRule> sequence = getRuleSequence(rule, tokenIdToDefinition);
if (sequence == null || sequence.isEmpty()) {
rules.add(rule);
return;
}
final ArrangementCompositeMatchCondition ruleTemplate = removeAliasRuleToken(rule.getMatcher().getCondition());
for (StdArrangementMatchRule matchRule : sequence) {
final ArrangementCompositeMatchCondition extendedRule = ruleTemplate.clone();
extendedRule.addOperand(matchRule.getMatcher().getCondition());
rules.add(new StdArrangementMatchRule(new StdArrangementEntryMatcher(extendedRule)));
}
}
@Nullable
private List<StdArrangementMatchRule> getRuleSequence(@NotNull final StdArrangementMatchRule rule,
@NotNull final Map<String, ArrangementRuleAlias> tokenIdToDefinition) {
final List<StdArrangementMatchRule> seqRule = ContainerUtil.newSmartList();
rule.getMatcher().getCondition().invite(new ArrangementMatchConditionVisitor() {
@Override
public void visit(@NotNull ArrangementAtomMatchCondition condition) {
final ArrangementRuleAlias token = tokenIdToDefinition.get(condition.getType().getId());
if (token != null && !token.getDefinitionRules().isEmpty()) {
seqRule.addAll(token.getDefinitionRules());
}
}
@Override
public void visit(@NotNull ArrangementCompositeMatchCondition condition) {
for (ArrangementMatchCondition operand : condition.getOperands()) {
if (!seqRule.isEmpty()) {
return;
}
operand.invite(this);
}
}
});
return seqRule;
}
@NotNull
private static ArrangementCompositeMatchCondition removeAliasRuleToken(final ArrangementMatchCondition original) {
final ArrangementCompositeMatchCondition composite = new ArrangementCompositeMatchCondition();
original.invite(new ArrangementMatchConditionVisitor() {
@Override
public void visit(@NotNull ArrangementAtomMatchCondition condition) {
if (!ArrangementUtil.isAliasedCondition(condition)) {
composite.addOperand(condition);
}
}
@Override
public void visit(@NotNull ArrangementCompositeMatchCondition condition) {
for (ArrangementMatchCondition c : condition.getOperands()) {
c.invite(this);
}
}
});
return composite;
}
@Override
public void addRule(@NotNull StdArrangementMatchRule rule) {
super.addRule(rule);
myExtendedSectionRules.clear();
}
@NotNull
@Override
public List<? extends ArrangementMatchRule> getRulesSortedByPriority() {
if (myRulesByPriority.isEmpty()) {
for (ArrangementSectionRule rule : getExtendedSectionRules()) {
myRulesByPriority.addAll(rule.getMatchRules());
}
ContainerUtil.sort(myRulesByPriority);
}
return myRulesByPriority;
}
@NotNull
@Override
public StdArrangementExtendableSettings clone() {
return new StdArrangementExtendableSettings(cloneGroupings(), cloneSectionRules(), cloneTokenDefinitions());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StdArrangementExtendableSettings settings = (StdArrangementExtendableSettings)o;
if (!super.equals(settings)) return false;
if (!myRulesAliases.equals(settings.myRulesAliases)) return false;
return true;
}
}
@@ -63,6 +63,7 @@ public class StdArrangementTokenType {
public static final String REG_EXP_ID = "REG_EXP";
public static final String ENTRY_TYPE_ID = "ENTRY_TYPE";
public static final String ORDER_ID = "ORDER";
public static final String ALIAS_ID = "ALIAS";
public static final StdArrangementTokenType GENERAL = new StdArrangementTokenType(StdArrangementTokenUiRole.LABEL, GENERAL_ID);
public static final StdArrangementTokenType GROUPING = new StdArrangementTokenType(StdArrangementTokenUiRole.CHECKBOX, GROUPING_ID);
@@ -70,4 +71,5 @@ public class StdArrangementTokenType {
public static final StdArrangementTokenType REG_EXP = new StdArrangementTokenType(StdArrangementTokenUiRole.TEXT_FIELD, REG_EXP_ID);
public static final StdArrangementTokenType ENTRY_TYPE = new StdArrangementTokenType(StdArrangementTokenUiRole.BULB, ENTRY_TYPE_ID);
public static final StdArrangementTokenType ORDER = new StdArrangementTokenType(StdArrangementTokenUiRole.COMBO_BOX, ORDER_ID);
public static final StdArrangementTokenType ALIAS = new StdArrangementTokenType(StdArrangementTokenUiRole.BULB, ALIAS_ID);
}
@@ -110,6 +110,7 @@ public class StdArrangementTokens {
@NotNull public static final ArrangementSettingsToken TYPE = token("TYPE", "arrangement.settings.text.general.type", StdArrangementTokenType.GENERAL);
@NotNull public static final ArrangementSettingsToken MODIFIER = token("MODIFIER", "arrangement.settings.text.general.modifier", StdArrangementTokenType.GENERAL);
@NotNull public static final ArrangementSettingsToken ORDER = token("ORDER", "arrangement.settings.text.general.order", StdArrangementTokenType.GENERAL);
@NotNull public static final ArrangementSettingsToken ALIAS = token("ALIAS", "arrangement.settings.text.general.sequence", StdArrangementTokenType.GENERAL);
private General() {
}
@@ -15,13 +15,16 @@
*/
package com.intellij.psi.codeStyle.arrangement;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementSectionRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementRuleAlias;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken;
import com.intellij.psi.codeStyle.arrangement.std.StdArrangementExtendableSettings;
import com.intellij.psi.codeStyle.arrangement.std.StdArrangementSettings;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Element;
@@ -30,13 +33,14 @@ import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.EntryType.FIELD;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.EntryType.METHOD;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Grouping.OVERRIDDEN_METHODS;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.PRIVATE;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.PUBLIC;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.*;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Order.BY_NAME;
import static org.junit.Assert.*;
@@ -76,15 +80,44 @@ public class ArrangementSettingsSerializationTest {
return section(null, null, rule(byName, tokens));
}
private static StdArrangementSettings sectionSettings(@NotNull List<ArrangementGroupingRule> groupings,
@NotNull List<ArrangementSectionRule> sections) {
private static StdArrangementSettings settings(@NotNull List<ArrangementGroupingRule> groupings,
@NotNull List<ArrangementSectionRule> sections) {
return new StdArrangementSettings(groupings, sections);
}
private static StdArrangementExtendableSettings extendableSettings(@NotNull List<ArrangementGroupingRule> groupings,
@NotNull List<ArrangementSectionRule> sections,
@NotNull Collection<ArrangementRuleAlias> tokens) {
return new StdArrangementExtendableSettings(groupings, sections, tokens);
}
private static StdArrangementSettings emptySettings() {
return new StdArrangementSettings(ContainerUtil.<ArrangementGroupingRule>emptyList(), ContainerUtil.<ArrangementSectionRule>emptyList());
}
private static ArrangementSettingsToken customToken(@NotNull String name) {
return ArrangementUtil.createRuleAliasToken(name, name);
}
private static ArrangementRuleAlias visibilityToken() {
final ArrayList<StdArrangementMatchRule> rules = new ArrayList<StdArrangementMatchRule>();
rules.add(rule(false, PUBLIC));
rules.add(rule(false, PROTECTED));
rules.add(rule(false, PRIVATE));
return new ArrangementRuleAlias(customToken("visibility"), rules);
}
private static ArrangementRuleAlias modifiersToken() {
final ArrayList<StdArrangementMatchRule> rules = new ArrayList<StdArrangementMatchRule>();
rules.add(rule(false, PUBLIC, STATIC));
rules.add(rule(false, PROTECTED, STATIC));
rules.add(rule(false, PRIVATE, STATIC));
rules.add(rule(false, PUBLIC));
rules.add(rule(false, PROTECTED));
rules.add(rule(false, PRIVATE));
return new ArrangementRuleAlias(customToken("modifiers"), rules);
}
@Test
public void all() {
final StdArrangementSettings settings = new StdArrangementSettings();
@@ -177,7 +210,7 @@ public class ArrangementSettingsSerializationTest {
@Test
public void testSimpleSectionSerialize() {
final StdArrangementSettings settings =
sectionSettings(ContainerUtil.newArrayList(group(OVERRIDDEN_METHODS)), ContainerUtil.newArrayList(section(true, FIELD)));
settings(ContainerUtil.newArrayList(group(OVERRIDDEN_METHODS)), ContainerUtil.newArrayList(section(true, FIELD)));
final Element holder = doSerializationTest(settings, emptySettings());
assertTrue(holder.getChildren().size() == 2);
assertNotNull(holder.getChild("groups"));
@@ -196,7 +229,7 @@ public class ArrangementSettingsSerializationTest {
ContainerUtil.newArrayList(section("start section", "end section", rule(true, METHOD, PRIVATE), rule(false, METHOD, PUBLIC)),
section("start section", "end section", rule(true, FIELD)));
final StdArrangementSettings settings =
sectionSettings(ContainerUtil.newArrayList(group(OVERRIDDEN_METHODS)), sections);
settings(ContainerUtil.newArrayList(group(OVERRIDDEN_METHODS)), sections);
final Element holder = doSerializationTest(settings, emptySettings());
assertTrue(holder.getChildren().size() == 2);
@@ -209,6 +242,104 @@ public class ArrangementSettingsSerializationTest {
assertEquals(section.getAttribute("end_comment").getValue(), "end section");
}
@Test
public void testDefaultCustomTokenSerialize() {
final Set<ArrangementRuleAlias> tokens = ContainerUtil.newHashSet(visibilityToken());
final ArrayList<ArrangementGroupingRule> groupings =
ContainerUtil.newArrayList(new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME));
final ArrayList<ArrangementSectionRule> rules = ContainerUtil.newArrayList(section(true, FIELD));
final StdArrangementExtendableSettings settings = extendableSettings(groupings, rules, tokens);
final Element holder = doSerializationTest(settings, settings.clone());
assertTrue(holder.getChildren().isEmpty());
}
@Test
public void testCustomTokenSerializeLessThanDefault() {
final Set<ArrangementRuleAlias> tokens = ContainerUtil.newHashSet(visibilityToken());
final ArrayList<ArrangementGroupingRule> groupings = ContainerUtil.newArrayList(
new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME));
final ArrayList<ArrangementSectionRule> rules = ContainerUtil.newArrayList(section(true, FIELD));
final StdArrangementExtendableSettings settings = extendableSettings(groupings, rules, tokens);
final Set<ArrangementRuleAlias> defaultTokens = ContainerUtil.newHashSet(visibilityToken(), modifiersToken());
final StdArrangementExtendableSettings defaultSettings = extendableSettings(groupings, rules, defaultTokens);
final Element holder = doSerializationTest(settings, defaultSettings);
assertTrue(holder.getChildren().size() == 1);
final Element tokenElement = holder.getChildren().get(0);
assertEquals(tokenElement.getName(), "tokens");
assertTrue(tokenElement.getChildren().size() == 1);
final List<Element> tokenElements = tokenElement.getChildren();
final Element element = tokenElements.get(0);
assertEquals(element.getName(), "token");
assertTrue(StringUtil.equals(element.getAttributeValue("id"), "visibility"));
}
@Test
public void testCustomTokenSerializeMoreThanDefault() {
final Set<ArrangementRuleAlias> tokens = ContainerUtil.newHashSet(visibilityToken(), modifiersToken());
final ArrayList<ArrangementGroupingRule> groupings = ContainerUtil.newArrayList(
new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME));
final ArrayList<ArrangementSectionRule> rules = ContainerUtil.newArrayList(section(true, FIELD));
final StdArrangementExtendableSettings settings = extendableSettings(groupings, rules, tokens);
final Set<ArrangementRuleAlias> defaultTokens = ContainerUtil.newHashSet(visibilityToken());
final StdArrangementExtendableSettings defaultSettings = extendableSettings(groupings, rules, defaultTokens);
final Element holder = doSerializationTest(settings, defaultSettings);
assertTrue(holder.getChildren().size() == 1);
final Element tokenElement = holder.getChildren().get(0);
assertEquals(tokenElement.getName(), "tokens");
assertTrue(tokenElement.getChildren().size() == 2);
final List<Element> tokenElements = tokenElement.getChildren();
final Element first = tokenElements.get(0);
final Element second = tokenElements.get(1);
assertEquals(first.getName(), "token");
assertEquals(second.getName(), "token");
assertTrue(StringUtil.equals(first.getAttributeValue("id"), "visibility") ||
StringUtil.equals(second.getAttributeValue("id"), "visibility"));
assertTrue(StringUtil.equals(first.getAttributeValue("id"), "modifiers") ||
StringUtil.equals(second.getAttributeValue("id"), "modifiers"));
}
@Test
public void testUseCustomTokenSerialize() {
final Set<ArrangementRuleAlias> tokens = ContainerUtil.newHashSet(visibilityToken(), modifiersToken());
final ArrayList<ArrangementGroupingRule> groupings = ContainerUtil.newArrayList(
new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME));
final ArrayList<ArrangementSectionRule> rules = ContainerUtil.newArrayList(section(true, FIELD, customToken("visibility")));
final StdArrangementExtendableSettings settings = extendableSettings(groupings, rules, tokens);
final ArrayList<ArrangementSectionRule> defaultRules = ContainerUtil.newArrayList(section(true, FIELD));
final StdArrangementExtendableSettings defaultSettings = extendableSettings(groupings, defaultRules, tokens);
final Element holder = doSerializationTest(settings, defaultSettings);
assertTrue(holder.getChildren().size() == 1);
final Element tokenElement = holder.getChildren().get(0);
assertEquals(tokenElement.getName(), "rules");
assertTrue(tokenElement.getChildren().size() == 1);
assertEquals(tokenElement.getChildren().get(0).getName(), "section");
final Element rule = tokenElement.getChildren().get(0).getChildren().get(0);
assertEquals(rule.getName(), "rule");
assertEquals(rule.getChildren().get(0).getName(), "match");
final Element and = rule.getChildren().get(0).getChildren().get(0);
assertEquals(and.getName(), "AND");
assertTrue(StringUtil.equals(and.getChildren().get(0).getName(), "visibility") ||
StringUtil.equals(and.getChildren().get(1).getName(), "visibility"));
}
@Test
public void testCustomTokenSerializeAndDeserialize() {
final Set<ArrangementRuleAlias> tokens = ContainerUtil.newHashSet(visibilityToken(), modifiersToken());
final ArrayList<ArrangementGroupingRule> groupings = ContainerUtil.newArrayList(
new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME));
final ArrayList<ArrangementSectionRule> rules = ContainerUtil.newArrayList(section(true, FIELD, customToken("visibility")));
final StdArrangementExtendableSettings settings = extendableSettings(groupings, rules, tokens);
final StdArrangementExtendableSettings defaultSettings = new StdArrangementExtendableSettings();
doSerializationTest(settings, defaultSettings);
}
private static class TestArrangementSettingsSerializer extends DefaultArrangementSettingsSerializer {
public TestArrangementSettingsSerializer(@NotNull StdArrangementSettings defaultSettings) {
@@ -42,6 +42,7 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -155,7 +156,12 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel {
private StdArrangementSettings createSettings() {
final List<ArrangementGroupingRule> groupingRules = myGroupingRulesPanel.getRules();
return new StdArrangementSettings(groupingRules, myMatchingRulesPanel.getSections());
final List<ArrangementSectionRule> sections = myMatchingRulesPanel.getSections();
final Collection<ArrangementRuleAlias> tokens = myMatchingRulesPanel.getRulesAliases();
if (tokens != null) {
return new StdArrangementExtendableSettings(groupingRules, sections, tokens);
}
return new StdArrangementSettings(groupingRules, sections);
}
@Override
@@ -169,6 +175,10 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel {
List<ArrangementGroupingRule> groupings = s.getGroupings();
myGroupingRulesPanel.setRules(ContainerUtilRt.newArrayList(groupings));
myMatchingRulesPanel.setSections(copy(s.getSections()));
if (s instanceof StdArrangementExtendableSettings) {
myMatchingRulesPanel.setRulesAliases(((StdArrangementExtendableSettings)s).getRuleAliases());
}
if (myForceArrangementPanel != null) {
myForceArrangementPanel.setSelectedMode(settings.getCommonSettings(myLanguage).FORCE_REARRANGE_MODE);
}
@@ -0,0 +1,60 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.action;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementSectionRulesControl;
import com.intellij.application.options.codeStyle.arrangement.match.tokens.ArrangementRuleAliasDialog;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationBundle;
import org.jetbrains.annotations.NotNull;
/**
* @author Svetlana.Zemlyanskaya
*/
public class EditRuleAliasesDefinitionAction extends AnAction {
public EditRuleAliasesDefinitionAction() {
getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.alias.rule.add.edit.text"));
getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.alias.rule.add.edit.description"));
getTemplatePresentation().setIcon(AllIcons.General.Gear);
}
@Override
public void update(AnActionEvent e) {
final ArrangementSectionRulesControl control = ArrangementSectionRulesControl.KEY.getData(e.getDataContext());
if (control == null) {
return;
}
e.getPresentation().setEnabledAndVisible(control.getRulesAliases() != null);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ArrangementSectionRulesControl control = ArrangementSectionRulesControl.KEY.getData(e.getDataContext());
if (control == null || control.getRulesAliases() == null) {
return;
}
control.hideEditor();
final ArrangementRuleAliasDialog dialog = control.createRuleAliasEditDialog();
dialog.show();
if (dialog.isOK() && dialog.isModified()) {
control.setRulesAliases(dialog.getRuleAliases());
}
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.action.tokens;
import com.intellij.application.options.codeStyle.arrangement.action.AddArrangementRuleAction;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.application.options.codeStyle.arrangement.match.tokens.ArrangementRuleAliasControl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.Nullable;
/**
* @author Svetlana.Zemlyanskaya
*/
public class AddArrangementAliasRuleAction extends AddArrangementRuleAction {
@Override
@Nullable
protected ArrangementMatchingRulesControl getRulesControl(AnActionEvent e) {
return ArrangementRuleAliasControl.KEY.getData(e.getDataContext());
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.action.tokens;
import com.intellij.application.options.codeStyle.arrangement.action.EditArrangementRuleAction;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.application.options.codeStyle.arrangement.match.tokens.ArrangementRuleAliasControl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.Nullable;
/**
* @author Svetlana.Zemlyanskaya
*/
public class EditArrangementAliasRuleAction extends EditArrangementRuleAction {
@Override
@Nullable
protected ArrangementMatchingRulesControl getRulesControl(AnActionEvent e) {
return ArrangementRuleAliasControl.KEY.getData(e.getDataContext());
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.action.tokens;
import com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementMatchingRuleDownAction;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.application.options.codeStyle.arrangement.match.tokens.ArrangementRuleAliasControl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.Nullable;
/**
* @author Svetlana.Zemlyanskaya
*/
public class MoveArrangementAliasRuleDownAction extends MoveArrangementMatchingRuleDownAction {
@Override
@Nullable
protected ArrangementMatchingRulesControl getRulesControl(AnActionEvent e) {
return ArrangementRuleAliasControl.KEY.getData(e.getDataContext());
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.action.tokens;
import com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementMatchingRuleUpAction;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.application.options.codeStyle.arrangement.match.tokens.ArrangementRuleAliasControl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.Nullable;
/**
* @author Svetlana.Zemlyanskaya
*/
public class MoveArrangementAliasRuleUpAction extends MoveArrangementMatchingRuleUpAction {
@Override
@Nullable
protected ArrangementMatchingRulesControl getRulesControl(AnActionEvent e) {
return ArrangementRuleAliasControl.KEY.getData(e.getDataContext());
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.action.tokens;
import com.intellij.application.options.codeStyle.arrangement.action.RemoveArrangementRuleAction;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.application.options.codeStyle.arrangement.match.tokens.ArrangementRuleAliasControl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.Nullable;
/**
* @author Svetlana.Zemlyanskaya
*/
public class RemoveArrangementAliasRuleAction extends RemoveArrangementRuleAction {
@Override
@Nullable
protected ArrangementMatchingRulesControl getRulesControl(AnActionEvent e) {
return ArrangementRuleAliasControl.KEY.getData(e.getDataContext());
}
}
@@ -55,7 +55,7 @@ public class ArrangementMatchingRulesControl extends JBTable {
@NotNull private final TIntArrayList mySelectedRows = new TIntArrayList();
@NotNull private final ArrangementMatchNodeComponentFactory myFactory;
@NotNull private final ArrangementMatchingRuleEditor myEditor;
@NotNull protected ArrangementMatchingRuleEditor myEditor;
@NotNull private final RepresentationCallback myRepresentationCallback;
@NotNull private final MatchingRulesRendererBase myRenderer;
@@ -23,6 +23,7 @@ import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementSectionRule;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementRuleAlias;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.ui.GridBag;
@@ -32,6 +33,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collection;
import java.util.List;
/**
@@ -101,6 +103,15 @@ public class ArrangementMatchingRulesPanel extends JPanel implements DataProvide
myControl.setSections(rules);
}
@Nullable
public Collection<ArrangementRuleAlias> getRulesAliases() {
return myControl.getRulesAliases();
}
public void setRulesAliases(@Nullable Collection<ArrangementRuleAlias> aliases) {
myControl.setRulesAliases(aliases);
}
@Nullable
@Override
public Object getData(@NonNls String dataId) {
@@ -17,6 +17,7 @@ package com.intellij.application.options.codeStyle.arrangement.match;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.match.tokens.ArrangementRuleAliasDialog;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.diagnostic.Logger;
@@ -24,13 +25,20 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementSectionRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchConditionVisitor;
import com.intellij.psi.codeStyle.arrangement.std.*;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static com.intellij.application.options.codeStyle.arrangement.match.ArrangementSectionRuleManager.ArrangementSectionRuleData;
@@ -42,12 +50,19 @@ public class ArrangementSectionRulesControl extends ArrangementMatchingRulesCont
@NotNull public static final DataKey<ArrangementSectionRulesControl> KEY = DataKey.create("Arrangement.Rule.Match.Control");
@NotNull private static final Logger LOG = Logger.getInstance("#" + ArrangementSectionRulesControl.class.getName());
@Nullable private final ArrangementSectionRuleManager mySectionRuleManager;
@Nullable private ArrangementExtendableSettingsManager myRuleAliasesManager;
public ArrangementSectionRulesControl(@NotNull Language language, @NotNull ArrangementStandardSettingsManager settingsManager,
private ArrangementStandardSettingsManager mySettingsManager;
private ArrangementColorsProvider myColorsProvider;
public ArrangementSectionRulesControl(@NotNull Language language,
@NotNull ArrangementStandardSettingsManager settingsManager,
@NotNull ArrangementColorsProvider colorsProvider,
@NotNull RepresentationCallback callback) {
super(settingsManager, colorsProvider, callback);
mySectionRuleManager = ArrangementSectionRuleManager.getInstance(language, settingsManager, colorsProvider, this);
mySettingsManager = settingsManager;
myColorsProvider = colorsProvider;
}
private static void appendBufferedSectionRules(@NotNull List<ArrangementSectionRule> result,
@@ -145,6 +160,18 @@ public class ArrangementSectionRulesControl extends ArrangementMatchingRulesCont
}
}
@Nullable
public Collection<ArrangementRuleAlias> getRulesAliases() {
return myRuleAliasesManager == null ? null : myRuleAliasesManager.getRuleAliases();
}
public void setRulesAliases(@Nullable Collection<ArrangementRuleAlias> aliases) {
if (aliases != null) {
myRuleAliasesManager = new ArrangementExtendableSettingsManager(mySettingsManager.getDelegate(), myColorsProvider, aliases);
myEditor = new ArrangementMatchingRuleEditor(myRuleAliasesManager, myColorsProvider, this);
}
}
public void showEditor(int rowToEdit) {
if (mySectionRuleManager != null && mySectionRuleManager.isSectionRule(getModel().getElementAt(rowToEdit))) {
mySectionRuleManager.showEditor(rowToEdit);
@@ -154,6 +181,35 @@ public class ArrangementSectionRulesControl extends ArrangementMatchingRulesCont
}
}
@NotNull
public ArrangementRuleAliasDialog createRuleAliasEditDialog() {
final Set<String> tokenIds = new THashSet<String>();
final List<ArrangementSectionRule> sections = getSections();
for (ArrangementSectionRule section : sections) {
for (StdArrangementMatchRule rule : section.getMatchRules()) {
rule.getMatcher().getCondition().invite(new ArrangementMatchConditionVisitor() {
@Override
public void visit(@NotNull ArrangementAtomMatchCondition condition) {
if (ArrangementUtil.isAliasedCondition(condition)) {
tokenIds.add(condition.getType().getId());
}
}
@Override
public void visit(@NotNull ArrangementCompositeMatchCondition condition) {
for (ArrangementMatchCondition operand : condition.getOperands()) {
operand.invite(this);
}
}
});
}
}
final Collection<ArrangementRuleAlias> aliases = getRulesAliases();
assert aliases != null;
return new ArrangementRuleAliasDialog(null, mySettingsManager, myColorsProvider, aliases, tokenIds);
}
private class MatchingRulesRenderer extends MatchingRulesRendererBase {
@Override
public boolean allowModifications(StdArrangementMatchRule rule) {
@@ -0,0 +1,108 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.match.tokens;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementRuleAlias;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.util.List;
/**
* @author Svetlana.Zemlyanskaya
*/
public class ArrangementRuleAliasConfigurable implements UnnamedConfigurable {
private ArrangementRuleAlias myToken;
private ArrangementRuleAliasesPanel myTokenRulesPanel;
public ArrangementRuleAliasConfigurable(@NotNull ArrangementStandardSettingsManager settingsManager,
@NotNull ArrangementColorsProvider colorsProvider,
@NotNull ArrangementRuleAlias token) {
myToken = token;
myTokenRulesPanel = new ArrangementRuleAliasesPanel(settingsManager, colorsProvider);
myTokenRulesPanel.setRuleSequences(token.getDefinitionRules());
registerShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_ADD, CommonShortcuts.getNew(), myTokenRulesPanel);
registerShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_REMOVE, CommonShortcuts.getDelete(), myTokenRulesPanel);
registerShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_MOVE_UP, CommonShortcuts.MOVE_UP, myTokenRulesPanel);
registerShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_MOVE_DOWN, CommonShortcuts.MOVE_DOWN, myTokenRulesPanel);
final CustomShortcutSet edit = new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
registerShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_EDIT, edit, myTokenRulesPanel);
}
private static void registerShortcut(@NotNull String actionId,
@NotNull ShortcutSet shortcut,
@NotNull JComponent component) {
final AnAction action = ActionManager.getInstance().getAction(actionId);
if (action != null) {
action.registerCustomShortcutSet(shortcut, component);
}
}
private static void unregisterShortcut(@NotNull String actionId, @NotNull JComponent component) {
final AnAction action = ActionManager.getInstance().getAction(actionId);
if (action != null) {
action.unregisterCustomShortcutSet(component);
}
}
@Nullable
@Override
public JComponent createComponent() {
return myTokenRulesPanel;
}
@Override
public boolean isModified() {
final List<StdArrangementMatchRule> newRules = myTokenRulesPanel.getRuleSequences();
return !newRules.equals(myToken.getDefinitionRules());
}
@Override
public void apply() throws ConfigurationException {
myToken.setDefinitionRules(myTokenRulesPanel.getRuleSequences());
}
@Override
public void reset() {
myTokenRulesPanel.setRuleSequences(myToken.getDefinitionRules());
}
@Override
public void disposeUIResources() {
Disposer.dispose(new Disposable() {
@Override
public void dispose() {
unregisterShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_ADD, myTokenRulesPanel);
unregisterShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_REMOVE, myTokenRulesPanel);
unregisterShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_MOVE_UP, myTokenRulesPanel);
unregisterShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_MOVE_DOWN, myTokenRulesPanel);
unregisterShortcut(ArrangementConstants.MATCHING_ALIAS_RULE_EDIT, myTokenRulesPanel);
}
});
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.match.tokens;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Svetlana.Zemlyanskaya
*/
public class ArrangementRuleAliasControl extends ArrangementMatchingRulesControl {
@NotNull public static final DataKey<ArrangementRuleAliasControl> KEY = DataKey.create("Arrangement.Alias.Rule.Control");
@NotNull private static final Logger LOG = Logger.getInstance("#" + ArrangementRuleAliasControl.class.getName());
public ArrangementRuleAliasControl(@NotNull ArrangementStandardSettingsManager settingsManager,
@NotNull ArrangementColorsProvider colorsProvider,
@NotNull RepresentationCallback callback) {
super(settingsManager, colorsProvider, callback);
}
public List<StdArrangementMatchRule> getRuleSequences() {
final List<StdArrangementMatchRule> rulesSequences = new ArrayList<StdArrangementMatchRule>();
for (int i = 0; i < getModel().getSize(); i++) {
Object element = getModel().getElementAt(i);
if (element instanceof StdArrangementMatchRule) {
rulesSequences.add((StdArrangementMatchRule)element);
}
}
return rulesSequences;
}
public void setRuleSequences(Collection<StdArrangementMatchRule> sequences) {
myComponents.clear();
getModel().clear();
if (sequences == null) {
return;
}
for (StdArrangementMatchRule rule : sequences) {
getModel().add(rule);
}
if (ArrangementConstants.LOG_ALIAS_RULE_MODIFICATION) {
LOG.info("Arrangement rules sequences is refreshed. Given rules:");
for (StdArrangementMatchRule rule : sequences) {
LOG.info(" " + rule.toString());
}
}
}
}
@@ -0,0 +1,85 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.match.tokens;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementRuleAlias;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
/**
* @author Svetlana.Zemlyanskaya
*/
public class ArrangementRuleAliasDialog extends DialogWrapper {
private final ArrangementRuleAliasesListEditor myEditor;
private boolean myModified;
public ArrangementRuleAliasDialog(@Nullable Project project,
@NotNull ArrangementStandardSettingsManager settingsManager,
@NotNull ArrangementColorsProvider colorsProvider,
@NotNull Collection<ArrangementRuleAlias> tokens,
@NotNull Set<String> tokensInUse) {
super(project, false);
final ArrayList<ArrangementRuleAlias> tokenList = ContainerUtil.newArrayList(tokens);
myEditor = new ArrangementRuleAliasesListEditor(settingsManager, colorsProvider, tokenList, tokensInUse);
if (!tokenList.isEmpty()) {
myEditor.selectItem(tokenList.get(0));
}
setTitle(ApplicationBundle.message("arrangement.settings.section.rule.custom.token.title"));
init();
}
public boolean isModified() {
return myModified;
}
public Collection<ArrangementRuleAlias> getRuleAliases() {
return myEditor.getItems();
}
@Nullable
@Override
protected JComponent createCenterPanel() {
return myEditor.createComponent();
}
@Override
protected void doOKAction() {
try {
myModified = myEditor.isModified();
if (myModified) {
myEditor.apply();
}
super.doOKAction();
}
catch (ConfigurationException e) {
// show error
}
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.match.tokens;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.ui.NamedItemsListEditor;
import com.intellij.openapi.ui.Namer;
import com.intellij.openapi.util.Cloner;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Factory;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementRuleAlias;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import gnu.trove.Equality;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
/**
* @author Svetlana.Zemlyanskaya
*/
public class ArrangementRuleAliasesListEditor extends NamedItemsListEditor<ArrangementRuleAlias> {
private static final Namer<ArrangementRuleAlias> NAMER = new Namer<ArrangementRuleAlias>() {
@Override
public String getName(ArrangementRuleAlias token) {
return token.getAliasToken().getRepresentationValue();
}
@Override
public boolean canRename(ArrangementRuleAlias item) {
return false;
}
@Override
public void setName(ArrangementRuleAlias token, String name) {
token.setAliasToken(ArrangementUtil.createRuleAliasToken(name.replaceAll("\\s+", "_"), name.replaceAll("\\s+", " ")));
}
};
private static final Factory<ArrangementRuleAlias> FACTORY = new Factory<ArrangementRuleAlias>() {
@Override
public ArrangementRuleAlias create() {
return new ArrangementRuleAlias();
}
};
private static final Cloner<ArrangementRuleAlias> CLONER = new Cloner<ArrangementRuleAlias>() {
@Override
public ArrangementRuleAlias cloneOf(ArrangementRuleAlias original) {
final ArrangementRuleAlias token = copyOf(original);
token.setAliasToken(original.getAliasToken());
return token;
}
@Override
public ArrangementRuleAlias copyOf(ArrangementRuleAlias original) {
final ArrangementRuleAlias token = new ArrangementRuleAlias();
token.setDefinitionRules(original.getDefinitionRules());
return token;
}
};
private static final Equality<ArrangementRuleAlias> COMPARER = new Equality<ArrangementRuleAlias>() {
@Override
public boolean equals(ArrangementRuleAlias o1, ArrangementRuleAlias o2) {
return Comparing.equal(o1.getAliasToken().getId(), o2.getAliasToken().getId());
}
};
@NotNull private Set<String> myUsedTokenIds;
@NotNull private ArrangementStandardSettingsManager mySettingsManager;
@NotNull private ArrangementColorsProvider myColorsProvider;
protected ArrangementRuleAliasesListEditor(@NotNull ArrangementStandardSettingsManager settingsManager,
@NotNull ArrangementColorsProvider colorsProvider,
@NotNull List<ArrangementRuleAlias> items,
@NotNull Set<String> usedTokenIds) {
super(NAMER, FACTORY, CLONER, COMPARER, items, false);
mySettingsManager = settingsManager;
myColorsProvider = colorsProvider;
myUsedTokenIds = usedTokenIds;
reset();
initTree();
}
@Override
protected UnnamedConfigurable createConfigurable(ArrangementRuleAlias item) {
return new ArrangementRuleAliasConfigurable(mySettingsManager, myColorsProvider, item);
}
@Override
protected boolean canDelete(ArrangementRuleAlias item) {
return !myUsedTokenIds.contains(item.getAliasToken().getId());
}
@Nls
@Override
public String getDisplayName() {
return "Custom Composite Tokens";
}
}
@@ -0,0 +1,102 @@
/*
* Copyright 2000-2014 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.application.options.codeStyle.arrangement.match.tokens;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.application.options.codeStyle.arrangement.util.TitleWithToolbar;
import com.intellij.ide.ui.customization.CustomizationUtil;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.ui.GridBag;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collection;
import java.util.List;
/**
* @author Svetlana.Zemlyanskaya
*/
public class ArrangementRuleAliasesPanel extends JPanel implements DataProvider {
@NotNull protected final ArrangementRuleAliasControl myControl;
public ArrangementRuleAliasesPanel(@NotNull ArrangementStandardSettingsManager settingsManager,
@NotNull ArrangementColorsProvider colorsProvider) {
super(new GridBagLayout());
JBScrollPane scrollPane = new JBScrollPane();
final JViewport viewport = scrollPane.getViewport();
ArrangementMatchingRulesControl.RepresentationCallback callback = new ArrangementMatchingRulesControl.RepresentationCallback() {
@Override
public void ensureVisible(@NotNull Rectangle r) {
Rectangle visibleRect = viewport.getViewRect();
if (r.y <= visibleRect.y) {
return;
}
int excessiveHeight = r.y + r.height - (visibleRect.y + visibleRect.height);
if (excessiveHeight <= 0) {
return;
}
int verticalShift = Math.min(r.y - visibleRect.y, excessiveHeight);
if (verticalShift > 0) {
viewport.setViewPosition(new Point(visibleRect.x, visibleRect.y + verticalShift));
}
}
};
myControl = new ArrangementRuleAliasControl(settingsManager, colorsProvider, callback);
scrollPane.setViewportView(myControl);
CustomizationUtil.installPopupHandler(
myControl, ArrangementConstants.ALIAS_RULE_CONTEXT_MENU, ArrangementConstants.ALIAS_RULE_CONTROL_PLACE
);
TitleWithToolbar top = new TitleWithToolbar(
ApplicationBundle.message("arrangement.settings.section.rule.sequence"),
ArrangementConstants.ALIAS_RULE_CONTROL_TOOLBAR,
ArrangementConstants.ALIAS_RULE_CONTROL_TOOLBAR_PLACE,
myControl
);
add(top, new GridBag().coverLine().fillCellHorizontally().weightx(1));
add(scrollPane, new GridBag().fillCell().weightx(1).weighty(1).insets(0, ArrangementConstants.HORIZONTAL_PADDING, 0, 0));
}
@NotNull
public List<StdArrangementMatchRule> getRuleSequences() {
return myControl.getRuleSequences();
}
public void setRuleSequences(@Nullable Collection<StdArrangementMatchRule> rules) {
myControl.setRuleSequences(rules);
}
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (ArrangementRuleAliasControl.KEY.is(dataId)) {
return myControl;
}
return null;
}
}
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementSectionRule;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsAware;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
@@ -89,7 +90,8 @@ public class MemberOrderService {
entriesWithNew.add(memberEntry);
//TODO: check insert new element
final List<? extends ArrangementMatchRule> rulesByPriority = arrangementSettings.getRulesSortedByPriority();
List<ArrangementEntry> arranged = ArrangementEngine.arrange(entriesWithNew, arrangementSettings.getSections(), rulesByPriority, null);
final List<ArrangementSectionRule> extendedSectionRules = ArrangementUtil.getExtendedSectionRules(arrangementSettings);
List<ArrangementEntry> arranged = ArrangementEngine.arrange(entriesWithNew, extendedSectionRules, rulesByPriority, null);
int i = arranged.indexOf(memberEntry);
if (i <= 0) {
@@ -555,7 +555,7 @@ public class ArrangementEngine {
changer = new DefaultChanger();
}
final List<? extends ArrangementMatchRule> rulesByPriority = arrangementSettings.getRulesSortedByPriority();
final List<ArrangementSectionRule> sectionRules = arrangementSettings.getSections();
final List<ArrangementSectionRule> sectionRules = ArrangementUtil.getExtendedSectionRules(arrangementSettings);
return new Context<T>(rearranger, wrappers, document, sectionRules, rulesByPriority, codeStyleSettings, changer);
}
}
@@ -606,8 +606,12 @@ arrangement.action.rule.move.up.text=Move up
arrangement.action.rule.move.up.description=Move selected arrangement rule(s) up
arrangement.action.rule.move.down.text=Move down
arrangement.action.rule.move.down.description=Move selected arrangement rule(s) down
arrangement.action.alias.rule.add.edit.text=Configure matching rules aliases
arrangement.action.alias.rule.add.edit.description=Configure aliases for arrangement matching rules
arrangement.settings.section.groups=Grouping rules
arrangement.settings.section.match=Matching rules
arrangement.settings.section.rule.custom.token.title=Rules Alias Definitions
arrangement.settings.section.rule.sequence=Rules alias definitions
arrangement.settings.groups.property.field=Group property field with corresponding getter/setter
arrangement.settings.groups.dependent.methods=Keep dependent methods together
arrangement.settings.groups.overridden.methods=Keep overridden methods together
@@ -621,6 +625,7 @@ arrangement.settings.text.general.modifier=Modifier:
arrangement.settings.text.general.name=Name:
arrangement.settings.text.general.text=Text:
arrangement.settings.text.general.order=Order:
arrangement.settings.text.general.sequence=Aliases:
arrangement.settings.text.general.xml.namespace=Namespace:
arrangement.settings.text.entry.type.xml.tag=tag
arrangement.settings.text.entry.type.xml.attribute=attribute
@@ -874,11 +874,37 @@
class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementMatchingRuleUpAction"/>
<action id="Arrangement.Rule.Match.Condition.Move.Down"
class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementMatchingRuleDownAction"/>
<action id="Arrangement.Custom.Token.Rule.Edit"
class="com.intellij.application.options.codeStyle.arrangement.action.EditRuleAliasesDefinitionAction"/>
<action id="Arrangement.Rule.Group.Condition.Move.Up"
class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementGroupingRuleUpAction"/>
<action id="Arrangement.Rule.Group.Condition.Move.Down"
class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementGroupingRuleDownAction"/>
<action id="Arrangement.Alias.Rule.Edit"
class="com.intellij.application.options.codeStyle.arrangement.action.tokens.EditArrangementAliasRuleAction"/>
<action id="Arrangement.Alias.Rule.Add"
class="com.intellij.application.options.codeStyle.arrangement.action.tokens.AddArrangementAliasRuleAction"/>
<action id="Arrangement.Alias.Rule.Remove"
class="com.intellij.application.options.codeStyle.arrangement.action.tokens.RemoveArrangementAliasRuleAction"/>
<action id="Arrangement.Alias.Rule.Match.Condition.Move.Up"
class="com.intellij.application.options.codeStyle.arrangement.action.tokens.MoveArrangementAliasRuleUpAction"/>
<action id="Arrangement.Alias.Rule.Match.Condition.Move.Down"
class="com.intellij.application.options.codeStyle.arrangement.action.tokens.MoveArrangementAliasRuleDownAction"/>
<group id="Arrangement.Alias.Rule.ToolBar">
<reference ref="Arrangement.Alias.Rule.Add"/>
<reference ref="Arrangement.Alias.Rule.Remove"/>
<reference ref="Arrangement.Alias.Rule.Match.Condition.Move.Up"/>
<reference ref="Arrangement.Alias.Rule.Match.Condition.Move.Down"/>
</group>
<group id="Arrangement.Alias.Rule.Context.Menu">
<reference ref="Arrangement.Alias.Rule.Add"/>
<reference ref="Arrangement.Alias.Rule.Remove"/>
<reference ref="Arrangement.Alias.Rule.Edit"/>
</group>
<group id="Arrangement.Rule.Match.Control.Context.Menu">
<reference ref="Arrangement.Rule.Add"/>
<reference ref="Arrangement.Rule.Section.Add"/>
@@ -892,6 +918,7 @@
<reference ref="Arrangement.Rule.Remove"/>
<reference ref="Arrangement.Rule.Match.Condition.Move.Up"/>
<reference ref="Arrangement.Rule.Match.Condition.Move.Down"/>
<reference ref="Arrangement.Custom.Token.Rule.Edit"/>
</group>
<group id="Arrangement.Rule.Group.Control.ToolBar">
@@ -31,9 +31,7 @@ import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken;
import com.intellij.psi.codeStyle.arrangement.std.StdArrangementSettings;
import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens;
import com.intellij.psi.codeStyle.arrangement.std.*;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -82,6 +80,10 @@ public abstract class AbstractRearrangerTest extends LightPlatformCodeInsightFix
return ArrangementSectionRule.create(start, end, rules);
}
protected static ArrangementRuleAlias alias(@NotNull String id, @NotNull StdArrangementMatchRule... rules) {
return new ArrangementRuleAlias(ArrangementUtil.createRuleAliasToken(id, id), ContainerUtil.newArrayList(rules));
}
@NotNull
protected static ArrangementGroupingRule group(@NotNull ArrangementSettingsToken type) {
return group(type, KEEP);
@@ -189,8 +191,14 @@ public abstract class AbstractRearrangerTest extends LightPlatformCodeInsightFix
}
});
@SuppressWarnings("unchecked")
List<ArrangementRuleAlias> aliases = (List<ArrangementRuleAlias>)args.get("aliases");
CommonCodeStyleSettings settings = CodeStyleSettingsManager.getInstance(myFixture.getProject()).getCurrentSettings().getCommonSettings(language);
settings.setArrangementSettings(new StdArrangementSettings(groupingRules, sectionRules));
final StdArrangementSettings arrangementSettings =
aliases == null ?
new StdArrangementSettings(groupingRules, sectionRules) :
new StdArrangementExtendableSettings(groupingRules, sectionRules, aliases);
settings.setArrangementSettings(arrangementSettings);
ArrangementEngine engine = ServiceManager.getService(myFixture.getProject(), ArrangementEngine.class);
engine.arrange(myFixture.getEditor(), myFixture.getFile(), info.ranges);