Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Fix parsing of private fields #566

Merged
merged 1 commit into from
Jun 6, 2017
Merged

Fix parsing of private fields #566

merged 1 commit into from
Jun 6, 2017

Conversation

danez
Copy link
Member

@danez danez commented Jun 5, 2017

Q A
Bug fix? yes
Breaking change? no
New feature? no
Deprecations? no
Spec compliancy? yes
Tests added/pass? yes
Fixed tickets
License MIT

Do not parse computed and literal keys for PrivateClassProperties. By looking at the spec it should always be an Identifier afaics. This also removes the computed key as it will always be false, and it is not mentioned in the spec.

so this should not work I think:

class B {
  #"x";
  #1;
  #["as"];
}

Little unrelated:
I also noticed that our spec and types say, that key for ClassProperties (non-private) is an Identifier, but the current official spec says it is: StringLiteral | NumericLiteral | Identifier | ComputerProperty so I went with Expression, same as ClassMethod.

This all parses fine and I think it is correct:

class A {
  "b" = 1;
  3=4;
  ["as"+"s"];
}

@codecov
Copy link

codecov bot commented Jun 5, 2017

Codecov Report

Merging #566 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #566   +/-   ##
=======================================
  Coverage   98.15%   98.15%           
=======================================
  Files          22       22           
  Lines        3625     3625           
  Branches     1012     1012           
=======================================
  Hits         3558     3558           
  Misses         24       24           
  Partials       43       43
Flag Coverage Δ
#babel 80.33% <50%> (ø) ⬆️
#babylon 96.82% <100%> (ø) ⬆️
Impacted Files Coverage Δ
src/plugins/flow.js 98.39% <ø> (ø) ⬆️
src/parser/expression.js 96.88% <100%> (ø) ⬆️
src/parser/statement.js 99.11% <100%> (ø) ⬆️

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 e579109...9026b8e. Read the comment docs.

@codecov
Copy link

codecov bot commented Jun 5, 2017

Codecov Report

Merging #566 into master will not change coverage.
The diff coverage is 66.66%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #566   +/-   ##
=======================================
  Coverage   98.14%   98.14%           
=======================================
  Files          22       22           
  Lines        3663     3663           
  Branches     1023     1023           
=======================================
  Hits         3595     3595           
  Misses         25       25           
  Partials       43       43
Flag Coverage Δ
#babel 79.66% <33.33%> (ø) ⬆️
#babylon 96.83% <66.66%> (ø) ⬆️
Impacted Files Coverage Δ
src/plugins/flow.js 98.39% <ø> (ø) ⬆️
src/parser/statement.js 99.11% <100%> (ø) ⬆️
src/parser/expression.js 96.88% <50%> (ø) ⬆️

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 e5e4981...7d3d7c1. Read the comment docs.

@hzoo hzoo requested a review from littledan June 5, 2017 15:16
equals(p) { return this.#x === p.#x && this.#y === p.#y }

toString() { return `Point<${ this.#x },${ this.#y }>` }
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This test was duplicate

@@ -1,4 +1,4 @@
class Foo {
#p = x
[#m] () {}
Copy link
Member Author

Choose a reason for hiding this comment

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

This would have been fine actually, besides the method. This looks totally valid to me:

class A {
  #x = 1 // private field
  [#x] = 2 // public field
}

Choose a reason for hiding this comment

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

That public field/method definition on the third line should throw a ReferenceError at parse time, as the private name is unresolvable. But, yes, totally fine from a narrow grammar perspective, if Babylon doesn't enforce Static Semantics: Early Errors.

Copy link
Contributor

Choose a reason for hiding this comment

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

Have you created a test for this?

Copy link
Member Author

@danez danez Jun 6, 2017

Choose a reason for hiding this comment

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

I think my example should throw, by looking at it again.

What I meant is this:

class A {
  #x = 1 
  [this.#x] = 2
  //or
  #y = this.#x
}

But these are also early errors?

Choose a reason for hiding this comment

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

#4 should be a syntax error, as # needs to be followed by an IdentifierName.\

[this.#x] should be a ReferenceError when the class declaration is executed, as #x is "in scope" as a name during the evaluation of computed property names, but then #x cannot possibly be present on this.

Copy link
Member Author

@danez danez Jun 6, 2017

Choose a reason for hiding this comment

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

Upps, the #4 was not intended to be there. Basically I wanted to show initializing a private field from another private field.

Copy link
Contributor

@diervo diervo left a comment

Choose a reason for hiding this comment

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

LGTM

@diervo
Copy link
Contributor

diervo commented Jun 5, 2017

@littledan should review the expression, we might be allowing more use cases than the spec intended

@@ -1,4 +1,4 @@
class Foo {
#p = x
[#m] () {}

Choose a reason for hiding this comment

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

That public field/method definition on the third line should throw a ReferenceError at parse time, as the private name is unresolvable. But, yes, totally fine from a narrow grammar perspective, if Babylon doesn't enforce Static Semantics: Early Errors.

@@ -0,0 +1,4 @@
class Foo {
#"p" = x
#2 = y

Choose a reason for hiding this comment

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

It'd be nice to break this out into a separate test file, so you can check that each of them is a syntax error.

@@ -0,0 +1,4 @@
class Foo {
#p = x
#m () {}

Choose a reason for hiding this comment

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

Good to have a test for this; I hope we can remove it soon :)

@littledan
Copy link

@diervo Looks like the key for a ClassMethod is an Expression. This should be the same as whatever the key of a class method is. With hindsight, Babel might've gone for a more restrictive choice that more closely encodes the grammar, so that transforms can operate with a little more confidence and determinism, but Expression is a reasonable choice that expresses the possibilities.

The computed key is not part of the spec.
key for ClassProperties is an Expression
Do not parse computed and literal keys for PrivateClassProperties
@hzoo hzoo merged commit 69cba43 into master Jun 6, 2017
@hzoo hzoo deleted the priv branch June 28, 2017 10:29
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants