mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Enchancing pattern matching with @vars ... issue #721
This commit is contained in:
parent
8eb283df2c
commit
d1bca6364a
7 changed files with 220 additions and 175 deletions
|
@ -88,7 +88,7 @@
|
|||
AssignObj: [
|
||||
o("Identifier", function() {
|
||||
return new ValueNode($1);
|
||||
}), o("AlphaNumeric"), o("Identifier : Expression", function() {
|
||||
}), o("AlphaNumeric"), o("ThisProperty"), o("Identifier : Expression", function() {
|
||||
return new AssignNode(new ValueNode($1), $3, 'object');
|
||||
}), o("AlphaNumeric : Expression", function() {
|
||||
return new AssignNode(new ValueNode($1), $3, 'object');
|
||||
|
@ -309,7 +309,7 @@
|
|||
],
|
||||
ThisProperty: [
|
||||
o("@ Identifier", function() {
|
||||
return new ValueNode(new LiteralNode('this'), [new AccessorNode($2)]);
|
||||
return new ValueNode(new LiteralNode('this'), [new AccessorNode($2)], 'this');
|
||||
})
|
||||
],
|
||||
Range: [
|
||||
|
|
15
lib/nodes.js
15
lib/nodes.js
|
@ -300,11 +300,14 @@
|
|||
return ReturnNode;
|
||||
})();
|
||||
exports.ValueNode = (function() {
|
||||
ValueNode = function(_arg, _arg2) {
|
||||
ValueNode = function(_arg, _arg2, tag) {
|
||||
this.properties = _arg2;
|
||||
this.base = _arg;
|
||||
ValueNode.__super__.constructor.call(this);
|
||||
this.properties || (this.properties = []);
|
||||
if (tag) {
|
||||
this.tags[tag] = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
__extends(ValueNode, BaseNode);
|
||||
|
@ -798,7 +801,9 @@
|
|||
join = '';
|
||||
}
|
||||
indent = prop instanceof CommentNode ? '' : this.idt(1);
|
||||
if (!(prop instanceof AssignNode || prop instanceof CommentNode)) {
|
||||
if (prop instanceof ValueNode && prop.tags['this']) {
|
||||
prop = new AssignNode(prop.properties[0].name, prop, 'object');
|
||||
} else if (!(prop instanceof AssignNode) && !(prop instanceof CommentNode)) {
|
||||
prop = new AssignNode(prop, prop, 'object');
|
||||
}
|
||||
return indent + prop.compile(o) + join;
|
||||
|
@ -1018,7 +1023,11 @@
|
|||
if (obj instanceof AssignNode) {
|
||||
_ref2 = [obj.value, obj.variable.base], obj = _ref2[0], idx = _ref2[1];
|
||||
} else {
|
||||
idx = obj;
|
||||
if (obj.tags['this']) {
|
||||
idx = obj.properties[0].name;
|
||||
} else {
|
||||
idx = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(obj instanceof ValueNode || obj instanceof SplatNode)) {
|
||||
|
|
332
lib/parser.js
332
lib/parser.js
File diff suppressed because one or more lines are too long
|
@ -149,6 +149,7 @@ grammar =
|
|||
AssignObj: [
|
||||
o "Identifier", -> new ValueNode $1
|
||||
o "AlphaNumeric"
|
||||
o "ThisProperty"
|
||||
o "Identifier : Expression", -> new AssignNode new ValueNode($1), $3, 'object'
|
||||
o "AlphaNumeric : Expression", -> new AssignNode new ValueNode($1), $3, 'object'
|
||||
o "Identifier : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'object'
|
||||
|
@ -340,7 +341,7 @@ grammar =
|
|||
|
||||
# A reference to a property on *this*.
|
||||
ThisProperty: [
|
||||
o "@ Identifier", -> new ValueNode new LiteralNode('this'), [new AccessorNode($2)]
|
||||
o "@ Identifier", -> new ValueNode new LiteralNode('this'), [new AccessorNode($2)], 'this'
|
||||
]
|
||||
|
||||
# The CoffeeScript range literal.
|
||||
|
|
|
@ -294,9 +294,10 @@ exports.ValueNode = class ValueNode extends BaseNode
|
|||
children: ['base', 'properties']
|
||||
|
||||
# A **ValueNode** has a base and a list of property accesses.
|
||||
constructor: (@base, @properties) ->
|
||||
constructor: (@base, @properties, tag) ->
|
||||
super()
|
||||
@properties or= []
|
||||
@tags[tag] = yes if tag
|
||||
|
||||
# Add a property access to the list.
|
||||
push: (prop) ->
|
||||
|
@ -713,7 +714,10 @@ exports.ObjectNode = class ObjectNode extends BaseNode
|
|||
join = "\n" if (prop is lastNoncom) or (prop instanceof CommentNode)
|
||||
join = '' if i is @properties.length - 1
|
||||
indent = if prop instanceof CommentNode then '' else @idt 1
|
||||
prop = new AssignNode prop, prop, 'object' unless prop instanceof AssignNode or prop instanceof CommentNode
|
||||
if prop instanceof ValueNode and prop.tags['this']
|
||||
prop = new AssignNode prop.properties[0].name, prop, 'object'
|
||||
else if prop not instanceof AssignNode and prop not instanceof CommentNode
|
||||
prop = new AssignNode prop, prop, 'object'
|
||||
indent + prop.compile(o) + join
|
||||
props = props.join('')
|
||||
obj = '{' + (if props then '\n' + props + '\n' + @idt() else '') + '}'
|
||||
|
@ -900,8 +904,12 @@ exports.AssignNode = class AssignNode extends BaseNode
|
|||
# A regular object pattern-match.
|
||||
[obj, idx] = [obj.value, obj.variable.base]
|
||||
else
|
||||
# A shorthand `{a, b, c} = val` pattern-match.
|
||||
idx = obj
|
||||
if obj.tags['this']
|
||||
# A shorthand `{@a, @b, @c} = val` pattern-match.
|
||||
idx = obj.properties[0].name
|
||||
else
|
||||
# A shorthand `{a, b, c} = val` pattern-match.
|
||||
idx = obj
|
||||
unless obj instanceof ValueNode or obj instanceof SplatNode
|
||||
throw new Error 'pattern matching must use only identifiers on the left-hand side.'
|
||||
accessClass = if isObject and IDENTIFIER.test(idx.value) then AccessorNode else IndexNode
|
||||
|
|
|
@ -249,3 +249,14 @@ ok b is 100
|
|||
eq '\\`', `
|
||||
"\\\`"
|
||||
`
|
||||
|
||||
|
||||
# Shorthand objects with property references.
|
||||
obj =
|
||||
one: 1
|
||||
two: 2
|
||||
func: -> {@one, @two}
|
||||
|
||||
result = obj.func()
|
||||
ok result.one is 1
|
||||
ok result.two is 2
|
||||
|
|
|
@ -142,3 +142,17 @@ ok a is 101
|
|||
|
||||
[x] = {0: y} = {'0': z} = [Math.random()]
|
||||
ok x is y is z, 'destructuring in multiple'
|
||||
|
||||
|
||||
# Destructuring into an object.
|
||||
obj =
|
||||
func: (list, object) ->
|
||||
[@one, @two] = list
|
||||
{@a, @b} = object
|
||||
|
||||
obj.func [1, 2], a: 'a', b: 'b'
|
||||
|
||||
eq obj.one, 1
|
||||
eq obj.two, 2
|
||||
eq obj.a, 'a'
|
||||
eq obj.b, 'b'
|
||||
|
|
Loading…
Reference in a new issue