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

feat(eslint-plugin): [no-floating-promise] add option to ignore IIFEs #1799

Merged
merged 18 commits into from Apr 20, 2020

Conversation

anikethsaha
Copy link
Contributor

@anikethsaha anikethsaha commented Mar 25, 2020

fixes #647
added a no check for iife

  • created a new function to detect iife isIife (please do suggest if the logic there doesn't cover all cases)
  • added tests

@typescript-eslint
Copy link
Contributor

Thanks for the PR, @anikethsaha!

typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community.

The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately.

Thanks again!


🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint. As a thank you, your profile/company logo will be added to our main README which receives thousands of unique visitors per day.

@bradzacher bradzacher added the enhancement: plugin rule option New rule option for an existing eslint-plugin rule label Mar 25, 2020
Copy link
Member

@bradzacher bradzacher left a comment

Choose a reason for hiding this comment

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

could you please gate this functionality behind an option, as per my comment: #647 (comment)

I want end-users to opt-in to this functionality so that they're consciously making the decision for a little unsafety from the rule.

@bradzacher bradzacher added the awaiting response Issues waiting for a reply from the OP or another party label Mar 25, 2020
@anikethsaha
Copy link
Contributor Author

could you please gate this functionality behind an option, as per my comment: #647 (comment)

I want end-users to opt-in to this functionality so that they're consciously making the decision for a little unsafety from the rule.

ok cool, also it should only check for async iife right ? not just iife ?

@bradzacher
Copy link
Member

it should check both - it should just be looking for an IIFE that returns a promise.

@bradzacher bradzacher changed the title fix: ignores iife for no-floating-promise (fixes #647) fix(eslint-plugin): [no-floating-promise] add option to ignore IIFEs Mar 25, 2020
@anikethsaha
Copy link
Contributor Author

it should check both - it should just be looking for an IIFE that returns a promise.

make sense , ok creating an options name ignoreIife

@anikethsaha
Copy link
Contributor Author

anikethsaha commented Mar 26, 2020

@bradzacher I think we need to change the selector for AST as well, cause

currently in ExpressionStatement

I have this check

if (options.ignoreIife && isAsyncIife(node)) {
  return;
}

And, here is the definition of isAsyncIife

    function isAsyncIife(node: TSESTree.ExpressionStatement): Boolean {
      if(node?.expression.type === AST_NODE_TYPES.AwaitExpression){
        return true
      }
      if (node?.expression.type === AST_NODE_TYPES.CallExpression) {
        if (possibleIifeCalleType.has(node?.expression?.callee.type)) {
          if (node?.expression?.callee?.hasAsync) {
            return true ;
          }
          return node?.expression?.callee?.body?.body.some(hasPromise);
        }
      }

      return false;
    }

And here is hasPromise

    function hasPromise( node: TSESTree.ExpressionStatement | TSESTree.ReturnStatement): Boolean {
      // has promise statement
      if (node?.expression.type === "NewExpression" && node?.expression?.callee.name === "Promise") {
        return true;
      }
      if (
        // returning promise
        node.type === AST_NODE_TYPES.ReturnStatement &&
        node?.argument.type === AST_NODE_TYPES.NewExpression &&
        node?.argument?.callee.name === "Promise"
      ) {
        return true;
      }
      return false
    }

It looks like when I give input like this

//  options : [{ ignoreIife : true }]
(async function() {
  // error cause of this
  await res(1);
})();

still the there is a floating error.

I did try changing the selectors

["ExpressionStatement > :not(ExpressionStatement )"](node){
  check(node)
},
"ExpressionStatement > ExpressionStatement "(node){
      if(node?.expression.type === AST_NODE_TYPES.AwaitExpression){
        return true
      }
      check(node)
}

Still no luck

@bradzacher
Copy link
Member

the code you've got currently in the PR doesn't look too far off.

I'd expect something along the lines of:

ExpressionStatement(node): void {
  if (options.ignoreIIFE && isIIFE(node)) {
    return;
  }

  // old code
}

function isIIFE(node: TSESTree.ExpressionStatement): boolean {
  const expr = node.expression;
  if (expr.type !== AST_NODE_TYPES.CallExpression) {
    return false;
  }

  return (
    expr.callee.type === AST_NODE_TYPES.ArrowFunctionExpression ||
    expr.callee.type === AST_NODE_TYPES.FunctionExpression
  );
}

To clarify what this option should do:

These cases should error with ignoreIIFE: false (the default)
They should not error with ignoreIIFE: true

(function foo() { return Promise.resolve() })();
(async function foo() { return Promise.resolve() })();
(async () => { return Promise.resolve() })();

However, setting the option to true should not ignore the contents of an IIFE. I.e. this should still error with ignoreIIFE: true

(async () => {
  Promise.resolve(); // error - floating promise
})();
// no other lint error

@anikethsaha
Copy link
Contributor Author

@bradzacher should I add custom type for isAsyncIife method as I added TSESTree.ExpressionStatement | TSESTree.ArrowFunctionExpression | TSESTree.TSTypeAnnotation type to node but still typecheck is failing.
also, i tried node?.expression.typeAnnotation.typeand still it failed

Copy link
Member

@bradzacher bradzacher left a comment

Choose a reason for hiding this comment

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

a few suggestions for you

@codecov
Copy link

codecov bot commented Mar 29, 2020

Codecov Report

Merging #1799 into master will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master    #1799   +/-   ##
=======================================
  Coverage   94.37%   94.37%           
=======================================
  Files         164      164           
  Lines        7572     7579    +7     
  Branches     2175     2178    +3     
=======================================
+ Hits         7146     7153    +7     
  Misses        183      183           
  Partials      243      243           
Flag Coverage Δ
#unittest 94.37% <100.00%> (+<0.01%) ⬆️
Impacted Files Coverage Δ
...es/eslint-plugin/src/rules/no-floating-promises.ts 100.00% <100.00%> (ø)

Copy link
Member

@bradzacher bradzacher left a comment

Choose a reason for hiding this comment

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

a few final comments, otherwise LGTM - thanks for this.

@bradzacher
Copy link
Member

@anikethsaha
Copy link
Contributor Author

same issue here as well

image

@bradzacher bradzacher removed the awaiting response Issues waiting for a reply from the OP or another party label Apr 4, 2020
@bradzacher bradzacher changed the title fix(eslint-plugin): [no-floating-promise] add option to ignore IIFEs feat(eslint-plugin): [no-floating-promise] add option to ignore IIFEs Apr 20, 2020
bradzacher
bradzacher previously approved these changes Apr 20, 2020
Copy link
Member

@bradzacher bradzacher left a comment

Choose a reason for hiding this comment

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

thanks!

bradzacher
bradzacher previously approved these changes Apr 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement: plugin rule option New rule option for an existing eslint-plugin rule
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[no-floating-promises] Should not report on async IIFEs
3 participants