bemdev
@bemdev

Как красиво обойти AST и получить нужные данные?

Добрый день!

Все не могу разобраться с обходом массивов, и конкретнее AST дерева.

Я написал рекурсивную функцию, которая идет в дерево.

function walk (node, cbProp, cbObj) {
    switch (node.type) {
        case 'Array':
            node.children.forEach((item) => {
                walk(item, cbProp, cbObj);
            });
            break;
        case 'Object':
            cbObj(node);
            node.children.forEach((property) => {
                cbProp(property);
                walk(property.value, cbProp, cbObj);
            });
            break;
    }
};


Мне надо обойти дерево и сохранить значения нужных элементов и потом их сравнить.

Я делаю это как то так

walk(obj, () => {}, (obj) => {
  if (obj.children[0].value.value == 'placeholder' || obj.children[0].value.value == 'button') {
    arr.push({
      [obj.children[0].value.value]: {
        index: obj.children[0].value.loc.start.line,
        loc: obj.loc
      }
    });
  }                    
});


НО кажется это какой-то тихий ужас и много вытекающих проблем. Чем больше элементов мне надо сохранить тем ужаснее эти [0] выглядят :(

Подскажите как правильнее сделать? может reduce как то использовать?
  • Вопрос задан
  • 109 просмотров
Пригласить эксперта
Ответы на вопрос 1
@twolegs
Если вас смущает только количество кода, то это решается банальным форматированием.
Например, если использовать одну вспомогательную переменную, то код уже становится чище.
walk(obj, () => {}, (obj) => {
  const nodeValue = obj.children[0].value;
  if (nodeValue.value == 'placeholder' || nodeValue.value == 'button') {
    arr.push({
      [nodeValue.value]: {
        index: nodeValue.loc.start.line,
        loc: obj.loc
      }
    });
  }

Также часть кода можно обернуть в отдельные функции, тогда он станет компактнее.
Большое количество одинаковых условий можно заменить на более простое
['placeholder', 'button', ...].includes(node.value);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы