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

Partial Application Syntax: Stage 1 #9343

Closed
wants to merge 0 commits into from
Closed

Partial Application Syntax: Stage 1 #9343

wants to merge 0 commits into from

Conversation

byara
Copy link
Contributor

@byara byara commented Jan 15, 2019

Q                       A
Fixed Issues? Fixes #9342
Patch: Bug Fix? No
Major: Breaking Change? No
Minor: New Feature? Yes
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT
  • I modified parseExprListItem and added a new condition that checks for tt.comma and another boolean called allowPlaceholder. Then I check for the plugin and add the node Partial
  • I added a boolean argument allowPlaceholder in parseCallExpressionArguments and parseExprListItem to able to check if using ? is allowed or not, so I can throw and error.
  • I added 9 tests.

@babel-bot
Copy link
Collaborator

babel-bot commented Jan 15, 2019

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

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.

Thank you for working on this proposal! I think that it could help having better discussions around the pipeline proposal.

cc @rbuckton (proposal champion) could you take a quick look at the tests?

@@ -807,6 +809,9 @@ export default class ExpressionParser extends LValParser {
}
return this.finishNode(node, "Super");

case tt.question:
node = this.startNode();
this.raise(node.start, "Partial Application syntax is not allowed");
Copy link
Member

Choose a reason for hiding this comment

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

What are these lines needed for?

Copy link
Contributor Author

@byara byara Jan 16, 2019

Choose a reason for hiding this comment

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

I wanted to be able to throw a message whenever the user is using an invalid syntax.
I added a boolean allowPlaceholder to parseExprListItem and parseCallExpressionArguments and thought, I could set it to false whenever we do not want to allow the usage of ?.
Maybe I could throw the error message with another conditional here:

} else if (this.match(tt.question)) {
      if (!allowPlaceholder){
        const node = this.startNode();
        this.raise(node.start, "Partial Application syntax is not allowed");
      }
      this.expectPlugin("partialApplication");
      const node = this.startNode();
      this.next();
      elt = this.finishNode(node, "Partial");
}

Copy link
Contributor Author

@byara byara Jan 16, 2019

Choose a reason for hiding this comment

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

Also another solution could be to let Babel throw its own errors.

Copy link
Member

Choose a reason for hiding this comment

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

The default error would be unexpected ?. it's ok either way.

Choose a reason for hiding this comment

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

I like the allowPlaceholder idea from @byara , it can evolve into something more specific and make the users aware of when a partial application is allowed and when it's not, taking examples from https://github.com/tc39/proposal-partial-application#syntax we can tell the user we can point the user on the right direction instead of having him figure out why he's seeing an unexpected ? error.

@@ -603,6 +605,16 @@ Any expression node. Since the left-hand side of an assignment may be any expres

## Super

