Допустим, у меня есть следующий код, который я хочу преобразовать с помощью пользовательского плагина Babel:
let c;
c = document;
console.log(c.readyState);
Цель состоит в том, чтобы заменить все вхождения document.readyState
пользовательской функцией, например, window.getDocumentReadyState()
, Поэтому выходные данные должны выглядеть примерно так:
let c;
c = document;
console.log(window.getDocumentReadyState());
Сложность состоит в том, чтобы определить, какое значение на самом деле имеет объект c
, когда вызывается посетитель MemberExpression
, так как я просто хочу заменить MemberExpressions для document
. Вот почему мне нужно выяснить, является ли текущее значение c
document
.
Вот реализация, которая просто заменяет каждое <obj>.readyState
MemberExpression:
/**
* Replace document.readyState with
* window.getDocumentReadyState();
*/
MemberExpression(path) {
const { node, parent } = path;
const objName = node.object.name;
const propName = node.property.name;
if (t.isAssignmentExpression(parent)) {
return;
}
if (t.isCallExpression(parent)) {
const isCallee = parent.callee === node;
if (isCallee) return;
}
if (propName === 'readyState') {
const customReadyStateFn = t.callExpression(
t.memberExpression(
t.identifier('window'),
t.identifier('getDocumentReadyState'),
),
[t.identifier(objName)],
);
path.replaceWith(customReadyStateFn);
}
},
Использование этой реализации Я выполняю проверку во время выполнения, чтобы определить, имеет ли объект тип document (HTMLDocument)
внутри window.getDocumentReadyState
, потому что я не смог сделать то же самое с помощью Babel. Но должен быть способ надежно определить, имеет ли эта переменная значение document
с использованием анализа stati c, верно?
По сути, мне нужно найти последнее выражение AssignmentExpression этой переменной в текущей области видимости.
Я уже пытался искать переменную в области видимости, используя path.scope.getBinding(<variableName>)
, но проблема в том, что последнее выражение AssignmentExpression не отображается в binding.references
. Если бы значение было назначено во время объявления (let c = document
), это не было бы проблемой, потому что к этой ссылке можно получить доступ, используя binding
.
. Я также пытался пройти через область действия, но посетитель AssignmentExpression не был не вызывается.
Я довольно плохо знаком с Babel и ASTs и достиг точки, когда я не знаю, что делать дальше, и я действительно хотел бы избавиться от этой проверки во время выполнения.
Как бы вы решили такую проблему?