Skip to content

Null Propagation Operator#5786

Closed
xtuc wants to merge 10 commits intobabel:7.0from
xtuc:feat-optionnal-chaining
Closed

Null Propagation Operator#5786
xtuc wants to merge 10 commits intobabel:7.0from
xtuc:feat-optionnal-chaining

Conversation

@xtuc
Copy link
Copy Markdown
Member

@xtuc xtuc commented May 28, 2017

Q A
Patch: Bug Fix? n
Major: Breaking Change? n
Minor: New Feature? y
Deprecations? n
Spec Compliancy? y
Tests Added/Pass? y/?
Fixed Tickets
License MIT
Doc PR
Dependency Changes

Parser PR babel/babylon#545

Supported transformations:

  • Function call
foo?.bar()
  • Member access
foo?.bar
  • Assignment
a?.b = 42

TODO

  • Create the corresponding syntax plugin (for the optionalChaining Babylon plugin)
  • Fully support delete

@xtuc xtuc added es-proposal area: experimental PR: New Feature 🚀 A type of pull request used for our changelog categories labels May 28, 2017

function setOptionalTransformed(node) {
t.assertMemberExpression(node); // Dev
node._optionalTransformed = true;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd prefer to add nodes to a WeakSet instead of putting extra props in it

@@ -0,0 +1,160 @@
export default function ({ types: t }) {
const nilIdentifier = t.identifier("undefined");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

t.unaryExpression('void', t.numericLiteral(0)) would be safer here; avoids any potential trouble with shadowing.

Copy link
Copy Markdown
Member Author

@xtuc xtuc May 29, 2017

Choose a reason for hiding this comment

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

Yes, and will avoid a custom undefined value.

);

// FIXME(sven): if will be a ConditionalExpression for childs, only top level will be ifStatement
const remplacement = t.ifStatement(isChainNil, t.blockStatement([t.expressionStatement(path.node)]));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

typo

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, thanks.

return;
}

if (!isNodeOptional(argument) || isOptionalTransformed(argument)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What happens on, say, delete a.b?.c? the argument is not directly optional.

nilIdentifier,
);

const remplacement = t.ifStatement(isChainNil, t.blockStatement([t.expressionStatement(path.node)]));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

typo here as well

nilIdentifier,
),
nilIdentifier,
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like it will skip deleting keys that exist but are set to undefined.

var o = { foo: undefined }
assertTrue(Object.keys(o).includes('foo'))
delete o?.foo
assertFalse(Object.keys(o).includes('foo'))

state.optionalTemp,
object,
property,
t.callExpression(t.identifier("Function"), []),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you do this under CSP? Or does it only block invoking Function if it actually receives an argument?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In the worst case it can be replaced with t.functionExpression(null, [], t.blockStatement([])). This also avoids risk of shadowing, though, at the cost of 2 extra bytes when minified.

@hzoo
Copy link
Copy Markdown
Member

hzoo commented Jun 5, 2017

Alright closing this in favor of #5813!

@hzoo hzoo closed this Jun 5, 2017
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 6, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Has PR outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: New Feature 🚀 A type of pull request used for our changelog categories Spec: Optional Chaining

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants