CodeBlanks Logo Icon CodeBlanks

Code fix

Code fix sağlayıcısını yazarsın.

CodeFixAction yapısı

Bir ts.CodeFixAction nesnesi fixName (fix kimliği), description (kullanıcı açıklaması) ve changes (dosya değişiklikleri) alanlarını taşır. changes bir FileTextChanges[]'dir; her eleman bir dosya için textChanges dizisi içerir.

const fix: ts.CodeFixAction = {
  fixName: "add-any",
  description: "Add type annotation",
  changes: [{
    fileName,
    textChanges: [
      { span: { start, length: 0 }, newText: ": any" }
    ],
  }],
};

getCodeFixesAtPosition

Dil servisinde code fix sağlayan metod getCodeFixesAtPosition'dır. Dosya adı, pozisyon aralığı ve hata kodları alır, CodeFixAction[] döndürür. Plugin içinde bu metodu sarıp ek fix'ler üretirsin.

getCodeFixesAtPosition: function(fileName, start, end) {
  const prior = ls.getCodeFixesAtPosition(fileName, start, end);
  // ek fixes üret
  return [...prior, ...fixes];
};

Uygulama Code fix sağla

Bir plugin yaz: getCodeFixesAtPosition'ı sar. Önce ls'nin fixes'ini al (prior). SourceFile'ı al. AST'yı gez: tür eklemesi olmayan VariableDeclaration düğümleri için bir ts.CodeFixAction üret (fixName: "add-any"). textChanges ile değişken adının sonuna : any ekle. prior ve fixes'i birleştir. Test: kaynak let x = 1;; ilk fix'in fixName'ini yazdır.

Başlangıç kodu

index.ts
import * as ts from "typescript";

// Bir plugin yaz: Code fix metodunu sar
// - Önce ls'nin fixes'ini al (prior)
// - SourceFile'ı al
// - AST'yı gez: tür eklemesi olmayan VariableDeclaration bul
// - Her biri için bir CodeFixAction üret (fixName: "add-any")
// - Metin değişikliği ile ": any" ekleme tanımla
// - prior ve fixes'i birleştir
// Test yaz ve ilk fix'in adını yazdır.

// kodunu buraya yaz

Örnek çözüm

index.ts
import ts from "typescript";

function createPlugin(info: ts.server.PluginCreateInfo): ts.LanguageService {
  const ls = info.languageService;
  return {
    ...ls,
    getCodeFixesAtPosition: function(fileName: string, start: number, end: number, errorCodes: readonly number[], formatOptions: ts.FormatCodeSettings, preferences: ts.UserPreferences) {
      const prior = ls.getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences);
      const sf = ls.getProgram().getSourceFile(fileName);
      if (!sf) return prior;
      const fixes: ts.CodeFixAction[] = [];
      function visit(node: ts.Node) {
        if (ts.isVariableDeclaration(node) && !node.type) {
          fixes.push({
            fixName: "add-any",
            description: "Add type annotation",
            changes: [{
              fileName,
              textChanges: [{ span: { start: node.name.getEnd(), length: 0 }, newText: ": any" }],
            }],
          });
        }
        ts.forEachChild(node, visit);
      }
      visit(sf);
      return [...prior, ...fixes];
    },
  };
}

const sf = ts.createSourceFile("app.ts", "let x = 1;", ts.ScriptTarget.Latest, true);
const fakeLs = {
  getCodeFixesAtPosition: function() { return [] as ts.CodeFixAction[]; },
  getProgram: function() { return { getSourceFile: function(n: string) { return n === "app.ts" ? sf : undefined; } } as unknown as ts.Program; },
} as unknown as ts.LanguageService;

const info = { languageService: fakeLs, config: {} } as unknown as ts.server.PluginCreateInfo;
const plugin = createPlugin(info);
const fixes = plugin.getCodeFixesAtPosition("app.ts", 0, 1, [], {} as ts.FormatCodeSettings, {} as ts.UserPreferences);
console.log(fixes[0].fixName);

Beklenen çıktı

add-any

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Bir CodeFixAction'ın changes alanı ne içerir?

  • Tek bir metin değişikliği
  • Dosya değişiklikleri (FileTextChanges[]) Doğru cevap
  • Diagnostic listesi
  • Kaynak dosya metni

Açıklama: changes alanı bir FileTextChanges[] taşır; her eleman bir dosya için textChanges dizisi içerir. Tek metin değişikliği, diagnostic listesi veya kaynak dosya metni değildir.

2 Fix adı

Soru
fixes.push({
  ____: "add-any",
  description: "Add type annotation",
  changes: [{ fileName, textChanges: [{ span: { start: node.name.getEnd(), length: 0 }, newText: ": any" }] }],
});
Cevap
fixes.push({
  fixName: "add-any",
  description: "Add type annotation",
  changes: [{ fileName, textChanges: [{ span: { start: node.name.getEnd(), length: 0 }, newText: ": any" }] }],
});

Açıklama: CodeFixAction.fixName fix'in kimliğini taşır; name, id ve fixId CodeFixAction üzerinde yoktur.

3 Code fix parçaları

Kavram Anlamı
fixName Fix kimliği
description Kullanıcı açıklaması
changes Dosya değişiklikleri
textChanges Metin değişiklikleri

Uzman bölümündeki tüm dersler