【问题标题】:TypeScript AST transformation removes all blank linesTypeScript AST 转换删除所有空行
【发布时间】:2018-12-23 12:55:47
【问题描述】:

我编写了一个 VS Code 扩展,它使用 TypeScrpt AST API 来组织类成员。我的问题是,在运行 ts.transform(...) 并将转换后的语法树转换回文本之后,所有空行都丢失了,从而导致生成的源代码格式不正确。如何防止 AST API 删除空行?

我正在使用的代码示例:

let sourceFile: ts.SourceFile;
let sourceCode: string;

sourceCode = editor.document.getText();
sourceFile = ts.createSourceFile(editor.document.fileName, sourceCode, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
  transformation = ts.transform(sourceFile, [organizeTransformer]);
  sourceCode = transformation.transformed[0].getFullText();

【问题讨论】:

  • 欢迎来到“保真”打印 AST 的问题。如果 typescript 引擎的输出逻辑没有准备好保留源格式,那么你会得到这种行为。 (它会保留 cmets 吗?)见 stackoverflow.com/a/5834775/120163
  • 是的,cmets 还在。就是这样。我真的不明白为什么有些琐事会被保留,而另一些则不会。
  • 这是解析为 AST 的副作用;它必须记录足够的琐事以使原始文本几乎可以完美地复制,包括垂直空白。 (在实践中,[几乎]没有人关心你是否复制水平空白的内容,除非你的制表符设置不是通用标准)。

标签: typescript visual-studio-code abstract-syntax-tree vscode-extensions


【解决方案1】:

解决方法:

  • 用注释替换空行
  • 变换
  • 用空行替换 cmets

    import {decodeEmptyLines, encodeEmptyLines} from 'ts-empty-line-encoder';
    
    let sourceCode = editor.document.getText();
    //encode empty lines
    sourceCode = encodeEmptyLines(sourceCode);
    const sourceFile = ts.createSourceFile(editor.document.fileName, sourceCode, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
    const transformation = ts.transform(sourceFile, [organizeTransformer]);
    sourceCode = transformation.transformed[0].getFullText();
    //decode empty lines
    sourceCode = decodeEmptyLines(sourceCode);
    

【讨论】:

    【解决方案2】:

    解析器并不是代码格式化的最佳工具:

    • 它要求输入没有错误。
    • 它通常会跳过空格 + cmets,因为它们与解析无关。
    • AST/解析树以最适合语言处理的方式表示输入结构,而不是代码生成。

    事实上,漂亮的打印根本不需要解析。它是源到源的转换,只需要一个词法分析器来识别各种类型的输入元素(因为它们与格式化相关,特别是空格 + cmets)。您可以在my vscode extension vscode-antlr4 中看到一种实现代码格式化程序的方法。原理很简单:为列表(包括 cmets)中的每个非空白元素收集源位置(不是源文本)。也添加格式化空格。然后通过将原始文本复制到输出来从此列表中生成新文本。这避免了引用、数字基数、注释类型等方面的麻烦,解析器可能会以一种更易于处理的方式进行转换,但不一定代表原始形式。

    【讨论】:

    • 那是我的 B 计划,但我想看看这是否可以完全通过使用 AST 来完成。我设法让它工作,除了新线。
    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    相关资源
    最近更新 更多