@Override public List<ArrangementSectionRule> getExtendedSectionRules() { synchronized (myExtendedSectionRules) { if (myExtendedSectionRules.isEmpty()) { final Map<String, StdArrangementRuleAliasToken> tokenIdToDefinition = new THashMap<String, StdArrangementRuleAliasToken>(myRulesAliases.size()); for (StdArrangementRuleAliasToken alias : myRulesAliases) { final String id = alias.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; }
/** * Check if comment can be recognized as section start/end * @return true for section comment, false otherwise */ public boolean processComment(@NotNull PsiComment comment) { final TextRange range = comment.getTextRange(); final TextRange expandedRange = myDocument == null ? range : ArrangementUtil.expandToLineIfPossible(range, myDocument); final TextRange sectionTextRange = new TextRange(expandedRange.getStartOffset(), expandedRange.getEndOffset()); final String commentText = comment.getText().trim(); final ArrangementSectionRule openSectionRule = isSectionStartComment(mySettings, commentText); if (openSectionRule != null) { mySectionEntryProducer.consume(new ArrangementSectionEntryTemplate(comment, START_SECTION, sectionTextRange, commentText)); myOpenedSections.push(openSectionRule); return true; } if (!myOpenedSections.isEmpty()) { final ArrangementSectionRule lastSection = myOpenedSections.peek(); if (lastSection.getEndComment() != null && StringUtil.equals(commentText, lastSection.getEndComment())) { mySectionEntryProducer.consume(new ArrangementSectionEntryTemplate(comment, END_SECTION, sectionTextRange, commentText)); myOpenedSections.pop(); return true; } } return false; }
private static void appendBufferedSectionRules(@NotNull List<ArrangementSectionRule> result, @NotNull List<StdArrangementMatchRule> buffer, @Nullable String currentSectionStart) { if (currentSectionStart == null) { return; } if (buffer.isEmpty()) { result.add(ArrangementSectionRule.create(currentSectionStart, null)); } else { result.add(ArrangementSectionRule.create(currentSectionStart, null, buffer.get(0))); for (int j = 1; j < buffer.size(); j++) { result.add(ArrangementSectionRule.create(buffer.get(j))); } buffer.clear(); } }
private static void appendBufferedSectionRules(@Nonnull List<ArrangementSectionRule> result, @Nonnull List<StdArrangementMatchRule> buffer, @Nullable String currentSectionStart) { if (currentSectionStart == null) { return; } if (buffer.isEmpty()) { result.add(ArrangementSectionRule.create(currentSectionStart, null)); } else { result.add(ArrangementSectionRule.create(currentSectionStart, null, buffer.get(0))); for (int j = 1; j < buffer.size(); j++) { result.add(ArrangementSectionRule.create(buffer.get(j))); } buffer.clear(); } }
protected List<ArrangementSectionRule> getSectionRules(List<?> rules) { List<ArrangementSectionRule> sectionRules = Collections.emptyList(); if (rules != null) sectionRules = ContainerUtil.map(rules, new Function<Object, ArrangementSectionRule>() { @Override public ArrangementSectionRule fun(Object o) { return o instanceof ArrangementSectionRule ? (ArrangementSectionRule)o : ArrangementSectionRule.create((StdArrangementMatchRule)o); } }); return sectionRules; }
@Test public void testDefaultCustomTokenSerialize() { final Set<StdArrangementRuleAliasToken> 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 testUseCustomTokenSerialize() throws IOException { final StdArrangementRuleAliasToken visibility = visibilityToken(); final StdArrangementRuleAliasToken modifiers = modifiersToken(); final Set<StdArrangementRuleAliasToken> tokens = ContainerUtil.newHashSet(visibility, modifiers); final ArrayList<ArrangementGroupingRule> groupings = ContainerUtil.newArrayList( new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME)); final ArrayList<ArrangementSectionRule> rules = ContainerUtil.newArrayList(section(true, FIELD, 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); final String expected = "<holder>\n" + " <rules>\n" + " <section>\n" + " <rule>\n" + " <match>\n" + " <AND>\n" + " <FIELD>true</FIELD>\n" + " <visibility />\n" + " </AND>\n" + " </match>\n" + " <order>BY_NAME</order>\n" + " </rule>\n" + " </section>\n" + " </rules>\n" + "</holder>"; assertXmlOutputEquals(expected, holder); }
@Test public void testCustomTokenSerializeAndDeserialize() { final StdArrangementRuleAliasToken visibility = visibilityToken(); final StdArrangementRuleAliasToken modifiers = modifiersToken(); final Set<StdArrangementRuleAliasToken> tokens = ContainerUtil.newHashSet(visibility, modifiers); final ArrayList<ArrangementGroupingRule> groupings = ContainerUtil.newArrayList( new ArrangementGroupingRule(OVERRIDDEN_METHODS, BY_NAME)); final ArrayList<ArrangementSectionRule> rules = ContainerUtil.newArrayList(section(true, FIELD, visibility)); final StdArrangementExtendableSettings settings = extendableSettings(groupings, rules, tokens); final StdArrangementExtendableSettings defaultSettings = new StdArrangementExtendableSettings(); doSerializationTest(settings, defaultSettings); }
public static StdArrangementSettings createByMatchRules(@NotNull List<ArrangementGroupingRule> groupingRules, @NotNull List<StdArrangementMatchRule> matchRules) { final List<ArrangementSectionRule> sectionRules = new ArrayList<ArrangementSectionRule>(); for (StdArrangementMatchRule rule : matchRules) { sectionRules.add(ArrangementSectionRule.create(rule)); } return new StdArrangementSettings(groupingRules, sectionRules); }
@NotNull protected List<ArrangementSectionRule> cloneSectionRules() { final ArrayList<ArrangementSectionRule> rules = new ArrayList<ArrangementSectionRule>(); for (ArrangementSectionRule rule : mySectionRules) { rules.add(rule.clone()); } return rules; }
@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; }
public static StdArrangementExtendableSettings createByMatchRules(@NotNull List<ArrangementGroupingRule> groupingRules, @NotNull List<StdArrangementMatchRule> matchRules, @NotNull Collection<StdArrangementRuleAliasToken> rulesAliases) { final List<ArrangementSectionRule> sectionRules = new ArrayList<ArrangementSectionRule>(); for (StdArrangementMatchRule rule : matchRules) { sectionRules.add(ArrangementSectionRule.create(rule)); } return new StdArrangementExtendableSettings(groupingRules, sectionRules, rulesAliases); }
@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; }
@Nullable public static ArrangementSectionRule isSectionStartComment(@NotNull ArrangementSettings settings, @NotNull String comment) { for (ArrangementSectionRule rule : settings.getSections()) { if (rule.getStartComment() != null && StringUtil.equals(comment, rule.getStartComment())) { return rule; } } return null; }
public List<ArrangementSectionRule> getSections() { if (getModel().getSize() <= 0) { return Collections.emptyList(); } final List<ArrangementSectionRule> result = ContainerUtil.newArrayList(); final List<StdArrangementMatchRule> buffer = ContainerUtil.newArrayList(); String currentSectionStart = null; for (int i = 0; i < getModel().getSize(); i++) { final Object element = getModel().getElementAt(i); if (element instanceof StdArrangementMatchRule) { final ArrangementSectionRuleData sectionRule = mySectionRuleManager == null ? null : mySectionRuleManager.getSectionRuleData((StdArrangementMatchRule)element); if (sectionRule != null) { if (sectionRule.isSectionStart()) { appendBufferedSectionRules(result, buffer, currentSectionStart); currentSectionStart = sectionRule.getText(); } else { result.add(ArrangementSectionRule.create(StringUtil.notNullize(currentSectionStart), sectionRule.getText(), buffer)); buffer.clear(); currentSectionStart = null; } } else { if (currentSectionStart == null) { result.add(ArrangementSectionRule.create((StdArrangementMatchRule)element)); } else { buffer.add((StdArrangementMatchRule)element); } } } } appendBufferedSectionRules(result, buffer, currentSectionStart); return result; }
private StdArrangementSettings createSettings() { final List<ArrangementGroupingRule> groupingRules = myGroupingRulesPanel.getRules(); final List<ArrangementSectionRule> sections = myMatchingRulesPanel.getSections(); final Collection<StdArrangementRuleAliasToken> tokens = myMatchingRulesPanel.getRulesAliases(); if (tokens != null) { return new StdArrangementExtendableSettings(groupingRules, sections, tokens); } return new StdArrangementSettings(groupingRules, sections); }
@NotNull private static List<ArrangementSectionRule> copy(@NotNull List<ArrangementSectionRule> rules) { List<ArrangementSectionRule> result = new ArrayList<ArrangementSectionRule>(); for (ArrangementSectionRule rule : rules) { result.add(rule.clone()); } return result; }
private static <E extends ArrangementEntry> NewSectionInfo create(@NotNull List<E> arranged, @NotNull Map<E, ArrangementSectionRule> entryToSection) { final NewSectionInfo<E> info = new NewSectionInfo<E>(); boolean sectionIsOpen = false; ArrangementSectionRule prevSection = null; E prev = null; for (E e : arranged) { final ArrangementSectionRule section = entryToSection.get(e); if (section != prevSection) { closeSection(prevSection, prev, info, sectionIsOpen); sectionIsOpen = false; if (section != null) { final String startComment = section.getStartComment(); if (StringUtil.isNotEmpty(startComment) && !isSectionEntry(e, startComment)) { sectionIsOpen = true; info.addSectionStart(e, startComment); } } prevSection = section; } prev = e; } closeSection(prevSection, prev, info, sectionIsOpen); return info; }
private static <E extends ArrangementEntry> void closeSection(@Nullable ArrangementSectionRule section, @Nullable E entry, @NotNull NewSectionInfo<E> info, boolean sectionIsOpen) { if (sectionIsOpen) { assert section != null && entry != null; if (StringUtil.isNotEmpty(section.getEndComment())) { info.addSectionEnd(entry, section.getEndComment()); } } }
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); }
public static StdArrangementSettings createByMatchRules(@Nonnull List<ArrangementGroupingRule> groupingRules, @Nonnull List<StdArrangementMatchRule> matchRules) { final List<ArrangementSectionRule> sectionRules = new ArrayList<ArrangementSectionRule>(); for (StdArrangementMatchRule rule : matchRules) { sectionRules.add(ArrangementSectionRule.create(rule)); } return new StdArrangementSettings(groupingRules, sectionRules); }
@Nonnull protected List<ArrangementSectionRule> cloneSectionRules() { final ArrayList<ArrangementSectionRule> rules = new ArrayList<ArrangementSectionRule>(); for (ArrangementSectionRule rule : mySectionRules) { rules.add(rule.clone()); } return rules; }
@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; }
public static StdArrangementExtendableSettings createByMatchRules(@Nonnull List<ArrangementGroupingRule> groupingRules, @Nonnull List<StdArrangementMatchRule> matchRules, @Nonnull Collection<StdArrangementRuleAliasToken> rulesAliases) { final List<ArrangementSectionRule> sectionRules = new ArrayList<ArrangementSectionRule>(); for (StdArrangementMatchRule rule : matchRules) { sectionRules.add(ArrangementSectionRule.create(rule)); } return new StdArrangementExtendableSettings(groupingRules, sectionRules, rulesAliases); }
@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; }
@Nonnull private static List<ArrangementSectionRule> copy(@Nonnull List<ArrangementSectionRule> rules) { List<ArrangementSectionRule> result = new ArrayList<ArrangementSectionRule>(); for (ArrangementSectionRule rule : rules) { result.add(rule.clone()); } return result; }
private static <E extends ArrangementEntry> NewSectionInfo create(@Nonnull List<E> arranged, @Nonnull Map<E, ArrangementSectionRule> entryToSection) { final NewSectionInfo<E> info = new NewSectionInfo<E>(); boolean sectionIsOpen = false; ArrangementSectionRule prevSection = null; E prev = null; for (E e : arranged) { final ArrangementSectionRule section = entryToSection.get(e); if (section != prevSection) { closeSection(prevSection, prev, info, sectionIsOpen); sectionIsOpen = false; if (section != null) { final String startComment = section.getStartComment(); if (StringUtil.isNotEmpty(startComment) && !isSectionEntry(e, startComment)) { sectionIsOpen = true; info.addSectionStart(e, startComment); } } prevSection = section; } prev = e; } closeSection(prevSection, prev, info, sectionIsOpen); return info; }
private static <E extends ArrangementEntry> void closeSection(@Nullable ArrangementSectionRule section, @Nullable E entry, @Nonnull NewSectionInfo<E> info, boolean sectionIsOpen) { if (sectionIsOpen) { assert section != null && entry != null; if (StringUtil.isNotEmpty(section.getEndComment())) { info.addSectionEnd(entry, section.getEndComment()); } } }
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); }
/** * Check if comment can be recognized as section start/end * * @return true for section comment, false otherwise */ public boolean processComment(@NotNull PsiComment comment) { final TextRange range = comment.getTextRange(); final TextRange expandedRange = myDocument == null ? range : ArrangementUtil.expandToLineIfPossible(range, myDocument); final TextRange sectionTextRange = new TextRange(expandedRange.getStartOffset(), expandedRange.getEndOffset()); final String commentText = comment.getText().trim(); final ArrangementSectionRule openSectionRule = isSectionStartComment(mySettings, commentText); if(openSectionRule != null) { mySectionEntryProducer.consume(new ArrangementSectionEntryTemplate(comment, START_SECTION, sectionTextRange, commentText)); myOpenedSections.push(openSectionRule); return true; } if(!myOpenedSections.isEmpty()) { final ArrangementSectionRule lastSection = myOpenedSections.peek(); if(lastSection.getEndComment() != null && StringUtil.equals(commentText, lastSection.getEndComment())) { mySectionEntryProducer.consume(new ArrangementSectionEntryTemplate(comment, END_SECTION, sectionTextRange, commentText)); myOpenedSections.pop(); return true; } } return false; }
@Nullable public static ArrangementSectionRule isSectionStartComment(@NotNull ArrangementSettings settings, @NotNull String comment) { for(ArrangementSectionRule rule : settings.getSections()) { if(rule.getStartComment() != null && StringUtil.equals(comment, rule.getStartComment())) { return rule; } } return null; }
protected static ArrangementSectionRule section(@NotNull StdArrangementMatchRule... rules) { return section(null, null, rules); }
protected static ArrangementSectionRule section(@Nullable String start, @Nullable String end, @NotNull StdArrangementMatchRule... rules) { return ArrangementSectionRule.create(start, end, rules); }
protected void doTest(@NotNull Map<String, ?> args) { String text = (String)args.get("initial"); String expected = (String)args.get("expected"); @SuppressWarnings("unchecked") List<TextRange> ranges = (List<TextRange>)args.get("ranges"); Info info = parse(text); if (!isEmpty(ranges) && !isEmpty(info.ranges)) { fail("Duplicate ranges set: explicit: " + ranges + ", " + "derived: " + info.ranges + ", text:\n" + text); } if (isEmpty(info.ranges)) { info.ranges = !isEmpty(ranges) ? ranges : Arrays.asList(TextRange.from(0, text.length())); } myFixture.configureByText(fileType, info.text); final FoldingModel foldingModel = myFixture.getEditor().getFoldingModel(); for (final FoldingInfo foldingInfo : info.foldings) { foldingModel.runBatchFoldingOperation(new Runnable() { @Override public void run() { FoldRegion region = foldingModel.addFoldRegion(foldingInfo.start, foldingInfo.end, foldingInfo.placeholder); if (region != null) region.setExpanded(false); } }); } @SuppressWarnings("unchecked") List<ArrangementGroupingRule> groupingRules = (List<ArrangementGroupingRule>)args.get("groups"); if (groupingRules == null) groupingRules = Collections.emptyList(); List<?> rules = (List<?>)args.get("rules"); List<ArrangementSectionRule> sectionRules = getSectionRules(rules); @SuppressWarnings("unchecked") List<StdArrangementRuleAliasToken> aliases = (List<StdArrangementRuleAliasToken>)args.get("aliases"); CommonCodeStyleSettings settings = CodeStyleSettingsManager.getInstance(myFixture.getProject()).getCurrentSettings().getCommonSettings(language); 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); // Check expectation. info = parse(expected); assertEquals(info.text, myFixture.getEditor().getDocument().getText()); for (FoldingInfo it : info.foldings) { FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(it.start); assertNotNull("Expected to find fold region at offset " + it.start, foldRegion); assertEquals(it.end, foldRegion.getEndOffset()); } }
private static ArrangementSectionRule section(@Nullable String start, @Nullable String end, StdArrangementMatchRule... rules) { return ArrangementSectionRule.create(start == null ? null : start.trim(), end == null ? null : end.trim(), rules); }
private static ArrangementSectionRule section(boolean byName, @NotNull ArrangementSettingsToken... tokens) { return section(null, null, rule(byName, tokens)); }