跳到正文
cccskills
免费在 GitHub 公开中文介绍

symbols-api

使用 IntelliJ Symbol API 为语言、框架或数据库建模声明与引用,并连接导航、查找用法、重命名和文档功能;同时说明何时优先考虑 PolySymbols。

原文查看原文说明

Use IntelliJ Symbol API for declarations, references, and rename.

JetBrains/intellij-community星标 20,684(GitHub 20,684 + cccskills 0)

实测评分 未实测

查看安装方法

适用场景

  • 设计语言功能的声明与引用
  • 从字符串中的引用跳转到定义
  • 为符号添加查找用法和重命名

中文介绍

功能

本技能介绍如何使用 IntelliJ Symbol API,将语言、框架或数据库中的语义元素表示为 Symbol。内容包括提供声明、解析引用,以及将符号连接到导航、查找用法、重命名和文档显示。引用可以是语言本身固有的引用、由其他插件提供的外部引用,也可以是只支持从目标进行导航的隐式引用。指南还说明如何依据语义身份实现相等判断,以及当符号需要跨越读操作时如何使用指针。

适用场景

在 IntelliJ 插件中为某种语言或框架实现声明与引用时,可以使用本技能。示例还包括不直接依附于 PSI 元素的符号,例如字符串中的占位符解析到调用参数。对于常见的语言或框架支持,指南建议先考虑 PolySymbols,因为它可以承担大部分实现工作。只有当需求不适合该模型,例如单一且自包含的解析逻辑时,才直接使用底层 Symbol API。

使用示例

  • “用 Symbol API 为这种语言设计声明和引用。”
  • “让字符串中的占位符可以跳转到对应参数。”
  • “说明如何为这个符号连接查找用法和重命名。”

注意事项

本技能以 IntelliJ 平台 Symbol API 和插件开发为前提。实现常见语言或框架支持时,指南建议先查看相关的 poly-symbols 技能。

本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。

文档检查

AI 根据 SKILL.md 的内容检查了需要注意的操作和使用前提。评分只依据实际运行的结果(实测对比)。

安全性发送数据、删除文件、执行命令等是否有说明
A良好资料描述 API 实现,没有提及外发、删除或读取凭据。
安装难易度所需工具和 API 密钥是否少且有说明
B部分不足需要 IntelliJ 平台 API 和插件开发环境,但未提供安装步骤。

不计入评分。 由 AI(OpenAI Codex)于 2026年10月28日 评估。仅供参考,安装前请同时查看原文。

如果您认为评估有误,请申请复核

请写明哪一项有误以及原因。无需登录。我们会对照 SKILL.md 重新评估,并在此处更新结果。

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

包含的文件(1)

  • SKILL.md10.6 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

<!-- Generated by community/.ai/render-guides.mjs; edit community/.agents/skills/symbols-api/SKILL.md -->

Symbol API

com.intellij.model.Symbol (community/platform/core-api/src/com/intellij/model/Symbol.java) is the platform's generic replacement for "resolve a PsiReference to a PsiElement". A Symbol represents a semantic element in some model — a language, a framework, a database schema — and decouples navigation/find-usages/rename/documentation from PSI. A Symbol is not required to be backed by a PsiElement, and it is incorrect to try to obtain one from a Symbol.

Canonical examples from the docs: a Java local variable (backed by PsiVariable), a compiled class from JDK stubs (not tied to any project), a Spring bean (created dynamically by framework support, project-bound but not PSI-backed), a database column (defined by a data source, not PSI-backed and not project-bound).

Before hand-wiring any of the mechanisms on this page, look at poly-symbols first. PolySymbol : Symbol, and the PolySymbols framework exists specifically to save you from writing this boilerplate by hand — its query executor, completion-provider base class, and default searchTarget/renameTarget/ getDocumentationTarget/getNavigationTargets implementations give you declarations, references, completion, search, rename, and navigation with a fraction of the code this page documents. Treat PolySymbols as the default, go-to way to implement a new language or framework's symbol support — it is not limited to cross-language microsyntax sharing, that's simply the feature that falls out for free once the query/pattern machinery exists. Reach for the raw Symbol/ PsiSymbolReference API on this page directly only when a symbol genuinely doesn't fit PolySymbols' model: a single, self-contained resolve with no query/completion surface of its own (a format-string placeholder resolved from one call expression, a markdown link label), or something not project-bound / not PSI-backed at all (a compiled-class symbol from JDK stubs, a database column) where the extra query/scope layer would add nothing.

Contract and lifecycle

