Merge pull request #1590 from geraldalewis/proto_access
#1234 Protoype Access in :: Operator
This commit is contained in:
commit
42f2bd926b
|
@ -135,7 +135,7 @@
|
|||
o('Identifier', function() {
|
||||
return new Value($1);
|
||||
}), o('Value Accessor', function() {
|
||||
return $1.push($2);
|
||||
return $1.add($2);
|
||||
}), o('Invocation Accessor', function() {
|
||||
return new Value($1, [$2]);
|
||||
}), o('ThisProperty')
|
||||
|
@ -162,7 +162,7 @@
|
|||
}), o('?. Identifier', function() {
|
||||
return new Access($2, 'soak');
|
||||
}), o(':: Identifier', function() {
|
||||
return new Access($2, 'proto');
|
||||
return [new Access(new Literal('prototype')), new Access($2)];
|
||||
}), o('::', function() {
|
||||
return new Access(new Literal('prototype'));
|
||||
}), o('Index')
|
||||
|
@ -174,10 +174,6 @@
|
|||
return extend($2, {
|
||||
soak: true
|
||||
});
|
||||
}), o('INDEX_PROTO Index', function() {
|
||||
return extend($2, {
|
||||
proto: true
|
||||
});
|
||||
})
|
||||
],
|
||||
IndexValue: [
|
||||
|
|
|
@ -344,9 +344,6 @@
|
|||
switch (prev[0]) {
|
||||
case '?':
|
||||
prev[0] = 'INDEX_SOAK';
|
||||
break;
|
||||
case '::':
|
||||
prev[0] = 'INDEX_PROTO';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -379,8 +379,8 @@
|
|||
return this;
|
||||
}
|
||||
Value.prototype.children = ['base', 'properties'];
|
||||
Value.prototype.push = function(prop) {
|
||||
this.properties.push(prop);
|
||||
Value.prototype.add = function(props) {
|
||||
this.properties = this.properties.concat(props);
|
||||
return this;
|
||||
};
|
||||
Value.prototype.hasProperties = function() {
|
||||
|
@ -454,7 +454,7 @@
|
|||
name = new Index(new Assign(nref, name.index));
|
||||
nref = new Index(nref);
|
||||
}
|
||||
return [base.push(name), new Value(bref || base.base, [nref || name])];
|
||||
return [base.add(name), new Value(bref || base.base, [nref || name])];
|
||||
};
|
||||
Value.prototype.compileNode = function(o) {
|
||||
var code, prop, props, _i, _len;
|
||||
|
@ -687,14 +687,17 @@
|
|||
function Access(name, tag) {
|
||||
this.name = name;
|
||||
this.name.asKey = true;
|
||||
this.proto = tag === 'proto' ? '.prototype' : '';
|
||||
this.soak = tag === 'soak';
|
||||
}
|
||||
Access.prototype.children = ['name'];
|
||||
Access.prototype.compile = function(o) {
|
||||
var name;
|
||||
name = this.name.compile(o);
|
||||
return this.proto + (IDENTIFIER.test(name) ? "." + name : "[" + name + "]");
|
||||
if (IDENTIFIER.test(name)) {
|
||||
return "." + name;
|
||||
} else {
|
||||
return "[" + name + "]";
|
||||
}
|
||||
};
|
||||
Access.prototype.isComplex = NO;
|
||||
return Access;
|
||||
|
@ -706,7 +709,7 @@
|
|||
}
|
||||
Index.prototype.children = ['index'];
|
||||
Index.prototype.compile = function(o) {
|
||||
return (this.proto ? '.prototype' : '') + ("[" + (this.index.compile(o, LEVEL_PAREN)) + "]");
|
||||
return "[" + (this.index.compile(o, LEVEL_PAREN)) + "]";
|
||||
};
|
||||
Index.prototype.isComplex = function() {
|
||||
return this.index.isComplex();
|
||||
|
@ -971,11 +974,11 @@
|
|||
}
|
||||
} else {
|
||||
if (!assign.variable["this"]) {
|
||||
assign.variable = new Value(new Literal(name), [new Access(base, 'proto')]);
|
||||
}
|
||||
if (func instanceof Code && func.bound && !assign.variable["this"]) {
|
||||
this.boundFuncs.push(base);
|
||||
func.bound = false;
|
||||
assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
|
||||
if (func instanceof Code && func.bound) {
|
||||
this.boundFuncs.push(base);
|
||||
func.bound = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -217,7 +217,7 @@ grammar =
|
|||
# Variables and properties that can be assigned to.
|
||||
SimpleAssignable: [
|
||||
o 'Identifier', -> new Value $1
|
||||
o 'Value Accessor', -> $1.push $2
|
||||
o 'Value Accessor', -> $1.add $2
|
||||
o 'Invocation Accessor', -> new Value $1, [$2]
|
||||
o 'ThisProperty'
|
||||
]
|
||||
|
@ -244,7 +244,7 @@ grammar =
|
|||
Accessor: [
|
||||
o '. Identifier', -> new Access $2
|
||||
o '?. Identifier', -> new Access $2, 'soak'
|
||||
o ':: Identifier', -> new Access $2, 'proto'
|
||||
o ':: Identifier', -> [(new Access new Literal 'prototype'), new Access $2]
|
||||
o '::', -> new Access new Literal 'prototype'
|
||||
o 'Index'
|
||||
]
|
||||
|
@ -253,7 +253,6 @@ grammar =
|
|||
Index: [
|
||||
o 'INDEX_START IndexValue INDEX_END', -> $2
|
||||
o 'INDEX_SOAK Index', -> extend $2, soak : yes
|
||||
o 'INDEX_PROTO Index', -> extend $2, proto: yes
|
||||
]
|
||||
|
||||
IndexValue: [
|
||||
|
|
|
@ -336,7 +336,6 @@ exports.Lexer = class Lexer
|
|||
tag = 'INDEX_START'
|
||||
switch prev[0]
|
||||
when '?' then prev[0] = 'INDEX_SOAK'
|
||||
when '::' then prev[0] = 'INDEX_PROTO'
|
||||
@token tag, value
|
||||
value.length
|
||||
|
||||
|
|
|
@ -345,9 +345,9 @@ exports.Value = class Value extends Base
|
|||
|
||||
children: ['base', 'properties']
|
||||
|
||||
# Add a property access to the list.
|
||||
push: (prop) ->
|
||||
@properties.push prop
|
||||
# Add a property (or *properties* ) `Access` to the list.
|
||||
add: (props) ->
|
||||
@properties = @properties.concat props
|
||||
this
|
||||
|
||||
hasProperties: ->
|
||||
|
@ -398,7 +398,7 @@ exports.Value = class Value extends Base
|
|||
nref = new Literal o.scope.freeVariable 'name'
|
||||
name = new Index new Assign nref, name.index
|
||||
nref = new Index nref
|
||||
[base.push(name), new Value(bref or base.base, [nref or name])]
|
||||
[base.add(name), new Value(bref or base.base, [nref or name])]
|
||||
|
||||
# We compile a value to JavaScript by compiling and joining each property.
|
||||
# Things get much more interesting if the chain of properties has *soak*
|
||||
|
@ -597,14 +597,13 @@ exports.Extends = class Extends extends Base
|
|||
exports.Access = class Access extends Base
|
||||
constructor: (@name, tag) ->
|
||||
@name.asKey = yes
|
||||
@proto = if tag is 'proto' then '.prototype' else ''
|
||||
@soak = tag is 'soak'
|
||||
|
||||
children: ['name']
|
||||
|
||||
compile: (o) ->
|
||||
name = @name.compile o
|
||||
@proto + if IDENTIFIER.test name then ".#{name}" else "[#{name}]"
|
||||
if IDENTIFIER.test name then ".#{name}" else "[#{name}]"
|
||||
|
||||
isComplex: NO
|
||||
|
||||
|
@ -617,7 +616,7 @@ exports.Index = class Index extends Base
|
|||
children: ['index']
|
||||
|
||||
compile: (o) ->
|
||||
(if @proto then '.prototype' else '') + "[#{ @index.compile o, LEVEL_PAREN }]"
|
||||
"[#{ @index.compile o, LEVEL_PAREN }]"
|
||||
|
||||
isComplex: ->
|
||||
@index.isComplex()
|
||||
|
@ -858,10 +857,10 @@ exports.Class = class Class extends Base
|
|||
assign = new Assign new Literal(@externalCtor), func
|
||||
else
|
||||
unless assign.variable.this
|
||||
assign.variable = new Value(new Literal(name), [new Access(base, 'proto')])
|
||||
if func instanceof Code and func.bound and not assign.variable.this
|
||||
@boundFuncs.push base
|
||||
func.bound = no
|
||||
assign.variable = new Value(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
|
||||
if func instanceof Code and func.bound
|
||||
@boundFuncs.push base
|
||||
func.bound = no
|
||||
assign
|
||||
compact exprs
|
||||
|
||||
|
|
|
@ -231,3 +231,12 @@ test "chained operations should evaluate each value only once", ->
|
|||
test "#891: incorrect inversion of chained comparisons", ->
|
||||
ok (true unless 0 > 1 > 2)
|
||||
ok (true unless (NaN = 0/0) < 0/0 < NaN)
|
||||
|
||||
test "#1234: Applying a splat to :: applies the splat to the wrong object", ->
|
||||
nonce = {}
|
||||
class C
|
||||
method: -> @nonce
|
||||
nonce: nonce
|
||||
|
||||
arr = []
|
||||
eq nonce, C::method arr... # should be applied to `C::`
|
||||
|
|
Loading…
Reference in New Issue