十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

IntelliJ Platform PolySymbols 集成案例研究:GDScript、JS/TS/HTML/CSS、Vue 与 Angular 的架构取舍与实现解析

IntelliJ Platform PolySymbols 集成案例研究:GDScript、JS/TS/HTML/CSS、Vue 与 Angular 的架构取舍与实现解析 IntelliJ Platform PolySymbols 集成案例研究GDScript、JS/TS/HTML/CSS、Vue 与 Angular 的架构取舍与实现解析【免费下载链接】intellij-communityIntelliJ IDEA IntelliJ Platform项目地址: https://gitcode.com/GitHub_Trending/in/intellij-community导读本文是 IntelliJ Platform 代码库中 PolySymbols 框架构建在平台 Symbol API 之上的跨语言符号共享与代码洞察框架涵盖补全、引用、文档、导航、重命名、查找用法与语义高亮的四个真实集成案例的深度解读。文章以.claude/skills/poly-symbols/references/case-studies.md为主体逐一拆解 GDScript、JS/TS/HTML/CSS、Vue、Angular 四个集成各自的位置、注册的扩展点、符号层级结构、作用域组织方式以及每个案例都附带的PolySymbols 对比 legacy 机制的最终裁决与文件行号证据。读完本文你将掌握何时该用 PolySymbols、何时必须保留 legacy PSI 机制的判断方法以及为一种新语言或框架设计 PolySymbols 集成时的具体行动清单。背景PolySymbols 是加法而非自动权威PolySymbols 是建立在平台 Symbol APIPolySymbol : Symbol之上的框架核心模块位于community/platform/polySymbols/src、backend、src-web。它曾在 2022.3–2025.1 被称为 Web Symbols目前仍标记为实验性特性。本案例研究文档存在的一个核心目的是防止一种失败模式假设 PolySymbols 是唯一的/权威的解析路径。事实上在被研究的每一个真实集成中PolySymbols 都并非唯一路径——没有任何一个语言完全通过它解析。这就是主技能文档中反复强调的additive, not authoritative加法而非权威规则JS/TS/HTML/CSS平台自带的原生支持把 PolySymbols 嫁接到既有扩展点XmlElementDescriptorProvider、css.elementDescriptorProvider、JSReferenceExpression.resolve()之上并显式为标准/规范符号让位。Vue 与 Angular——文档口中的 heaviest adopters最重的采用者——对它们的模板/标记表面组件、指令/选择器、props/inputs、slots、事件、修饰符几乎完全由 PolySymbols 驱动但 Vuex、style src、ref、文件路径引用、CSSv-bind()绑定Vue 侧以及 Angular2 表达式语言层、templateUrl/pipe 名称引用Angular 侧仍然完全运行在普通PsiReferenceContributor/CompletionContributor代码中与 PolySymbols 无关。GDScript最新的集成明确承认自己是双轨制——其树内 README 记载 PSI 与 PolySymbols 两套实现在 legacy 路径删除前同时运行并产生重复的 Find Usages 结果。四个集成的概览来源case-studies.md集成位置一句话裁决GDScriptdotnet/Plugins/godot-support/gdscript/.../polySymbols/双轨制SDK/引擎符号由 PolySymbols 优先用户代码的局部变量、资源引用与 TSCN 仅走 legacy部分元素上两条路径并发运行JS/TS、HTML、CSSplugins/JavaScriptLanguage/web-platform/、community/xml、plugins/cssPolySymbols 嫁接在 legacy 扩展点上并对一切标准/规范定义的内容主动让位Vuecontrib/vuejs/vuejs-backend/src/org/jetbrains/vuejs/web/模板/标记表面组件/指令/props/slots/事件几乎完全 PolySymbolsVuex、refs、CSS 绑定不是Angularcontrib/Angular/angular-backend/src/org/angular2/web/标记/选择器表面几乎完全 PolySymbolsAngular2 表达式语言层与部分文件/pipe 名称引用不是GDScript双轨制从无条件并存走向own references 主导位置与注册的扩展点GDScript 集成位于dotnet/Plugins/godot-support/gdscript/src/main/kotlin/gdscript/polySymbols/包含psi/、sdk/、scope/、reference/、completion/、index/、config/子目录此外还在引用 PSI 类自身gdscript/psi/impl/以及 TSCNtscn/psi/impl/TscnNamedElementImpl.kt上做了 own-references 接线。需要特别说明的是模块自带的polySymbols/README.md是初始部分采用阶段2026-03的快照目前已经过时例如它仍把局部变量/参数/for-loop 绑定列为未实现——应将其视为历史参考而非当前事实。本文反映的是RIDER-140303own-references 迁移2026-07-22 完成之后的代码状态。在.../gdscript/src/main/resources/META-INF/plugin.xml中注册的扩展点如下enableInLanguage同时启用GdScript和Tscn两种语言一个queryScopeContributorGdPolySymbolQueryScopeContributor零个psiReferenceProvider、零个psiLinkedSymbol二者在初始实现中存在own references 接管后被删除——见下文 Verdict两个declarationProviderGdSdkPolySymbolDeclarationProvider为合成 SDK 文件与GdPsiPolySymbolDeclarationProvider为真实 PSI一个highlightingCustomizerGdPolySymbolHighlightingCustomizer一个inspectionToolMapping用于抑制qualifiable-symbol种类的通用未解析引用警告由刻意保持惰性的GdUnrecognizedIdentifierInspection支撑机制见 query-model.md两个referencesSearch执行器GdOwnReferencesSearcher与GdConstructorReferencesSearcher详见下文。没有queryConfigurator。补全至今不是 PolySymbols 扩展点——五个普通completion.contributorgdscript.polySymbols.completion.*各自手工继承PolySymbolsCompletionProviderBase。两个符号层级PSI 与 SDKGDScript 维护两个符号层级二者都是abstract class GdPolySymbol : PolySymbol定义于gdscript/polySymbols/GdPolySymbols.ktGdPsiPolySymbol : PolySymbolDeclaredInPsigdscript/polySymbols/psi/GdPsiPolySymbol.kt——真实 PSI 支撑类、方法、属性、信号、枚举、autoloads、加载类别名、局部变量、参数、for-loop/绑定模式变量。它过去实现的是PsiLinkedPolySymbol桥接而不是朴素的PolySymbolDeclaredInPsi因为曾经注册在同一宿主元素上的 legacypsi.referenceContributor/PsiReferenceBase提供者会直接解析到底层PsiElement而桥接正是让 legacy 解析目标在旧机制之外也被识别为新PolySymbol的用法/重命名目标的关键。一旦这些 legacy contributor 被删除、own references 接管桥接的存在意义也随之消失。PolySymbolDeclaredInPsi自己的 doc 注释清楚地说明了它接受的取舍——针对sourceElement返回的PsiElement发起的任何用法或重命名搜索都不会导致该符号被识别为用法或重命名目标。GdSdkPolySymbol——合成的、以 XML 文档为支撑的符号Godot 引擎类/方法/信号/注解/运算符。没有真实PsiElement导航时通过GdSdkSyntheticPsiCache惰性生成一个合成 GDScript 文件并导航到那里。renameTarget nullSDK 代码不可重命名。它既不实现PolySymbolDeclaredInPsi也不实现PsiLinkedPolySymbol——因为它从来就没有真实的声明位置可以链接。从PsiLinkedPolySymbol桥到GdOwnReferencesSearcherGdOwnReferencesSearchergdscript/search/GdOwnReferencesSearcher.kt是弥补上述空白的通用修复一个ReferencesSearch执行器先对声明名称做经典词搜索再解析每个文本出现位置的 own references并与目标比对——从而在不引入桥接的情况下恢复PsiLinkedPolySymbol曾免费提供的被识别为用法行为。GdConstructorReferencesSearcher则是这个通用方案由之泛化而来的更早、更窄的特例它让对构造函数_init的 Find Usages 也能浮出ClassName.new(...)调用点——这些调用点文本上根本不包含_init。局部变量与作用域层级局部变量、参数、for-loop 绑定、绑定模式现在都可解析GdPsiPolySymbolDeclarationProvider从真实 PSI 产出GdPsiLocalVariableSymbol/GdPsiParameterSymbol/GdPsiForVariableSymbol/GdPsiBindingPatternSymbol专用的GdLocalSymbolsStructuredScope遍历每个文件的 method/lambda/loop/conditional 块以正确的嵌套关系暴露它们并接入无限定GdRefIdRef的作用域列表与QUALIFIABLE_SYMBOLS模式组并列。这弥补了平台通用的PolySymbolDeclarationProvider/作用域方案 query-model.md 覆盖不到的空白无限定局部解析需要自己的按文件结构作用域而不只是声明提供者。GdPolySymbolQueryScopeContributor把 PSI 位置映射到作用域列表覆盖的 PSI 位置包括get/set-method-id 引用、继承引用含嵌套的extends Outer.Inner子引用、类型提示引用、ref-id 引用局部变量在其上叠加GdLocalSymbolsStructuredScope、注解类型SDK 作用域GdSdkClassesPolySymbolScope、GdSdkGlobalPolySymbolScope、GdSdkAnnotationsPolySymbolScope按需从 Godot doctool XML 经GdSdkXmlParser解析并通过PolySymbolScopeWithCache缓存限定引用a.b、Outer.Inner委托给PolySymbolCompoundScope子类GdQualifiedRefIdResolveScope、GdQualifiedTypeHintResolveScope、GdQualifiedInheritanceResolveScope它们先把限定符解析为一个符号再重新暴露该符号的queryScope——这正是 query-model.md 中描述的queryScope链式模式。Own references 成为 canonical resolve 机制除了一个例外own references而非 EP 注册的外部引用现在是 GDScript 每种引用 PSI 种类的权威解析机制GdRefElementgdscript/psi/GdRefElement.kt所有叶子引用类型的共享基接口直接实现PolySymbolOwnReferenceHost标记接口本身的说明见 query-model.md。GdRefIdRef、GdTypeHintRef、GdInheritanceIdRef、GdInheritanceSubIdRef、GdGetMethodIdRef、GdSetMethodIdRef都在各自的*Impl类上覆写getOwnReferences()并通过polySymbolOwnReferences { ... }构建结果——其中GdRefIdRefImpl是 query-model 文档中底层reference(range, kind, resolver)形式的现成例子先对new/self/super/数学常量 token 分派再回退到按名称匹配的查询。唯一的例外是GdStringValRef资源路径字符串字面量它没有getOwnReferences()覆写纯粹通过仍然注册的 legacyGdResourceReferenceContributor注册在GdTypes.STRING_VAL_NM上的psi.referenceContributor解析——资源路径的 PolySymbols 覆盖为零与之前相同。TSCN 的 own-references-only 覆盖TSCN 现在有了仅 own-references 的 PolySymbols 覆盖2026-07-18 加入晚于本案例研究初稿——此前 TSCN 完全没有覆盖。TscnNamedElement实现PolySymbolOwnReferenceHostTscnNamedElementImpl.getOwnReferences()只解析两样东西且都解析为 GDScript 侧的符号script_classMyClass头部值 → 匹配的GdClassSymbol.tres数据行键 → 被包含的ExtResource所引用脚本上的export var字段对应的GdPsiPropertySymbol。TSCN 中没有其他东西参与无 scope contributor、无 declaration provider、无 PolySymbols 驱动的补全同一宿主元素上的普通res://资源路径值继续走经典的TscnResourceReferenceContributorTscnNamedElementImpl.kt中的注释明确说明这是刻意保留的。Verdict仍然双轨但分界已变原始两个机制无条件注册在同一宿主上问题的引用半边已解决——除了资源路径GdStringValRef/TSCNres://之外own references 已完全取代每种引用种类的 legacypsi.referenceContributor资源路径是唯一刻意未迁移的 legacy 孤岛。以下结论仍然成立且至关重要补全仍然不是 PolySymbols 扩展点——五个普通completion.contributor各自手工调用PolySymbolsCompletionProviderBase的查询辅助方法然后依赖平台默认的getCodeCompletions()由getSymbols()派生加上一个GdPolySymbolCodeCompletionItemCustomizerEPcom.intellij.polySymbols.codeCompletionItemCustomizer见 query-model.md来填充icon/priority/tailText/typeText。这统一覆盖 SDK 与用户定义/PSI 符号——曾经只针对 SDK 的补全过滤器已消失。资源路径引用GdResourceReferenceContributor及 TSCN 的镜像完全保持 legacy这是刻意选择而非疏漏——当前的GdStringValRef设计压根不把它们路由进 PolySymbols。脱离PsiLinkedPolySymbol是把一个更小的问题换成了另一个用一个问题两个并存的活动解析机制导致重复的 Find Usages 结果模块 README 曾明确指出换来了一个更窄的问题需要手写ReferencesSearch执行器GdOwnReferencesSearcher来恢复用法搜索的等价性。这证实了PolySymbolDeclaredInPsi的无用例搜索桥接取舍见 query-model.md是每个采用者都必须以某种方式付出的真实代价而非现实中没人撞上的角落。值得阅读的测试当前文件名此前列出的文件已在 own-references 迁移中被重命名/替换test/.../gdscript/model/GdCoreSdkModelTest.ktSDK 查询执行器构建、继承/成员作用域查询test/.../gdscript/resolve/ResolveTestBase.ktResolveInSingleFileTest.kt/ResolveMultiFileTest.ktmigration.md 中的 Symbol-API-first 解析转储模式test/.../gdscript/completion/GdCompletionTest.kt补全现在被积极测试不再是此前指针引用的被Ignore的占位test/.../tscn/refactoring/rename/ScriptClassRenamingTest.ktResourceFieldRenamingTest.ktown references 端到端——纯通过CodeInsightTestFixture.renameSymbolAtCaret(...)重命名无任何 own-references 专用管线见 testing.mdtest/.../gdscript/highlight/GdPolySymbolHighlightingCustomizerTest.kt针对上文GdPolySymbolHighlightingCustomizer。JS/TS、HTML、CSS嫁接在既有扩展点之上位置JS 专用胶水代码在plugins/JavaScriptLanguage/web-platform/src/com/intellij/polySymbols/js/通用的html命名空间核心支持在community/platform/polySymbols/src-web/.../html/legacy 集成桥接在community/xml/xml-psi-impl/.../polySymbols/html/与plugins/css/backend/src/com/intellij/polySymbols/css/。标准 HTML 如何解析PolySymbols 主动让位XmlTagDelegate.computeElementDescriptor()community/xml/xml-psi-impl/.../XmlTagDelegate.java:514-548迭代所有XmlElementDescriptorProvider回退到由 RelaxNG schema 支撑的HtmlNSDescriptorImpl。PolySymbols 自己的提供者HtmlElementSymbolDescriptorsProvider.../polySymbols/html/elements/HtmlElementSymbolDescriptorsProvider.kt:16-36在查询结果hasOnlyStandardHtmlSymbols()时返回null——即它刻意对普通的div让位让 legacy 的 RelaxNG-HTML5-schema 路径community/xml/relaxng/resources/.../html5-schema/来回答。属性侧的形状完全相同HtmlAttributeSymbolDescriptorsProvider.kt:43-67。CSS 的显式回退CSS 完全镜像了这一模式而且更显式intellij.css.backend.xml把CssElementSymbolDescriptorProvider注册在legacy的css.elementDescriptorProvider扩展点上与既有的CssElementDescriptorProviderImpl并列——后者以orderlast注册第 216-217 行作为有保证的回退。标准属性/伪类/函数知识来自CssElementDescriptorFactory2其数据源是 webref 派生的 XML schema 文件syntax-data/webref/*.xml与 Web Types 完全无关。捆绑的plugins/css/backend/resources/web-types/css.web-types.json只有约 330 行单位 一个兜底的 class 模式——它不枚举标准 CSS 属性列表。纯 JS/TS 解析仍是经典引擎TypeScriptReferenceExpressionResolver.resolve()plugins/JavaScriptLanguage/js-analysis-impl/.../TypeScriptReferenceExpressionResolver.kt:53-102只在一个狭窄分支中咨询 PolySymbols注入/嵌入表达式宿主JSEmbeddedContent即框架模板表达式内部的无限定引用第 65-69 行。其他一切——限定访问、调用、普通属性查找——都走doResolveReference/WalkUpResolveProcessor/TS 类型引擎先于并绕开了 PolySymbols。JSReferenceExpressionSymbolReferenceProvider自己的 doc 注释说仅靠 PolySymbols 解析是不够的因为我们需要 JS 支持提供的正确类型求值——它只是延续一个限定符已解析为 PolySymbol 的链从不发起新链。真正路由进 PolySymbols 的 JS 部分js/properties对象字面量形状符号、索引访问经JSLiteralExpressionSymbolReferenceProviderjs/symbols的修饰符合并经JSPolySymbolMatchCustomizerJSDoc 标签经JSDocSymbolQueryScopeContributor。Web Types 作为静态符号源Web Types 由WebTypesDefinitionsEPcommunity/platform/polySymbols/src-web/.../webTypes/impl/WebTypesDefinitionsEP.kt加载进WebTypesScopeBase/StaticPolySymbolScope。PackageJsonPolySymbolsRegistryManagerplugins/JavaScriptLanguage/web-platform/.../nodejs/PackageJsonPolySymbolsRegistryManager.kt监视package.json/node_modules加载每个依赖自带/npm 分发的web-types.json或customElements.json——这也是 poly-context 中node-packages规则的输入来源。Verdict对这三种语言PolySymbols 都是作为额外的、按条件激活的提供者叠放在既有扩展点xml.elementDescriptorProvider、css.elementDescriptorProvider、JSReferenceExpression.resolve()之上——从来不是替代品而且每个 PolySymbols 提供者内部都包含显式的对标准内容让位给 legacy逻辑。捆绑的 Web Types 从不编码核心规范数据没有完整的 HTML5 标签列表、没有完整的 CSS 属性列表它们存在的意义是框架/库增强Vue/Angular/htmx/npm 包和小型可枚举词汇CSS 单位。插件作者新增命名字符串或对象形状约定时用 PolySymbols任何触碰真实 JS/TS 代码中foo.bar如何解析的人碰的都是经典引擎。值得阅读的测试JSPolySymbolsObjectLiteralFeatureTest.kt最清晰的自定义端到端集成——注册了自己的 scope contributorPolySymbolsHtmlResolveTest.kt自定义标签 → 经 Web Types 到.ts源模块PolySymbolsCssHighlightingTest.kt/PolySymbolsCssCodeCompletionTest.kt。Vue最重的采用者与其边界位置与扩展点Vue 集成位于contrib/vuejs/vuejs-backend/src/org/jetbrains/vuejs/web/scopes/、symbols/外加一个更古老、更大的 Vue Model 领域层model/、model/source/、model/typed/——后者被改造为直接实现PolySymbol/PolySymbolScope而不是由新类包装。在contrib/vuejs/vuejs-backend/resources/intellij.vuejs.backend.xml中注册的扩展点framework idvuecontext kindframework namevue→VueFileContextProviderqueryScopeContributor×2VueSymbolQueryScopeContributor、VueI18NSymbolQueryScopeContributorqueryConfiguratorVueSymbolQueryConfiguratorqueryResultsCustomizerFactorydeclarationProviderVueSymbolDeclarationProvider一个psiReferenceProvider已弃用的slotx属性为向后兼容而保持 PolySymbols 感知17 个webTypes注册Vue 1.x–3.6 每个次版本一个外加vue-i18n、vue-contexts、nuxt。Vue Model 领域对象直接实现 PolySymbol组件/props/slots/事件如何变成符号——静态与动态双源并对齐VueContainer/VueComponent/VueInputProperty/VueSlot既有的 Vue Model 领域对象经VueSymbolmixin 直接实现PolySymbol/PolySymbolScope。源派生数据来自四个vuejs.containerInfoProvider实现Options API 的props:/emits:对象、defineComponent、class-API 的Component装饰器以及script setup的defineProps/defineEmits/defineModel/defineSlots宏VueScriptSetupInfoProvider.kt:181-232。静态库组件来自 Web Types。VueWebTypesMergedSymbol一个CompositePolySymbol合并同名源符号与静态符号使文档/图标/apiStatus 汇聚。邻近度local/app/library/global经VueComponentWithProximity风格的包装器挂接并映射为PolySymbol.Priority。指令微语法在 Web Types JSON 中声明而不是 Kotlin DSL——完整的v-on:click.once.alt工作示例见 patterns.md。Verdictmarkup 表面几乎 100% PolySymbols其余仍是 legacy模板/标记表面指令、组件、props、slots、事件、修饰符本质上 100% 由 PolySymbols 驱动并以声明方式做模式匹配——与文档中最重的采用者的定位相符。但该表面之外存在真实、公认的空白VueAttributeValueCompletionProvider.kt:20有一行字面意义上的// TODO move to web-types注释——lang...与 slot 名称补全仍是手写的CompletionProvider不是 PolySymbols。VueReferenceContributor普通psi.referenceContributor仍处理style src/template src文件引用与refx→ 脚本侧声明——对文件路径或PSI 变量符号种类没有 PolySymbols 等价物。VuexmapState/mapActions/store 模块键是完全自成一体的 legacy 子系统从未与 PolySymbols 集成。CSSv-bind()/CSS-modules 类引用VueCssReferencesContributor是普通 PSI 引用。值得阅读的测试VueCompletionTest.kttestEventModifiers、testEventsAfterVOn——指令微语法补全端到端setUp()显式调用来自com.intellij.polySymbols.testFramework的enableIdempotenceChecksOnEveryCache()以捕获注册表回归VueComponentTest.kt跨 Options/Composition/script setupAPI 的 props/emits/slots 解析golden 文件比对。Angular最深的框架特性集成位置与扩展点Angular 集成位于contrib/Angular/angular-backend/src/org/angular2/web/scopes/——21 个文件findUsages/、references/、declarations/外加用于 Reactive Forms 的library/forms/唯一的library/特性模块——没有专门的 CDK/Material/Router 模块那些走通用选择器解析 Web Types。在contrib/Angular/angular-plugin/resources/META-INF/plugin.xml中注册的扩展点framework idangularcontext kindframework nameangular→AngularCliContextProviderqueryScopeContributorAngular2SymbolQueryScopeContributorqueryConfiguratorqueryResultsCustomizerFactory×2base Forms6 个psiReferenceProvider选择器、指令属性字面量、block/block-param 引用、模板绑定键5 个declarationProviderpsiLinkedSymbolProviderAngular2PsiLinkedPolySymbolProviderhighlightingCustomizer18 个webTypesAngular 每个版本一个外加angular-base、angular-hacks、hammerjs、ionic-angular。entities 领域图直接实现 PolySymbol组件/指令/pipe 如何变成符号先在entities/中预建模为完整领域图Angular2ClassBasedComponent/Directive/Pipe、Angular2DirectiveProperty、Angular2DirectiveSelector带三个并行后端——source/ivy/metadata——经entitiesSource扩展点选择由Component/Directive/Pipe/Input/Output装饰器元数据计算而来。这些 entities直接实现PolySymbol/Angular2Symbolscope 类只查询Angular2EntitiesProvider并浮出它们经Angular2SymbolQueryResultsCustomizer按 module/standalone-imports 作用域过滤in-scope / importable / unreachable → 警告 import 快速修复。PsiLinkedPolySymbolProvider——为什么 Angular 特别需要它Angular2PsiLinkedPolySymbolProvider为裸TypeScriptField例如在.ts文件中右键单击Input() foo恢复Angular2DirectiveProperty使PsiLinkedPolySymbolReferenceSearcher能经PolySymbolNamesProvider.getNames(...)展开每一个名称变体Input(alias)、kebab-case 属性形式、banana-in-a-box 绑定形式并逐一搜索。没有它从类字段发起的 Find Usages 会静默退化为字面名称文本搜索漏掉别名化的模板用法。通用机制见 query-model.md。自定义事件微语法Angular 自己angular-base0.0.0.web-types.json中的js/ng-custom-events用法覆盖扩展键事件修饰符(keydown.control.shift.enter)但不覆盖.prevent/.stop——这一对修饰符只出现在一个测试夹具中contrib/Angular/angular-tests/testData/highlighting/customUserEvents/custom-user-events.web-types.json它证明任何第三方库都可以纯粹通过 Web Types 贡献添加自己的事件修饰符微语法无需任何 Kotlin。JSON 见 patterns.md。Angular Formslibrary/forms/是研究中最深、最完整的框架特性集成Angular2FormsPolySymbolQueryResultsCustomizer包装匹配的formControlName/formGroupName/formArrayName属性符号使其值解析为符号引用PolySymbolHtmlAttributeValue.create(PLAIN, Type.SYMBOL, required true)Angular2FormsSymbolQueryScopeContributor提供实际的FormGroup/FormBuilder.group()派生属性符号经Angular2FormSymbolsBuilder外加一个ReferencingPolySymbol风格的映射作用域。净效果formControlNameusern|ame获得完整的 go-to-declaration/rename/find-usages/completion/diagnostics完全构建在通用 PolySymbols 机制之上。Verdict标记/选择器表面指令、组件、pipes、选择器、Forms约 100% 由 PolySymbols 驱动。但Angular2TSReferencesContributor普通PsiReferenceContributor仍在 PolySymbols 之外处理templateUrl/styleUrl(s)文件引用与Pipe({name: ...})字面量引用这是恰当的——它们是文件/通用 PSI 引用不是符号种类更重要的是{{ }}内部与绑定中的 Angular2 表达式语言是作为真正的JSLanguageDialect实现的因此其引用/补全基础设施是原生 JS/TS PSI 机制PolySymbols 只是补充经PolySymbolsCompletionProviderBase和少数几个针对 block 参数/模板绑定键的psiReferenceProvider而非替代。值得阅读的测试Angular2HighlightingTest.testCustomUserEvents.prevent/.stop模式端到端含诊断Angular2RenameTest.testDirectiveInputMappedObject/testHostDirectiveInputForwardedPsiLinkedPolySymbolProvider名称变体重命名故事Angular2FormsCodeCompletionTest.kt/Angular2FormsRenameRefactoringTest.ktForms 端到端。跨案例总结给新集成作者的行动清单四个案例的一致结论可以归纳为一条可执行规则源自 SKILL.md对于每一个新集成或新特性都要显式决定对某个 PSI 元素/特性而言PolySymbols 是记录在案的解析路径还是仅仅是在既有机制之上补充额外符号的附加层。如果 legacyPsiReferenceContributor/CompletionContributor与新的 PolySymbols 注册可能在同一宿主PsiElement上同时触发要么用某种方式门控其一特性开关、context检查、应由谁让位的早期return null/空列表要么接受并文档化这种重叠——不要假设平台会替你选一个。结合 query-model.md 与 SKILL.md 中的接线清单新集成的标准步骤是启用语言注册polySymbols.enableInLanguage贡献作用域实现PolySymbolQueryScopeContributor几乎总是你要写的第一个、也是最重要的类解析引用实现PsiPolySymbolReferenceProvider或让 PSI 元素实现PolySymbolOwnReferenceHost后直接覆写getOwnReferences()走polySymbolOwnReferencesDSLown references 是语言自己的 canonical resolve用于替代 legacyPsiReferenceContributor同一宿主不要两者都注册——own references 一旦非空就优先于外部引用后者会变成死代码。无论哪种方式宿主类型必须实现PsiExternalReferenceHost外部或PolySymbolOwnReferenceHostown——否则PolySymbolHighlightingAnnotator根本不会处理该元素高亮与诊断会静默缺失提供声明符号与真实PsiElement一一对应时实现PolySymbolDeclaredInPsiPolySymbolDeclarationProviderprovider 是纯分派只有当同一个PsiElement还必须继续作为legacy、非 PolySymbols的 find-usages/rename 机制的目标时才使用PsiLinkedPolySymbol部分迁移的桥不是通用捷径完全没有PsiElement支撑的合成/SDK 符号则手写PolySymbolDeclarationProvider接线补全注册普通completion.contributor其 provider 继承PolySymbolsCompletionProviderBase并调用queryExecutor.codeCompletionQuery(...)可选PolySymbolQueryConfiguratorcontext 规则/名称转换规则、PolySymbolQueryResultsCustomizerFactory结果后过滤/重映射、polySymbols.webTypes标准库符号以静态 JSON 分发、PolySymbolFrameworkPolyContextProvider引入新的框架身份语言/框架在基础语法之上叠加微语法指令式属性名、事件修饰符链时使用PolySymbolWithPattern/模式 DSL详见 patterns.md。最后一条贯穿始终的工程纪律见 SKILL.md消费PolySymbol的代码永远不要向下转型到具体符号类来探测种类或读取数据——种类判定用symbol.kind其他数据用PolySymbolPropertyT注解 symbol[TheProperty]读取。这是平台约定四个案例的消费方代码都遵循它GDScript 的GdPsiPolySymbol迁移与 Angular 的 Forms 集成都证明遵守这一约定才能在符号种类混杂的查询结果中保持正确。如需继续深入可阅读 patterns.md模式 DSL 与v-on:click.once.alt微语法工作示例、testing.mdPolySymbolsTestCase层级与特性级测试配方与 migration.mdPSI 特性迁移到 PolySymbols 的测试优先方法论。【免费下载链接】intellij-communityIntelliJ IDEA IntelliJ Platform项目地址: https://gitcode.com/GitHub_Trending/in/intellij-community创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表