菜单

重构和代码修复

相关源文件

本文档描述了 TypeScript 编译器用于自动代码转换的基础设施,主要包括代码修复(对诊断的快速修复)和重构(结构性代码更改)。有关诊断生成的信息,请参阅 诊断系统

概述

TypeScript 提供了两种主要的自动代码转换机制:

  1. 代码修复:对报告的错误和警告的自动修复,通常在编辑器中显示为带有灯泡图标的“快速修复”。
  2. 重构:用户发起的、保留行为的结构性代码转换。

这两种机制都围绕 ChangeTracker 类共享代码分析和源代码文本修改的通用基础设施,该类提供了一致的代码修改 API。

系统架构

来源:src/services/codefixes/fixAddMissingMember.ts158-185 src/services/refactors/extractSymbol.ts180-187

Change Tracker

ChangeTracker 是用于修改 TypeScript 源文件的核心实用类。它提供了结构化代码修改的方法,跟踪可应用于源文件的累积更改。

来源:src/services/textChanges.ts493-508 src/services/textChanges.ts528-564

核心操作

ChangeTracker 提供了丰富的代码修改操作:

类别方法描述
删除deletedeleteNodedeleteRange删除节点或范围
替换replaceNodereplaceRangereplaceNodeWithNodes用新内容替换节点
插入insertNodeAtinsertNodeBeforeinsertNodeAfter在不同位置插入新节点
专业insertNodeAtConstructorStartinsertMemberAtStartinsertNodeAtEndOfScope上下文感知的插入

每个操作都会在内部跟踪系统中创建一个更改,而 getChanges() 将所有累积的更改作为 FileTextChanges 对象返回。

来源:src/services/textChanges.ts524-656

Change Options

Operations accept various options to control how changes are applied

  1. Position Adjustment Options:

    • LeadingTriviaOption: Controls handling of whitespace and comments before nodes
    • TrailingTriviaOption: Controls handling of whitespace and comments after nodes
  2. Insert Node Options:

    • prefix: Text to insert before the new node
    • suffix: Text to insert after the new node
    • indentation: Formatting indentation level

来源:src/services/textChanges.ts204-241 src/services/textChanges.ts282-300

代码修复

代码修复是编译器报告的特定诊断的自动化解决方案。每个代码修复都会注册其能够处理的诊断代码,并提供修复这些错误的逻辑。

注册和结构

来源:src/services/codefixes/fixAddMissingMember.ts158-251

每个代码修复提供程序都实现了:

  1. getCodeActions:返回特定诊断实例的修复建议
  2. getAllCodeActions:实现“全部修复”功能,以处理所有类似的 issues

示例:修复缺失成员

一个常见的代码修复是处理引用但不存在的属性或方法的错误。该修复会在类或接口中添加缺失的成员。

来源:src/services/codefixes/fixAddMissingMember.ts158-166 src/services/codefixes/fixAddMissingMember.ts185-251

重构

重构是用户发起的更复杂的代码转换,通常用于代码重组而不是错误修复。与代码修复不同,重构不与特定的错误诊断相关联。

注册和结构

来源:src/services/refactors/extractSymbol.ts180-187 src/services/refactors/extractSymbol.ts195-343

每个重构实现:

  1. getAvailableActions:确定重构在当前上下文中是否可用
  2. getEditsForAction:在请求时执行实际的转换

示例:提取到函数/常量

Extract Symbol 重构允许将选定的代码提取到函数或常量中。

来源:src/services/refactors/extractSymbol.ts168-187 src/services/refactors/extractSymbol.ts195-343

辅助基础设施

代码修复和重构都利用了几个辅助系统来简化实现并确保一致性:

1. 类型构造上下文

提供从现有类型构建 TypeScript 类型和类型节点的方法。

来源:src/services/codefixes/helpers.ts153-158 src/services/codefixes/helpers.ts129-145

2. Import Management

在代码重构中,确保正确的导入是一个常见的挑战。ImportAdder 助手用于管理导入的跟踪和插入。

来源:src/services/codefixes/helpers.ts607-617

通用模式和技术

1. Extract-Analyze-Transform Pattern

大多数代码修复和重构都遵循此模式:

  1. Extract:获取有关代码和上下文的信息(位置、错误等)。
  2. Analyze:确定转换是否可以应用以及如何应用。
  3. Transform:使用 ChangeTracker 应用转换。

2. Range and Position Management

处理源范围需要仔细处理空格和注释。该系统提供了精确控制范围如何调整的选项。

来源:src/services/textChanges.ts204-241 src/services/refactors/extractType.ts348-366

3. 支持“全部修复”

代码修复通常需要支持“全部修复”操作。一种常见的模式是

  1. 跟踪已处理的节点/符号以避免重复
  2. 对使用相同代码路径的所有实例应用相同的修复

来源:src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts45-55

结论

TypeScript 的重构和代码修复系统为自动代码转换提供了强大的基础。通过使用 ChangeTracker 在注册、分析和转换方面的一致模式,它能够实现各种代码修复和重构,同时确保高质量、一致的代码修改。