microsoft / microsoft/TypeScript

feat(contentmapper): support whole-symbol rename edit projection

未关闭
#63,879 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Suggestion
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
132

描述

Problem

Content Mapper protocol v1 cannot safely rename one semantic symbol when generated and authored spellings differ.

A Vue mapper, for example, needs to project this authored listener:

<Child @save-item="handler" />

to a TypeScript reference to the child's saveItem declaration. A protocol Atom correctly maps the whole generated saveItem span to the whole authored save-item span and works for hover, definition, and references. Rename still fails closed even when the Atom advertises FeatureRename.

At bddd2162710e50281fa838456a875fd59ee7c91f (the Content Mappers PR microsoft/typescript-go#4712 head):

  • GetRenameInfo skips every mapped input whose fidelity is not exact.
  • getRenameInfoSuccess rejects a non-exact trigger span.
  • renameEditRange skips every mapped occurrence whose writeback is not exact.
  • the fourslash contract explicitly verifies that Atom origins cannot be renamed.

Changing the projection to verbatim "save-item" is not equivalent: TypeScript then sees a different property symbol, so definition/reference navigation no longer reaches the child saveItem declaration. It also cannot express the required per-occurrence replacement: renaming to semantic nextItem must write next-item in the template and nextItem in the TypeScript-shaped declaration.

Requested design

Please add a safe whole-symbol edit projection mechanism for Content Mappers. Two possible shapes:

  1. A mapper RPC that receives the complete rename transaction (semantic replacement plus generated/original spans) and returns validated authored text edits.
  2. A declared per-segment edit codec/strategy that can map a semantic replacement in both directions for whole-symbol Atom or Alias segments.

The contract should:

  • allow prepare-rename from a single whole-symbol Atom without pretending it has verbatim geometry;
  • transform each reference's replacement according to its authored spelling;
  • validate bounds, overlap, URI ownership, and document versions before returning one atomic workspace edit;
  • fail closed if any required occurrence cannot be projected exactly;
  • never return edits targeting generated documents;
  • preserve the existing exact-only behavior for ordinary Atom segments without an edit projection;
  • clarify whether FeatureRename is valid on Atom segments in protocol v1, since it is currently accepted by validation but cannot make rename succeed.

Acceptance test

Given a child declaration named saveItem and parent usages authored as both @saveItem and @save-item:

  • rename from any character of either parent usage updates the child declaration and all parent usages;
  • rename from the child declaration updates all parent usages;
  • semantic replacement nextItem writes valid camel/kebab spellings at the corresponding sites;
  • semantic or authored replacement input with kebab casing has a defined, deterministic normalization policy;
  • hover, definition, and references retain their current Atom fidelity;
  • no approximate (0, 0) or generated-file edit is returned.

This is not Vue-specific: template languages commonly normalize casing, prefixes, or sigils while keeping one semantic symbol.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

先从 GetRenameInfo、getRenameInfoSuccess 和 renameEditRange 开始,然后阅读现有的 fourslash contract,该 contract 用于验证 Atom origin 无法被重命名。将提议的两种 projection shape 与 Content Mappers PR 的行为和 acceptance test 进行比较。完成标准是:atomic edit 支持整个 symbol 的 Atom 或 Alias occurrence,且不编辑生成文件,同时在其他情况下保持 exact-only 行为。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
tooling
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
冷清
描述清晰度
基本清楚
新手友好度
32/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。