@SuppressWarnings("unchecked") private static <E extends ArrangementEntry> void doArrange( @NotNull List<ArrangementEntryWrapper<E>> wrappers, @NotNull Context<E> context) { if (wrappers.isEmpty()) { return; } Map<E, ArrangementEntryWrapper<E>> map = ContainerUtilRt.newHashMap(); List<E> arranged = ContainerUtilRt.newArrayList(); List<E> toArrange = ContainerUtilRt.newArrayList(); for (ArrangementEntryWrapper<E> wrapper : wrappers) { E entry = wrapper.getEntry(); map.put(wrapper.getEntry(), wrapper); if (!entry.canBeMatched()) { // Split entries to arrange by 'can not be matched' rules. // See IDEA-104046 for a problem use-case example. if (toArrange.isEmpty()) { arranged.addAll(arrange(toArrange, context.rules, context.rulesByPriority)); } arranged.add(entry); toArrange.clear(); } else { toArrange.add(entry); } } if (!toArrange.isEmpty()) { arranged.addAll(arrange(toArrange, context.rules, context.rulesByPriority)); } context.changer.prepare(wrappers, context); // We apply changes from the last position to the first position in order not to bother with // offsets shifts. for (int i = arranged.size() - 1; i >= 0; i--) { ArrangementEntryWrapper<E> arrangedWrapper = map.get(arranged.get(i)); ArrangementEntryWrapper<E> initialWrapper = wrappers.get(i); context.changer.replace( arrangedWrapper, initialWrapper, i > 0 ? map.get(arranged.get(i - 1)) : null, context); } }
@NotNull private List<AnnotationData> collectExternalAnnotations(@NotNull PsiModifierListOwner listOwner) { if (!hasAnyAnnotationsRoots()) return Collections.emptyList(); List<AnnotationData> cached; while (true) { cached = (List<AnnotationData>) cache.get(listOwner); if (cached == NO_DATA || !cached.isEmpty()) return cached; List<AnnotationData> computed = doCollect(listOwner, false); if (cache.replace(listOwner, cached, computed)) { cached = computed; break; } } return cached; }
@Override @Nullable public PsiAnnotation[] findExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) { final List<AnnotationData> result = collectExternalAnnotations(listOwner); return result.isEmpty() ? null : ContainerUtil.map2Array( result, PsiAnnotation.EMPTY_ARRAY, new Function<AnnotationData, PsiAnnotation>() { @Override public PsiAnnotation fun(AnnotationData data) { return data.getAnnotation(BaseExternalAnnotationsManager.this); } }); }