编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载本文档是 Dart Analysis Server 内部关于重构Refactor功能的设计说明原文见 pkg/analysis_server/doc/design/features/refactors.md它界定了 analysis_server 中所有代码修改类操作的分类方式、语义保持的取舍原则以及生成代码的工程规范。阅读本文后你将理解编辑器里灯泡quick fix / assist / refactor背后的统一架构Fix、Assist、Global Refactor 三类操作的差异与 UX 影响服务端在何种情况下允许改变代码语义以及生成代码时应遵循的风格与不完整代码处理策略并能结合仓库源码定位到具体的实现位置。从协议入口看 Refactor 的定位Refactor 是用户可以从编辑器中选择执行、从而修改代码的动作。在 Analysis Server 中这类能力通过两套协议暴露LSP 协议通过textDocument/codeActions请求提供对应 LSP 3.17 规范原文以链接形式引用Legacy 协议通过edit.getAssists、edit.getAvailableRefactorings、edit.getFixes、edit.getRefactoring四个请求提供。在 LSP 实现侧可以找到这些请求对应的处理链例如 pkg/analysis_server/lib/src/lsp/handlers/code_actions/abstract_code_actions_producer.dart 中即围绕textDocument/codeAction请求组织 code action 的产出与优先级。虽然用户倾向于把所有重构都看成同一件事但服务器内部将其划分为三类。这种划分部分源于实现层面的考量更重要的是因为三类操作在**用户体验UX**上有着不同的含义与影响。划分依据两个特征维度三类重构的分类基于重构的两个特征编辑创建时间edit creation timeEager Refactor即时重构在 code action 返回之前就完成代码变更的计算。如果无法计算出代码编辑则该 code action 根本不会返回。这样能保证只要用户选中该操作编辑就能成功应用。Lazy Refactor惰性重构返回 code action 时并不计算具体的代码编辑。通常只做一组最小化的检查确保仅在重构有意义时才显示该操作但用户选中后仍可能失败。此类失败场景下服务器会显示一条消息向用户解释失败原因。可用性availability部分重构仅在存在诊断diagnostic指示问题时才可用另一些重构只要编辑器选区位于恰当的 token 上就始终可用无论是否有诊断。三种重构类型Fixes修复Fixes 是用于解决代码中由诊断所指示问题的代码变更始终以 eager 方式计算。Fixes 可以被触发用于修复单个文件中单个位置上的单个诊断修复单个文件中某个诊断报告的所有位置修复工作区所有文件中全部诊断的所有位置通过dart fix以及基于 LSP 的 IDE。在仓库中Fix 的实现集中在 pkg/analysis_server/lib/src/services/correction/fix.dart及其fix_internal.dart具体到每个诊断的修复产出于 pkg/analysis_server/lib/src/services/correction/dart/ 目录下——该目录包含数百个以行为命名的修复生产者例如remove_unused_import.dart移除未使用导入、add_null_check.dart添加空检查、convert_to_switch_expression.dart转换为 switch 表达式等。跨文件的批量修复由 pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart 负责调度这正是dart fix命令在命令行侧的对应实现。Assists辅助操作Assists 是即使没有诊断也始终可用的代码变更始终以 eager 方式计算。Assists 只能在单个文件的单个位置触发。Assist 的统一入口位于 pkg/analysis_server/lib/src/services/correction/assist.dart以及assist_internal.dart。由于不依赖诊断Assists 的可用性完全取决于编辑器选区所在的代码上下文例如将if-else转换为条件表达式、提取局部变量等操作在无错误代码上同样可以被触发。Global Refactors全局重构Global Refactors 是可能涉及多个库、甚至跨多个 package 变更的代码重构当这些 package 同时打开在 IDE 工作区中时。Global Refactors始终以 lazy 方式计算。Global Refactors 只能在单个文件的单个位置触发。全局重构的实现框架位于 pkg/analysis_server/lib/src/services/refactoring/framework/其中refactoring_processor.dart 负责重构的整体执行流程refactoring_producer.dart 定义重构生产者refactoring_context.dart 封装触发重构时的上下文信息。具体的全局重构如移动顶层声明到新文件move_top_level_to_file.dart、重命名相关的add_import_prefix.dart/remove_import_prefix.dart等则放在 pkg/analysis_server/lib/src/services/refactoring/ 目录下。术语提醒在很多语境下例如 issue tracker 中术语 refactor 有时泛指任意类型的重构有时又特指 global refactor。本文档统一使用更长的名字以保持清晰。语义保持Preserving Semantics对于重构是否应该改变代码语义文档明确表示没有一刀切的禁令——有些重构正是因为改变了语义才有价值。甚至可以论证大多数 Fix 都在改变语义把代码从无法编译变为可编译本身就是语义变化。本节讨论的是一组判断准则用于决定何时应当保持语义、何时允许改变语义。用户期望User Expectations首先要问的问题用户在多大程度上会合理地期望语义被保持合理假设保持语义的例子把switch 语句转换为 switch 表达式的重构用户会期望它保持 switch 的语义。合理期望语义发生变化的例子把方法标记为async并把返回类型改为Future的重构用户能预期到这会改变代码语义。微妙 vs. 明显的变化Subtle vs. Obvious Changes如果某个重构将改变代码语义那么这种改变应当对用户显而易见。语义变化越微妙就越不适合让语义发生改变。例如合适把方法转换为async的 assist——虽然改变了语义但因为返回类型被修改、新增了关键字改变非常容易看见对应实现见 pkg/analysis_server/lib/src/services/correction/dart/add_async.dart。不合适一种会改变查找作用域、使得某些标识符在没有任何提示的情况下被解析到不同目标的修改——这种变化过于微妙。此外作用范围也影响判断若 Fix 只在单个位置应用语义变化通常更明显若 Fix 在大型代码库中批量应用语义变化可能很容易被忽略因为受影响的文件可能根本没有被打开用户看不到变化。产出损坏代码Producing Broken Code几乎不存在如果有的话合理的理由让重构产出无法编译的代码。但存在两个已知例外作用于已损坏代码的重构某些重构会作用在本来就无法编译的代码上此时结果仍然损坏是合理的——只要没有坏得更厉害。但通常不应由重构引入新的诊断到代码中。客户端明确告知且用户确认继续如果客户端允许服务器向用户通报当前状况并且用户明确表示希望继续那么继续执行重构是有意义的。生成代码Generated Code大多数重构在运行时会生成代码。本节描述生成代码时应遵循的工程实践而遵循这些实践的最佳方式之一就是使用DartFileEditBuilder和DartEditBuilder类中定义的工具方法来生成代码。这两个类位于 pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart实现位于 pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart。从实现可以看到DartEditBuilderImpl会依据CodeStyleOptions由启用的 lint 推导决定生成代码的细节例如是否在dynamic类型处写明类型注解对应always_specify_types等 lint见shouldWriteDynamicNonReturnTypes/shouldWriteDynamicReturnTypes的判定逻辑提供addLinkedEdit、canWriteType、createLinkedEditBuilder等能力支持生成带关联编辑linked edit的代码片段。这从源码层面印证了文档生成的代码应尽量遵循已启用 lint 所强制执行的风格这一要求。风格Style生成的代码应尽可能接近用户可能亲手写出的代码。例如如果认为用户更可能写带块体的方法而不是表达式体方法那么生成方法时应产出块体同样如果认为大多数用户在返回Future的方法上会使用async生成时应包含该修饰符。生成的代码应尽可能遵循已启用 lint 所强制执行的风格。例如若启用了强制统一字符串字面量定界符的 lint则生成的所有字符串字面量都应使用该定界符。生成的代码应在格式上接近 formatter 的输出。服务器会合理尝试生成带恰当缩进和 token 间空格的代码但不需要包含自动换行、刻意添加或省略的逗号等。一旦未来获得对文件局部区域运行 formatter 的能力就应该对生成代码使用 formatter。不完整代码Incomplete Code有时生成不完整代码是必要的。例如根据一个示例调用生成方法时服务器可以推断出参数的数量与类型、甚至返回类型但无法知道方法体该如何实现。生成不完整代码时应尽量让代码不完整这一事实显而易见有两种做法生成带编译错误的代码在生成代码中附带TODO注释。例如生成一个需要返回值的方法时可以选择生成返回null的代码。但如果返回类型本身可空就不会有任何信号提示该方法是不完整的——这种情况下更好的选择是生成一个不返回值的方法从而产生编译错误作为信号。一个反例当服务器生成对某个具体方法的 override 时会添加对被覆盖方法的super 调用。如果原方法有返回值则返回被覆盖方法的返回值——这样代码没有任何诊断因此服务器会补上一个TODO注释。同时代码保持了语义等价。这看似违反了上面的建议但严格来说这段代码并非不完整只是通常不是用户真正想写的内容。这类补齐 override的逻辑可在 pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart 等生产者中查看其实现形态。小结Analysis Server 的重构体系可以用一张表概括维度FixesAssistsGlobal Refactors是否依赖诊断依赖由诊断触发不依赖选区在合适 token 上即可不依赖选区在合适 token 上即可编辑计算方式Eager返回前算好Eager返回前算好Lazy选中后才计算可能失败作用范围单位置 / 单文件全部位置 / 全工作区dart fix单文件单位置多库、跨 package但触发点仍是单文件单位置语义保持允许改变如修复编译错误但变化需可感知默认保持变化需明显由具体重构决定需在 UX 上可感知无论哪一类其共同的工程底线是尽量不产出比原来更坏的代码、不引入新的诊断生成代码时贴近用户习惯、贴近 lint 与 formatter 的约束必要的不完整代码必须给出显式信号编译错误或 TODO 注释。理解了这套分类与准则无论是阅读 pkg/analysis_server/lib/src/services/correction/dart/ 下数百个修复/辅助生产者的源码还是自己为 Analysis Server 或分析器插件编写新的 code action都能快速定位其定位与应遵守的规则。赞分享编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载相关推荐PhoneInfoga 实战指南scan 命令行扫描与 Web 服务部署PhoneInfoga 实战指南scan 命令行扫描与 Web 服务部署 PhoneInfoga 是一个面向电话号码的信息收集OSINT框架其核心使用方编程语言编译器语言运行时标准库开发工具OBS Studio 代码风格规范深度解读clang-format 强制规则、各语言守则与架构设计准则OBS Studio 代码风格规范深度解读clang format 强制规则、各语言守则与架构设计准则 OBS Studio 的 CODESTYLE.md h音视频直播屏幕录制桌面应用视频Dart Analysis Server 的 Sort Members 命令成员排序规则与源码实现深度解析Dart Analysis Server 的 Sort Members 命令成员排序规则与源码实现深度解析 Sort Members排序成员是 Dart编程语言编译器语言运行时标准库开发工具上一篇GetQzonehistory5分钟快速导出QQ空间历史说说完整指南下一篇终极指南如何用ChoEazyCopy图形化工具简化Windows文件复制备份创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
C语言01:初识C程序的结构 文章目录前言1.第一个C程序1.1 #include <stdio.h>1.2 int main()1.3 printf("Hello,C Language!");1.4 return 0;前言 本文的目标是:看懂一个 C 程序的每一行是干什么的 如果你也是刚学 C 语言的新手,跟着我一行一行拆解,保… · 2026/9/24 16:27:16
drawio-desktop 免费打开编辑 VSDX 文件的安装与使用指南 drawio-desktop 免费打开编辑 VSDX 文件的安装与使用指南 【免费下载链接】drawio-desktop Official electron build of draw.io 项目地址: https://gitcode.com/GitHub_Trending/dr/drawio-desktop
老 Visio 的 .vsdx 文件打不开、又用不上 Visio?drawio-de… · 2026/9/24 16:27:16
第24篇-MCP-Client架构-Host应用如何管理多个Server连接 【MCP 全栈教程】第 24 篇:MCP Client 架构——Host 应用如何管理多个 Server 连接 本系列定位:从协议原理到 Server 开发、Client 开发、再到各大平台实战集成,系统化掌握 MCP(Model Context Protocol)全栈技术体系。… · 2026/9/24 17:01:59
第21篇-MCP-Server测试-MCP-Inspector与自动化测试 【MCP 全栈教程】第 21 篇:MCP Server 测试——MCP Inspector 与自动化测试 本系列定位:从协议原理到 Server 开发、Client 开发、再到各大平台实战集成,系统化掌握 MCP(Model Context Protocol)全栈技术体系。 本篇你… · 2026/9/24 17:01:59
OneNote 笔记如何备份才不丢数据:3 种方案完整保姆级攻略 OneNote 笔记如何备份才不丢数据:3 种方案完整保姆级攻略 【免费下载链接】cs-408 计算机考研专业课程408相关的复习经验,资源和OneNote笔记 项目地址: https://gitcode.com/GitHub_Trending/cs/cs-408
用 OneNote 攒了几个月笔记,某次… · 2026/9/24 17:01:59
使用 AWS SDK for C++ 编写 Hello SNS:通过 ListTopics 入门 Amazon SNS 示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地… · 2026/9/24 17:01:53
Visual Explainer Quick 模式深度指南:用紧凑 JSON Spec 一键渲染自包含 HTML 可视化页面 【免费下载链接】visual-explainer Agent skill that generates rich HTML pages or slide decks for diagrams, diff reviews, plan audits, data tables, and project recaps 项目地址: https://gitcode.com/gh_mirrors/vi/visual-explainer 点击查看 免费下载 Q… · 2026/9/24 17:01:53
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44