mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
GPUB: sync with GK 1.3.1 (hooks)
This commit is contained in:
@@ -39,6 +39,7 @@ import com.intellij.util.Function;
|
||||
import com.intellij.util.PairProcessor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.LimitedPool;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -92,6 +93,59 @@ public class GeneratedParserUtilBase {
|
||||
}
|
||||
};
|
||||
|
||||
public interface Hook<T> {
|
||||
|
||||
@Contract("_,null,_->null")
|
||||
PsiBuilder.Marker run(PsiBuilder builder, PsiBuilder.Marker marker, T param);
|
||||
|
||||
}
|
||||
|
||||
public static final Hook<WhitespacesAndCommentsBinder> LEFT_BINDER =
|
||||
new Hook<WhitespacesAndCommentsBinder>() {
|
||||
@Override
|
||||
public PsiBuilder.Marker run(PsiBuilder builder,
|
||||
PsiBuilder.Marker marker,
|
||||
WhitespacesAndCommentsBinder param) {
|
||||
if (marker != null) marker.setCustomEdgeTokenBinders(param, null);
|
||||
return marker;
|
||||
}
|
||||
};
|
||||
|
||||
public static final Hook<WhitespacesAndCommentsBinder> RIGHT_BINDER =
|
||||
new Hook<WhitespacesAndCommentsBinder>() {
|
||||
@Override
|
||||
public PsiBuilder.Marker run(PsiBuilder builder,
|
||||
PsiBuilder.Marker marker,
|
||||
WhitespacesAndCommentsBinder param) {
|
||||
if (marker != null) marker.setCustomEdgeTokenBinders(null, param);
|
||||
return marker;
|
||||
}
|
||||
};
|
||||
|
||||
public static final Hook<WhitespacesAndCommentsBinder[]> WS_BINDERS =
|
||||
new Hook<WhitespacesAndCommentsBinder[]>() {
|
||||
@Override
|
||||
public PsiBuilder.Marker run(PsiBuilder builder,
|
||||
PsiBuilder.Marker marker,
|
||||
WhitespacesAndCommentsBinder[] param) {
|
||||
if (marker != null) marker.setCustomEdgeTokenBinders(param[0], param[1]);
|
||||
return marker;
|
||||
}
|
||||
};
|
||||
|
||||
public static final Hook<String> LOG_HOOK = new Hook<String>() {
|
||||
@Override
|
||||
public PsiBuilder.Marker run(PsiBuilder builder, PsiBuilder.Marker marker, String param) {
|
||||
PsiBuilderImpl.ProductionMarker m = (PsiBuilderImpl.ProductionMarker)marker;
|
||||
int start = m == null ? builder.getCurrentOffset() : m.getStartOffset();
|
||||
int end = m == null ? start : m.getEndOffset();
|
||||
String prefix = "[" + start + ", " + end + "]" + (m == null ? "" : " " + m.getTokenType());
|
||||
builder.mark().error(prefix + ": " + param);
|
||||
return marker;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static boolean eof(PsiBuilder builder, int level) {
|
||||
return builder.eof();
|
||||
}
|
||||
@@ -481,9 +535,35 @@ public class GeneratedParserUtilBase {
|
||||
close_frame_impl_(state, frame, builder, marker, elementType, result, pinned);
|
||||
exit_section_impl_(state, frame, builder, elementType, result, pinned, eatMore);
|
||||
}
|
||||
if (state.hooks != null) {
|
||||
run_hooks_impl_(builder, state, level, pinned || result ? elementType : null);
|
||||
}
|
||||
state.FRAMES.recycle(frame);
|
||||
}
|
||||
|
||||
public static <T> void register_hook_(PsiBuilder builder, int level, Hook<T> hook, T param) {
|
||||
ErrorState state = ErrorState.get(builder);
|
||||
state.hooks = Hooks.concat(hook, param, level, state.hooks);
|
||||
}
|
||||
|
||||
public static <T> void register_hook_(PsiBuilder builder, int level, Hook<T[]> hook, T... param) {
|
||||
ErrorState state = ErrorState.get(builder);
|
||||
state.hooks = Hooks.concat(hook, param, level, state.hooks);
|
||||
}
|
||||
|
||||
private static void run_hooks_impl_(PsiBuilder builder, ErrorState state, int level, @Nullable IElementType elementType) {
|
||||
PsiBuilder.Marker marker = elementType == null ? null : (PsiBuilder.Marker)builder.getLatestDoneMarker();
|
||||
if (elementType != null && marker == null) {
|
||||
builder.error("No expected done marker at offset " + builder.getCurrentOffset());
|
||||
}
|
||||
while (state.hooks != null && state.hooks.level >= level) {
|
||||
if (state.hooks.level == level) {
|
||||
marker = ((Hook<Object>)state.hooks.hook).run(builder, marker, state.hooks.param);
|
||||
}
|
||||
state.hooks = state.hooks.next;
|
||||
}
|
||||
}
|
||||
|
||||
private static void exit_section_impl_(ErrorState state,
|
||||
Frame frame,
|
||||
PsiBuilder builder,
|
||||
@@ -831,6 +911,7 @@ public class GeneratedParserUtilBase {
|
||||
int predicateCount;
|
||||
boolean predicateSign = true;
|
||||
boolean suppressErrors;
|
||||
Hooks<?> hooks;
|
||||
public Frame currentFrame;
|
||||
public CompletionState completionState;
|
||||
|
||||
@@ -1042,6 +1123,24 @@ public class GeneratedParserUtilBase {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Hooks<T> {
|
||||
final Hook<T> hook;
|
||||
final T param;
|
||||
final int level;
|
||||
final Hooks<?> next;
|
||||
|
||||
Hooks(Hook<T> hook, T param, int level, Hooks next) {
|
||||
this.hook = hook;
|
||||
this.param = param;
|
||||
this.level = level;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
static <E> Hooks<E> concat(Hook<E> hook, E param, int level, Hooks<?> hooks) {
|
||||
return new Hooks<E>(hook, param, level, hooks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final int MAX_CHILDREN_IN_TREE = 10;
|
||||
public static boolean parseAsTree(ErrorState state, final PsiBuilder builder, int level, final IElementType chunkType,
|
||||
|
||||
Reference in New Issue
Block a user