问题描述
我创建了一个遍历AST并更改来自的数组调用的打字稿转换器
myArr.push(el)
至Array.prototype.push.call(myArr,args)
这适用于所有情况,除了数组在类内使用this
关键字的情况下
this.myArr.push(el)
转换为Array.prototype.push.call(this.myArr,args)
而正确的转换应为:
this.myArr.push(el)
至Array.prototype.push.call(_this.myArr,args)
(_this
已由ts-loader插件创建)
我该如何实现?
这是我的转换器的代码:
function getType(type) {
if (type && type.symbol && type.symbol.name) {
return type.symbol.name;
} else if (
type &&
type.literalType &&
type.literalType.symbol &&
type.literalType.symbol.name
) {
return type.literalType.symbol.name;
}
return null;
}
exports.__esModule = true;
const { ClassificationTypeNames } = require("typescript");
var ts = require("typescript");
var transformer = function (typechecker) {
return function (context) {
var visitor = function (node) {
// 1. First check: chained expression
// if it's array.filter().join().map() then I want to change only the first part
// meaning
// if property access is a call expression - ignore and dont change
if (
ts.isCallExpression(node) &&
ts.isPropertyAccessExpression(node.expression) &&
ts.isCallExpression(node.expression.expression)
) {
return ts.visitEachChild(node,visitor,context);
}
if (
ts.isCallExpression(node) &&
ts.isPropertyAccessExpression(node.expression)
) {
const type = typechecker.getTypeAtLocation(node.expression.expression);
const typeNameS = getType(type);
if (typeNameS === "Array") {
const methodName = node.expression.name.getText();
const callArgs = node.arguments;
const identifier = node.expression.expression.getText();
return ts.createCall(
ts.createPropertyAccess(
ts.createPropertyAccess(
ts.createPropertyAccess(
ts.createIdentifier("Array"),ts.createIdentifier("prototype")
),ts.createIdentifier(methodName)
),ts.createIdentifier("call")
),undefined,[ts.createIdentifier(identifier),...callArgs]
);
}
}
return ts.visitEachChild(node,context);
};
return function (node) {
return ts.visitNode(node,visitor);
};
};
};
解决方法
发现错误。
我正在获取标识符并手动创建。
const identifier = node.expression.expression.getText();
然后
ts.createIdentifier(identifier)
构造新节点的正确方法是将node.expression.expression
直接传递给构造调用。
return ts.createCall(
ts.createPropertyAccess(
ts.createPropertyAccess(
ts.createPropertyAccess(
ts.createIdentifier("Array"),ts.createIdentifier("prototype")
),ts.createIdentifier(methodName)
),ts.createIdentifier("call")
),undefined,[node.expression.expression,...callArgs]
);
打字机引擎知道如何正确构建_this
和this
引用。