CodeBlanks Logo Icon CodeBlanks

Custom transformer

Kendi transformer'ını yazmayı öğrenirsin.

Custom transformer yazma

Kendi transformer'ını yazarken bir visitor fonksiyonu tanımlarsın. Visitor belirli düğümleri tanır ve onları ts.factory ile üretilen yeni düğümlerle değiştirir. Diğer düğümler için ts.visitEachChild ile alt düğümlere iner.

function visit(node: ts.Node): ts.Node {
  if (ts.isStringLiteral(node)) {
    return ts.factory.createStringLiteral("X");
  }
  return ts.visitEachChild(node, visit, context);
}

Visitor yeni bir düğüm döndürdüğünde o dal tamamen değiştirilir.

Düğüm değişimi ve visitEachChild

Bir düğümü değiştirmenin iki yolu vardır: tamamen yeni bir düğüm döndürmek veya ts.factory.updateX ile mevcut düğümün alanlarını güncellemek. visitEachChild bir alt düğüm değiştiğinde üst düğümü otomatik olarak yeni kopyasıyla günceller.

// identity için bile visitEachChild önerilir
return ts.visitEachChild(node, visit, context);

Uygulama String'leri "X" ile değiştir

const a = 'merhaba'; ve const b = 'dünya'; içeren bir kaynak oluştur. Bir transformer yaz: ts.isStringLiteral ile bulunan her StringLiteral düğümünü ts.factory.createStringLiteral("X") ile değiştir. ts.transform ile uygula ve sonucu Printer ile yazdır.

Başlangıç kodu

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

// Kaynak: const a = 'merhaba'; const b = 'dünya';
// SourceFile oluştur
// Bir transformer yaz: StringLiteral düğümlerini "X" ile değiştir
// transform ile uygula
// Printer ile sonucu yazdır

// kodunu buraya yaz

Örnek çözüm

index.ts
import ts from "typescript";

const sourceText = `const a = 'merhaba';\nconst b = 'dünya';`;
const sf = ts.createSourceFile("app.ts", sourceText, ts.ScriptTarget.Latest, true);

const transformer: ts.TransformerFactory<ts.SourceFile> = (context) => {
  function visit(node: ts.Node): ts.Node {
    if (ts.isStringLiteral(node)) {
      return ts.factory.createStringLiteral("X");
    }
    return ts.visitEachChild(node, visit, context);
  }
  return (node) => ts.visitEachChild(node, visit, context);
};

const result = ts.transform(sf, [transformer]);
const printer = ts.createPrinter();
process.stdout.write(printer.printFile(result.transformed[0] as ts.SourceFile));
result.dispose();

Beklenen çıktı

const a = "X";
const b = "X";

Soru ve cevaplar

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

1 Custom transformer'da bir düğümü değiştirmek için ne yaparsın?

  • program.getTypeChecker çağırırsın
  • Düğümün text özelliğini doğrudan değiştirirsin
  • Visitor fonksiyonunda yeni bir düğüm döndürürsün Doğru cevap
  • console.log ile düğümü yazdırırsın

Açıklama: AST düğümleri değişmezdir; text özelliğini değiştiremezsin. Visitor yeni bir düğüm döndürdüğünde o dal değiştirilir.

2 String literal değiştir

Soru
function visit(node: ts.Node): ts.Node {
  if (ts.isStringLiteral(node)) {
    return ts.factory.____("X");
  }
  return ts.visitEachChild(node, visit, context);
}
Cevap
function visit(node: ts.Node): ts.Node {
  if (ts.isStringLiteral(node)) {
    return ts.factory.createStringLiteral("X");
  }
  return ts.visitEachChild(node, visit, context);
}

Açıklama: createStringLiteral yeni bir StringLiteral düğümü üretir; createString factory'de yoktur, updateStringLiteral mevcut düğümü günceller (burada yeni düğüm istiyoruz).

3 Custom transformer parçaları

Kavram Anlamı
Visitor fonksiyonu Düğümleri tanır ve döndürür
ts.factory.createStringLiteral Yeni string düğüm üretir
ts.visitEachChild Alt düğümleri dönüştürür
ts.isStringLiteral Düğüm türünü sınar

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