Skip to content
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

js2-mode does not recognize asynchronous generators within class or object #598

Closed
belden opened this issue Dec 18, 2023 · 3 comments
Closed

Comments

@belden
Copy link

belden commented Dec 18, 2023

js2-mode struggles with this code. async *... within class context seems not to be recognized. The parsed function ends up not being set as async, which means the await is incorrectly flagged as occurring within a non-async function ("msg.bad.await").

#!/usr/bin/env node

class Toy {
  // (1) `async` not detected correctly
  // (2) `*` not treated correctly
  // (3) `await` treated as "msg.bad.await"


  async *oneByOne() {
    const resp = await this.getRecords();
    for (const rec of resp.records) {
      yield rec;
    }
  }

  // `async` / `await` have no parsing errors here
  async getRecords() {
    const out = await Promise.resolve({ records: [1, 2, 3] });
    return out;
  }

  // `*` treated correctly here
  *correctGeneratorDetection() {
    for (const r of [1, 2, 3]) {
      yield r;
    }
  }
}

(async () => {
  const toy = new Toy();
  for await (const rec of toy.oneByOne()) {
    console.log(rec);
  }
})();

There's also a superflous complaint from the code above that the * at *all requires a colon ("msg.no.colon.prop").

📸 click here to see screenshot

image


Similar, but not identical, parsing errors occur when converting the above code to a simple object. In this next example, the * in *all still shows an error ("msg.no.colon.prop"). The function is not recognized as a generator though, since yield also shows an error ("msg.bad.yield").

#!/usr/bin/env node

const obj = {
  // (1) `async` not detected correctly
  // (2) `*` not treated correctly (error: "msg.no.colon.prop")
  // (3) `yield` treated as an error (error: "msg.bad.yield")


  async *all() {
    const resp = await getRecords();
    for (const rec of resp.records) {
      yield rec;
    }
  }
};


// (4) generic "syntax error" (error: "msg.syntax")

async function getRecords() {
  return Promise.resolve({ records: [1, 2, 3] });
}

(async () => {
  for await (const rec of obj.all()) {
    console.log(rec);
  }
})();
📸 click here to see screenshot

image


In both cases, both pieces of code really do run, and simply log 1\n2\n3\n.


My environment:

  • node version: 14, 16, 18
  • js2-mode version: 20230408 (specifically, a fresh clone of this repo, with HEAD at 79bc78d)
  • GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.20, cairo version 1.16.0) of 2023-11-27
@dgutov dgutov closed this as completed in d3d8723 Dec 19, 2023
@dgutov
Copy link
Collaborator

dgutov commented Dec 19, 2023

Hi!

Thanks for the excellent report, both cases should work now.

@belden
Copy link
Author

belden commented Dec 23, 2023

@dgutov Thanks for the fast fix! Indeed, both toy scripts render correctly now.

@dgutov
Copy link
Collaborator

dgutov commented Dec 24, 2023

Thanks for checking. I've tagged a new release too, so that the fix is out to stable channels.

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

No branches or pull requests

2 participants