Search code examples
typescriptabstract-syntax-treestatic-analysistypescript-compiler-api

Is it possible to get comments as nodes in the AST using the typescript compiler API?


I would like to extract the comments from a typescript source file, preferably with their line numbers. I tried doing it like this:

var program = ts.createProgram(files, {
    target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS, removeComments: false
});
ts.forEachChild(sourceFile, visit);

function visit(node) {
    if (node.kind == ts.SyntaxKind.SingleLineCommentTrivia){
        //print something
    }
    ts.forEachChild(node, visit);
}

In fact, when I printed all the nodes' text, I could see that the comments were discarded entirely. The input source code I used for testing is:

//test comment
declare namespace myLib {
    //another comment
    function makeGreeting(s: string): string;
    let numberOfGreetings: number;
}

Solution

  • It's not possible to get comments as nodes but it is still possible to get comments from the source file. The function to use is getLeadingCommentRanges(text: string, pos: number).

    I used it like this:

    for(var sourceFile of program.getSourceFiles()){
            ts.forEachChild(sourceFile, visit);
        }
    
    function visit(node: ts.Node){
        const commentRanges = ts.getLeadingCommentRanges(
            sourceFile.getFullText(), 
            node.getFullStart());
        if (commentRange?.length)
            const commentStrings:string[] = 
              commentRanges.map(r=>sourceFile.getFullText().slice(r.pos,r.end))
    }
    

    NOTE: sourceFile.getFullText() does not skip leading comments, and sourceFile.getText() does skip leading comments. Using .getText in the above usage case is apparently a common source of errors.