public interface Symbol {
  @NotNull Pointer<? extends Symbol> createPointer();
  @Override boolean equals(Object obj);
  @Override int hashCode();
}
  • equals/hashCode must reflect semantic identity, not object identity — the platform uses Symbol as a cache key and de-duplicates concurrently-computed instances that are equal.
  • Lifecycle is a single read action. A Symbol is safe to pass between APIs within one read action, but must not be referenced across read actions. Call createPointer() while still valid, store the Pointer, and call Pointer.dereference() in the next read action to get a fresh (or the same, if still valid) instance.
  • All of this applies unchanged to PolySymbol, which extends Symbol.

Declarations

Model where a symbol is declared in a PSI tree via PsiSymbolDeclaration (community/platform/core-api/src/com/intellij/model/psi/PsiSymbolDeclaration.java): getDeclaringElement(), getRangeInDeclaringElement(), getSymbol(). A symbol can have zero declarations (files — "only references"), one (a Java local variable), or several (a C# partial class, a property key declared in multiple files).

Two ways to supply declarations:

  • Register a PsiSymbolDeclarationProvider (getDeclarations(element, offsetInElement)) at EP com.intellij.psi.declarationProvider. The platform calls it for each PsiElement from the leaf at the caret up to the containing file, with offsetInElement as a hint (-1 means "all declarations").
  • Implement PsiSymbolDeclaration directly on the PsiElement.

References — three kinds

References are modeled by PsiSymbolReference (community/platform/core-api/src/com/intellij/model/psi/PsiSymbolReference.java): getElement(), getRangeInElement(), resolveReference(): Collection<? extends Symbol> (empty collection = unresolved), and resolvesTo(target) (override to short-circuit before a full resolve, e.g. by comparing text first). For the common single-target case, extend SingleTargetReference.

KindWhenMechanism
OwnReference is intrinsic to the language itself (e.g. x in x * 2 referencing var x = 42)PsiElement.getOwnReferences()
ExternalReference is not recognized by the host language, contributed by another plugin (e.g. a filename string in new File("users.txt"))Host implements PsiExternalReferenceHost; other plugins register a PsiSymbolReferenceProvider
ImplicitReference only supports resolving to a target (navigation, hover doc) — not find-usages/rename starting from the target (e.g. var in var x = new Person())ImplicitReferenceProvider

Language support should not assume external references are absent — they may be contributed by any plugin. Own vs. external is a modeling choice about who "owns" the reference semantics, not a technical distinction in PsiSymbolReference itself.

External references — PsiSymbolReferenceProvider

Interface (community/platform/core-api/src/com/intellij/model/psi/PsiSymbolReferenceProvider.java):

public interface PsiSymbolReferenceProvider {
  Collection<? extends PsiSymbolReference> getReferences(PsiExternalReferenceHost element, PsiSymbolReferenceHints hints);
  Collection<? extends SearchRequest> getSearchRequests(Project project, Symbol target);
}

Register via PsiSymbolReferenceProviderBean at EP com.intellij.psi.symbolReferenceProvider, declaring hostLanguage, hostElementClass, targetClass (common supertype of resolved symbols), referenceClass (defaults to PsiSymbolReference; narrow it so the platform can skip providers that can't possibly answer a query for a more specific reference type), and implementationClass.

Worked examples in this repo:

  • community/java/java-impl/src/com/siyeh/ig/format/StringFormatSymbolReferenceProvider.java — resolves %s/{0}-style placeholders inside String.format/printf/MessageFormat call arguments back to the corresponding call argument, complete with its own Symbol (FormatArgumentSymbol-style), NavigatableSymbol, and a SearchTarget/rename-capable design — read this file end to end as the reference implementation for "symbol lives inside a string literal, references live inside sibling call arguments."
  • community/jvm/jvm-analysis-impl/src/com/intellij/analysis/logging/resolve/LoggingArgumentSymbolReferenceProvider.kt — the same idea for JVM logging framework {}/{0} placeholders across Java/Kotlin.
  • Markdown link-label resolution (linked from the official docs as a third sample) follows the same shape one level simpler: label text in [text][label] resolves to the [label]: url definition.

Implicit references — ImplicitReferenceProvider

(community/platform/core-api/src/com/intellij/model/psi/ImplicitReferenceProvider.java, EP com.intellij.psi.implicitReferenceProvider):

public interface ImplicitReferenceProvider {
  default PsiSymbolReference getImplicitReference(PsiElement element, int offsetInElement) { ... }
  default Collection<? extends Symbol> resolveAsReference(PsiElement element) { return emptyList(); }
}

Usually you only override resolveAsReference — the default getImplicitReference wraps a non-empty result in an ImmediatePsiSymbolReference. This enables navigation and hover-link highlighting on the target Symbol, but the platform will never find this "reference" via find-usages or rename-from-target, because it was never indexed as a searchable reference. Called for every element from the caret leaf up to the file — keep it cheap.

PolySymbols' PsiPolySymbolReferenceProvider is built on top of exactly this external-reference mechanism, but replaces the manual getReferences/getSearchRequests plumbing with a single getReferencedSymbol(element): PolySymbol? you implement once — resolution, search, and rename all follow from the returned symbol. Prefer it over hand-writing PsiSymbolReferenceProvider unless you have a concrete reason not to — see the "References" section of poly-symbols/references/query-model.md.

Hooking a Symbol into platform features

A bare Symbol only gives you resolve. To light up the rest of the IDE, implement (or delegate to) these on your Symbol/PolySymbol:

FeatureInterfaceNotes
NavigationNavigatableSymbol (community/platform/core-api/src/com/intellij/navigation/NavigatableSymbol.java)getNavigationTargets(project); SymbolNavigationService helps build NavigationTargets
Find usagesSearchTarget/SearchTargetSymbol (community/platform/lang-impl/src/com/intellij/find/usages/api/SearchTarget.kt)presentation(), usageHandler, maximalSearchScope, textSearchRequests; register a factory at com.intellij.lang.symbolSearchTarget if you don't want the Symbol itself to implement it
RenameRenameableSymbol/RenameTarget (community/platform/lang-impl/src/com/intellij/refactoring/rename/symbol/RenameableSymbol.kt)or register a SymbolRenameTargetFactory at com.intellij.rename.symbolRenameTargetFactory
DocumentationDocumentationTargetvia PsiSymbolReferenceService/language-specific hookup

PolySymbol (see poly-symbols) already wires all four of these through searchTarget/renameTarget/getDocumentationTarget/getNavigationTargets properties with sensible defaults. This is the general pattern across this whole page: almost everything above is what PolySymbol implements for you. Implement PolySymbol and get all four; implementing raw Symbol means writing every row of the table above by hand for every symbol kind you add.

Related

  • poly-symbols — start here for new language/framework symbol support. It's built on Symbol and is the intended default implementation path, not a specialized add-on — reach for the mechanisms on this page directly only when a symbol falls outside its model (see the decision note above).
  • poly-context — general-purpose, performance-optimized context detection; PolySymbols is one consumer, not a dependency.
  • Official docs: Symbols, Declarations and References.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

actions

免费有简介

实现或修改 IntelliJ `AnAction`,并在 `plugin.xml` 中注册。将显示名称和说明写入消息资源文件,按需设置图标,并通过事件协程作用域启动挂起任务,避免同步处理阻塞 IDE。

  • 为 IDE 菜单添加操作
  • 修改操作注册或图标
  • 整理操作名称和说明
JetBrains/intellij-community2.1万2026年10月29日 更新

bazel-test-migration

免费有简介

将 IntelliJ JPS 测试模块迁移到 Bazel,并排查仅在 Bazel 中出现的失败。根据症状检查依赖、插件、测试数据和 runfiles,重新生成并验证目标。

  • 将 JPS 测试模块迁移到 Bazel
  • 排查仅在 Bazel 中失败的测试
  • 检查测试依赖和数据配置
JetBrains/intellij-community2.1万2026年10月29日 更新

code-style

免费有简介

按 IntelliJ 项目规范编写或审查 Kotlin 和 Java 代码,涵盖语言选择、格式、密封类型、线程注解及控制流异常处理。

  • 按 IntelliJ 规范编写 Kotlin
  • 审查 Java 代码
  • 检查异常处理和密封类型分支
JetBrains/intellij-community2.1万2026年10月29日 更新

commits

免费有简介

本指南帮助您按 IntelliJ 项目规则拆分更改并撰写提交信息:有工单时使用编号和变更说明,无工单时使用标签与子系统名,并在需要时说明原因和决定。

  • 按项目格式编写带工单号的提交信息
  • 整理测试或文档提交并选择合适标签
  • 按规则修改已有提交信息
JetBrains/intellij-community2.1万2026年10月29日 更新

使用多个 Python 类型检查器比较代码片段或文件的类型推断和报错判断,并汇总各工具的结论、耗时与诊断信息,可保存为 Markdown 报告。

  • 比较不同检查器的类型推断
  • 确认代码是否会被判为类型错误
  • 查看多个工具的诊断差异
JetBrains/intellij-community2.1万2026年10月29日 更新

整理 Compose Desktop 界面中的状态和副作用,让可组合函数负责绘制,由展示器或协调器处理应用决策。了解状态归属、Effect、可复用组件接口、延迟列表键、动画和性能,适用于单项界面修改。

  • 分离界面绘制与展示器决策
  • 整理界面状态的归属
  • 检查 Effect 键和协程用法
JetBrains/intellij-community2.1万2026年10月29日 更新

查看 JetBrains 的全部技能

报告此技能的问题