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

fix: infer array type from outside of arrow function #12727

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

fedeci
Copy link
Member

@fedeci fedeci commented Jan 31, 2021

Q                       A
Fixed Issues? Fixes #12714
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

If ArrowFunctionExpression is a child of VariableDeclarator we can try to guess the execution status relative to another expression. This allows to infer array type from outside of an arrow function.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jan 31, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 20fad3c:

Sandbox Source
babel-repl-custom-plugin Configuration
babel-plugin-multi-config Configuration

@babel-bot
Copy link
Collaborator

babel-bot commented Jan 31, 2021

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/41225/

Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

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

Can you also add some tests at packages/babel-traverse/test/inference.js?

packages/babel-traverse/src/path/introspection.ts Outdated Show resolved Hide resolved
packages/babel-traverse/src/path/introspection.ts Outdated Show resolved Hide resolved
@nicolo-ribaudo nicolo-ribaudo added pkg: traverse PR: Bug Fix 🐛 A type of pull request used for our changelog categories labels Feb 1, 2021
@merceyz
Copy link
Contributor

merceyz commented Feb 1, 2021

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/39050/

This REPL doesn't seem to work, I get this error:

Could not load Babel build #39050: Could not find valid @babel/standalone artifact in build #39050

@nicolo-ribaudo
Copy link
Member

Yeah I know, it should be fixed by #12728 😅

@fedeci
Copy link
Member Author

fedeci commented Feb 2, 2021

I don't know why the CI failed and I cannot reproduce it locally. If I run make -j tscheck flowcheck-ci lint-ci I just get a bunch of errors from babel-generator, but nothing from babel-traverse.

// A possible fix?
((target.parent as t.VariableDeclarator).id as t.Identifier).name

@merceyz
Copy link
Contributor

merceyz commented Feb 2, 2021

Since #12728 has been merged could you rebase this PR so the REPL works please

Copy link

@iabooo553 iabooo553 left a comment

Choose a reason for hiding this comment

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

EDIT by @nicolo-ribaudo: spam

@merceyz
Copy link
Contributor

merceyz commented Feb 3, 2021

Tested and it does indeed fix the REPL provided in the issue, but when applied on the real code I extracted it from it doesn't as it returns the function that was created

// Fixed in this PR
{
  const keys = [];

  const foo = () => {
    for (const key of keys) {
    }
  };
}

// Same output as before
{
  const foo = () => {
    const keys = [];

    const bar = () => {
      for (const key of keys) {
      }
    };

    return bar;
  };
}

@fedeci
Copy link
Member Author

fedeci commented Feb 3, 2021

The return statement seems to break it🤔

@merceyz
Copy link
Contributor

merceyz commented Feb 3, 2021

Can also be reproduced if the function is exported - REPL

const keys = [];

export const foo = () => {
  for (const key of keys) {
  }
};

@fedeci
Copy link
Member Author

fedeci commented Feb 4, 2021

Exported function execution status is not guessed since #10417 and I think we should check it only when keys type is immutable.
However I just realised that this should not be transformed to a C-like for since keys is mutable and may no longer be an iterable when the function is executed. Right?

// Don't infer type
var keys = []
const foo = () => {
  for (const key of keys) {}
}

// Infer type
const keys = []
export const foo = () => {
  for (const key of keys) {}
}

// Infer type
export const bar = () => {
  const keys = []
  for (const key of keys) {}
}

// Don't infer type
var keys = []
export const baz = () => {
  for (const key of keys) {}
}

/cc @nicolo-ribaudo

@nicolo-ribaudo
Copy link
Member

In that case keys is mutable, but it's not mutated so we can safely consider it as an array. It's similar to what we do in this example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: traverse PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

for of transform is unable to infer array type from outside of arrow function
5 participants