-
Notifications
You must be signed in to change notification settings - Fork 97
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
Add support for printing Literal nodes #310
Conversation
Fixes "Error: unknown node type: Literal" when using _prettier.__debug.formatAST with an AST from svelte.parse.
Could you give more context? What is |
@dummdidumm no worries, I'll try to elaborate. Much like #211, we're asking Prettier to print using an AST which is generated from
A common alternative to using __debug.formatAST is creating a plugin that extends prettier-plugin-svelte and overriding parse() to return your AST, like so prettier/prettier#5998 (comment). You still run into this issue with that approach, so #221 used Interestingly, the "Literal" node is already referenced in https://github.com/sveltejs/prettier-plugin-svelte/blob/master/src/print/index.ts#L1154 So it seems to have been a consideration at some point. Both expandNode() and print() check if the type of the node is "Identifier" and handle it appropriately, so I don't see why the same isn't done for "Literal". Happy to write a test case for this if you're happy with the justification. |
I still don't understand how this related to some AST formatting methods in Prettier. "Literal" isn't a Svelte AST node, it's a AST node inside JS expressions (which are inside Svelte AST Mustache Tag nodes for example), which shouldn't appear at this code position. A test or at least a code snippet with some explanation why it fails would be very helpful for me to better understand what the problem is. |
I don't have time this evening to write a full test and add it to the PR, but hopefully this code snippet gives you an idea: const prettier = require("prettier");
const sveltePrettier = require("prettier-plugin-svelte");
const svelteCompiler = require("svelte/compiler");
try {
/** prettier config */
const config = {
tabWidth: 4,
// ... etc
};
/** input source code */
const src = "<some-component data-foo={123}>Hello world.</some-component>";
// get ast from svelte compiler
const ast = svelteCompiler.parse(src);
console.log("[ast]", JSON.stringify(ast, null, 4));
// ^ shows a node with type literal for 123
// try to output the ast as code using prettier-plugin-svelte
const out = prettier.__debug.formatAST(ast, {
...config,
parser: "svelte",
printer: sveltePrettier,
plugins: [sveltePrettier],
originalText: src,
});
// ^ falls over with "Error: unknown node type: undefined"
console.log("[out.formatted]", out.formatted);
// ^ should print the same as src
console.error(
out.formatted === src ? "[PASS] ✅" : "[FAIL] ❌ mismatched string"
);
} catch (err) {
console.error("[FAIL] ❌", err);
} |
I have a hunch why this doesn't work: Do you need to pass all plugins that transform the code to |
Hi, sorry for the late response. Your reply makes a lot of sense, but passing the parsers from Prettier manually results in the same error at the moment. --- a/index.cjs
+++ b/index.cjs
@@ -1,5 +1,7 @@
const prettier = require("prettier");
const sveltePrettier = require("prettier-plugin-svelte");
+const __tsPrettier = require("prettier/parser-typescript");
+const __babelPrettier = require("prettier/parser-typescript");
const svelteCompiler = require("svelte/compiler");
try {
/** prettier config */
@@ -20,7 +22,7 @@ try {
...config,
parser: "svelte",
printer: sveltePrettier,
- plugins: [sveltePrettier],
+ plugins: [__tsPrettier, __babelPrettier, sveltePrettier],
originalText: src,
});
// ^ falls over with "Error: unknown node type: undefined"
Maybe embed() should be called in the default case of print() here? |
mhm that sounds like a Prettier bug then, because Prettier states that it tries to call |
I can't seem to figure out what I should pass as the third argument for textToDoc, but function print(path, options, print) {
const bracketSameLine = isBracketSameLine(options);
const n = path.getValue();
if (!n) {
return '';
}
const e = embed(path, print);
debugger;
if (e) {
return e;
} I just hacked the dist file for this quick patch as I didn't have to mess around with setting up the build, apologies if it doesn't match src exactly.
This is very likely in all honesty, stuff under the __debug namespace is probably not supposed to be used yet. That being said, the same thing occurs if you do the following hack to construct a plugin (from #211)
This works for #211 because they have a default in their switch which pipes unknown nodes through astring - see dc8ddb2#diff-fdd9b7cec43f9e7c596cd66d5e1656a3fc2ad2c0ae98cc7a165273a560a022e1R626 I think adding a |
Closing because printing Literal nodes specifically isn't valid. I imagine the update to prettier 3 will change how embed() internally has to be used, and may fix this issue by proxy |
I am having the same problem - can't hijack |
@benjaminpreiss i think prettier needs both originalText and an ast when doing furthermore this __debug.formatAST api doesnt call other languages from within it, so if you're processing a svelte file it wont be able to understand the javascript part of the AST. to fix this, you need to patch in Literal support into we had to solve various other problems with this manually, like indentation being wrong and losing comments in conclusion, something like this:
|
Fixes "Error: unknown node type: Literal" when using
prettier.__debug.formatAST
with an AST from svelte.parse.Related: #211