Skip to content
This repository has been archived by the owner on Jun 12, 2020. It is now read-only.

Update to Adrian's fork #6

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
54a699c
Add missing properties in tests
adrianheine Oct 26, 2017
4978d1a
Make tests check for missing expected properties
adrianheine Oct 26, 2017
546d9ad
Add test for object literal without spread
adrianheine Oct 26, 2017
bf078fa
Remove unused dev dependencies
adrianheine Oct 26, 2017
2265317
Update to acorn 5
adrianheine Oct 26, 2017
7f95015
Add runtime acorn version check
adrianheine Oct 27, 2017
c3777ad
Bump version and switch package name
adrianheine Oct 27, 2017
9b6a4f3
Update package name in README, too
adrianheine Oct 27, 2017
d10af71
Don't handle range and loc in tests
adrianheine Oct 27, 2017
db3122b
Support object rest properties
adrianheine Oct 29, 2017
d32f2b2
Re-use RestElement and SpreadElement
adrianheine Oct 29, 2017
be94d8e
Update README, description and authors
adrianheine Oct 29, 2017
5a71ded
v3.0.0
adrianheine Oct 29, 2017
db17881
Remove dead code
adrianheine Nov 1, 2017
e3db306
Add clarifying comment about AssignmentProperty
adrianheine Nov 1, 2017
685ddfc
Add test
adrianheine Oct 31, 2017
bb92c01
Use parser.extend method
adrianheine Oct 31, 2017
084db53
Support complex rest params
adrianheine Oct 31, 2017
591d0d9
Support rest elements in arrow function arguments
adrianheine Nov 1, 2017
f839494
Check for trailing commas in rest properties
adrianheine Nov 1, 2017
9ef7204
Detect duplicate exports with rest properties
adrianheine Nov 1, 2017
e37209e
Document differences to acorn-object-rest-spread
adrianheine Nov 1, 2017
3308504
Don't complain about duplicate property names in patterns
adrianheine Nov 1, 2017
a203855
v3.1.0
adrianheine Nov 1, 2017
93c2f7f
Fix markdown syntax in README and add difference
adrianheine Nov 1, 2017
6677deb
Disallow nested destructuring or binding
adrianheine Nov 4, 2017
dae631f
v4.0.0
adrianheine Nov 4, 2017
bbe6397
Use parseProperty from recent acorn
adrianheine Oct 29, 2017
3914004
v5.0.0
adrianheine Dec 17, 2017
a70548b
Make compatible with acorn 5.3.0
adrianheine Jan 13, 2018
917165b
Update changelog
adrianheine Jan 13, 2018
658a4f4
v5.1.0
adrianheine Jan 13, 2018
a4ea794
Backport check for default values
adrianheine Jan 16, 2018
49839ac
v5.1.1
adrianheine Jan 16, 2018
55b72c3
New version and deprecate
adrianheine Feb 2, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# acorn5-object-spread changelog

## 5.1.1

* Backport check for default values from acorn 5.3.0

## 5.1.0

* Make plugin compatible with acorn 5.3.x

## 5.0.0

* Require acorn 5.2.x

## 4.0.0

* Remove support for complex rest properties since they are forbidded by the
spec

## 3.1.0

* Support complex rest properties like `{...{a = 5, ...as}}`
* Support rest properties in arrow function arguments
* Fail if rest property is not last property or has a trailing comma
* Detect duplicate exports with rest properties
* Don't complain about duplicate property names in patterns

## 3.0.0

* Support rest properties
* Emit `SpreadElement` instead of `SpreadProperty` nodes
34 changes: 3 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,5 @@
# ObjectSpread support in acorn
# Spread and rest properties support in acorn 5

