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

False positive W024: Expected an identifier and instead saw 'yield' (a reserved word) #3534

Open
Andrew-Cottrell opened this issue Feb 18, 2021 · 2 comments
Labels

Comments

@Andrew-Cottrell
Copy link

Andrew-Cottrell commented Feb 18, 2021

In ES3, yield is neither a keyword nor a future reserved word; and since ES5, keywords may be used as object property keys.

As far as I know, the code below is valid in ES3, ES5, and all later editions

/*jshint esversion: 3 */
(function () {
    "use strict";
    console.log( { yield: 0 } );
}());

However, https://jshint.com/ — currently using JSHint version 2.12.0 — reports

One warning
4 | Expected an identifier and instead saw 'yield' (a reserved word).


A potential fix is to modify the following line in function optionalidentifier

if (state.inES5()) {

to

      if (state.inES5() || val === "yield") {
@Andrew-Cottrell Andrew-Cottrell changed the title False positive warning - Expected an identifier and instead saw 'yield' (a reserved word) False positive W024: Expected an identifier and instead saw 'yield' (a reserved word) Feb 18, 2021
@jugglinmike
Copy link
Member

Confirmed. Anyway, thanks for the report!

Other curiosities:

  • this depends on ES5's strict mode
  • let in the same position is tolerated (that's correct, but unexpected given the reported bug)

I'm labeling this as low-priority because I've seen very little evidence of anyone targeting ES3 these days. I'd love to hear more about your use case, though!

@jugglinmike jugglinmike added the P4 label Feb 20, 2021
@Andrew-Cottrell
Copy link
Author

Andrew-Cottrell commented Feb 21, 2021

I'm labeling this as low-priority because I've seen very little evidence of anyone targeting ES3 these days.

I'm happy for this issue to be low-priority. A realistic workaround is simply to not use the esversion: 3 option.

I'd love to hear more about your use case, though!

Thanks for the interest; although sadly my use case is not particularly exciting!

Many years ago I wrote a library that needed to be compatible with IE 8, and also with YUI Compressor version 2.4.8 (no ES5 support), due to a built-in minification framework used by a content management system. Fortunately, these restrictions no longer apply, but I do still need to support IE 11 and the CMS's build system & minification framework makes use of a transpiler awkward. However, I have not yet had any particular reason to use ES5 syntax; so I have continued to maintain compatibility with ES3 browsers, although this is no longer necessary. The library includes a function that implements a cross-browser equivalent of generator objects, which enables me to use modern JavaScript idioms. The term "yield" is used by generator-context objects passed to generator-body functions.

For example, the library enables the following to work in ES3 compatible browsers

/**
 * Generator functions return generator objects, which implement Iterable and Iterator.
 * @return {!Generator<number>} A non-null generator of numbers.
 */
function fibonacciNumbers() {
    var memo = [1, -1]; // create the initial state (e.g. a vector of "negafibonacci" numbers)
    return generator(function (context) { // repeat indefinitely
        memo = [memo[0] + memo[1], memo[0]]; // update the state on each evaluation
        context.yield(memo[0]); // yield the next value and suspend execution until resumed
    });
}

var count = 0;
for_of(fibonacciNumbers(), function (number, break_) {
    count += 1;
    console.log(count, number);
    if (count === 16) break_();
});

which is equivalent to the modern syntax

/**
 * Generator functions return generator objects, which implement Iterable and Iterator.
 * @return {!Generator<number>} A non-null generator of numbers.
 */
function* fibonacciNumbers() {
    let memo = [1, -1]; // create the initial state (e.g. a vector of "negafibonacci" numbers)
    while (true) { // repeat indefinitely
        memo = [memo[0] + memo[1], memo[0]]; // update the state on each evaluation
        yield memo[0]; // yield the next value and suspend execution until resumed
    }
}

let count = 0;
for (let number of fibonacciNumbers()) {
    count += 1;
    console.log(count, number);
    if (count === 16) break;
}

A big thank you for maintaining the JSHint project; I use it almost every weekday and sometimes at weekends!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants