TypeScript API Factory.updatesourcefile,如何设置“ pos”并“结束”新声明(及其子节点)的成员?
I'm updating a sourceFile in a transform -
export function transformBefore(
absTsconfigPath: string
): ts.TransformerFactory<ts.SourceFile> | ts.CustomTransformerFactory {
return (ctx) => (sf) => {
const add:ts.Statement[]=[];
if (...){
add.push(...createSomeSyntheticStatements(ctx.factory))
}
if (!add.length) return sf;
const flags:ts.NodeFlags = sf.flags;
const sf1 = ctx.factory.updateSourceFile(
sf,ctx.factory.createNodeArray([...add,...sf.statements]));
ts.setSourceMapRange(sf1,
ts.getSourceMapRange(sf)); // no effect on pos,end of added nodes
const sf3 = visitorWalk(sf1,ctx); // no effect on pos,end of added nodes
return sf3;
}
It looks very much like the 2017 suggestion by Typescript's @weswigham
在调试器中查看我可以在Start sf3
上看到新节点,所有节点都具有pos
和结束
成员等于-1
代码>。
我想这不一定是一个问题,但是稍后,在之后的转换在同一文件上工作,调用node.getText()
导致例外情况深处打字稿。调试异常,我可以看到pos
和结束
成员仍然是-1
,并且在此类语句中,异常发生。
在没有前转换的情况下运行后转换时,也不例外。
我有一个预感,应该有一种方法来更新pos
和end
成员,但我不知道。这些都没有做到:
ctx.factory.createnodearray
ts.setsourcemaprange
(希望有副作用)- 普通的访问者步行呼叫
ts.foreachchild
递归也没有(侧)效应。
如何更新pos
和结束
成员?
(与此同时,避免在变换之后的后期中崩溃的解决方法是访问node.text
,而不是node.getText()
,因为node.text
具有正确的本地值,而node.getText()
似乎依赖于pos
和end 代码>要访问源文件全文,该文件不超出同步。)
更新:
我通过更新源文件尝试了另一种方法 使用其他函数ts.updatesourcefile
,而不是 ctx.factory.updatesourcefile
-
const oldText = sf.getFullText();
const newText = addedText + oldText;
// The function checkChangeRange in typescript.js code-documents the specs for TextChangeRange and newText
const textChangeRange:ts.TextChangeRange = {newLength:addedText.length,span:{start:0,length:0}};
const updatedSf = ts.updateSourceFile(sf,newText,textChangeRange,true);
return updatedSf;
调试器显示pos
和end end
已正确设置。 但是,在“成功”之后,Typescript继续执行自己的 在结果源文件上转换之前,但是当尝试访问符号数据时,它崩溃了。也许这是因为新源文件尚未被类型检查,因此没有符号数据。
I'm updating a sourceFile in a transform -
export function transformBefore(
absTsconfigPath: string
): ts.TransformerFactory<ts.SourceFile> | ts.CustomTransformerFactory {
return (ctx) => (sf) => {
const add:ts.Statement[]=[];
if (...){
add.push(...createSomeSyntheticStatements(ctx.factory))
}
if (!add.length) return sf;
const flags:ts.NodeFlags = sf.flags;
const sf1 = ctx.factory.updateSourceFile(
sf,ctx.factory.createNodeArray([...add,...sf.statements]));
ts.setSourceMapRange(sf1,
ts.getSourceMapRange(sf)); // no effect on pos,end of added nodes
const sf3 = visitorWalk(sf1,ctx); // no effect on pos,end of added nodes
return sf3;
}
It looks very much like the 2017 suggestion by Typescript's @weswigham here.
Looking in the debugger I can see the new nodes at the start sf3
all have pos
and end
members equal to -1
.
I guess that shouldn't necessarily be a problem, but later, in an after transform working on the same file, a call to node.getText()
results in an exception deep in Typescript. Debugging the exception I can see the pos
and end
members are still -1
, and on such a statement the exception occurs.
When running the after-transform without the before-transform, there is no exception.
I have a hunch there should be a way to update the pos
and end
member but I don't know it. None of these threee did it:
ctx.factory.createNodeArray
ts.setSourceMapRange
(hoping for side effect)- a plain visitor walk calling
ts.forEachChild
recursively also had no (side) effect.
How can the pos
and end
members be updated?
(In the meantime, a workaround to avoid a crash in the later after transform is to access node.text
instead of node.getText()
, because node.text
has the correct local value, while node.getText()
appears to rely on pos
and end
to access the source files full text, which is out of sync.)
UPDATE:
I tried a different approach by updating the source file
using a different function ts.updateSourceFile
, instead ofctx.factory.updateSourceFile
-
const oldText = sf.getFullText();
const newText = addedText + oldText;
// The function checkChangeRange in typescript.js code-documents the specs for TextChangeRange and newText
const textChangeRange:ts.TextChangeRange = {newLength:addedText.length,span:{start:0,length:0}};
const updatedSf = ts.updateSourceFile(sf,newText,textChangeRange,true);
return updatedSf;
The debugger showed that pos
and end
were correctly set.
However, following that "success", typescript continued to perform it's own before transforms on the resulting source file, but it crashed when trying to access symbol data. Perhaps this is because the new source file has not been type-checked, so there is no symbol data.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论