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

Replace x != undefined with x != null #572

Merged
merged 29 commits into from
May 14, 2018
Merged

Replace x != undefined with x != null #572

merged 29 commits into from
May 14, 2018

Conversation

j-f1
Copy link
Contributor

@j-f1 j-f1 commented Jun 8, 2017

Bonus: replace undefined == null and null != null with !0 and !1, respectively.

Tests included.


const babel = require("babel-core");
const plugin = require("../src/index");
const unpad = require("../../../utils/unpad");
Copy link
Member

@vigneshshanmugam vigneshshanmugam Jun 8, 2017

Choose a reason for hiding this comment

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

can be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -9,6 +14,17 @@ module.exports = function() {
BinaryExpression(path) {
const { node } = path;
const op = node.operator;
const negated = node.operator.startsWith("!");

if (["!=", "=="].includes(node.operator)) {
Copy link
Member

Choose a reason for hiding this comment

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

use indexOf, we still support node 4

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@codecov
Copy link

codecov bot commented Jun 8, 2017

Codecov Report

Merging #572 into master will increase coverage by 0.44%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #572      +/-   ##
==========================================
+ Coverage   83.02%   83.46%   +0.44%     
==========================================
  Files          41       42       +1     
  Lines        2763     2867     +104     
  Branches      967     1008      +41     
==========================================
+ Hits         2294     2393      +99     
- Misses        282      283       +1     
- Partials      187      191       +4
Impacted Files Coverage Δ
...ansform-simplify-comparison-operators/src/index.js 100% <100%> (ø) ⬆️
...plugin-minify-constant-folding/src/replacements.js 96.82% <0%> (ø)
.../babel-plugin-minify-constant-folding/src/index.js 85.56% <0%> (+3.02%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cb993ed...fc230db. Read the comment docs.

});

it("should shorten `undefined == null`", () => {
const source = "undefined == null";
Copy link
Member

Choose a reason for hiding this comment

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

this should be already taken care of by constant-folding plugin. This plugin should not worry about these folding constants.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn’t appear to handle this. Are you saying that I should move it there?

Copy link
Member

Choose a reason for hiding this comment

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

That can be fixed in path.evaluate of babel if that doesn't handle it. Or it's an ordering issue of who runs first - #61 #422.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could add void 0 to isNull.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How does that sound @boopathi?

Copy link
Member

Choose a reason for hiding this comment

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

I meant this entire replacement shouldn't be a part of this plugin. It should be handled in path.evaluate of babel.

Copy link
Contributor Author

@j-f1 j-f1 Jun 10, 2017

Choose a reason for hiding this comment

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

@boopathi done.

@xtuc
Copy link
Member

xtuc commented Jun 12, 2017

I'm wondering if we can do this, isn't it unsafe? null and undefined are not equal.

@j-f1
Copy link
Contributor Author

j-f1 commented Jun 12, 2017

@xtuc null and undefined are double-equals equal, not triple-equals equal.

@@ -9,6 +9,13 @@ module.exports = function() {
BinaryExpression(path) {
const { node } = path;
const op = node.operator;

if (["!=", "=="].indexOf(node.operator) !== -1) {
if (t.isIdentifier(node.right, { name: "undefined" })) {
Copy link
Member

Choose a reason for hiding this comment

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

void 0 will not be transformed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@boopathi
Copy link
Member

Can you add some tests for this ?

@j-f1
Copy link
Contributor Author

j-f1 commented Jun 13, 2017

@boopathi Are you assuming in babili that people won’t do void someFunctionWithSideEffects()?

@j-f1
Copy link
Contributor Author

j-f1 commented Jun 13, 2017

@boopathi Tests restored.

@boopathi
Copy link
Member

boopathi commented Jun 13, 2017

Are you assuming in babili that people won’t do void someFunctionWithSideEffects()?

Constant-folding plugin should take care of folding constants. void foo() should be a deopt anyway here. It should check only for void x where pathOfX.isPure() is true.

@boopathi boopathi added the Tag: New Feature Pull Request adding a new feature label Aug 7, 2017
@boopathi
Copy link
Member

Just a few thoughts on this -

  1. Should it go into comparison-operators?
  2. Since this is an unsafe transformation, it's better to put this entire transformation behind an option - undefinedToNull or voidToNull or anything else relevant.
  3. Update tests to use thePlugin
  4. t.isIdentifier("undefined") check should also check for bindings in the scope path.scope.getBinding("undefined") there is a defined undefined.

@j-f1
Copy link
Contributor Author

j-f1 commented Aug 14, 2017

@boopathi

  1. 👍
  2. I don’t think it’s unsafe. Why do you think it’s unsafe?
  3. 👍
  4. 👍

@xtuc
Copy link
Member

xtuc commented Aug 17, 2017

@j-f1
Copy link
Contributor Author

j-f1 commented Aug 17, 2017

@boopathi

  1. It’s already in comparison-operators.

@boopathi
Copy link
Member

My question is whether it should go into comparison operators, or should it go into simplify. IMO, Comparison operators simplifies the operator used without changing the operands.

function undefinedToNull(path) {
if (isRealUndefined(path) || isPureVoid(path)) {
path.replaceWith(t.nullLiteral());
return true;
Copy link
Member

@vigneshshanmugam vigneshshanmugam Aug 17, 2017

Choose a reason for hiding this comment

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

is this return true / false required? I don't see it used anywhere for conditional check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed 🔥

Copy link
Member

Choose a reason for hiding this comment

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

👍

function isRealUndefined(path) {
return (
path.isIdentifier({ name: "undefined" }) &&
!path.scope.getBinding("undefined")
Copy link
Member

Choose a reason for hiding this comment

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

why is this check required?. Even if someone does

var undefined = 'blah';

Its a read only property and does not impact our null conversion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@boopathi said:

t.isIdentifier("undefined") check should also check for bindings in the scope path.scope.getBinding("undefined") there is a defined undefined.

Copy link
Member

Choose a reason for hiding this comment

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

/cc @boopathi Any reason why the check is needed? Am i missing some edge case?

Copy link
Member

Choose a reason for hiding this comment

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

function foo(undefined) { return undefined == void 0 } 
foo("bar"); // true or false ?

Copy link
Member

Choose a reason for hiding this comment

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

true even if undefined or both are converted to null

Copy link
Contributor Author

Choose a reason for hiding this comment

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

> function foo(undefined) { return undefined == void 0 } 
> foo("bar"); // true or false ?
// false

Copy link
Member

Choose a reason for hiding this comment

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

okay got it 👍

@boopathi
Copy link
Member

It's not immediately obvious that this goes into comparison-operators plugin. This question still applies -

My question is whether it should go into comparison operators, or should it go into simplify. IMO, Comparison operators simplifies the operator used without changing the operands

@j-f1
Copy link
Contributor Author

j-f1 commented Aug 26, 2017

@boopathi If you’d like me to move it to simplify, I’ll gladly do so. Should I?

@j-f1
Copy link
Contributor Author

j-f1 commented Nov 18, 2017

Sorry for the delay on this @boopathi 😢

I’ve moved the changes to babel-plugin-minify-simplify.

@j-f1
Copy link
Contributor Author

j-f1 commented Nov 19, 2017

Looks like the Travis failure is unrelated. Closing and reopening to restart the build.

@j-f1 j-f1 closed this Nov 19, 2017
@j-f1 j-f1 reopened this Nov 19, 2017
@j-f1
Copy link
Contributor Author

j-f1 commented Dec 10, 2017

Ping @boopathi and @vigneshshanmugam for 👀

@boopathi
Copy link
Member

@j-f1 Hi, Thanks for the PR. Right now let's concentrate on fixing the existing bugs, babel-7, improving the speed of transformations and fixing the memory issue to get it to 1.0. New set of features may delay that. I'll leave it open and postpone it to sometime later.

@boopathi boopathi merged commit 540d75e into babel:master May 14, 2018
@j-f1 j-f1 deleted the patch-1 branch May 14, 2018 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Tag: New Feature Pull Request adding a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants