二、Editor 子包实现类完整反编译
19. EditorManagerServiceImpl (类, 源文件: ec)
java
public class EditorManagerServiceImpl implements EditorManagerService {
// --- 静态字段 ---
private static final Key<Boolean> new; // 某个布尔标记
private static final Logger long; // SLF4J 日志器
public static final Key<RequestResultList> CACHE_KEY_LAST_REQUEST;
public static final Key<RequestResultList> KEY_LAST_REQUEST;
private static final Key<Boolean> try; // 另一个布尔标记
private static final Set<String> super; // 不支持的文件类型集合
public static final Key<Boolean> enum; // Inlay 显示标记
// --- 实例字段 ---
public static final AtomicInteger docChangeCount; // 文档变更计数器
public static Boolean for; // 某个全局布尔
public static final boolean if; // assert 开关
public static final String ACCEPT_CODE_FOR_LINE; // 行级接受操作 ID
public static final String ACCEPT_CODE_FOR_WORD; // 单词级接受操作 ID
public static final int DELAY_MILLIS; // 延迟毫秒数
public static String byte; // 全局字符串状态
private Integer case; // 当前索引
private Integer float; // 最大显示索引
public static OperateActionEnum final; // 当前操作枚举
public static final Map<String, String> keyMap; // 键映射表
public final CancelRequestTip requestAlarm; // 请求取消定时器
// --- 核心方法 ---
void showPreviousInlaySet(Editor editor);
// -> KEY_LAST_REQUEST.get(editor).getPrevCodeTip() -> fC(inlayList, request, editor, true, Cycling)
void showNextInlaySet(Editor editor);
// -> KEY_LAST_REQUEST.get(editor).getNextCodeTip() -> fC(inlayList, request, editor, true, Cycling)
private boolean fC(CodeInlayList, EditorRequestService, Editor, boolean forced, OperateActionEnum);
// 1. mc(request, editor) — 验证请求有效性
// 2. mB(inlayList, request, editor, forced, action) — 执行显示
private void NC(CodeInlayList, EditorRequestService, Editor, boolean, OperateActionEnum);
// 核心渲染逻辑:
// 1. 如果 forced=true,先 disposeTips
// 2. 获取 InlayModel
// 3. 遍历 CodeInlayList 中的每个 CodeEditorInlay
// 4. 跳过 isEmptyTip() 的元素
// 5. 处理 replacementRange:
// - 如果有替换范围,使用 matchSuffixSection 分割
// - 创建 TipInlayRenderer
// 6. 根据 CodeTipType 分派渲染:
// case Inline: addInlineElement(offset, relatesToPrecedingText, priority, renderer)
// case AfterLineEnd: addAfterLineEndElement(offset, relatesToPrecedingText, renderer)
// case Block: addBlockElement(offset, showAbove, showIfCollapsed, priority, renderer)
private static void HC(Editor, EditorRequestService, CodeEditorInlay, String, InlayModel, int);
// 创建 TipInlayRenderer 并添加为 inline element
private Inlay<TipRenderer> Za(EditorRequestService, Editor, CodeInlayList, TipInlayRenderer, int);
// 高级 Inlay 创建:
// 1. 获取当前行后缀文本
// 2. 使用 CodeCheckUtil.matcher 检查括号匹配
// 3. 使用 matchSuffixSection 分割重叠部分
// 4. 创建多个 TipInlayRenderer 对应不同偏移
private boolean mc(EditorRequestService, Editor);
// 请求有效性验证:
// 1. editor.isDisposed() 检查
// 2. request.getDocumentModificationSequence() == doc 序列号
// 3. EditorUtil.isSelectedEditor(editor) 检查
private boolean mB(CodeInlayList, EditorRequestService, Editor, boolean, OperateActionEnum);
// 显示补全:
// 1. mc() 验证
// 2. editor.isDisposed() 检查
// 3. NC() 执行渲染
boolean Xc(Editor, List<CodeInlayList>);
// 检查是否已有相同偏移的 Inlay 显示中
// --- 其他方法 ---
boolean isAvailable(Editor editor);
// 检查编辑器是否支持补全(非二进制文件、文件大小等)
void editorChanged(Editor editor, int offset, CodeTipRequestType type, boolean forced);
// 核心入口: 创建请求 -> fetchTips/fetchCachedTips -> 渲染
boolean acceptTip(Editor editor);
boolean acceptTipForLine(Editor editor);
boolean acceptWordTip(Editor editor);
void acceptTip(Project, Editor, EditorRequestService, CodeInlayList);
void acceptWordTip(Project, Editor, EditorRequestService, CodeInlayList);
void cancelTipRequests(Editor editor);
void disposeTips(Editor editor, OperateActionEnum action);
List<TipRenderer> getInlays(Editor editor, int start, int end);
int countTipInlays(Editor editor, TextRange range, boolean b1, boolean b2, boolean b3, boolean b4);
boolean hasCacheData(Editor editor, char c);
}关键分析:
NC()是 Inlay 渲染的核心方法,按CodeTipType分三种渲染模式mc()是请求有效性验证,检查文档修改序列号防止过期请求fC()/mB()是显示/切换补全候选的入口Za()处理行后缀与补全文本的重叠分割- H() 调用:
EditorUtils.H(),Content.util.EditorUtils.H()
20. EditorManagerServiceImpl$B (类, 源文件: ec)
java
public class EditorManagerServiceImpl$B {
public static final int[] enum; // CodeTipType.ordinal() -> switch 映射表
static {} // 初始化 switch 映射: Inline=1, AfterLineEnd=2, Block=3
}关键分析: 纯粹的 switch 表映射类,用于 CodeTipType 的 tableswitch 优化
21. EditorManagerServiceImpl$F (类, 源文件: ec)
java
public class EditorManagerServiceImpl$F implements Flow.Subscriber<List<CodeInlayList>> {
public final EditorRequestService super; // 关联的请求
public final EditorManagerServiceImpl for; // 外部类引用
public static final boolean if; // assert 开关
public final long case; // 请求时间戳
public final Editor final; // 关联的编辑器
private volatile Flow.Subscription try; // Reactive 订阅
public final Consumer float; // 完成回调
private volatile boolean byte; // 是否已结束
public final AtomicBoolean enum; // 原子标记(防重入)
void onNext -> KB(List<CodeInlayList>);
// 1. 日志记录
// 2. mc(request, editor) 验证请求有效性
// 3. enum.compareAndSet(false, true) — 防重入
// 4. 重置 KEY_LAST_REQUEST 中的 RequestResultList
// 5. Xc(editor, inlays) 检查是否已有显示
// 6. 如果没有,请求下一个: try.request(1)
// 7. 发布 TipReceivedMessage.TOPIC 消息
// 8. 如果有 Consumer 回调且数据已结束:
// -> invokeLater 执行回调,记录响应时间
void onSubscribe(Flow.Subscription s);
// 1. 保存订阅
// 2. request(1) 请求第一个元素
// 3. 注册 Disposer: 当 request.getDisposable() 销毁时取消订阅
void onComplete(); // 空
void onError(Throwable t); // 静默
private static void cc(Consumer, CodeInlayList, long, Editor);
// 回调执行 + 响应时间日志
}关键分析:
- Reactive Flow 订阅者,连接 RequestTipService 的流式输出与 EditorManagerServiceImpl 的渲染
AtomicBoolean enum防止多次 onNext 处理Consumer float是完成回调,用于 Agent 模式下的延迟渲染- 响应时间通过
System.currentTimeMillis() - case计算
22. RequestTipServiceImpl (类, 源文件: zc)
java
public class RequestTipServiceImpl implements RequestTipService, Disposable {
public final TipCache cache; // SimpleCodeTipCache(32)
private static final Logger final; // SLF4J
public String try; // 当前文件路径
public static final Map<String, CodeTipRequestDto> CODE_TIP_MAP; // ConcurrentHashMap
public static final boolean float; // assert 开关
public static final Map<Project, String> LATEST_RESPONSE_DATA; // ConcurrentHashMap
public String byte; // 当前语言 ID
public static final Object object; // 同步锁
public static final Map<Project, Map<String, Long>> LAST_REQUEST; // ConcurrentHashMap
public Language enum; // 当前语言
// --- 核心方法 ---
EditorRequestService createRequest(Editor editor, int offset, TipType type);
// 创建补全请求对象
boolean isAvailable(Editor editor);
// 1. 获取 PsiFile
// 2. 检查是否 PsiBinaryFile
// 3. 检查 FileType.isBinary()
// 4. FileSizeUtil.isSupported(virtualFile)
private void jA(Editor editor, Span span);
// 初始化语言信息:
// 1. PsiDocumentManager.getPsiFile()
// 2. 获取 Language, language.getID().toLowerCase()
// 3. 获取 VirtualFile, 记录文件大小到 span
// 4. 设置 try (文件路径)
List<CodeInlayList> fetchCachedTips(EditorRequestService request);
// 从缓存获取补全结果
void fetchTips(EditorRequestService request, Flow.Subscriber<List<CodeInlayList>> subscriber,
Editor editor, String requestId, CodeTipRequestType type);
// 流式获取补全:
// 1. 检查缓存 isLatestPrefix
// 2. 创建 SubmissionPublisher
// 3. 调用 Agent 服务获取补全
// 4. 处理结果并提交到 publisher
private void ib(String requestId, List<String> lines, EditorRequestService request,
Flow.Subscriber<List<CodeInlayList>> subscriber, ResponseStreamDto.ResponseData data);
// 核心补全处理管线:
// 1. 创建 SubmissionPublisher
// 2. 分割文档前缀 (按换行符)
// 3. 遍历补全行:
// a. 替换制表符
// b. 去除前导空白(如果前缀最后一行非空)
// c. stripTrailing
// d. AgentCodeTip.FromString()
// e. replaceLeadingTabs
// f. setRequestId, setScene, setLanguage
// g. CodeTipUtil.createEditorCodeTip()
// h. 包装为 AgentCodeTipList
// 4. 提交到 publisher
// 5. 更新 AICodeStatus
void dealStreamAgentTips(String requestId, ResponseStreamDto data, Project project, MessageDto message);
// 流式 Agent 补全处理
void dealAgentTips(String requestId, JsonObject data, Project project);
// 非流式 Agent 补全处理
private String Rb(ResponseStreamDto.ResponseData data, CodeTipRequestDto request);
// 从响应数据提取替换文本:
// 1. 如果 isEnded,取 lastReplacementText
// 2. 否则取 data.getText()
// 3. 处理特殊后缀 (如 "```" 结尾)
EditorRequestService createInlineChatRequest(Editor editor, int offset, TipType type);
// 创建 Inline Chat 请求(委托给 createRequest)
void fetchInlineChatContent(...);
// 获取 Inline Chat 内容
}关键分析:
ib()是补全处理管线的核心,将原始文本行转换为CodeInlayListAgentCodeTip.FromString()将文本转为补全提示对象CodeTipUtil.createEditorCodeTip()创建编辑器补全结构AgentCodeTipList包装结果,关联ResponseStreamDto.ResponseData- H() 调用:
RequestCancelException.H(),CodeCompleteService.H(),GitReviewService.H()
23. RequestTipServiceImpl$j (类, 源文件: zc)
java
public class RequestTipServiceImpl$j extends TypeToken<String[]> {
public final RequestTipServiceImpl enum; // 外部类引用
RequestTipServiceImpl$j(RequestTipServiceImpl outer);
}关键分析: Gson TypeToken 子类,用于 JSON 反序列化 String[] 类型
24. InlayRendering (类, 源文件: oc)
java
public final class InlayRendering {
private static final Key<Map<Font, FontMetrics>> byte; // 字体度量缓存
private static final Method enum; // 反射方法缓存
// --- 渲染方法 ---
private static void PB(Graphics2D g, TextAttributes attr, double x, double y, double w, double h);
// 绘制圆角矩形背景:
// 1. 获取 backgroundColor
// 2. setColor
// 3. fillRoundRect(x, y, w, h, 1, 1)
private static void ic(Graphics2D g, double x, double y, double h, int start, int end,
TextAttributes attr, Font font);
// 绘制文本效果(下划线/删除线/波浪线):
// 根据 EffectType 分派:
// LINE_UNDERSCORE -> EffectPainter2D.LINE_UNDERSCORE
// BOLD_LINE_UNDERSCORE -> EffectPainter2D.BOLD_LINE_UNDERSCORE
// STRIKEOUT -> EffectPainter2D.STRIKEOUT
// WAVE_UNDERSCORE -> EffectPainter2D.WAVE_UNDERSCORE
// BOLD_DOTTED_LINE -> EffectPainter2D.BOLD_DOTTED_LINE
static void paint(Graphics2D g, TipRenderer renderer, Rectangle r, Editor editor);
// 主渲染入口:
// 1. 获取 TextAttributes
// 2. 绘制背景 (PB)
// 3. 遍历内容行:
// a. 绘制文本
// b. 绘制效果 (ic)
// 4. 处理多行 Block 类型
static int getWidth(TipRenderer renderer, Editor editor);
// 计算渲染宽度
// --- 辅助方法 ---
private static FontMetrics getFontMetrics(Graphics2D g, Font font);
// 获取/缓存字体度量
}关键分析:
InlayRendering是纯渲染工具类,处理 Graphics2D 绘制PB()绘制圆角矩形背景(radius=1)ic()根据EffectType分派 5 种效果绘制paint()是主渲染入口,处理背景、文本、效果三层绘制- 使用
Key<Map<Font, FontMetrics>>缓存字体度量避免重复计算
25. InlayRendering$G (类, 源文件: oc)
java
public class InlayRendering$G {
public static final int[] enum; // EffectType.ordinal() -> switch 映射表
static {} // LINE_UNDERSCORE=1, BOLD_LINE_UNDERSCORE=2, STRIKEOUT=3, WAVE_UNDERSCORE=4, BOLD_DOTTED_LINE=5
}26. TipInlayRenderer (类, 源文件: dc)
java
public class TipInlayRenderer implements TipRenderer {
private Inlay<TipRenderer> if; // 关联的 Inlay 对象
private int case; // 缓存宽度
private final String final; // 行后缀文本(用于行内补全)
private int try; // 行数
private final CodeTipType float; // 补全类型
private final List<String> byte; // 内容行
private final TextAttributes enum; // 文本属性
// --- TipRenderer 接口实现 ---
CodeTipType getType();
List<String> getContentLines();
Inlay<TipRenderer> getInlay();
void setInlay(Inlay<TipRenderer> inlay);
void setCachedWidth(int width);
// --- EditorCustomElementRenderer 接口实现 ---
int calcWidthInPixels(Inlay inlay);
// -> InlayRendering.getWidth(this, editor)
void paint(Graphics2D g, Rectangle r, Inlay inlay);
// -> InlayRendering.paint(g, this, r, editor)
// --- 静态工具方法 ---
static List<String> replaceLeadingTabs(List<String> lines, EditorRequestService request);
// 替换前导 Tab 为空格:
// 1. 如果 request.isUseTabIndents(),直接返回
// 2. 否则将每行前导 \t 替换为 request.getTabWidth() 个空格
static int ya(CharSequence seq, int start, boolean b);
// 计算前导空白长度(空格和Tab)
}关键分析:
TipInlayRenderer是TipRenderer的唯一实现- 渲染委托给
InlayRendering静态方法 replaceLeadingTabs()确保补全缩进与用户设置一致ya()计算前导空白长度,用于重叠文本分割
27. DocumentActionTracker (类, 源文件: bc)
java
public final class DocumentActionTracker {
public static final boolean float; // assert 开关
private static final Logger byte; // 诊断日志
private final AtomicInteger enum; // 强制补全计数器
boolean getExecutingForcedCodeGenerateAction();
// -> enum.get() > 0
void exitForcedCodeGenerateAction();
// -> enum.decrementAndGet()
// assert: 结果 >= 0
private void Hb();
// -> enum.incrementAndGet()
static DocumentActionTracker getInstance();
// -> ApplicationManager.getApplication().getService(DocumentActionTracker.class)
private static boolean oB(AnAction action);
// 检查是否为删除/退格操作:
// action instanceof DeleteAction || action instanceof BackspaceAction
}关键分析:
AtomicInteger enum跟踪强制补全操作的嵌套层级oB()判断 Delete/Backspace 操作,这些操作后需要触发强制补全- H() 调用:
JComponentKt.H(),IdeAction.H(),FileInfo.H(),EditorUtils.H()
28. DocumentActionTracker$ActionListener (类, 源文件: bc)
java
public final class DocumentActionTracker$ActionListener implements AnActionListener {
private final AtomicReference<Editor> enum; // 当前活跃编辑器引用
void beforeActionPerformed(AnAction action, AnActionEvent event);
// 1. 获取当前编辑器
// 2. 检查 containEditor(editor)
// 3. 如果是 SaveAllAction: 移除编辑器 + invokeLater 关闭按钮面板
// 4. 如果是 UndoAction: handleUndoAction(editor)
// 5. 设置 enum: 如果 EditorManagerService.isAvailable(editor) 则保存,否则 null
// 6. 如果 oB(action) (Delete/Backspace): Hb() 增加强制补全计数
void afterActionPerformed(AnAction action, AnActionEvent event);
// 1. 如果 oB(action): exitForcedCodeGenerateAction()
// 2. 如果不再 executingForcedCodeGenerateAction:
// 获取保存的编辑器引用
// 检查 editor/project/disposed 状态
// 检查 isSelectedEditor
// 检查 EditorManagerService.isAvailable
// -> editorChanged(editor, Forced, false) 触发强制补全
private static void Ya(Editor editor);
// closeButtonPanel(editor) — 关闭 Inline Chat 按钮面板
}关键分析:
ActionListener是 IntelliJ AnActionListener 扩展点实现- Delete/Backspace 触发强制补全:
beforeActionPerformed增加Hb(),afterActionPerformed减少exitForcedCodeGenerateAction() - SaveAllAction: 关闭 Inline Chat 按钮面板
- UndoAction: 委托给
InlineChatService.handleUndoAction() afterActionPerformed中,如果不再处于强制补全状态,触发editorChanged(Forced, false)
29. EditorUtil (类, 源文件: ac)
java
public final class EditorUtil {
public static final Key<List<EditorRequestService>> enum; // 编辑器请求列表 Key
static long getDocumentModificationStamp(Document doc);
// 优先使用 DocumentEx.getModificationSequence()
// 否则使用 Document.getModificationStamp()
static boolean isSelectedEditor(Editor editor);
// 1. 获取 FileEditorManager
// 2. 检查是否 Split Editor (通过反射 isSplit())
// 3. 否则检查 getSelectedEditor() instanceof TextEditor
// -> textEditor.getEditor().equals(editor)
static List<EditorRequestService> getEditorRequests(Editor editor);
// -> enum Key.get(editor, List.of())
static boolean isFocusedEditor(Editor editor);
// 1. 单元测试模式: 始终返回 true
// 2. 远程 IDE: 始终返回 true
// 3. 否则: editor.contentComponent.isFocusOwner()
static void addEditorRequest(Editor editor, EditorRequestService request);
// 1. disposeWithEditor(editor, request.getDisposable())
// 2. 如果 Key 不存在,创建 CopyOnWriteList
// 3. 添加到列表
static int whitespacePrefixLength(String text);
// 计算前导空白长度(空格和Tab)
static {} // enum = Key.create(H("..."))
}关键分析:
isSelectedEditor()使用反射处理 Split Editor 场景(IntelliJ 内部 API)addEditorRequest()将请求与编辑器生命周期绑定isFocusedEditor()对远程 IDE 和单元测试特殊处理- H() 调用:
RequestCancelException.H(),JComponentKt.H()
30. AgentCodeTipList (类, 源文件: tc)
java
public class AgentCodeTipList implements CodeInlayList {
private ResponseStreamDto.ResponseData long; // data
private String super; // scene
public static final boolean for; // assert 开关
private final EditorRequestService if; // request
private String case; // replacementText
private boolean final; // removeBlank
private final AgentCodeTip try; // agentCodeTip
private String float; // language
private String byte; // requestId
private final CodeInlayList enum; // delegate
// --- 构造器 ---
AgentCodeTipList(CodeInlayList delegate, AgentCodeTip tip, EditorRequestService request);
// 1. 保存 delegate, tip, request
// 2. removeBlank = true
// 3. replacementText = CodeTipUtil.dropOverlappingTrailingLines(tip.getText(), request.getDocumentContent(), request.getOffset())
// --- CodeInlayList 接口实现 ---
boolean isEmpty(); // -> delegate.isEmpty()
List<CodeEditorInlay> getInlays(); // -> delegate.getInlays() 或空列表
int getOffset(); // -> request.getOffset()
TextRange getReplacementRange();
// 1. 如果 delegate 有 replacementRange,使用它
// 2. 否则从 tip.getRange() 计算偏移
String getReplacementText();
// -> case (构造时计算的 replacementText)
CodeTip getAICodeTip(); // -> try (agentCodeTip)
Iterator<CodeEditorInlay> iterator(); // -> delegate.iterator() 或空迭代器
}关键分析:
AgentCodeTipList是CodeInlayList的装饰器,包装 Agent 补全结果dropOverlappingTrailingLines()去除与文档已有内容重叠的尾部行getReplacementRange()从 Agent 返回的 Range 对象计算 IntelliJ TextRange- H() 调用:
RequestCancelException.H(),CodeCompleteService.H()
31. CancelRequestTip (类, 源文件: yc)
java
public class CancelRequestTip {
private final Object byte; // 同步锁
private final Alarm enum; // IntelliJ Alarm 定时器
CancelRequestTip(Disposable parent);
// 初始化: byte = new Object(), enum = new Alarm(POOLED_THREAD, parent)
void cancelAllAndAddRequest(Runnable task, int delayMs);
// synchronized(byte):
// enum.cancelAllRequests()
// enum.addRequest(task, delayMs)
void lA();
// synchronized(byte):
// enum.cancelAllRequests()
void ab(int timeout, TimeUnit unit);
// synchronized(byte):
// enum.waitForAllExecuted(timeout, unit)
static String H(Object input);
// 字符串解混淆方法:
// 1. 获取调用者类名+方法名构建 key
// 2. 使用 XOR 解码: result[i] = input[i] ^ key[j] ^ key[k]
// 3. 双向遍历解码
}关键分析:
CancelRequestTip是防抖定时器,用于延迟触发补全请求cancelAllAndAddRequest()— 取消旧请求,添加新延迟请求H()是一个独立的字符串解混淆方法,使用调用栈信息作为 XOR 密钥- H() 调用:
GitReviewService.H(),FileExtensionLanguageDetails.H()
32. CodeTipTypedHandlerDelegate (类, 源文件: sc)
java
public class CodeTipTypedHandlerDelegate extends TypedHandlerDelegate {
private static final Logger enum;
Result checkAutoPopup(char c, Project project, Editor editor, PsiFile file);
// 1. 检查 AICodeRequestSettings.isShowIdeCodeTips()
// 2. 如果不显示 IDE 补全,但有缓存数据: hasCacheData(editor, c)
// -> 返回 STOP(阻止 IDE 自动补全弹窗)
// 3. 否则委托给父类
}关键分析:
- 当 AI 补全有缓存数据时,阻止 IDE 原生自动补全弹窗
- 这是 AI 补全与 IDE 补全的冲突解决策略
- H() 调用:
PropertyUtils.H(),Maps.H()
33. TipTypedHandlerDelegate (类, 源文件: pc)
java
public class TipTypedHandlerDelegate extends TypedHandlerDelegate {
private static final Key<Long> enum; // pendingTypeOver Key
static boolean getPendingTypeOverAndReset(Editor editor);
// 1. 获取 enum Key 中的 Long 值
// 2. 清除 Key (set null)
// 3. 比较 Long 值与 document.modificationStamp
// -> 相等返回 true(表示是补全接受后的 type-over)
Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType);
// 1. 检查是否为括号/引号/分号闭合字符: ) ] } " ' > ;
// 2. 如果是,且在 CommandProcessor 中:
// -> 保存 document.modificationStamp 到 enum Key
// 3. 返回 CONTINUE
}关键分析:
TipTypedHandlerDelegate处理 "type-over" 场景:用户输入闭合字符时,如果补全已包含该字符,则跳过getPendingTypeOverAndReset()在acceptTip时被调用,判断是否应跳过补全中的闭合字符- H() 调用:
RequestTimeoutException.H(),ChatInputController.H()
34. RequestResultList (类, 源文件: uc)
java
public class RequestResultList {
public final Object case; // inlayLock
public final EditorRequestService final; // request
public boolean try; // hasOnDemandCodeTips
public int float; // index
public int enum; // maxShownIndex
public final ObjectLinkedOpenHashSet<CodeInlayList> byte; // inlayLists
// --- 方法 ---
Object getInlayLock(); // -> case
EditorRequestService getRequest(); // -> final
int getIndex(); // -> float
void setIndex(int); // -> float = value
int getMaxShownIndex(); // -> enum
void setMaxShownIndex(int); // -> enum = value
boolean isHasOnDemandCodeTips(); // -> try
void setHasOnDemandCodeTips(boolean); // -> try = value
void setHasOnDemandCodeTips(); // synchronized(case): try = true
boolean hasOnDemandCodeTips();
// synchronized(case): try || byte.size() > 1
boolean hasPrev(); // synchronized(case): byte.size() > 1
boolean hasNext(); // synchronized(case): byte.size() > 1
CodeInlayList getPrevCodeTip();
// synchronized(case):
// if size <= 1: return null, index = 0
// index-- (wrap around)
// return TB(byte, index)
CodeInlayList getNextCodeTip();
// synchronized(case):
// if size <= 1: return null, index = 0
// index++ (wrap around)
// maxShownIndex = max(maxShownIndex, index)
// return TB(byte, index)
CodeInlayList getCurrentCodeTip();
// synchronized(case): TB(byte, index)
void addInlays(CodeInlayList inlayList);
// synchronized(case):
// byte.add(inlayList)
// maxShownIndex = max(maxShownIndex, byte.size())
void resetInlays();
// synchronized(case): byte.clear()
static String H(Object input);
// 字符串解混淆方法(同 CancelRequestTip.H 模式)
private static CodeInlayList TB(ObjectSortedSet<CodeInlayList> set, int index);
// -> set.stream().skip(index).findFirst().orElse(null)
String toString();
// -> "RequestResultList(request=..., inlayLock=..., inlayLists=..., index=..., maxShownIndex=..., hasOnDemandCodeTips=...)"
}关键分析:
RequestResultList管理单个补全请求的所有候选结果- 使用
ObjectLinkedOpenHashSet保持插入顺序且去重 index实现循环切换(wrap around),maxShownIndex记录最大展示索引- 所有操作在
synchronized(case)下进行,线程安全 - H() 调用:
GeneratorConfig.H(),ConditionalActionConfiguration.H()