Skip to content

Conversation

@fisker
Copy link

@fisker fisker commented Aug 2, 2022

  • I’ve added tests to confirm my change works.
  • (If changing the API or CLI) I’ve documented the changes I’ve made (in the docs/ directory)
  • (If the change is user-facing) I’ve added my changes to changelog_unreleased/*/pr-XXXX.md file following changelog_unreleased/TEMPLATE.md.
  • I’ve read the contributing guidelines.

Try the playground for this PR

return doc ? [doc, hardline] : "";
return async () => {
const doc = await printFrontMatter(node, textToDoc);
return doc ? [doc, hardline] : "";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to these PRs, but returning "" from here means that the usual print function will be called for this node. I wonder if this is intended.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

@fisker fisker Aug 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW the plugin should always handle all node types in print, even if embed return a fallback doc, because we have embeddedLanguageFormatting option to skip embed.

printer.detectEmbeddedLanguage?.bind(printer) ?? (() => true);
const { ignoredProperties } = printer.massageAstNode;

const pathStacks = [];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable needs a better name. embedCallResults?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yah, need more work, just testing if it works.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good. One more name idea: embedThunks

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this 5c1a383 😄

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like it might work :)

Copy link
Owner

@thorn0 thorn0 Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we're breakingly changing the signature of embed anyway (the textToDoc parameter becomes async), I think we should simply forbid sync embeds, i.e. the return type should become undefined | () => Promise<Doc | undefined>.

Copy link
Author

@fisker fisker Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They can be sync, but they shouldn't use print in that case (because it's print that can try to get things from embeds that haven't become available yet). Should we probably remove print from the parameters of embed and pass it only to the returned functions then?

Copy link
Author

@fisker fisker Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they shouldn't use print in that case

When calling print in the returned function, it's still possible not settled? Visting siblings doc, for example.

Should we probably remove print

In that case, why not pass both print and textToDoc to the returned function, to prevent

const promise = textToDoc();
return () => promise

Copy link
Owner

@thorn0 thorn0 Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When calling print in the returned function, it's still possible not settled? Visting siblings doc, for example

I guess we should just say that it's a design limitation: print should be used only to print the current node's descendents.

In that case, why not pass both print and textToDoc

👍

@fisker
Copy link
Author

fisker commented Aug 2, 2022

We are calling hasPrettierIgnore in this function, maybe we can also print ignored node during this process.

@thorn0
Copy link
Owner

thorn0 commented Aug 2, 2022

We are calling hasPrettierIgnore in this function, maybe we can also print ignored node during this process.

I wanted to do that, then decided to keep this change simple.

@fisker
Copy link
Author

fisker commented Aug 2, 2022

In theory, args can be passed by parent node (before this change), right?

@fisker
Copy link
Author

fisker commented Aug 2, 2022

@thorn0
Copy link
Owner

thorn0 commented Aug 2, 2022

Passed to where? printPrettierIgnoredNode doesn't use args, so it should be safe indeed to print ignored nodes together with embeds.

@fisker
Copy link
Author

fisker commented Aug 2, 2022

No, I mean embed

@thorn0
Copy link
Owner

thorn0 commented Aug 2, 2022

Embed doesn't take args too, so nothing to worry about here

@thorn0
Copy link
Owner

thorn0 commented Aug 3, 2022

Let's go back to 05cc6d5
I can't see any benifits in building the promise chain.

@fisker fisker force-pushed the embed-async-function branch from 03db215 to 08c7dd9 Compare August 3, 2022 12:38
@fisker
Copy link
Author

fisker commented Aug 3, 2022

Have you benchmarked this?

@thorn0
Copy link
Owner

thorn0 commented Aug 3, 2022

Have you benchmarked this?

Not yet.

@fisker
Copy link
Author

fisker commented Aug 3, 2022

Pass options too? When checking languages, the printer may don't need that to make decision.

@thorn0
Copy link
Owner

thorn0 commented Aug 3, 2022

Pass options too? When checking languages, the printer may don't need that to make decision.

We should treat options and path the same way then. If we pass options to returned functions, then let's pass path too. So that code like this would be possible:

if (language === "graphql") {
  return formatGraphql;
}

@fisker
Copy link
Author

fisker commented Aug 3, 2022

Does this order textToDoc, print, options, path make sense to you?

@thorn0
Copy link
Owner

thorn0 commented Aug 3, 2022

Does this order textToDoc, print, options, path make sense to you?

textToDoc, print, path, options seems to be slightly better. path is used more often than options.

@fisker
Copy link
Author

fisker commented Aug 3, 2022

The isNode() you added can be replaced to return children keys, so we can use eslint-visitor-keys or @typescript-eslint/visitor-keys, maybe the traverse can be faster, but this can be done later.

@thorn0
Copy link
Owner

thorn0 commented Aug 3, 2022

but this can be done later

Yep. Let me bring my second PC to run benchmarks on it :)

@thorn0
Copy link
Owner

thorn0 commented Aug 4, 2022

No changes in performance compared to prettier#13211:

  'node ./bench.mjs alt-async parallel' ran
    1.00 ± 0.01 times faster than 'node ./bench.mjs embed-async-function parallel'
    1.02 ± 0.04 times faster than 'node ./bench.mjs alt-async serial'
    1.02 ± 0.01 times faster than 'node ./bench.mjs embed-async-function serial'

@fisker fisker marked this pull request as ready for review August 4, 2022 16:18
@thorn0 thorn0 merged commit 0c5faa5 into thorn0:alt-async Aug 4, 2022
@fisker fisker deleted the embed-async-function branch August 4, 2022 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants