Skip to content

Commit

Permalink
Merge pull request #19 from eslint/methodshorthand
Browse files Browse the repository at this point in the history
New: Add support for object literal method shorthand (refs #10)
  • Loading branch information
nzakas committed Dec 23, 2014
2 parents 620579d + cf86722 commit b3276f9
Show file tree
Hide file tree
Showing 8 changed files with 510 additions and 34 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ var ast = espree.parse(code, {
forOf: false,

// enable parsing computed object literal properties
objectLiteralComputedProperties: false
objectLiteralComputedProperties: false,

// enable parsing of shorthand object literal methods
objectLiteralShorthandMethods: false
}
});
```
Expand Down
102 changes: 70 additions & 32 deletions espree.js
Original file line number Diff line number Diff line change
Expand Up @@ -1941,17 +1941,41 @@ function parseArrayInitialiser() {

// 11.1.5 Object Initialiser

function parsePropertyFunction(param, first) {
var previousStrict, body, startToken;
function parsePropertyFunction(params, first) {
var previousStrict = strict,
startToken = lookahead,
body;

previousStrict = strict;
startToken = lookahead;
body = parseFunctionSourceElements();
if (first && strict && syntax.isRestrictedWord(param[0].name)) {
params = params || [];
body = parseConciseBody();

if (first && strict && syntax.isRestrictedWord(params[0].name)) {
throwErrorTolerant(first, Messages.StrictParamName);
}

strict = previousStrict;

return delegate.markEnd(delegate.createFunctionExpression(null, params, [], body), startToken);
}


function parsePropertyMethodFunction() {
var previousStrict, tmp, method;

previousStrict = strict;
strict = true;

tmp = parseParams();

if (tmp.stricted) {
throwErrorTolerant(tmp.stricted, tmp.message);
}

method = parsePropertyFunction(tmp.params);

strict = previousStrict;
return delegate.markEnd(delegate.createFunctionExpression(null, param, [], body), startToken);

return method;
}

function parseObjectPropertyKey() {
Expand Down Expand Up @@ -1985,7 +2009,8 @@ function parseObjectPropertyKey() {

function parseObjectProperty() {
var token, key, id, value, param, startToken, computed;
var allowComputed = extra.ecmaFeatures.objectLiteralComputedProperties;
var allowComputed = extra.ecmaFeatures.objectLiteralComputedProperties,
allowMethod = extra.ecmaFeatures.objectLiteralShorthandMethods;

token = lookahead;
startToken = lookahead;
Expand Down Expand Up @@ -2024,6 +2049,10 @@ function parseObjectProperty() {
return delegate.markEnd(delegate.createProperty("init", id, parseAssignmentExpression(), false, false, computed), startToken);
}

if (allowMethod && match("(")) {
return delegate.markEnd(delegate.createProperty("init", id, parsePropertyMethodFunction({ generator: false }), true, false, computed), startToken);
}

if (computed) {
// Computed properties can only be used with full notation.
throwUnexpected(lookahead);
Expand Down Expand Up @@ -2052,34 +2081,36 @@ function parseObjectInitialiser() {
while (!match("}")) {
property = parseObjectProperty();

if (property.key.type === astNodeTypes.Identifier) {
name = property.key.name;
} else {
name = toString(property.key.value);
}

/*eslint-disable no-nested-ternary*/
kind = (property.kind === "init") ? PropertyKind.Data : (property.kind === "get") ? PropertyKind.Get : PropertyKind.Set;
/*eslint-enable no-nested-ternary*/
if (!property.computed) {
if (property.key.type === astNodeTypes.Identifier) {
name = property.key.name;
} else {
name = toString(property.key.value);
}

key = "$" + name;
if (Object.prototype.hasOwnProperty.call(map, key)) {
if (map[key] === PropertyKind.Data) {
if (strict && kind === PropertyKind.Data) {
throwErrorTolerant({}, Messages.StrictDuplicateProperty);
} else if (kind !== PropertyKind.Data) {
throwErrorTolerant({}, Messages.AccessorDataProperty);
/*eslint-disable no-nested-ternary*/
kind = (property.kind === "init") ? PropertyKind.Data : (property.kind === "get") ? PropertyKind.Get : PropertyKind.Set;
/*eslint-enable no-nested-ternary*/

key = "$" + name;
if (Object.prototype.hasOwnProperty.call(map, key)) {
if (map[key] === PropertyKind.Data) {
if (strict && kind === PropertyKind.Data) {
throwErrorTolerant({}, Messages.StrictDuplicateProperty);
} else if (kind !== PropertyKind.Data) {
throwErrorTolerant({}, Messages.AccessorDataProperty);
}
} else {
if (kind === PropertyKind.Data) {
throwErrorTolerant({}, Messages.AccessorDataProperty);
} else if (map[key] & kind) {
throwErrorTolerant({}, Messages.AccessorGetSet);
}
}
map[key] |= kind;
} else {
if (kind === PropertyKind.Data) {
throwErrorTolerant({}, Messages.AccessorDataProperty);
} else if (map[key] & kind) {
throwErrorTolerant({}, Messages.AccessorGetSet);
}
map[key] = kind;
}
map[key] |= kind;
} else {
map[key] = kind;
}

properties.push(property);
Expand Down Expand Up @@ -3262,6 +3293,13 @@ function parseStatement() {

// 13 Function Definition

function parseConciseBody() {
if (match("{")) {
return parseFunctionSourceElements();
}
return parseAssignmentExpression();
}

function parseFunctionSourceElements() {
var sourceElement, sourceElements = [], token, directive, firstRestricted,
oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, startToken;
Expand Down
5 changes: 4 additions & 1 deletion lib/features.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,8 @@ module.exports = {
forOf: false,

// enable parsing computed object literal properties
objectLiteralComputedProperties: false
objectLiteralComputedProperties: false,

// enable parsing of shorthand object literal methods
objectLiteralShorthandMethods: false
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
objectLiteralShorthandMethods: true,
objectLiteralComputedProperties: true
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
module.exports = {
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "x",
"range": [
4,
5
],
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
}
}
},
"init": {
"type": "ObjectExpression",
"properties": [
{
"type": "Property",
"key": {
"type": "Identifier",
"name": "foo",
"range": [
15,
18
],
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 8
}
}
},
"value": {
"type": "FunctionExpression",
"id": null,
"params": [],
"defaults": [],
"body": {
"type": "BlockStatement",
"body": [
{
"type": "ReturnStatement",
"argument": {
"type": "Identifier",
"name": "bar",
"range": [
39,
42
],
"loc": {
"start": {
"line": 3,
"column": 15
},
"end": {
"line": 3,
"column": 18
}
}
},
"range": [
32,
43
],
"loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 19
}
}
}
],
"range": [
22,
49
],
"loc": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 4,
"column": 5
}
}
},
"rest": null,
"generator": false,
"expression": false,
"range": [
22,
49
],
"loc": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 4,
"column": 5
}
}
},
"kind": "init",
"method": true,
"shorthand": false,
"computed": true,
"range": [
14,
49
],
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 4,
"column": 5
}
}
}
],
"range": [
8,
51
],
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 5,
"column": 1
}
}
},
"range": [
4,
51
],
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 5,
"column": 1
}
}
}
],
"kind": "var",
"range": [
0,
52
],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 5,
"column": 2
}
}
}
],
"range": [
0,
52
],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 5,
"column": 2
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var x = {
[foo]() {
return bar;
}
};
Loading

0 comments on commit b3276f9

Please sign in to comment.