找出tsx脚本中未解析的标识符

时间:2018-06-20 06:55:04

标签: typescript abstract-syntax-tree tsx typescript-compiler-api

我目前正在为网络应用开发自定义生成器。 现在需要自动检测导入,因此我需要知道tsx源代码中的哪些标识符未解析,以便我的脚本可以导入正确的模块。

我目前正在研究的解决方案遍历脚本的AST,将声明的标识符存储在当前处理的范围中,然后返回未解析的标识符。但这需要对不同类型的AST元素进行不同处理的大量工作。

因此,既然tsc以及ts后台服务器都内置了这样的功能。我想知道是否有人可以告诉我他们是怎么做的,或者至少是在哪里做的,因为我找不到特定的的代码。

谢谢

路卡

1 个答案:

答案 0 :(得分:0)

我想我找到了一种解决方案。使用AST并不是那么容易,而且我很难解决一些情况,因为很难确定哪个标识符对当前范围有效。

所以我正在使用打字稿编译器来获取错误消息。过滤每个错误消息,并分析错误消息以获取标识符Name。这不是很漂亮,但是可以。我还看到,在诊断出带有错误的SourfeFileObjects之后,还包括了导出的标识符。我也需要those,但我直接通过AST来获取它们。

let compilerHost = {
    getSourceFile: (fname: string) => {...},
    writeFile: (name: string, text: string) => {...},
    getDefaultLibFileName: () => Path.join(__dirname, "node_modules/typescript/lib/lib.d.ts"),
    useCaseSensitiveFileNames: () => false,
    getCanonicalFileName: (fileName : string) => fileName,
    getCurrentDirectory: () => "",
    getNewLine: () => "\n",
    fileExists: (fname: string): boolean => {...},
    readFile: (fileName: string) => {...},
    directoryExists: (dname: string) => {...},
    getDirectories: () => []
};

let unresolved = []
let sourceFile = TS.createSourceFile(filepath, tsCode, TS.ScriptTarget.ES5, true, TS.ScriptKind.TSX);
let program = TS.createProgram([filepath], tsCompilerOptions, compilerHost);
let semanticDiagnostic = program.getSemanticDiagnostics();
if(semanticDiagnostic.length){
    unresolved = <string[]>semanticDiagnostic
        // Filter for Unresolved names
        .filter(m=>m.code == 2304 && m.file == this.sourceFile)
        .map(m=>{
            let matches = (m.messageText as string).match(/^Cannot find name '([A-Z]\w+)'.$/)
            if(matches){
                return matches[1];
            }
        })
        .filter(sym=>typeof(sym)=="string");
}