【问题标题】:traversing unvisited nodes in Babel遍历 Babel 中未访问的节点
【发布时间】:2023-02-08 12:06:31
【问题描述】:

我想在一次遍历中遍历一些字符串文字并生成输出。而第一次遍历没有访问到的字符串字面量应该在第二次遍历中遍历。在第一次遍历中应该访问哪些字符串文字以及在第二次遍历中应该访问哪些字符串文字的规则并不重要。重要的是我想在第二次遍历中遍历未访问的节点。为了知道在第一次遍历中访问了哪些节点,我使用了一个弱集并将访问过的节点放在弱集中。在第二次遍历中,我检查弱集节点是否存在,如果不存在,我将更改它。但这种方法行不通。我知道当我将一些节点放入弱集中并在第二次遍历检查该节点是否存在时,结果为假(该节点存在于弱集中但它说它不存在)。看下面的代码:

const babel = require('@babel/core');

const code = `
function greet(name) {
  return 'Hello ' + name;
}
console.log(greet('tanhauhau')); 
`;
var visited_past = new WeakSet(); 

const output = babel.transformSync(code, {
  plugins: [
    function myCustomPlugin() {
      return {
        visitor: {
            
          StringLiteral(path) {
          console.log("first traversal :");
            console.log(path.node);
            visited_past.add(path.node);
          },
          
        },
      };
    },
  ],
});
const output2 = babel.transformSync(code, {
  plugins: [
    function myCustomPlugin() {
      return {
        visitor: {
       
          StringLiteral(path) {  
           console.log("second traversal :");
              console.log(path.node);       
            console.log(visited_past.has(path.node));
          },
        },
      };
    },
  ],
});

输出是:

first traversal :
Node {
  type: 'StringLiteral',
  start: 33,
  end: 41,
  loc: SourceLocation {
    start: Position { line: 3, column: 9, index: 33 },
    end: Position { line: 3, column: 17, index: 41 },
    filename: undefined,
    identifierName: undefined
  },
  extra: { rawValue: 'Hello ', raw: "'Hello '" },
  value: 'Hello ',
  leadingComments: undefined,
  innerComments: undefined,
  trailingComments: undefined
}
first traversal :
Node {
  type: 'StringLiteral',
  start: 70,
  end: 81,
  loc: SourceLocation {
    start: Position { line: 5, column: 18, index: 70 },
    end: Position { line: 5, column: 29, index: 81 },
    filename: undefined,
    identifierName: undefined
  },
  extra: { rawValue: 'tanhauhau', raw: "'tanhauhau'" },
  value: 'tanhauhau',
  leadingComments: undefined,
  innerComments: undefined,
  trailingComments: undefined
}
second traversal :
Node {
  type: 'StringLiteral',
  start: 33,
  end: 41,
  loc: SourceLocation {
    start: Position { line: 3, column: 9, index: 33 },
    end: Position { line: 3, column: 17, index: 41 },
    filename: undefined,
    identifierName: undefined
  },
  extra: { rawValue: 'Hello ', raw: "'Hello '" },
  value: 'Hello ',
  leadingComments: undefined,
  innerComments: undefined,
  trailingComments: undefined
}
false
second traversal :
Node {
  type: 'StringLiteral',
  start: 70,
  end: 81,
  loc: SourceLocation {
    start: Position { line: 5, column: 18, index: 70 },
    end: Position { line: 5, column: 29, index: 81 },
    filename: undefined,
    identifierName: undefined
  },
  extra: { rawValue: 'tanhauhau', raw: "'tanhauhau'" },
  value: 'tanhauhau',
  leadingComments: undefined,
  innerComments: undefined,
  trailingComments: undefined
}
false

我应该怎么办?

【问题讨论】:

  • 每次遍历都会生成节点吗?这是我的假设,所以用一个字符串表示节点可能会有用。也许只是将路径存储到集合中的节点?

标签: javascript node.js plugins babeljs babel-plugin


【解决方案1】:

根据您的用例,您可以做一些事情:

如果您没有更改文件中的任何内容,则可以只存储访问过的节点的 path.node.start,然后在第二次遍历时跳过这些节点。

如果事情可以改变长度,但不能改变顺序,你可以使用 path.scope.generateUidIdentifier("uid") 作为访问每个节点的键。

否则,您将不得不变得聪明一些,例如跟随节点 parentPath 链来构建密钥,或使用文本值本身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多