Search in sources :

Example 1 with ArrangementMatchRule

use of com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule in project intellij-community by JetBrains.

the class ArrangementMatchingRuleEditor method reset.

/**
   * Asks current editor to refresh its state in accordance with the arrangement rule shown at the given row.
   *
   * @param row  row index of the rule which match condition should be edited (if defined);
   *              {@code '-1'} as an indication that no settings should be active
   */
public void reset(int row) {
    // Reset state.
    myRow = row;
    myFocusRequestor = myDefaultFocusRequestor;
    mySkipStateChange = true;
    try {
        for (ArrangementUiComponent component : myComponents.values()) {
            component.reset();
        }
    } finally {
        mySkipStateChange = false;
    }
    ArrangementMatchingRulesModel model = myControl.getModel();
    if (row < 0 || row >= model.getSize()) {
        myRow = -1;
        return;
    }
    Object element = model.getElementAt(row);
    ArrangementSettingsToken orderType = element instanceof ArrangementMatchRule ? ((ArrangementMatchRule) element).getOrderType() : null;
    final ArrangementMatchCondition condition;
    final Map<ArrangementSettingsToken, Object> conditionTokens;
    if (element instanceof EmptyArrangementRuleComponent) {
        // We need to disable conditions which are not applicable for empty rules (e.g. we don't want to enable 'volatile' condition
        // for java rearranger if no 'field' condition is selected.
        condition = null;
        conditionTokens = ContainerUtilRt.newHashMap();
    } else if (!(element instanceof StdArrangementMatchRule)) {
        return;
    } else {
        condition = ((StdArrangementMatchRule) element).getMatcher().getCondition();
        conditionTokens = ArrangementUtil.extractTokens(condition);
    }
    mySkipStateChange = true;
    try {
        for (ArrangementUiComponent component : myComponents.values()) {
            ArrangementSettingsToken token = component.getToken();
            if (token != null && (component.getAvailableTokens().contains(orderType) || isEnabled(condition, token))) {
                component.setEnabled(true);
                if (component.getAvailableTokens().contains(orderType)) {
                    component.chooseToken(orderType);
                } else {
                    component.setSelected(conditionTokens.containsKey(token));
                }
                Object value = conditionTokens.get(token);
                if (value != null) {
                    component.setData(value);
                }
            }
        }
        refreshConditions();
    } finally {
        mySkipStateChange = false;
    }
}
Also used : StdArrangementMatchRule(com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule) ArrangementMatchRule(com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule) ArrangementMatchCondition(com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition) StdArrangementMatchRule(com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule)

Example 2 with ArrangementMatchRule

use of com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule in project intellij-community by JetBrains.

the class ArrangementEngine method arrange.

/**
   * Arranges (re-orders) given entries according to the given rules.
   *
   * @param entries            entries to arrange
   * @param sectionRules       rules to use for arrangement
   * @param rulesByPriority    rules sorted by priority ('public static' rule will have higher priority than 'public')
   * @param entryToSection     mapping from arrangement entry to the parent section
   * @return                   arranged list of the given rules
   */
@SuppressWarnings("AssignmentToForLoopParameter")
@NotNull
public static <E extends ArrangementEntry> List<E> arrange(@NotNull Collection<E> entries, @NotNull List<ArrangementSectionRule> sectionRules, @NotNull List<? extends ArrangementMatchRule> rulesByPriority, @Nullable Map<E, ArrangementSectionRule> entryToSection) {
    List<E> arranged = ContainerUtilRt.newArrayList();
    Set<E> unprocessed = ContainerUtilRt.newLinkedHashSet();
    List<Pair<Set<ArrangementEntry>, E>> dependent = ContainerUtilRt.newArrayList();
    for (E entry : entries) {
        List<? extends ArrangementEntry> dependencies = entry.getDependencies();
        if (dependencies == null) {
            unprocessed.add(entry);
        } else {
            if (dependencies.size() == 1 && dependencies.get(0) == entry.getParent()) {
                // Handle a situation when the entry is configured to be at the first parent's children.
                arranged.add(entry);
            } else {
                Set<ArrangementEntry> first = new HashSet<>(dependencies);
                dependent.add(Pair.create(first, entry));
            }
        }
    }
    Set<E> matched = new HashSet<>();
    MultiMap<ArrangementMatchRule, E> elementsByRule = new MultiMap<>();
    for (ArrangementMatchRule rule : rulesByPriority) {
        matched.clear();
        for (E entry : unprocessed) {
            if (entry.canBeMatched() && rule.getMatcher().isMatched(entry)) {
                elementsByRule.putValue(rule, entry);
                matched.add(entry);
            }
        }
        unprocessed.removeAll(matched);
    }
    for (ArrangementSectionRule sectionRule : sectionRules) {
        for (ArrangementMatchRule rule : sectionRule.getMatchRules()) {
            final Collection<E> arrangedEntries = arrangeByRule(arranged, elementsByRule, rule);
            if (entryToSection != null && arrangedEntries != null) {
                for (E entry : arrangedEntries) {
                    entryToSection.put(entry, sectionRule);
                }
            }
        }
    }
    arranged.addAll(unprocessed);
    for (int i = 0; i < arranged.size() && !dependent.isEmpty(); i++) {
        E e = arranged.get(i);
        List<E> shouldBeAddedAfterCurrentElement = ContainerUtil.newArrayList();
        for (Iterator<Pair<Set<ArrangementEntry>, E>> iterator = dependent.iterator(); iterator.hasNext(); ) {
            Pair<Set<ArrangementEntry>, E> pair = iterator.next();
            pair.first.remove(e);
            if (pair.first.isEmpty()) {
                iterator.remove();
                shouldBeAddedAfterCurrentElement.add(pair.second);
            }
        }
        // add dependent entries to the same section as main entry
        if (entryToSection != null && entryToSection.containsKey(e)) {
            final ArrangementSectionRule rule = entryToSection.get(e);
            for (E e1 : shouldBeAddedAfterCurrentElement) {
                entryToSection.put(e1, rule);
            }
        }
        arranged.addAll(i + 1, shouldBeAddedAfterCurrentElement);
    }
    return arranged;
}
Also used : ArrangementMatchRule(com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule) HashSet(com.intellij.util.containers.HashSet) ArrangementSectionRule(com.intellij.psi.codeStyle.arrangement.match.ArrangementSectionRule) Pair(com.intellij.openapi.util.Pair) HashSet(com.intellij.util.containers.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

ArrangementMatchRule (com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule)2 Pair (com.intellij.openapi.util.Pair)1 ArrangementSectionRule (com.intellij.psi.codeStyle.arrangement.match.ArrangementSectionRule)1 StdArrangementMatchRule (com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule)1 ArrangementMatchCondition (com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition)1 HashSet (com.intellij.util.containers.HashSet)1 NotNull (org.jetbrains.annotations.NotNull)1