[![Build Status](https://travis-ci.org/UXtemple/acorn-object-spread.svg?branch=master)](https://travis-ci.org/UXtemple/acorn-object-spread)
[![NPM version](https://img.shields.io/npm/v/acorn-object-spread.svg)](https://www.npmjs.org/package/acorn-object-spread)
[![NPM version](https://img.shields.io/npm/v/acorn5-object-spread.svg)](https://www.npmjs.org/package/acorn5-object-spread)

This is plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.

## Usage

You can use this module directly in order to get Acorn instance with plugin installed:

```javascript
var acorn = require('acorn-object-spread');
```

Or you can use `inject.js` for injecting plugin into your own version of Acorn like this:

```javascript
var acorn = require('acorn-object-spread/inject')(require('./custom-acorn'));
```

Then, use the `plugins` option whenever you need to support objectSpread while parsing:

```javascript
var ast = acorn.parse(code, {
plugins: { objectSpread: true }
});
```
## License

This plugin is issued under the [MIT license](./LICENSE).

With <3 by UXtemple.
Since spread and rest properties are part of ECMAScript 2018, acorn now supports them out of the box. Just make sure that you use acorn >= 5.4.1 and set `ecmaVersion` >= 9. This plugin is deprecated.
120 changes: 85 additions & 35 deletions inject.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,99 @@
'use strict';

module.exports = function(acorn) {
let acornVersion = acorn.version.match(/^5\.(\d+)\./)
if (!acornVersion || Number(acornVersion[1]) < 2) {
throw new Error("Unsupported acorn version " + acorn.version + ", please use acorn 5 >= 5.2");
}
var tt = acorn.tokTypes;
var pp = acorn.Parser.prototype;

// this is the same parseObj that acorn has with...
function parseObj(isPattern, refDestructuringErrors) {
let node = this.startNode(), first = true, propHash = {}
node.properties = []
this.next()
while (!this.eat(tt.braceR)) {
if (!first) {
this.expect(tt.comma)
if (this.afterTrailingComma(tt.braceR)) break
} else first = false
const getCheckLVal = origCheckLVal => function (expr, bindingType, checkClashes) {
if (expr.type == "ObjectPattern") {
for (let prop of expr.properties)
this.checkLVal(prop, bindingType, checkClashes)
return
} else if (expr.type === "Property") {
// AssignmentProperty has type == "Property"
return this.checkLVal(expr.value, bindingType, checkClashes)
}
return origCheckLVal.apply(this, arguments)
}

let prop = this.startNode(), isGenerator, startPos, startLoc
if (this.options.ecmaVersion >= 6) {
// ...the spread logic borrowed from babylon :)
if (this.type === tt.ellipsis) {
prop = this.parseSpread()
prop.type = isPattern ? "RestProperty" : "SpreadProperty"
node.properties.push(prop)
continue
acorn.plugins.objectSpread = function objectSpreadPlugin(instance) {
instance.extend("parseProperty", nextMethod => function (isPattern, refDestructuringErrors) {
if (this.options.ecmaVersion >= 6 && this.type === tt.ellipsis) {
let prop
if (isPattern) {
prop = this.startNode()
this.next()
prop.argument = this.parseIdent()
this.finishNode(prop, "RestElement")
} else {
prop = this.parseSpread(refDestructuringErrors)
}
if (this.type === tt.comma) {
if (isPattern) {
this.raise(this.start, "Comma is not permitted after the rest element")
} else if (refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
refDestructuringErrors.trailingComma = this.start
}
}
return prop
}

prop.method = false
prop.shorthand = false
if (isPattern || refDestructuringErrors) {
startPos = this.start
startLoc = this.startLoc
return nextMethod.apply(this, arguments)
})
instance.extend("checkPropClash", nextMethod => function(prop, propHash) {
if (prop.type == "SpreadElement" || prop.type == "RestElement") return
return nextMethod.apply(this, arguments)
})
instance.extend("checkLVal", getCheckLVal)

// This backports toAssignable from 5.3.0 to 5.2.x
instance.extend("toAssignable", nextMethod => function(node, isBinding, refDestructuringErrors) {
if (this.options.ecmaVersion >= 6 && node) {
if (node.type == "ObjectExpression") {
node.type = "ObjectPattern"
if (refDestructuringErrors) this.checkPatternErrors(refDestructuringErrors, true)
for (let prop of node.properties)
this.toAssignable(prop, isBinding, refDestructuringErrors)
return node
} else if (node.type === "Property") {
// AssignmentProperty has type == "Property"
if (node.kind !== "init") this.raise(node.key.start, "Object pattern can't contain getter or setter")
return this.toAssignable(node.value, isBinding, refDestructuringErrors)
} else if (node.type === "SpreadElement") {
node.type = "RestElement"
this.toAssignable(node.argument, isBinding, refDestructuringErrors)
if (node.argument.type === "AssignmentPattern")
this.raise(node.argument.start, "Rest elements cannot have a default value")
return
}
if (!isPattern)
isGenerator = this.eat(tt.star)
}
this.parsePropertyName(prop)
this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors)
this.checkPropClash(prop, propHash)
node.properties.push(this.finishNode(prop, "Property"))
}
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
}
return nextMethod.apply(this, arguments)
})
instance.extend("toAssignableList", nextMethod => function (exprList, isBinding) {
const result = nextMethod.call(this, exprList, isBinding)
if (exprList.length && exprList[exprList.length - 1] && exprList[exprList.length - 1].type === "RestElement") {
// Backport check from 5.3.0
if (exprList[exprList.length - 1].argument.type === "AssignmentPattern")
this.raise(exprList[exprList.length - 1].argument.start, "Rest elements cannot have a default value")
}
return result
})

acorn.plugins.objectSpread = function objectSpreadPlugin(instance) {
pp.parseObj = parseObj;
instance.extend("checkPatternExport", nextMethod => function(exports, pat) {
if (pat.type == "ObjectPattern") {
for (let prop of pat.properties)
this.checkPatternExport(exports, prop)
return
} else if (pat.type === "Property") {
return this.checkPatternExport(exports, pat.value)
} else if (pat.type === "RestElement") {
return this.checkPatternExport(exports, pat.argument)
}
nextMethod.apply(this, arguments)
})
};

return acorn;
Expand Down
21 changes: 10 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
{
"name": "acorn-object-spread",
"description": "Support object spread in acorn",
"homepage": "https://github.com/UXtemple/acorn-object-spread",
"author": "Darío Javier Cravero <dario@uxtemple.com>",
"name": "acorn5-object-spread",
"description": "Support for rest and spread properties in acorn 5",
"homepage": "https://github.com/adrianheine/acorn5-object-spread",
"contributors": [
"Darío Javier Cravero <dario@uxtemple.com>",
"Adrian Heine <mail@adrianheine.de>"
],
"repository": {
"type": "git",
"url": "https://github.com/UXtemple/acorn-object-spread"
"url": "https://github.com/adrianheine/acorn5-object-spread"
},
"license": "MIT",
"scripts": {
"test": "node test/run.js"
},
"dependencies": {
"acorn": "^3.1.0"
"acorn": "^5.2.1"
},
"devDependencies": {
"chai": "^3.0.0",
"mocha": "^2.2.5"
},
"version": "1.0.0"
"version": "5.1.2"
}
18 changes: 6 additions & 12 deletions test/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,11 @@ var misMatch = exports.misMatch = function(exp, act) {
var mis = misMatch(exp[prop], act[prop]);
if (mis) return addPath(mis, prop);
}
for (var prop in act) {
if (!(prop in exp)) {
var mis = misMatch(exp[prop], act[prop]);
if (mis) return addPath(mis, prop);
}
}
}
};

function mangle(ast) {
if (typeof ast != "object" || !ast) return;
if (ast.slice) {
for (var i = 0; i < ast.length; ++i) mangle(ast[i]);
} else {
var loc = ast.start && ast.end && {start: ast.start, end: ast.end};
if (loc) { delete ast.start; delete ast.end; }
for (var name in ast) if (ast.hasOwnProperty(name)) mangle(ast[name]);
if (loc) ast.loc = loc;
}
}
Loading