@Nullable private static <E extends ArrangementEntry> Collection<E> arrangeByRule(@NotNull List<E> arranged, @NotNull MultiMap<ArrangementMatchRule, E> elementsByRule, @NotNull ArrangementMatchRule rule) { if (elementsByRule.containsKey(rule)) { final Collection<E> arrangedEntries = elementsByRule.remove(rule); // Sort by name if necessary. if (StdArrangementTokens.Order.BY_NAME.equals(rule.getOrderType())) { sortByName((List<E>)arrangedEntries); } arranged.addAll(arrangedEntries); return arrangedEntries; } return null; }
@Nullable private static <E extends ArrangementEntry> Collection<E> arrangeByRule(@Nonnull List<E> arranged, @Nonnull MultiMap<ArrangementMatchRule, E> elementsByRule, @Nonnull ArrangementMatchRule rule) { if (elementsByRule.containsKey(rule)) { final Collection<E> arrangedEntries = elementsByRule.remove(rule); // Sort by name if necessary. if (StdArrangementTokens.Order.BY_NAME.equals(rule.getOrderType())) { sortByName((List<E>)arrangedEntries); } arranged.addAll(arrangedEntries); return arrangedEntries; } return null; }
@NotNull @Override public List<? extends ArrangementMatchRule> getRulesSortedByPriority() { synchronized (myRulesByPriority) { if (myRulesByPriority.isEmpty()) { for (ArrangementSectionRule rule : mySectionRules) { myRulesByPriority.addAll(rule.getMatchRules()); } ContainerUtil.sort(myRulesByPriority); } } return myRulesByPriority; }
@NotNull @Override public List<? extends ArrangementMatchRule> getRulesSortedByPriority() { synchronized (myExtendedSectionRules) { if (myRulesByPriority.isEmpty()) { for (ArrangementSectionRule rule : getExtendedSectionRules()) { myRulesByPriority.addAll(rule.getMatchRules()); } ContainerUtil.sort(myRulesByPriority); } } return myRulesByPriority; }
private Context(@NotNull Rearranger<E> rearranger, @NotNull Collection<ArrangementEntryWrapper<E>> wrappers, @NotNull Document document, @NotNull List<ArrangementSectionRule> sectionRules, @NotNull List<? extends ArrangementMatchRule> rulesByPriority, @NotNull CodeStyleSettings settings, @NotNull Changer changer) { this.rearranger = rearranger; this.wrappers = wrappers; this.document = document; this.sectionRules = sectionRules; this.rulesByPriority = rulesByPriority; this.settings = settings; this.changer = changer; }
public static <T extends ArrangementEntry> Context<T> from(@NotNull Rearranger<T> rearranger, @NotNull Document document, @NotNull PsiElement root, @NotNull Collection<TextRange> ranges, @NotNull ArrangementSettings arrangementSettings, @NotNull CodeStyleSettings codeStyleSettings) { Collection<T> entries = rearranger.parse(root, document, ranges, arrangementSettings); Collection<ArrangementEntryWrapper<T>> wrappers = new ArrayList<ArrangementEntryWrapper<T>>(); ArrangementEntryWrapper<T> previous = null; for (T entry : entries) { ArrangementEntryWrapper<T> wrapper = new ArrangementEntryWrapper<T>(entry); if (previous != null) { previous.setNext(wrapper); wrapper.setPrevious(previous); } wrappers.add(wrapper); previous = wrapper; } Changer changer; if (document instanceof DocumentEx) { changer = new RangeMarkerAwareChanger<T>((DocumentEx)document); } else { changer = new DefaultChanger(); } final List<? extends ArrangementMatchRule> rulesByPriority = arrangementSettings.getRulesSortedByPriority(); final List<ArrangementSectionRule> sectionRules = ArrangementUtil.getExtendedSectionRules(arrangementSettings); return new Context<T>(rearranger, wrappers, document, sectionRules, rulesByPriority, codeStyleSettings, changer); }
@NotNull @Override public List<? extends ArrangementMatchRule> getRulesSortedByPriority() { if (myRulesByPriority.isEmpty()) { myRulesByPriority.addAll(myRules); ContainerUtil.sort(myRulesByPriority); } return myRulesByPriority; }
@Nullable public Element serialize(@NotNull ArrangementMatchRule rule) { Element matcherElement = myMatcherSerializer.serialize(rule.getMatcher()); if (matcherElement == null) { return null; } Element result = new Element(RULE_ELEMENT_NAME); result.addContent(new Element(MATCHER_ELEMENT_NAME).addContent(matcherElement)); if (rule.getOrderType() != ArrangementMatchRule.DEFAULT_ORDER_TYPE) { result.addContent(new Element(ORDER_TYPE_ELEMENT_NAME).setText(rule.getOrderType().getId())); } return result; }
private Context(@NotNull Rearranger<E> rearranger, @NotNull Collection<ArrangementEntryWrapper<E>> wrappers, @NotNull Document document, @NotNull List<? extends ArrangementMatchRule> rules, @NotNull List<? extends ArrangementMatchRule> rulesByPriority, @NotNull CodeStyleSettings settings, @NotNull Changer changer) { this.rearranger = rearranger; this.wrappers = wrappers; this.document = document; this.rules = rules; this.rulesByPriority = rulesByPriority; this.settings = settings; this.changer = changer; }
public static <T extends ArrangementEntry> Context<T> from(@NotNull Rearranger<T> rearranger, @NotNull Document document, @NotNull PsiElement root, @NotNull Collection<TextRange> ranges, @NotNull ArrangementSettings arrangementSettings, @NotNull CodeStyleSettings codeStyleSettings) { Collection<T> entries = rearranger.parse(root, document, ranges, arrangementSettings); Collection<ArrangementEntryWrapper<T>> wrappers = new ArrayList<ArrangementEntryWrapper<T>>(); ArrangementEntryWrapper<T> previous = null; for (T entry : entries) { ArrangementEntryWrapper<T> wrapper = new ArrangementEntryWrapper<T>(entry); if (previous != null) { previous.setNext(wrapper); wrapper.setPrevious(previous); } wrappers.add(wrapper); previous = wrapper; } Changer changer; if (document instanceof DocumentEx) { changer = new RangeMarkerAwareChanger<T>((DocumentEx)document); } else { changer = new DefaultChanger(); } final List<? extends ArrangementMatchRule> rulesByPriority = ArrangementUtil.getRulesSortedByPriority(arrangementSettings); return new Context<T>(rearranger, wrappers, document, arrangementSettings.getRules(), rulesByPriority, codeStyleSettings, changer); }
@Nonnull @Override public List<? extends ArrangementMatchRule> getRulesSortedByPriority() { synchronized (myRulesByPriority) { if (myRulesByPriority.isEmpty()) { for (ArrangementSectionRule rule : mySectionRules) { myRulesByPriority.addAll(rule.getMatchRules()); } ContainerUtil.sort(myRulesByPriority); } } return myRulesByPriority; }
@Nonnull @Override public List<? extends ArrangementMatchRule> getRulesSortedByPriority() { synchronized (myExtendedSectionRules) { if (myRulesByPriority.isEmpty()) { for (ArrangementSectionRule rule : getExtendedSectionRules()) { myRulesByPriority.addAll(rule.getMatchRules()); } ContainerUtil.sort(myRulesByPriority); } } return myRulesByPriority; }
private Context(@Nonnull Rearranger<E> rearranger, @Nonnull Collection<ArrangementEntryWrapper<E>> wrappers, @Nonnull Document document, @Nonnull List<ArrangementSectionRule> sectionRules, @Nonnull List<? extends ArrangementMatchRule> rulesByPriority, @Nonnull CodeStyleSettings settings, @Nonnull Changer changer) { this.rearranger = rearranger; this.wrappers = wrappers; this.document = document; this.sectionRules = sectionRules; this.rulesByPriority = rulesByPriority; this.settings = settings; this.changer = changer; }
public static <T extends ArrangementEntry> Context<T> from(@Nonnull Rearranger<T> rearranger, @Nonnull Document document, @Nonnull PsiElement root, @Nonnull Collection<TextRange> ranges, @Nonnull ArrangementSettings arrangementSettings, @Nonnull CodeStyleSettings codeStyleSettings) { Collection<T> entries = rearranger.parse(root, document, ranges, arrangementSettings); Collection<ArrangementEntryWrapper<T>> wrappers = new ArrayList<ArrangementEntryWrapper<T>>(); ArrangementEntryWrapper<T> previous = null; for (T entry : entries) { ArrangementEntryWrapper<T> wrapper = new ArrangementEntryWrapper<T>(entry); if (previous != null) { previous.setNext(wrapper); wrapper.setPrevious(previous); } wrappers.add(wrapper); previous = wrapper; } Changer changer; if (document instanceof DocumentEx) { changer = new RangeMarkerAwareChanger<T>((DocumentEx)document); } else { changer = new DefaultChanger(); } final List<? extends ArrangementMatchRule> rulesByPriority = arrangementSettings.getRulesSortedByPriority(); final List<ArrangementSectionRule> sectionRules = ArrangementUtil.getExtendedSectionRules(arrangementSettings); return new Context<T>(rearranger, wrappers, document, sectionRules, rulesByPriority, codeStyleSettings, changer); }
/** * Tries to find an element at the given context which should be the previous sibling for the given 'member'element according to the * {@link CommonCodeStyleSettings#getArrangementSettings() user-defined arrangement rules}. * <p/> * E.g. the IDE might generate given 'member' element and wants to know element after which it should be inserted * * @param member target member which anchor should be calculated * @param settings code style settings to use * @param context given member's context * @return given member's anchor if the one can be computed; * given 'context' element if given member should be the first child * <code>null</code> otherwise */ @SuppressWarnings("MethodMayBeStatic") @Nullable public PsiElement getAnchor(@NotNull PsiElement member, @NotNull CommonCodeStyleSettings settings, @NotNull PsiElement context) { Language language = context.getLanguage(); Rearranger<?> rearranger = Rearranger.EXTENSION.forLanguage(language); if (rearranger == null) { return null; } ArrangementSettings arrangementSettings = settings.getArrangementSettings(); if (arrangementSettings == null && rearranger instanceof ArrangementStandardSettingsAware) { arrangementSettings = ((ArrangementStandardSettingsAware)rearranger).getDefaultSettings(); } if (arrangementSettings == null) { return null; } Pair<? extends ArrangementEntry,? extends List<? extends ArrangementEntry>> pair = rearranger.parseWithNew(context, null, Collections.singleton(context.getTextRange()), member, arrangementSettings); if (pair == null || pair.second.isEmpty()) { return null; } ArrangementEntry memberEntry = pair.first; List<? extends ArrangementEntry> entries = pair.second; ArrangementEntry parentEntry = entries.get(0); List<? extends ArrangementEntry> nonArranged = parentEntry.getChildren(); List<ArrangementEntry> entriesWithNew = new ArrayList<ArrangementEntry>(nonArranged); entriesWithNew.add(memberEntry); //TODO: check insert new element final List<? extends ArrangementMatchRule> rulesByPriority = arrangementSettings.getRulesSortedByPriority(); final List<ArrangementSectionRule> extendedSectionRules = ArrangementUtil.getExtendedSectionRules(arrangementSettings); List<ArrangementEntry> arranged = ArrangementEngine.arrange(entriesWithNew, extendedSectionRules, rulesByPriority, null); int i = arranged.indexOf(memberEntry); if (i <= 0) { return context; } ArrangementEntry anchorEntry = null; if (i >= arranged.size() - 1) { anchorEntry = nonArranged.get(nonArranged.size() - 1); } else { Set<ArrangementEntry> entriesBelow = new HashSet<ArrangementEntry>(); entriesBelow.addAll(arranged.subList(i + 1, arranged.size())); for (ArrangementEntry entry : nonArranged) { if (entriesBelow.contains(entry)) { break; } anchorEntry = entry; } } if (anchorEntry == null) { return context; } int offset = anchorEntry.getEndOffset() - 1 - context.getTextRange().getStartOffset(); PsiElement element = context.findElementAt(offset); for (PsiElement e = element; e != null && e.getTextRange().getStartOffset() >= anchorEntry.getStartOffset(); e = e.getParent()) { element = e; } return element; }
@NotNull List<? extends ArrangementMatchRule> getRules();
/** * Tries to find an element at the given context which should be the previous sibling for the given 'member'element according to the * {@link CommonCodeStyleSettings#getArrangementSettings() user-defined arrangement rules}. * <p/> * E.g. the IDE might generate given 'member' element and wants to know element after which it should be inserted * * @param member target member which anchor should be calculated * @param settings code style settings to use * @param context given member's context * @return given member's anchor if the one can be computed; * given 'context' element if given member should be the first child * <code>null</code> otherwise */ @SuppressWarnings("MethodMayBeStatic") @Nullable public PsiElement getAnchor(@NotNull PsiElement member, @NotNull CommonCodeStyleSettings settings, @NotNull PsiElement context) { Language language = context.getLanguage(); Rearranger<?> rearranger = Rearranger.EXTENSION.forLanguage(language); if (rearranger == null) { return null; } ArrangementSettings arrangementSettings = settings.getArrangementSettings(); if (arrangementSettings == null && rearranger instanceof ArrangementStandardSettingsAware) { arrangementSettings = ((ArrangementStandardSettingsAware)rearranger).getDefaultSettings(); } if (arrangementSettings == null) { return null; } Pair<? extends ArrangementEntry,? extends List<? extends ArrangementEntry>> pair = rearranger.parseWithNew(context, null, Collections.singleton(context.getTextRange()), member, arrangementSettings); if (pair == null || pair.second.isEmpty()) { return null; } ArrangementEntry memberEntry = pair.first; List<? extends ArrangementEntry> entries = pair.second; ArrangementEntry parentEntry = entries.get(0); List<? extends ArrangementEntry> nonArranged = parentEntry.getChildren(); List<ArrangementEntry> entriesWithNew = new ArrayList<ArrangementEntry>(nonArranged); entriesWithNew.add(memberEntry); final List<? extends ArrangementMatchRule> rulesByPriority = ArrangementUtil.getRulesSortedByPriority(arrangementSettings); List<ArrangementEntry> arranged = ArrangementEngine.arrange(entriesWithNew, arrangementSettings.getRules(), rulesByPriority); int i = arranged.indexOf(memberEntry); if (i <= 0) { return context; } ArrangementEntry anchorEntry = null; if (i >= arranged.size() - 1) { anchorEntry = nonArranged.get(nonArranged.size() - 1); } else { Set<ArrangementEntry> entriesBelow = new HashSet<ArrangementEntry>(); entriesBelow.addAll(arranged.subList(i + 1, arranged.size())); for (ArrangementEntry entry : nonArranged) { if (entriesBelow.contains(entry)) { break; } anchorEntry = entry; } } if (anchorEntry == null) { return context; } int offset = anchorEntry.getEndOffset() - 1 - context.getTextRange().getStartOffset(); PsiElement element = context.findElementAt(offset); for (PsiElement e = element; e != null && e.getTextRange().getStartOffset() >= anchorEntry.getStartOffset(); e = e.getParent()) { element = e; } return element; }
/** * Tries to find an element at the given context which should be the previous sibling for the given 'member'element according to the * {@link CommonCodeStyleSettings#getArrangementSettings() user-defined arrangement rules}. * <p/> * E.g. the IDE might generate given 'member' element and wants to know element after which it should be inserted * * @param member target member which anchor should be calculated * @param settings code style settings to use * @param context given member's context * @return given member's anchor if the one can be computed; * given 'context' element if given member should be the first child * <code>null</code> otherwise */ @SuppressWarnings("MethodMayBeStatic") @Nullable public PsiElement getAnchor(@Nonnull PsiElement member, @Nonnull CommonCodeStyleSettings settings, @Nonnull PsiElement context) { Language language = context.getLanguage(); Rearranger<?> rearranger = Rearranger.EXTENSION.forLanguage(language); if (rearranger == null) { return null; } ArrangementSettings arrangementSettings = settings.getArrangementSettings(); if (arrangementSettings == null && rearranger instanceof ArrangementStandardSettingsAware) { arrangementSettings = ((ArrangementStandardSettingsAware)rearranger).getDefaultSettings(); } if (arrangementSettings == null) { return null; } Pair<? extends ArrangementEntry,? extends List<? extends ArrangementEntry>> pair = rearranger.parseWithNew(context, null, Collections.singleton(context.getTextRange()), member, arrangementSettings); if (pair == null || pair.second.isEmpty()) { return null; } ArrangementEntry memberEntry = pair.first; List<? extends ArrangementEntry> entries = pair.second; ArrangementEntry parentEntry = entries.get(0); List<? extends ArrangementEntry> nonArranged = parentEntry.getChildren(); List<ArrangementEntry> entriesWithNew = new ArrayList<ArrangementEntry>(nonArranged); entriesWithNew.add(memberEntry); //TODO: check insert new element final List<? extends ArrangementMatchRule> rulesByPriority = arrangementSettings.getRulesSortedByPriority(); final List<ArrangementSectionRule> extendedSectionRules = ArrangementUtil.getExtendedSectionRules(arrangementSettings); List<ArrangementEntry> arranged = ArrangementEngine.arrange(entriesWithNew, extendedSectionRules, rulesByPriority, null); int i = arranged.indexOf(memberEntry); if (i <= 0) { return context; } ArrangementEntry anchorEntry = null; if (i >= arranged.size() - 1) { anchorEntry = nonArranged.get(nonArranged.size() - 1); } else { Set<ArrangementEntry> entriesBelow = new HashSet<ArrangementEntry>(); entriesBelow.addAll(arranged.subList(i + 1, arranged.size())); for (ArrangementEntry entry : nonArranged) { if (entriesBelow.contains(entry)) { break; } anchorEntry = entry; } } if (anchorEntry == null) { return context; } int offset = anchorEntry.getEndOffset() - 1 - context.getTextRange().getStartOffset(); PsiElement element = context.findElementAt(offset); for (PsiElement e = element; e != null && e.getTextRange().getStartOffset() >= anchorEntry.getStartOffset(); e = e.getParent()) { element = e; } return element; }
/** * @deprecated collect match rules from {@link #getSections()} * @return */ @NotNull List<? extends ArrangementMatchRule> getRules();
/** * <b>Note:</b> It's expected that rules sort is stable * <p/> * Example: 'public static' rule would have higher priority then 'public' * @return list of rules sorted in order of matching */ @NotNull List<? extends ArrangementMatchRule> getRulesSortedByPriority();
/** * <b>Note:</b> It's expected that rules sort is stable * @return list of rules sorted in order of matching */ @NotNull List<? extends ArrangementMatchRule> getRulesSortedByPriority();
/** * @deprecated collect match rules from {@link #getSections()} * @return */ @Nonnull List<? extends ArrangementMatchRule> getRules();
/** * <b>Note:</b> It's expected that rules sort is stable * <p/> * Example: 'public static' rule would have higher priority then 'public' * @return list of rules sorted in order of matching */ @Nonnull List<? extends ArrangementMatchRule> getRulesSortedByPriority();
/** * <b>Note:</b> It's expected that rules sort is stable * @return list of rules sorted in order of matching */ @Nonnull List<? extends ArrangementMatchRule> getRulesSortedByPriority();