Skip to content

Commit

Permalink
all good
Browse files Browse the repository at this point in the history
  • Loading branch information
JamsonChan committed Oct 10, 2024
1 parent ef000da commit c29cea6
Showing 1 changed file with 33 additions and 62 deletions.
95 changes: 33 additions & 62 deletions babel-plugin-expose-private-functions-and-variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,100 +118,71 @@ module.exports = function ({types: t}) {
);
});

// replace private function calls to `window.PACKAGE._._func()`
// replace private function calls to window.PACKAGE._.FUNC
path.traverse({
AssignmentExpression(assignPath) {
const left = assignPath.node.left,
right = assignPath.node.right;
// 如果賦值的右側是一個私有函式名稱,將其替換成 `window.PACKAGE._._func`
const right = assignPath.node.right;
// TODO: assignPath.node.left ?
// case: x = FUNC -> x = window.PACKAGE._.FUNC
if (t.isIdentifier(right) && privateFuncs.has(right.name)) {
assignPath.node.right = createNestedMemberExpression([right.name, ...dir]);
funcCallCount.set(right.name, funcCallCount.get(right.name) + 1);
assignPath.node.right = createNestedMemberExpression([right.name, ...dir]);
}
},
ConditionalExpression(condPath) {
const { test, consequent, alternate } = condPath.node;
// TODO: test ?
// case: x ? FUNC : x -> x ? window.PACKAGE._.FUNC : x
if (t.isIdentifier(consequent) && privateFuncs.has(consequent.name)) {
funcCallCount.set(consequent.name, funcCallCount.get(consequent.name) + 1);
condPath.get('consequent').replaceWith(createNestedMemberExpression([consequent.name, ...dir]));
}
// case: x ? x : FUNC -> x ? x : window.PACKAGE._.FUNC
if (t.isIdentifier(alternate) && privateFuncs.has(alternate.name)) {
funcCallCount.set(alternate.name, funcCallCount.get(alternate.name) + 1);
condPath.get('alternate').replaceWith(createNestedMemberExpression([alternate.name, ...dir]));
}
},
CallExpression(callPath) {
const callee = callPath.node.callee;

// 替換直接的函式呼叫
if (t.isIdentifier(callee) && privateFuncs.has(callee.name)) {
callPath.node.callee = createNestedMemberExpression([callee.name, ...dir]);
funcCallCount.set(callee.name, funcCallCount.get(callee.name) + 1);
}

// 檢查是否是 setTimeout 的函式參數
if (t.isIdentifier(callee) && callee.name === 'setTimeout') {
if (t.isIdentifier(callee)) {
// case: FUNC() -> window.PACKAGE._.FUNC()
// this case includes `FUNC() in ?: conditional`
if (privateFuncs.has(callee.name)) {
funcCallCount.set(callee.name, funcCallCount.get(callee.name) + 1);
callPath.node.callee = createNestedMemberExpression([callee.name, ...dir]);
}
const args = callPath.get('arguments');
args.forEach(arg => {
// 檢查是否為 FunctionExpression
if (t.isFunctionExpression(arg.node)) {
arg.traverse({
CallExpression(innerCallPath) {
const innerCallee = innerCallPath.node.callee;

// 如果內部的呼叫是私有函式
if (t.isIdentifier(innerCallee) && privateFuncs.has(innerCallee.name)) {
innerCallPath.node.callee = createNestedMemberExpression([innerCallee.name, ...dir]);
funcCallCount.set(innerCallee.name, funcCallCount.get(innerCallee.name) + 1);
}
}
});
} else if (t.isConditionalExpression(arg.node)) {
// 處理條件運算子
const { test, consequent, alternate } = arg.node;

// 檢查 consequent 和 alternate 是否是 Identifier
if (t.isIdentifier(consequent) && privateFuncs.has(consequent.name)) {
arg.get('consequent').replaceWith(createNestedMemberExpression([consequent.name, ...dir]));
funcCallCount.set(consequent.name, funcCallCount.get(consequent.name) + 1);
}
if (t.isIdentifier(alternate) && privateFuncs.has(alternate.name)) {
arg.get('alternate').replaceWith(createNestedMemberExpression([alternate.name, ...dir]));
funcCallCount.set(alternate.name, funcCallCount.get(alternate.name) + 1);
}
} else if (t.isIdentifier(arg.node) && privateFuncs.has(arg.node.name)) {
// 替換 setTimeout 中的函式參數
// case: xxx(FUNC) -> xxx(window.PACKAGE._.FUNC)
if (t.isIdentifier(arg.node) && privateFuncs.has(arg.node.name)) {
funcCallCount.set(arg.node.name, funcCallCount.get(arg.node.name) + 1);
arg.replaceWith(createNestedMemberExpression([arg.node.name, ...dir]));
// funcCallCount.set(arg.node.name, funcCallCount.get(arg.node.name) + 1);
}
});
}
},
FunctionExpression(funcPath) {
// 遍歷函式內部的語句,檢查是否使用私有函式
funcPath.traverse({
CallExpression(innerCallPath) {
const callee = innerCallPath.node.callee;

if (t.isIdentifier(callee) && privateFuncs.has(callee.name)) {
innerCallPath.node.callee = createNestedMemberExpression([callee.name, ...dir]);
funcCallCount.set(callee.name, funcCallCount.get(callee.name) + 1);
}
}
});
},
ObjectExpression(objectPath) {
objectPath.node.properties.forEach((property) => {
// 確保屬性值是 Identifier,且在私有函式中
// case: x = { x: FUNC } -> x = { x: window.PACKAGE._.FUNC }
// case: x.x = FUNC -> x.x = window.PACKAGE._.FUNC
if (t.isIdentifier(property.value) && privateFuncs.has(property.value.name)) {
// 替換屬性值
funcCallCount.set(property.value.name, funcCallCount.get(property.value.name) + 1);
property.value = createNestedMemberExpression([property.value.name, ...dir]);
// funcCallCount.set(property.value.name, funcCallCount.get(property.value.name) + 1);
}
});
}
});

// 4. 構建一個變數來輸出呼叫次數結果
const callCountArray = Array.from(funcCallCount.entries()).map(([name, count]) =>
t.objectProperty(t.identifier(name), t.numericLiteral(count))
);
const callCountVariable = t.variableDeclaration('var', [
t.variableDeclarator(
t.identifier('dlwlrmaXXX'),
t.identifier('dlwlrma'),
t.objectExpression(callCountArray)
)
]);
// 5. 在程式結尾插入計算結果變數
path.pushContainer('body', callCountVariable);
}
}
Expand Down

0 comments on commit c29cea6

Please sign in to comment.