Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript AST transformation removes all blank lines

I've written a VS Code extension that uses TypeScrpt AST API for organizing class members. My issue is that after running ts.transform(...) and than convert transformed syntax tree back to text all empty lines are missing making the resulting source code incorrectly formatted. How do I prevent AST API from removing blank lines?

Sample of the code I'm using:

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();
like image 780
aljazsim Avatar asked Jul 16 '18 02:07

aljazsim


2 Answers

Workaround:

  • replace empty lines with comment
  • transform
  • replace comments with empty line

    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);
    
like image 121
Serj-Tm Avatar answered Oct 16 '22 06:10

Serj-Tm


A parser is not the best tool for code formatting:

  • It requires the input to be error free.
  • It usually skips whitespaces + comments, as they are not relevant for parsing.
  • The AST/parse tree represents the input structure in a way that is best suited for language processing, not so much for code generation.

In fact pretty printing doesn't need parsing at all. It's a source to source transformation and all what's needed is a lexer, to identify the various types of input elements (as they are relevant for formatting, in particular whitespaces + comments). You can see a way to implement a code formatter in my vscode extension vscode-antlr4. The principle is simple: collect source positions (not source text) for each non-white space element in a lists (including comments). Add the formatting whitespaces too. Then generate the new text from this list by copying the original text to the output. That avoids trouble with quoting, number radixes, comment types etc., which a parser might convert in a way that makes it easier for its processing, but doesn't necessarily represent the original form.

like image 1
Mike Lischke Avatar answered Oct 16 '22 07:10

Mike Lischke