Легко создать SoureFile
объект из простой строки:
ts.createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind)
Однако я не вижу способа создать объект из массива Statement
-узлов (созданных различные фабричные функции).
Я пытался найти решение, подобное этому:
const source = ts.createSourceFile(fileName, '', languageVersion);
source.statements = myNodeArray;
Но это (возможно, неудивительно) не работает. Я также попытался (ab) использовать API-интерфейс преобразователя следующим образом:
function createSourcefile(filename: string, ast: ts.Node[], languageVersion: ts.ScriptTarget): ts.SourceFile {
const dummy = ts.createSourceFile(filename, 'dummy', languageVersion); // need at least 1 node
return ts.transform(
dummy,
[ transformContext => sourceFile => ts.visitEachChild(sourceFile, node => ast, transformContext) ]
).transformed[0];
}
Но, похоже, это тоже не работает.
При обоих методах я получаю следующую ошибку во время emit
process:
Error: start < 0
at createTextSpan (node_modules\typescript\lib\typescript.js:10263:19)
at Object.createTextSpanFromBounds (node_modules\typescript\lib\typescript.js:10272:16)
at getErrorSpanForNode (node_modules\typescript\lib\typescript.js:13544:19)
at createDiagnosticForNodeInSourceFile (node_modules\typescript\lib\typescript.js:13449:20)
at Object.createDiagnosticForNode (node_modules\typescript\lib\typescript.js:13440:16)
at lookupOrIssueError (node_modules\typescript\lib\typescript.js:34976:22)
at addDuplicateDeclarationError (node_modules\typescript\lib\typescript.js:35177:23)
at \node_modules\typescript\lib\typescript.js:35173:17
at Object.forEach (node_modules\typescript\lib\typescript.js:317:30)
at addDuplicateDeclarationErrorsForSymbols (node_modules\typescript\lib\typescript.js:35171:16)
at mergeSymbol (node_modules\typescript\lib\typescript.js:35158:21)
at \node_modules\typescript\lib\typescript.js:35200:47
at Map.forEach (<anonymous>)
at mergeSymbolTable (node_modules\typescript\lib\typescript.js:35198:20)
at initializeTypeChecker (node_modules\typescript\lib\typescript.js:66463:21)
at Object.createTypeChecker (node_modules\typescript\lib\typescript.js:34935:9)
at getDiagnosticsProducingTypeChecker (node_modules\typescript\lib\typescript.js:98560:93)
at emitWorker (node_modules\typescript\lib\typescript.js:98588:32)
at \node_modules\typescript\lib\typescript.js:98569:66
at runWithCancellationToken (node_modules\typescript\lib\typescript.js:98665:24)
at Object.emit (node_modules\typescript\lib\typescript.js:98569:20)
*snip*
Есть ли способ заставить это работать?
Полагаю, я теоретически мог бы использовать принтер для преобразования AST в строку , но это, очевидно, было бы огромной тратой.
Я сделал gist с автономным примером с использованием "виртуального хоста компилятора" и предложение Дэвида Шеррета по удалению диапазона.
Как ни странно, я обнаружил, что эта ошибка возникает не для всех типов узлов. В моем (ограниченном) тестировании я столкнулся с этим, только когда AST содержал ImportDeclaration
узел.