targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift) {
return createAlignmentPerTypeStrategy(targetTypes, parentType, allowBackwardShift, Alignment.Anchor.LEFT);
}
/**
* Creates strategy that creates and caches one alignment per given type internally and returns it on subsequent calls
* to {@link #getAlignment(IElementType, IElementType)} for elements which type is listed at the given collection and parent type
* (if defined) is the same as the given one; null
is returned from {@link #getAlignment(IElementType, IElementType)} for all
* other elements.
*
* This strategy is assumed to be used at following situations - suppose we want to align code blocks that doesn't belong
* to the same parent but have similar structure, e.g. variable declaration assignments like the one below:
*
* int start = 1;
* int finish = 2;
*
* We can provide parent blocks of that target blocks with the same instance of this alignment strategy and let them eventually
* reuse the same alignment objects for target sub-blocks of the same type.
*
* @param targetTypes target types for which cached alignment should be returned
* @param parentType target parent type
* @param allowBackwardShift flag that specifies if former aligned element may be shifted to right in order to align
* to subsequent element (e.g. '='
block of 'int start = 1'
statement
* below is shifted one symbol right in order to align to the '='
block
* of 'int finish = 1'
statement)
* @return alignment retrieval strategy that follows the rules described above
*/
public static AlignmentPerTypeStrategy createAlignmentPerTypeStrategy(
@NotNull Collection targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift,
@NotNull Alignment.Anchor anchor) {
return new AlignmentPerTypeStrategy(targetTypes, parentType, allowBackwardShift, anchor);
}
/**
* Delegates the processing to {@link #getAlignment(IElementType, IElementType)} without parent element type
* filtering (null
is used as parent element type).
*
* @param childType target child type
* @return alignment to use
*/
@Nullable
public Alignment getAlignment(@Nullable IElementType childType) {
return getAlignment(null, childType);
}
/**
* Requests current strategy for alignment to use for the child of the given type assuming that parent node has the given type.
*
* @param parentType parent type to use for filtering (if not null
)
* @param childType child type to use for filtering (if not null
)
* @return alignment to use for the given arguments
*/
@Nullable
public abstract Alignment getAlignment(@Nullable IElementType parentType, @Nullable IElementType childType);
/**
* Stands for {@link AlignmentStrategy} implementation that is configured to return single pre-configured {@link Alignment} object
* or null
for all calls to {@link #getAlignment(IElementType)}.
*/
private static class SharedAlignmentStrategy extends AlignmentStrategy {
private final Set myFilterElementTypes = new HashSet();
private final Alignment myAlignment;
private final boolean myIgnoreFilterTypes;
private SharedAlignmentStrategy(Alignment alignment, boolean ignoreFilterTypes, IElementType... disabledElementTypes) {
myAlignment = alignment;
myIgnoreFilterTypes = ignoreFilterTypes;
myFilterElementTypes.addAll(asList(disabledElementTypes));
}
@Override
@Nullable
public Alignment getAlignment(@Nullable IElementType parentType, @Nullable IElementType childType) {
return myFilterElementTypes.contains(childType) ^ myIgnoreFilterTypes ? myAlignment : null;
}
}
/**
* Alignment strategy that creates and caches alignments for target element types and returns them for elements with the
* same types.
*/
public static class AlignmentPerTypeStrategy extends AlignmentStrategy {
private final Map myAlignments = new HashMap();
private final IElementType myParentType;
private final boolean myAllowBackwardShift;
AlignmentPerTypeStrategy(Collection targetElementTypes,
IElementType parentType,
boolean allowBackwardShift,
Alignment.Anchor anchor) {
myParentType = parentType;
myAllowBackwardShift = allowBackwardShift;
for (IElementType elementType : targetElementTypes) {
myAlignments.put(elementType, Alignment.createAlignment(myAllowBackwardShift, anchor));
}
}
@Override
public Alignment getAlignment(@Nullable IElementType parentType, @Nullable IElementType childType) {
if (myParentType != null && parentType != null && myParentType != parentType) {
return null;
}
return myAlignments.get(childType);
}
public void renewAlignment(IElementType elementType) {
myAlignments.put(elementType, Alignment.createAlignment(myAllowBackwardShift));
}
}
}