-
-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: replaceComponentValues() continues iterating replaced values #1202
Comments
Hi @nex3, Thank you for reaching out about this. I think the root cause is how we The current
The issue you are encountering is between I think we can trivially check in In your case it would no longer be part of the same parent and But it also introduces another question. For this tree :
If we replace
We form :
We can prevent visiting There is no plugin system here, as there is in PostCSS. So I think it's fine to assume that we don't want to visit I hope this notation and naming is a bit clear and that I am not making things worse. |
I think not visiting One thing that's worth noting: PostCSS provides strong guarantees that modifying an AST during a walk is safe by storing the index of each active iteration and updating them as necessary when replacements are made. It would be really nice if this tool did so as well, although somewhat out-of-scope for this issue. |
I took a closer look at what PostCSS does and found that it does visit child nodes, even after they are replaced : const creator = () => {
return {
postcssPlugin: "creator",
Root: (root, helpers) => {
root.walk((x) => {
console.log(x.type);
if (x.type === 'rule') {
x.replaceWith(helpers.atRule({ name: 'media', params: '(min-width: 100px)' }));
}
});
}
};
};
creator.postcss = true; .baz {
/* A comment */
color: green;
} This prints
And const ast = valueParser('foo(bar(baz))');
ast.walk((node) => {
console.log(node.type, node.value);
if (node.type === 'function' && node.value === 'bar') {
// postcss-value-parser doesn't expose the parent during walking
ast.nodes[0].nodes.splice(0, 1, {
type: 'word',
value: 'x',
})
}
})
Is it possible that this goes unnoticed because it is more common to mutate nodes with PostCSS and PostCSS-like libs? That said, I think it's obvious that this is sub optimal behavior and that we should fix this. |
the patch hasn't been released yet |
@nex3 Patches for this issue have been released as part of Can you let us know if this resolves the bugs you encountered? |
It'll be a bit before I can get back to trying to integrate this, but I'll keep you posted when we do. |
@nex3 going to close this for now. |
(Runkit)
In line with other AST-walking and -replacement APIs, I would expect that if I replace a parent node in the AST, the replacement algorithm will stop traversing any of that node's children. (Note that this is how PostCSS's
walk()
andreplaceWith()
interact.) Instead,replaceComponentValues()
continues traversing the removed nodes. This is extra unnecessary work and can even cause data corruption if, for example, information is being stored about nodes encountered during the traversal.The text was updated successfully, but these errors were encountered: