acorn-class-fields
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -0,1 +1,5 @@ | ||
## 0.3.0 (2019-02-09) | ||
* Require acorn >= 6.1.0 | ||
## 0.2.1 (2018-11-06) | ||
@@ -2,0 +6,0 @@ |
98
index.js
@@ -7,3 +7,3 @@ "use strict" | ||
const tt = acorn.tokTypes | ||
const TokenType = acorn.TokenType | ||
const privateClassElements = require("acorn-private-class-elements") | ||
@@ -19,46 +19,5 @@ function maybeParseFieldValue(field) { | ||
function parsePrivateName() { | ||
const node = this.startNode() | ||
node.name = this.value | ||
this.next() | ||
this.finishNode(node, "PrivateName") | ||
if (this.options.allowReserved == "never") this.checkUnreserved(node) | ||
return node | ||
} | ||
const privateNameToken = new TokenType("privateName") | ||
module.exports = function(Parser) { | ||
Parser = privateClassElements(Parser) | ||
return class extends Parser { | ||
// Parse # token | ||
getTokenFromCode(code) { | ||
if (code === 35) { | ||
++this.pos | ||
const word = this.readWord1() | ||
return this.finishToken(privateNameToken, word) | ||
} | ||
return super.getTokenFromCode(code) | ||
} | ||
// Manage stacks and check for undeclared private names | ||
parseClass(node, isStatement) { | ||
this._privateBoundNamesStack = this._privateBoundNamesStack || [] | ||
const privateBoundNames = Object.create(this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1] || null) | ||
this._privateBoundNamesStack.push(privateBoundNames) | ||
this._unresolvedPrivateNamesStack = this._unresolvedPrivateNamesStack || [] | ||
const unresolvedPrivateNames = Object.create(null) | ||
this._unresolvedPrivateNamesStack.push(unresolvedPrivateNames) | ||
const _return = super.parseClass(node, isStatement) | ||
this._privateBoundNamesStack.pop() | ||
this._unresolvedPrivateNamesStack.pop() | ||
if (!this._unresolvedPrivateNamesStack.length) { | ||
const names = Object.keys(unresolvedPrivateNames) | ||
if (names.length) { | ||
names.sort((n1, n2) => unresolvedPrivateNames[n1] - unresolvedPrivateNames[n2]) | ||
this.raise(unresolvedPrivateNames[names[0]], "Usage of undeclared private name") | ||
} | ||
} else Object.assign(this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1], unresolvedPrivateNames) | ||
return _return | ||
} | ||
// Parse private fields | ||
@@ -68,3 +27,3 @@ parseClassElement(_constructorAllowsSuper) { | ||
const node = this.startNode() | ||
if (!(this.options.ecmaVersion >= 8) || this.type != privateNameToken) { | ||
if (!(this.options.ecmaVersion >= 8) || this.type != this.privateNameToken) { | ||
// Special-case for `async`, since `parseClassMember` currently looks | ||
@@ -87,8 +46,3 @@ // for `(` to determine whether `async` is a method name | ||
} | ||
node.key = parsePrivateName.call(this) | ||
node.computed = false | ||
if (node.key.name == "constructor") this.raise(node.start, "Classes may not have a field named constructor") | ||
if (Object.prototype.hasOwnProperty.call(this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1], node.key.name)) this.raise(node.start, "Duplicate private element") | ||
this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1][node.key.name] = true | ||
delete this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1][node.key.name] | ||
this.parsePrivateClassElementName(node) | ||
maybeParseFieldValue.call(this, node) | ||
@@ -113,38 +67,2 @@ this.finishNode(node, "FieldDefinition") | ||
// Parse private element access | ||
parseSubscripts(base, startPos, startLoc, noCalls) { | ||
for (let computed; ;) { | ||
if ((computed = this.eat(tt.bracketL)) || this.eat(tt.dot)) { | ||
let node = this.startNodeAt(startPos, startLoc) | ||
node.object = base | ||
if (computed) { | ||
node.property = this.parseExpression() | ||
} else if (this.type == privateNameToken) { | ||
node.property = parsePrivateName.call(this) | ||
if (!this._privateBoundNamesStack.length || !this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1][node.property.name]) { | ||
this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1][node.property.name] = node.property.start | ||
} | ||
} else { | ||
node.property = this.parseIdent(true) | ||
} | ||
node.computed = Boolean(computed) | ||
if (computed) this.expect(tt.bracketR) | ||
base = this.finishNode(node, "MemberExpression") | ||
} else { | ||
return super.parseSubscripts(base, startPos, startLoc, noCalls) | ||
} | ||
} | ||
} | ||
// Prohibit delete of private class elements | ||
parseMaybeUnary(refDestructuringErrors, sawUnary) { | ||
const _return = super.parseMaybeUnary(refDestructuringErrors, sawUnary) | ||
if (_return.operator == "delete") { | ||
if (_return.argument.type == "MemberExpression" && _return.argument.property.type == "PrivateName") { | ||
this.raise(_return.start, "Private elements may not be deleted") | ||
} | ||
} | ||
return _return | ||
} | ||
// Prohibit arguments in class field initializers | ||
@@ -156,11 +74,3 @@ parseIdent(liberal, isBinding) { | ||
} | ||
// Prohibit super in class field initializers | ||
// FIXME: This is not necessary in acorn >= 6.0.3 | ||
parseExprAtom(refDestructuringErrors) { | ||
const atom = super.parseExprAtom(refDestructuringErrors) | ||
if (this._inFieldValue && atom.type == "Super") this.raise(atom.start, "A class field initializer may not contain super") | ||
return atom | ||
} | ||
} | ||
} |
@@ -24,11 +24,14 @@ { | ||
}, | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"devDependencies": { | ||
"acorn": "^6.0.4", | ||
"eslint": "^5.5.0", | ||
"eslint-plugin-node": "^8.0.0", | ||
"acorn": "^6.1.0", | ||
"eslint": "^5.13.0", | ||
"eslint-plugin-node": "^8.0.1", | ||
"mocha": "^5.2.0", | ||
"test262": "git+https://github.com/tc39/test262.git#c0ffc8f6da0f2a7ec87afb87ec5f2664b1ba57ec", | ||
"test262-parser-runner": "^0.4.0" | ||
"test262": "git+https://github.com/tc39/test262.git#33a306d1026b72227eb50a918db19ada16f12b3d", | ||
"test262-parser-runner": "^0.5.0" | ||
}, | ||
"dependencies": { | ||
"acorn-private-class-elements": "^0.1.0" | ||
} | ||
} |
@@ -60,3 +60,3 @@ "use strict" | ||
testFail("class A { constructor = 4 }", "Unexpected token (1:22)") | ||
testFail("class A { #constructor = 4 }", "Classes may not have a field named constructor (1:10)") | ||
testFail("class A { #constructor = 4 }", "Classes may not have a private element named constructor (1:10)") | ||
testFail("class A { a = () => arguments }", "A class field initializer may not contain arguments (1:20)") | ||
@@ -63,0 +63,0 @@ testFail("class A { a = () => super() }", "'super' keyword outside a method (1:20)") |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25245
2
714
+ Addedacorn-private-class-elements@0.1.1(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedbrowser-stdout@1.3.1(transitive)
+ Addedcommander@2.15.1(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addeddebug@3.1.0(transitive)
+ Addeddiff@3.5.0(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.1.2(transitive)
+ Addedgrowl@1.10.5(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addedhe@1.1.1(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedminimatch@3.0.4(transitive)
+ Addedminimist@0.0.8(transitive)
+ Addedmkdirp@0.5.1(transitive)
+ Addedmocha@5.2.0(transitive)
+ Addedms@2.0.0(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedsupports-color@5.4.0(transitive)
+ Addedwrappy@1.0.2(transitive)