```js
interface PartialExpression <: Node {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we could call it ArgumentPlaceholder?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I was just trying to follow the Grammar section of the proposal: Grammar. But I also think, ArgumentPlaceholder shows the purpose better.

@nicolo-ribaudo nicolo-ribaudo added PR: New Feature 🚀 A type of pull request used for our changelog categories pkg: parser Spec: Partial Application labels Jan 15, 2019
@@ -125,6 +125,10 @@ export function OptionalMemberExpression(node: Object) {
}
}

export function Partial() {
Copy link
Member

Choose a reason for hiding this comment

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

This name doesn't match with the name defined in the parser. Also, could you add a generator test?

Copy link
Contributor Author

@byara byara Jan 16, 2019

Choose a reason for hiding this comment

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

Sure, I'll add tests for the generator.
Do you mean in: packages/babel-parser/src/types.js
I see that I made a mistake there. I'll fix it 👍
I named it PartialExpression, thinking we can take it as an expression but remembered that the proposal does not consider this to be an expression.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Additionally, I suppose, I can move this function to src/generators/types.js? Because we are not considering Partial (or if we call it ArgumentPlaceholder) to be an expression.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah good idea (I still prefer ArgumentPlaceholder)

@byara
Copy link
Contributor Author

byara commented Jan 18, 2019

  • I renamed the node to ArgumentPlaceholder and added tests for the babel-generator.
  • I'm not sure about the type of the node though. In babel-types/src/validators/generated/index.js and babel-types/src/definitions/experimental.js I have put the node under UnaryLike but I'm not sure about it.
  • After I made the change in babel-types/src/validators/generated/index.js, adding ArgumentPlaceholder under UnaryLike, make build, creates a few functions automatically, not sure if that is normal.
  • for now, I removed the Error message, but if we decide it is a good idea, I'll put it back.
    (I'm also working on my own implementation of the plugin for this proposal)

@nicolo-ribaudo
Copy link
Member

I renamed the node to ArgumentPlaceholder and added tests for the babel-generator.

👍

I'm not sure about the type of the node though. In babel-types/src/validators/generated/index.js and babel-types/src/definitions/experimental.js I have put the node under UnaryLike but I'm not sure about it.

? is not an unary operator, I don't think that there should be any alias.

After I made the change in babel-types/src/validators/generated/index.js, adding ArgumentPlaceholder under UnaryLike, make build, creates a few functions automatically, not sure if that is normal.

All the files inside */generated/* are automatically created by the build process. You should only edit the files inside definitions.

@byara
Copy link
Contributor Author

byara commented Jan 18, 2019

? is not an unary operator, I don't think that there should be any alias.

removed the alias

All the files inside /generated/ are automatically created by the build process. You should only edit the files inside definitions.

removed my changes from the generated folder.

I'll try to add more test cases for the parser and generator.

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.

removed my changes from the generated folder.

Sorry if I wasn't clear; I meant that it is correct to have those auto-generated files.

visitor: ["argument"],
fields: {
argument: {
validate: assertNodeType("ArgumentPlaceholder"),
Copy link
Member

Choose a reason for hiding this comment

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

This would mean that the AST is something like this:

{
  "type": "ArgumentPlaceholder",
  "argument": {
    "type": "ArgumentPlaceholder",
    // ...
  }
}

It should only be this:

defineType("ArgumentPlaceholder", {});

@@ -1940,6 +1943,11 @@ export default class ExpressionParser extends LValParser {
if (refTrailingCommaPos && this.match(tt.comma)) {
refTrailingCommaPos.start = this.state.start;
}
} else if (allowPlaceholder && this.match(tt.question)) {
Copy link
Member

Choose a reason for hiding this comment

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

Wdyt about this logic, to have better errors?

} else if (this.match(tt.question)) {
  this.expectPlugin("partialApplication");
  if (allowPlaceholder) {
    this.raise(this.state.start, "Unexpected argument placeholder");
  }
  // ...

Copy link
Contributor Author

@byara byara Jan 21, 2019

Choose a reason for hiding this comment

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

I like this! It has a clear message and does not confuse the user. The user will understand that they should not use ArgumentPlaceholder there. I'll apply it in my next push.

P.S. I should apply the negated one right?

if (!allowPlaceholder) {
    this.raise(this.state.start, "Unexpected argument placeholder");
  }

@@ -36,7 +37,7 @@ These are the core @babel/parser (babylon) AST node types.
- [DoWhileStatement](#dowhilestatement)
- [ForStatement](#forstatement)
- [ForInStatement](#forinstatement)
- [ForOfStatement](#forofstatement)
- [ForOfStatement](#forofstatement)
Copy link
Member

Choose a reason for hiding this comment

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

Are these indent changes auto-generated? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I didn't change anything about the list, I just added my change in spec and the list was generated for me 🤔

Copy link
Member

@danez danez Feb 12, 2019

Choose a reason for hiding this comment

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

I don't think this file is autogenerated, maybe it was one of your ide extensions, or formatter?
Can you revert this line and the one above in Changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. Apparently, Markdown All in One was doing auto formatting.

@@ -10,6 +10,8 @@ import {
classMethodOrDeclareMethodCommon,
} from "./es2015";

defineType("ArgumentPlaceholder", {});
Copy link
Member

Choose a reason for hiding this comment

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

We should also update the CallExpression definition to accept placeholder arguments

Copy link
Contributor Author

@byara byara Jan 23, 2019

Choose a reason for hiding this comment

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

@nicolo-ribaudo You mean in /packages/babel-types/src/definitions/core.js I have to add another assert node type like this:

defineType("CallExpression", {
  visitor: ["callee", "arguments", "typeParameters", "typeArguments"],
  builder: ["callee", "arguments"],
  aliases: ["Expression"],
  fields: {
    callee: {
      validate: assertNodeType("Expression"),
    },
    arguments: {
      validate: chain(
        assertValueType("array"),
        assertEach(
          assertNodeType(
            "Expression",
            "SpreadElement",
            "JSXNamespacedName",
            "ArgumentPlaceholder",
          ),
        ),
      ),
    },
...

{
"name": "@babel/plugin-syntax-partial-application",
"version": "7.2.0",
"description": "Allow parsing of optional properties",
Copy link
Member

Choose a reason for hiding this comment

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

This description needs to be updated

@byara
Copy link
Contributor Author

byara commented Jan 24, 2019

@nicolo-ribaudo I was looking through the changes and I noticed that I have missed a few one things thing:

  • forbidding the usage with SpreadElement
  • allowing the usage in TemplateLiteral
    What do you think? Should I address them in this PR? or another one?

@rbuckton
Copy link

Partial application in tagged templates was pretty much rejected in a previous TC39 meeting, so I plan to remove that from the proposal for the time being.

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Jan 24, 2019

forbidding the usage with SpreadElement

Do you mean that foo(?, ...arr) isn't valid? Or are you talking about foo(...)?

@byara
Copy link
Contributor Author

byara commented Jan 24, 2019

forbidding the usage with SpreadElement

Do you mean that foo(?, ...arr) isn't valid? Or are you talking about foo(...)?

Right now, we can parse foo(?, ...arr). But as I was reading this part of the proposal, I had the impression that maybe we shouldn't parse it?

@nicolo-ribaudo
Copy link
Member

I think that that part is only disallowing the old proposed foo(...) syntax (rest placeholder), not foo(?, ...a).

@byara
Copy link
Contributor Author

byara commented Jan 24, 2019

I think that that part is only disallowing the old proposed foo(...) syntax (rest placeholder), not foo(?, ...a).

I knew I got it wrong! Then I guess everything is alright!
I'm also ready to make a PR for the plugin (It's like 90% done).

@nicolo-ribaudo
Copy link
Member

Lets just wait for anather review so that this PR can be merged. Can you rebase it in the meantime?

@byara
Copy link
Contributor Author

byara commented Jan 24, 2019

Lets just wait for anather review so that this PR can be merged. Can you rebase it in the meantime?

Sure! I'll do that 👍

Copy link
Member

@danez danez left a comment

Choose a reason for hiding this comment

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

Looks good to me, I only added some comments about some nits in the markdown file.
Thank you

@@ -862,6 +865,14 @@ interface SpreadElement <: Node {
}
```

## ArgumentPlaceholder
Copy link
Member

Choose a reason for hiding this comment

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

on more level please ###

@@ -72,6 +73,7 @@ These are the core @babel/parser (babylon) AST node types.
- [LogicalExpression](#logicalexpression)
- [LogicalOperator](#logicaloperator)
- [SpreadElement](#spreadelement)
- [ArgumentPlaceholder](#argumentplaceholder)
Copy link
Member

Choose a reason for hiding this comment

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

should also be intended one more level.

@@ -36,7 +37,7 @@ These are the core @babel/parser (babylon) AST node types.
- [DoWhileStatement](#dowhilestatement)
- [ForStatement](#forstatement)
- [ForInStatement](#forinstatement)
- [ForOfStatement](#forofstatement)
- [ForOfStatement](#forofstatement)
Copy link
Member

@danez danez Feb 12, 2019

Choose a reason for hiding this comment

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

I don't think this file is autogenerated, maybe it was one of your ide extensions, or formatter?
Can you revert this line and the one above in Changes?

@@ -601,6 +603,7 @@ interface Expression <: Node { }

Any expression node. Since the left-hand side of an assignment may be any expression in general, an expression can also be a pattern.


Copy link
Member

Choose a reason for hiding this comment

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

not necessary

@nicolo-ribaudo nicolo-ribaudo added the PR: Ready to be Merged A pull request with already two approvals, but waiting for the next minor release label Feb 19, 2019
@nicolo-ribaudo
Copy link
Member

@byara Thank you! We will merge this PR when we decide to release v7.4.0. In the meantime, could you squash it and rebase the other PR on top of this one?

Copy link
Member

@existentialism existentialism left a comment

Choose a reason for hiding this comment

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

Nice work 👍

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Mar 4, 2019

I'm merging this locally since it has some conflicts

nicolo-ribaudo pushed a commit that referenced this pull request Mar 4, 2019
* add partial application syntax and some tests

* remove unnecessary error message and hasPartial function from parseNewArguments

* add types for PartialExpression

* Update the tests

* rename PartialExpression to Partial

* move Partial from expressions to types and rename to ArgumentPlaceholder

* add tests for ArgumentPlaceholder in babel-generator

* rename Partial to ArgumentPlaceholder

* update the tests

* remove alias from the type and undo changes in generated folder

* adds a nice error message

* better definition for the type

* auto-generated files

* update the conditional for allowPlaceholder message and tests

* update CallExpression definition to accept ArgumentPlaceholder

* change description

* clean up

* indent ArgumentPlaceholder entry and revert unwanted changes
@nicolo-ribaudo nicolo-ribaudo changed the title Partial Application Syntax: Stage 1 [MERGED] Partial Application Syntax: Stage 1 Mar 4, 2019
@nicolo-ribaudo nicolo-ribaudo changed the title [MERGED] Partial Application Syntax: Stage 1 Partial Application Syntax: Stage 1 Mar 16, 2019
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 4, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser PR: New Feature 🚀 A type of pull request used for our changelog categories PR: Ready to be Merged A pull request with already two approvals, but waiting for the next minor release Spec: Partial Application
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Partial Application syntax: Stage 1
7 participants