编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载analyzer_plugin是 Dart SDK 中用于构建 analysis server 插件的官方框架其 CHANGELOG.md 记录了从 0.0.1 到 0.14.18-dev 的完整演进轨迹。本文以该变更日志为核心骨架结合pkg/analyzer_plugin/lib下的源码实现系统梳理插件框架的架构、关键 API 的破坏性变更、版本兼容策略帮助插件开发者理解 API 的来龙去脉并据此规划插件升级路径。一、框架定位为 analysis server 构建插件的支持代码analyzer_plugin是一套用于构建 analysis server 插件的框架与支持代码。按 README.md 的说明插件用 Dart 编写运行在与 analysis server 相同的 VM 中每个插件运行在独立 isolate 中通过插件 API与 analysis server 和客户端通信的 API 类似与服务器通信并被服务器自动发现和运行。从 pubspec.yaml 可以看到该包除依赖analyzer外还依赖collection、dart_style、pub_semver、yaml和path其版本策略声明We use any version constraints here as we get our package versions from the dart-lang/sdk repos DEPS file。这意味着在 SDK 仓库内联开发时依赖版本由 DEPS 统一管理。需要特别说明的是README 已明确标注该包为legacy support新插件开发推荐使用analysis_server_plugin包。但对维护既有插件、理解 analysis server 插件协议演进历史的开发者而言本变更日志仍是权威资料。二、版本兼容策略与analyzer包严格对齐变更日志中超过一半的条目是同一句话的变体——Require version X of theanalyzerpackage。这构成了该包最重要的工程策略每个 analyzer_plugin 版本都严格绑定一个 analyzer 版本范围二者必须同步升级。analyzer_plugin 版本要求的 analyzer 版本备注0.14.18-dev14.5.0-dev当前开发版本0.14.1714.4.00.14.1614.3.00.14.1514.2.00.14.1414.1.00.14.1314.0.00.14.1213.3.00.14.1113.2.00.14.1013.1.00.14.913.0.00.14.812.1.00.14.712.0.00.14.6-dev11.1.0-dev0.14.5^11.0.0-00.14.4-dev10.3.0-dev0.14.410.2.00.14.310.1.00.14.210.0.20.14.110.0.10.14.010.0.0本版本含大量破坏性变更见下文0.13.119.0.00.13.88.2.0同时要求 Dart SDK^3.9.00.13.5^8.0.00.13.4^7.5.10.13.2^7.4.6同时弃用RangeFactory.error0.12.07.x协议枚举转为真枚举0.11.36.x0.11.25.x0.10.04.x0.9.03.x0.7.02.x0.5.0^1.3.0稳定版空安全0.4.00.41.0 0.42.00.2.5^0.39.120.2.2^0.39.00.2.10.39.0同时修复 issue #37916、#38326可见早期版本约束写法经历了从^0.39.0、0.39.0到^1.3.0再到^8.0.0、7.x和精确版本14.4.0的演化。当前仓库中 pubspec.yaml 实际锁定analyzer: 14.5.0-dev与 0.14.18-dev 条目完全对应。对于插件作者这一策略意味着升级 analyzer_plugin 时必须同步升级 analyzer二者版本一一对应不存在跨大版本混用的空间。这也是该包频繁发布小版本、每条记录都只有一行版本声明的原因。三、插件生命周期与核心基类 ServerPlugin在 lib/plugin/plugin.dart 中ServerPlugin是所有插件必须继承的抽象基类。它定义了插件的核心形态基本属性name用户可见插件名、version插件协议版本号、fileGlobsToAnalyze插件关注的文件 glob 模式、contactInfo作者联系信息可空。通信通道start(PluginCommunicationChannel channel)启动插件并监听通道channelgetter 返回当前通信通道。版本握手handlePluginVersionCheck处理plugin.versionCheck请求记录 SDK 路径并返回isCompatibleWith(serverVersion)、插件名、版本与 glob 模式isCompatibleWith的判定逻辑是serverVersion Version.parse(version)。上下文管理handleAnalysisSetContextRoots根据客户端下发的根路径创建AnalysisContextCollectionImpl并在创建后回调afterNewContextCollection执行初始分析销毁前回调beforeContextCollectionDispose。文件内容同步handleAnalysisUpdateContent支持AddContentOverlay、ChangeContentOverlay、RemoveContentOverlay三种 overlay 变更并将变更路径交给contentChanged最终触发handleAffectedFiles对受影响文件重分析。订阅机制handleAnalysisSetSubscriptions把客户端订阅的服务集合写入subscriptionManager并立即对新订阅文件发送通知sendNotificationsForFile按订阅的AnalysisServiceFOLDING、HIGHLIGHTS、NAVIGATION、OCCURRENCES、OUTLINE分发通知。各功能请求的默认实现handleAnalysisGetNavigation、handleCompletionGetSuggestions、handleEditGetAssists、handleEditGetFixes、handleEditGetAvailableRefactorings、handleEditGetRefactoring等均返回空结果子类按需覆写。启动入口在 lib/starter.dartServerPluginStarter工厂创建Driver(plugin)start(SendPort sendPort)建立与服务器通信的通道并启动插件。插件由此运行在独立 isolate 中与 analysis server 通过 SendPort 交换消息。ServerPlugin内部还维护了priorityPaths优先分析文件集合与ByteStore跨 AnalysisContext 复用的字节缓存默认实现为 256MB 内存缓存。flushAnalysisState可清理元素模型状态以降低堆占用代价是下次分析会从缓存恢复、速度变慢。四、分析上下文模型的演进0.11.00.11.0 的条目写明UsingAnalysisContextCollectionandAnalysisContextfor analysis.这是插件分析模型的一次架构升级。在 0.11.0 之前插件内部直接基于AnalysisDriver进行文件分析之后统一改为AnalysisContextCollection上下文集合AnalysisContext单个上下文模型。这一模型与 analyzer 包自身的分析驱动一致使得插件可以按 context root 组织分析单元。从 plugin.dart 的实现看handleAnalysisSetContextRoots会基于请求中的includedPaths、resourceProvider、_byteStore、_sdkPath等构造新的AnalysisContextCollectionImpl并开启withFineDependencies: true以支持细粒度依赖跟踪。contentChanged则对每个上下文调用analysisContext.changeFile(path)与applyPendingFileChanges()得到受影响文件后再交给handleAffectedFiles。0.11.1 进一步修正了行为细节handleAffectedFiles默认仅对该分析上下文中确实被分析的文件调用analyzeFiles。对应实现是 plugin.dart 中的paths.where(analysisContext.contextRoot.isAnalyzed)过滤避免把不属于当前上下文如未纳入分析根目录的文件也纳入分析减少无效工作。getResolvedUnitResult(path)是对外暴露的关键方法通过当前上下文会话调用analysisSession.getResolvedUnit(path)获取ResolvedUnitResult失败时抛出RequestFailure并返回pluginError。五、变更构建器ChangeBuilder体系的演进变更构建器是插件为 IDE/编辑器生成代码修改assists、fixes的核心设施也是历次破坏性变更最密集的区域。5.1 从 DartChangeBuilder 到 ChangeBuilder0.4.0 → 0.5.00.4.0 引入三个重要变化弃用DartChangeBuilder类增强ChangeBuilder作为替代弃用ChangeBuilder.addFileEdit新增addDartFileEdit与addGenericFileEditanalyzer 支持范围改为0.41.0 0.42.0。0.5.0 在稳定空安全null safety发布时正式移除DartChangeBuilder、DartChangeBuilderImpl与addFileEdit()并弃用Plugin.fileContentOverlay——资源提供者统一改为OverlayResourceProvider由analysis.updateContent更新。当前 change_builder_core.dart 中ChangeBuilder的工厂签名要求传入AnalysisSession或ChangeWorkspace二选一不能同时并提供defaultEol参数默认Platform.lineTerminator已有 EOL 标记的文件保持原 EOL。三个文件编辑入口分工明确addDartFileEdit(path, buildFileEdit)针对 Dart 源文件builder 具备 Dart 专用能力createEditsForImports参数默认true控制是否自动生成缺失 import 的编辑addGenericFileEdit(path, buildFileEdit)通用文件无特殊支持addYamlFileEdit(path, buildFileEdit)针对 YAML 源文件builder 具备 YAML 专用能力。0.14.0 又移除了ChangeBuilder.new已弃用的eol参数与addDartFileEdit已弃用的importPrefixGenerator参数并删除ChangeBuilder.copy方法。5.2 DartEditBuilder 的新增 API0.12.00.12.0 在DartEditBuilder上新增了writeFormalParameter与writeFormalParameters在DartFileEditBuilder上新增了getIndent按层级返回缩进insertCaseClauseAtEnd在 switch 语句/表达式末尾插入 case 子句insertConstructor、insertField、insertGetter、insertMethod按 lint 规则与代码风格把成员插入到合适位置writeIndent写出缩进每个层级两个空格。在 change_builder_dart.dart 中可以确认这些 API 的完整签名与语义。例如insertConstructor会考虑sort_constructors_first、sort_unnamed_constructors_first两条 lint 规则来决定插入点insertField会参考CodeStyleOptionswriteIndent([int level 1])默认写两级空格缩进。0.12.0 还加入了一套实验性 APIwriteOverride2、writeReference2、writeType2、writeTypeParameter2、writeTypeParameters2作为下一代成员写入接口的试验性前身。5.3 DartFileEditBuilder 的破坏性变更0.12.0 → 0.13.00.12.0convertFunctionFromSyncToAsync与replaceTypeWithFuture发生破坏性变更。在源码中这两个方法目前都需要FunctionBody/TypeAnnotation加TypeSystem、TypeProvider三个参数用于在同步/异步函数间转换时同步调整返回类型FutureT。另一个方向convertFunctionFromAsyncToSync与replaceTypeWithFutureArgument同样存在。二者对生成器函数generator体有限制不满足条件时抛出ArgumentError。0.13.0DartFileEditBuilder与DartEditBuilder再次发生破坏性变更日志未列出细节但可推断与写入 API 的重新设计相关。0.14.0移除各方法上已弃用的methodBeingCopied参数。5.4 链接编辑Linked Edit与导入管理EditBuilder.addLinkedEdit(groupName, builder)与addSimpleLinkedEdit支持把编辑中的文本区域归入链接编辑组并附带LinkedEditSuggestionKind类型的建议值供 IDE 实现重命名一处、联动多处的交互。FileEditBuilder.addLinkedPosition(range, groupName)则把既有代码区域纳入链接组。导入管理集中在DartFileEditBuilder.importLibrary与importLibraryElementimportLibrary(uri, {prefix, showName, useShow})安排为给定 URI 的库添加 import可指定前缀、show 子句返回实际写入指令的 URI 文本可能因 lint 规则从绝对 URI 转为相对 URIimportLibraryElement确保库已导入——若已存在且未带前缀则修改现有 import 以展示showName若已带前缀则新增一个无前缀 importimportsLibrary(uri)查询某库是否已被现有或计划中的编辑导入fileHeadersetter设置在生成的 import 之前的文件头自动补一个空行requiredImports列出编辑中引用的新类型所必须导入的 URI。ImportPrefixGenerator类型在 change_builder_dart.dart 中已被标注Deprecated(This type is no longer used or necessary)呼应 0.14.0 移除importPrefixGenerator参数的变更。六、RangeFactory 的两次改名0.13.0 → 0.13.2 → 0.14.0RangeFactory是生成SourceRange的工厂类range_factory.dart 提供了从 AST 节点、token、语法实体、offset 组合派生范围的大量方法例如node(AstNode)、token(Token)、entity(SyntacticEntity)覆盖单个语法实体startEnd(left, right)、endEnd(left, right)、startStart、endStart按两个实体的起止位置组合范围startLength、endLength、offsetBy按偏移与长度构造argumentRange(argumentList, lower, upper, forDeletion)覆盖参数列表中的一段forDeletion为true时包含邻近逗号以支持安全删除对(a, b, c, d)取下标 12 时范围分别是b, c或, b, cdeletionRange(node, {overrideEnd})考虑节点前后的空白与注释计算可安全删除的范围nodeInList(list, item)返回列表中单个元素含前导/尾随逗号的范围。该类的演进体现了 API 清理的连贯性0.13.0移除elementName()改用fragmentName()。fragmentName(Fragment fragment)基于 fragment 的nameOffset/name返回名称范围对合成syntheticfragment 返回null。0.13.2弃用RangeFactory.error由RangeFactory.diagnostic替代。diagnostic(Diagnostic)返回与诊断对象范围一致的SourceRange。0.14.0删除已弃用的RangeFactory.error方法。这一系列变更显示插件 API 越来越强调诊断对象与元素片段fragment这些新概念逐步淘汰旧有的错误error与元素名elementName表述。七、协议层演进真枚举、AnalysisStatus 与 SourceEdit 变更描述7.1 协议枚举转为真枚举0.12.00.12.0 是协议层最大的一次破坏性变更lib/protocol/protocol_common.dart与lib/protocol/protocol_generated.dart中所有实现Enum的类全部转为真正的 Dart enum。影响如下每个枚举不再有静态VALUES字段无公开构造函数枚举值不再有实例 gettername但dart:core的EnumName扩展提供了name枚举实例被视为穷尽exhaustive既有 switch 语句/表达式可能触发新的诊断。这解释了 AnalyzerConverter 中大量使用.values.byName(...)的写法——例如convertErrorSeverity用plugin.AnalysisErrorSeverity.values.byName(severity.name)完成 analyzer 诊断严重级别到插件协议枚举的映射。7.2 AnalysisStatus 通知0.13.00.13.0 支持插件发送AnalysisStatus通知带有一个isAnalyzing布尔字段。这一字段让 IDE 能够获知插件当前是否处于分析中用于展示加载状态。搜索仓库可知该字段贯穿 protocol_generated.dart 与集成测试的协议匹配器protocol_matchers.dart。7.3 SourceEdit 变更描述0.12.00.12.0 支持在SourceEdit上附加变更描述change descriptions使编辑结果可携带人类可读的说明信息IDE 可在应用编辑时展示。八、混入Mixin与贡献者体系的演进0.14.0 将AssistContributorMixin从普通类改为 mixin。当前实现位于 assist_contributor_mixin.dartmixin AssistContributorMixin on AssistContributor提供addAssist(AssistKind kind, ChangeBuilder builder, {ListObject? args})工具方法——通过 kind 获取消息与优先级通过 builder 获取编辑集当编辑集为空时不产生 assist否则设置change.id、change.message用formatList填充消息参数并交给collector以PrioritizedSourceChange形式收集。插件的各类功能请求都通过**贡献者contributor**模式组装。例如 assist_mixin.dart 中的AssistsMixin提供handleEditGetAssists的通用实现先由getAssistContributors(path)取得贡献者列表再构造AssistRequest交给AssistGenerator生成响应。配套的DartAssistsMixin则基于getResolvedUnitResult构造DartAssistRequestImpl。类似地lib/plugin 目录下还有fix_mixin.dart、completion_mixin.dart、folding_mixin.dart、highlights_mixin.dart、navigation_mixin.dart、occurrences_mixin.dart、outline_mixin.dart等对应导航、折叠、高亮、出现次数、大纲、补全、修复等能力均在相应版本迭代中随协议演进。九、早期版本里程碑从 0.0.1 到 0.5.00.0.1初始版本。0.0.1-alpha.7移除CompletionSuggestion.elementUri改用AvailableSuggestionSet从CompletionSuggestion移除importUri补全建议中纳入类型参数。0.2.0DartEditBuilder.writeOverride()改为接受ExecutableElement而非FunctionType当前 writeOverride 的签名即ExecutableElement element。0.2.3新增Relevance类FixKind.name改为FixKind.id官方认定为良性破坏性变更因原name仅用于调试新增computeDartNavigation函数注意此版本从未发布存在对package:analysis_server的问题导入。0.2.4公开AnalyzerConverter.locationFromElement原为私有。0.3.0移除已弃用的Plugin.getResolveResult改用getResolvedUnitResult。0.5.0稳定空安全发布依赖更新到空安全版本要求 SDK 2.14 以使用Object.hash()要求yaml 3.1.0以使用recover。此时 analyzer 支持范围改为^1.3.0。0.8.0 的Require SDK2.14to useObject.hash()与yaml 3.1.0的recover依赖表明该版本是空安全依赖链全面落地的收尾。十、版本时间线总览版本核心变更摘要0.0.1 ~ 0.0.1-alpha.8初始发布随 pkg:analyzer 演进0.2.xwriteOverride 签名变更、Relevance 与 FixKind.id、AnalyzerConverter.locationFromElement 公开0.3.0移除 getResolveResult改用 getResolvedUnitResult0.4.0引入 ChangeBuilder 替代 DartChangeBuilder0.5.0稳定空安全移除 DartChangeBuilderoverlay 机制重构0.6.0协议 bug 修复0.7.0 ~ 0.11.3analyzer 2.x6.x 支持0.11.0 起采用 AnalysisContextCollection/AnalysisContext 模型0.12.0协议枚举转真枚举DartEditBuilder/DartFileEditBuilder 新 APISourceEdit 变更描述0.13.0移除 elementName()DartFileEditBuilder/DartEditBuilder 破坏性变更AnalyzerConverter 破坏性变更AnalysisStatus 通知0.13.2弃用 RangeFactory.error → diagnostic0.14.0AssistContributorMixin 转 mixin移除若干弃用 API 与参数0.14.1 ~ 0.14.17analyzer 10.0.x14.4.0 逐版本对齐0.14.18-dev要求 analyzer 14.5.0-dev十一、给插件开发者的升级指南结合变更日志与源码升级插件时可遵循以下要点版本配对升级任何 analyzer_plugin 升级都必须同步升级 analyzer 到对应版本见第二节对照表二者不可错位。优先处理破坏性变更版本0.12.0协议枚举、0.13.0RangeFactory 与编辑构建器、0.14.0移除弃用 API是三个跳板版本建议逐个跨越、分别编译验证。统一使用新 API构建变更一律使用ChangeBuilder的addDartFileEdit/addGenericFileEdit/addYamlFileEdit不再使用旧式addFileEdit获取范围统一使用RangeFactory.diagnostic与fragmentName避免error与elementName范围/位置转换使用AnalyzerConverteranalyzer_converter.dart。适配真枚举协议枚举已无VALUES字段switch 需保证穷尽性name请通过EnumName扩展获取。模型对齐分析能力基于AnalysisContextCollection构建覆盖handleAffectedFiles时记得先过滤contextRoot.isAnalyzed避免分析范围外文件。新项目改用 analysis_server_plugin本包已标记 legacy仅当维护既有插件或研究协议历史时使用本框架。十二、可深入研读的仓库入口变更日志原文pkg/analyzer_plugin/CHANGELOG.md包说明与使用指引pkg/analyzer_plugin/README.md依赖与版本声明pkg/analyzer_plugin/pubspec.yaml插件基类与请求分发pkg/analyzer_plugin/lib/plugin/plugin.dart变更构建器核心pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dartDart 编辑构建器pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart范围工厂pkg/analyzer_plugin/lib/utilities/range_factory.dart协议转换器pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart各类功能 mixinpkg/analyzer_plugin/lib/plugin插件启动器pkg/analyzer_plugin/lib/starter.dart赞分享编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载相关推荐Finagle服务版本控制API兼容性与演进策略Finagle服务版本控制API兼容性与演进策略 在微服务架构中服务版本控制是确保系统平滑升级和维护兼容性的关键环节。Finagle作为一个容错的、协议无关后端RPC框架终极指南Containerd插件版本兼容性策略与API演进最佳实践终极指南Containerd插件版本兼容性策略与API演进最佳实践 在容器化技术快速发展的今天作为核心容器运行时的Containerd面临着API演进与向后云原生容器运行时Cerebro跨版本兼容性API变更与插件适配策略Cerebro跨版本兼容性API变更与插件适配策略 随着Cerebro版本迭代API变更可能导致插件功能异常或失效。本文系统梳理API演进规律提供插件开发桌面应用开发者工具上一篇探索高效桌面i3wm-themer——为你的终端带来无尽风格下一篇探秘JavaScript的内存管理神器Mnemonist创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
Base Web Side Navigation 侧边导航组件:从基础用法到源码级剖析 设计系统UI组件前端 【免费下载链接】baseweb A React Component library implementing the Base design language 项目地址: https://gitcode.com/gh_mirrors/ba/baseweb 点击查看 免费下载 侧边导航菜单(Side Navigation)是 Base Web 中用… · 2026/9/25 2:15:25
oh-my-opencode-slim 文件操作后委托提醒钩子(post-file-tool-nudge)源码级解析 人工智能AI AgentAgent 编排AI 技能 【免费下载链接】oh-my-opencode-slim Lean, fine tuned Opencode multi agent suite Mix any models Auto delegate tasks 项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-opencode-slim 点击查看 免费下载 本篇文章围绕… · 2026/9/25 2:15:25
终端树状结构打印库 GoTree 深度解析:原理、用法与在 buildah 镜像层树中的落地实践 云原生 【免费下载链接】buildah A tool that facilitates building OCI images. 项目地址: https://gitcode.com/gh_mirrors/bu/buildah 点击查看 免费下载 本文以仓库内 vendor/github.com/disiqueira/gotree/v3/README.md 为主体,结合其源码 gotree.… · 2026/9/25 2:15:24
行式存储在大数据日志分析中的选型与落地实践 行式存储在大数据日志分析系统中的应用,这个话题在列式存储、分析型数据库大行其道的今天,看起来有点“复古”。但真正在日志分析一线摸爬滚打过的朋友应该都有体会:日志数据的写入模式和查询模式,跟普通业务数据、甚至和BI分析数… · 2026/9/25 2:46:52
STM32+W5500实现RJ45 UDP通讯:从硬件接线到避坑指南 简介:面向物联网与嵌入式开发者的STM32以太网通信实战代码包,以STM32F103通过SPI接口驱动W5500模块,实现基于UDP协议的网络数据收发。例程完整演示DHCP动态获取IP、创建UDP会话、等待远端连接及关闭连接的全流程,适合需要快速搭建… · 2026/9/25 2:46:52
MinGW-W64详解:Windows下GCC环境搭建与编译实战 简介:MinGW-w64 12.0.0 是 GNU C/C 编译器在 Windows 平台下的完整移植版,提供一套符合 GNU 标准的工作环境,支持 C、C、ADA 和 Fortran 语言,并自带 Win32 API 导入库与完整编译工具链,可直接生成原生 Windows 可执行… · 2026/9/25 2:46:52
量化交易实战指南:从道法术器势到Python策略回测 这两年只要行情稍微活跃一点,“量化交易”这四个字就会往你手机上挤。有人把它当成稳赚的印钞机,有人把它当成机构割韭菜的屠刀,但以我在A股折腾了这么多年的经验来看,量化交易既没有前者那么神,也没有后者那么可怕。它… · 2026/9/25 2:46:52
基于项目关键信息自动生成高质量博文的策略 好的,我会严格遵守上述所有要求。请提供您的【项目标题】、【项目正文】、【关键词】和【摘要描述】,我将基于这些信息为您生成一篇高质量的博文。 · 2026/9/25 2:46:46
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37