mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-04-11 03:00:13 -04:00
Putting 'constructor' back. Improving constructor definitions.
This commit is contained in:
@@ -185,7 +185,7 @@
|
|||||||
],
|
],
|
||||||
Object: [
|
Object: [
|
||||||
o('{ AssignList OptComma }', function() {
|
o('{ AssignList OptComma }', function() {
|
||||||
return new Obj($2);
|
return new Obj($2, $1.generated);
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
AssignList: [
|
AssignList: [
|
||||||
|
|||||||
66
lib/nodes.js
66
lib/nodes.js
@@ -369,9 +369,6 @@
|
|||||||
Value.prototype.isArray = function() {
|
Value.prototype.isArray = function() {
|
||||||
return !this.properties.length && this.base instanceof Arr;
|
return !this.properties.length && this.base instanceof Arr;
|
||||||
};
|
};
|
||||||
Value.prototype.isObject = function() {
|
|
||||||
return !this.properties.length && this.base instanceof Obj;
|
|
||||||
};
|
|
||||||
Value.prototype.isComplex = function() {
|
Value.prototype.isComplex = function() {
|
||||||
return this.hasProperties() || this.base.isComplex();
|
return this.hasProperties() || this.base.isComplex();
|
||||||
};
|
};
|
||||||
@@ -398,6 +395,12 @@
|
|||||||
Value.prototype.assigns = function(name) {
|
Value.prototype.assigns = function(name) {
|
||||||
return !this.properties.length && this.base.assigns(name);
|
return !this.properties.length && this.base.assigns(name);
|
||||||
};
|
};
|
||||||
|
Value.prototype.isObject = function(onlyGenerated) {
|
||||||
|
if (this.properties.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
|
||||||
|
};
|
||||||
Value.prototype.makeReturn = function() {
|
Value.prototype.makeReturn = function() {
|
||||||
if (this.properties.length) {
|
if (this.properties.length) {
|
||||||
return Value.__super__.makeReturn.call(this);
|
return Value.__super__.makeReturn.call(this);
|
||||||
@@ -664,7 +667,8 @@
|
|||||||
return Index;
|
return Index;
|
||||||
}();
|
}();
|
||||||
exports.Obj = Obj = function() {
|
exports.Obj = Obj = function() {
|
||||||
function Obj(props) {
|
function Obj(props, _arg) {
|
||||||
|
this.generated = _arg != null ? _arg : false;
|
||||||
this.objects = this.properties = props || [];
|
this.objects = this.properties = props || [];
|
||||||
}
|
}
|
||||||
__extends(Obj, Base);
|
__extends(Obj, Base);
|
||||||
@@ -821,6 +825,7 @@
|
|||||||
Class.prototype.children = ['variable', 'parent', 'body'];
|
Class.prototype.children = ['variable', 'parent', 'body'];
|
||||||
Class.prototype.compileNode = function(o) {
|
Class.prototype.compileNode = function(o) {
|
||||||
var bname, boundFuncs, bvar, convert, ctor, decl, exps, i, klass, lname, name, node, others, tail, _fn, _i, _j, _len, _len2, _len3, _ref, _ref2;
|
var bname, boundFuncs, bvar, convert, ctor, decl, exps, i, klass, lname, name, node, others, tail, _fn, _i, _j, _len, _len2, _len3, _ref, _ref2;
|
||||||
|
ctor = null;
|
||||||
if (this.variable) {
|
if (this.variable) {
|
||||||
decl = (tail = last(this.variable.properties)) ? tail instanceof Accessor && tail.name.value : this.variable.base.value;
|
decl = (tail = last(this.variable.properties)) ? tail instanceof Accessor && tail.name.value : this.variable.base.value;
|
||||||
decl && (decl = IDENTIFIER.test(decl) && decl);
|
decl && (decl = IDENTIFIER.test(decl) && decl);
|
||||||
@@ -838,19 +843,33 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
convert = function(node) {
|
convert = function(node) {
|
||||||
var assign, base, func, _i, _len, _ref, _results;
|
var assign, base, func, props, _results;
|
||||||
_ref = node.base.properties;
|
props = node.base.properties.slice(0);
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
while (assign = props.shift()) {
|
||||||
assign = _ref[_i];
|
|
||||||
if (assign instanceof Assign) {
|
if (assign instanceof Assign) {
|
||||||
base = assign.variable.base;
|
base = assign.variable.base;
|
||||||
assign.variable = new Value(lname, [new Accessor(base, 'proto')]);
|
|
||||||
delete assign.context;
|
delete assign.context;
|
||||||
func = assign.value;
|
func = assign.value;
|
||||||
if (func instanceof Code && func.bound) {
|
if (base.value === 'constructor') {
|
||||||
boundFuncs.push(base);
|
if (ctor) {
|
||||||
func.bound = false;
|
throw new Error('cannot define more than one constructor in a class');
|
||||||
|
}
|
||||||
|
if (func.bound) {
|
||||||
|
throw new Error('cannot define a constructor as a bound function');
|
||||||
|
}
|
||||||
|
if (func instanceof Code) {
|
||||||
|
ctor = func;
|
||||||
|
} else {
|
||||||
|
ctor = new Assign(new Value(lname), func);
|
||||||
|
}
|
||||||
|
assign = null;
|
||||||
|
} else {
|
||||||
|
assign.variable = new Value(lname, [new Accessor(base, 'proto')]);
|
||||||
|
if (func instanceof Code && func.bound) {
|
||||||
|
boundFuncs.push(base);
|
||||||
|
func.bound = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_results.push(assign);
|
_results.push(assign);
|
||||||
@@ -862,18 +881,8 @@
|
|||||||
_ref = exps = this.body.expressions;
|
_ref = exps = this.body.expressions;
|
||||||
for (i = 0, _len = _ref.length; i < _len; i++) {
|
for (i = 0, _len = _ref.length; i < _len; i++) {
|
||||||
node = _ref[i];
|
node = _ref[i];
|
||||||
if (node instanceof Value && node.isObject()) {
|
if (node instanceof Value && node.isObject(true)) {
|
||||||
exps[i] = convert(node);
|
exps[i] = compact(convert(node));
|
||||||
} else if (node instanceof Code) {
|
|
||||||
if (ctor) {
|
|
||||||
throw new Error('cannot define more than one constructor in a class');
|
|
||||||
}
|
|
||||||
if (node.bound) {
|
|
||||||
throw new Error('cannot define a constructor as a bound function');
|
|
||||||
}
|
|
||||||
ctor = node;
|
|
||||||
exps.splice(i, 1);
|
|
||||||
exps.unshift(ctor);
|
|
||||||
} else {
|
} else {
|
||||||
others.push(node);
|
others.push(node);
|
||||||
}
|
}
|
||||||
@@ -885,8 +894,8 @@
|
|||||||
_ref = n2.expressions;
|
_ref = n2.expressions;
|
||||||
for (j = 0, _len = _ref.length; j < _len; j++) {
|
for (j = 0, _len = _ref.length; j < _len; j++) {
|
||||||
expr2 = _ref[j];
|
expr2 = _ref[j];
|
||||||
if (expr2 instanceof Value && expr2.isObject()) {
|
if (expr2 instanceof Value && expr2.isObject(true)) {
|
||||||
n2.expressions[j] = convert(expr2);
|
n2.expressions[j] = compact(convert(expr2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n2.expressions = flatten(n2.expressions);
|
return n2.expressions = flatten(n2.expressions);
|
||||||
@@ -899,7 +908,7 @@
|
|||||||
}
|
}
|
||||||
this.body.expressions = exps = flatten(exps);
|
this.body.expressions = exps = flatten(exps);
|
||||||
if (!ctor) {
|
if (!ctor) {
|
||||||
exps.unshift(ctor = new Code);
|
ctor = new Code;
|
||||||
if (this.parent) {
|
if (this.parent) {
|
||||||
ctor.body.push(new Call('super', [new Splat(new Literal('arguments'))]));
|
ctor.body.push(new Call('super', [new Splat(new Literal('arguments'))]));
|
||||||
}
|
}
|
||||||
@@ -908,8 +917,9 @@
|
|||||||
ctor.klass = null;
|
ctor.klass = null;
|
||||||
ctor.noReturn = true;
|
ctor.noReturn = true;
|
||||||
if (this.parent) {
|
if (this.parent) {
|
||||||
exps.splice(1, 0, new Extends(lname, this.parent));
|
exps.unshift(new Extends(lname, this.parent));
|
||||||
}
|
}
|
||||||
|
exps.unshift(ctor);
|
||||||
exps.push(lname);
|
exps.push(lname);
|
||||||
if (boundFuncs.length) {
|
if (boundFuncs.length) {
|
||||||
for (_j = 0, _len3 = boundFuncs.length; _j < _len3; _j++) {
|
for (_j = 0, _len3 = boundFuncs.length; _j < _len3; _j++) {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ case 84:this.$ = yy.extend($$[$0-2+2-1], {
|
|||||||
proto: true
|
proto: true
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 85:this.$ = new yy.Obj($$[$0-4+2-1]);
|
case 85:this.$ = new yy.Obj($$[$0-4+2-1], $$[$0-4+1-1].generated);
|
||||||
break;
|
break;
|
||||||
case 86:this.$ = [];
|
case 86:this.$ = [];
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
|
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
|
||||||
};
|
};
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var ago1, ago2, idx, tag, tok, _ref, _ref2;
|
var ago1, ago2, idx, tag, tok, value, _ref, _ref2;
|
||||||
if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||||||
stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]);
|
stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -139,7 +139,9 @@
|
|||||||
if (this.tag(idx - 2) === 'HERECOMMENT') {
|
if (this.tag(idx - 2) === 'HERECOMMENT') {
|
||||||
idx -= 2;
|
idx -= 2;
|
||||||
}
|
}
|
||||||
tok = ['{', '{', token[2]];
|
value = new String('{');
|
||||||
|
value.generated = true;
|
||||||
|
tok = ['{', value, token[2]];
|
||||||
tok.generated = true;
|
tok.generated = true;
|
||||||
tokens.splice(idx, 0, tok);
|
tokens.splice(idx, 0, tok);
|
||||||
this.detectEnd(i + 2, condition, action);
|
this.detectEnd(i + 2, condition, action);
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ grammar =
|
|||||||
|
|
||||||
# In CoffeeScript, an object literal is simply a list of assignments.
|
# In CoffeeScript, an object literal is simply a list of assignments.
|
||||||
Object: [
|
Object: [
|
||||||
o '{ AssignList OptComma }', -> new Obj $2
|
o '{ AssignList OptComma }', -> new Obj $2, $1.generated
|
||||||
]
|
]
|
||||||
|
|
||||||
# Assignment of properties within an object literal can be separated by
|
# Assignment of properties within an object literal can be separated by
|
||||||
|
|||||||
102
src/nodes.coffee
102
src/nodes.coffee
@@ -157,7 +157,7 @@ exports.Expressions = class Expressions extends Base
|
|||||||
|
|
||||||
children: ['expressions']
|
children: ['expressions']
|
||||||
|
|
||||||
(nodes) ->
|
constructor: (nodes) ->
|
||||||
@expressions = compact flatten nodes or []
|
@expressions = compact flatten nodes or []
|
||||||
|
|
||||||
# Tack an expression on to the end of this expression list.
|
# Tack an expression on to the end of this expression list.
|
||||||
@@ -257,7 +257,7 @@ exports.Expressions = class Expressions extends Base
|
|||||||
# `true`, `false`, `null`...
|
# `true`, `false`, `null`...
|
||||||
exports.Literal = class Literal extends Base
|
exports.Literal = class Literal extends Base
|
||||||
|
|
||||||
(@value) ->
|
constructor: (@value) ->
|
||||||
|
|
||||||
makeReturn: ->
|
makeReturn: ->
|
||||||
if @isPureStatement() then this else new Return this
|
if @isPureStatement() then this else new Return this
|
||||||
@@ -292,7 +292,7 @@ exports.Return = class Return extends Base
|
|||||||
isStatement : YES
|
isStatement : YES
|
||||||
isPureStatement: YES
|
isPureStatement: YES
|
||||||
|
|
||||||
(@expression) ->
|
constructor: (@expression) ->
|
||||||
|
|
||||||
makeReturn: THIS
|
makeReturn: THIS
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ exports.Value = class Value extends Base
|
|||||||
children: ['base', 'properties']
|
children: ['base', 'properties']
|
||||||
|
|
||||||
# A **Value** has a base and a list of property accesses.
|
# A **Value** has a base and a list of property accesses.
|
||||||
(base, props, tag) ->
|
constructor: (base, props, tag) ->
|
||||||
return base if not props and base instanceof Value
|
return base if not props and base instanceof Value
|
||||||
@base = base
|
@base = base
|
||||||
@properties = props or []
|
@properties = props or []
|
||||||
@@ -329,7 +329,6 @@ exports.Value = class Value extends Base
|
|||||||
|
|
||||||
# Some boolean checks for the benefit of other nodes.
|
# Some boolean checks for the benefit of other nodes.
|
||||||
isArray : -> not @properties.length and @base instanceof Arr
|
isArray : -> not @properties.length and @base instanceof Arr
|
||||||
isObject : -> not @properties.length and @base instanceof Obj
|
|
||||||
isComplex : -> @hasProperties() or @base.isComplex()
|
isComplex : -> @hasProperties() or @base.isComplex()
|
||||||
isAssignable : -> @hasProperties() or @base.isAssignable()
|
isAssignable : -> @hasProperties() or @base.isAssignable()
|
||||||
isSimpleNumber : -> @base instanceof Literal and SIMPLENUM.test @base.value
|
isSimpleNumber : -> @base instanceof Literal and SIMPLENUM.test @base.value
|
||||||
@@ -341,6 +340,10 @@ exports.Value = class Value extends Base
|
|||||||
isStatement : (o) -> not @properties.length and @base.isStatement o
|
isStatement : (o) -> not @properties.length and @base.isStatement o
|
||||||
assigns : (name) -> not @properties.length and @base.assigns name
|
assigns : (name) -> not @properties.length and @base.assigns name
|
||||||
|
|
||||||
|
isObject: (onlyGenerated) ->
|
||||||
|
return no if @properties.length
|
||||||
|
(@base instanceof Obj) and (not onlyGenerated or @base.generated)
|
||||||
|
|
||||||
makeReturn: ->
|
makeReturn: ->
|
||||||
if @properties.length then super() else @base.makeReturn()
|
if @properties.length then super() else @base.makeReturn()
|
||||||
|
|
||||||
@@ -401,7 +404,7 @@ exports.Value = class Value extends Base
|
|||||||
# at the same position.
|
# at the same position.
|
||||||
exports.Comment = class Comment extends Base
|
exports.Comment = class Comment extends Base
|
||||||
|
|
||||||
(@comment) ->
|
constructor: (@comment) ->
|
||||||
|
|
||||||
isPureStatement: YES
|
isPureStatement: YES
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
@@ -420,7 +423,7 @@ exports.Call = class Call extends Base
|
|||||||
|
|
||||||
children: ['variable', 'args']
|
children: ['variable', 'args']
|
||||||
|
|
||||||
(variable, @args = [], @soak) ->
|
constructor: (variable, @args = [], @soak) ->
|
||||||
@isNew = false
|
@isNew = false
|
||||||
@isSuper = variable is 'super'
|
@isSuper = variable is 'super'
|
||||||
@variable = if @isSuper then null else variable
|
@variable = if @isSuper then null else variable
|
||||||
@@ -523,7 +526,7 @@ exports.Extends = class Extends extends Base
|
|||||||
|
|
||||||
children: ['child', 'parent']
|
children: ['child', 'parent']
|
||||||
|
|
||||||
(@child, @parent) ->
|
constructor: (@child, @parent) ->
|
||||||
|
|
||||||
# Hooks one constructor into another's prototype chain.
|
# Hooks one constructor into another's prototype chain.
|
||||||
compile: (o) ->
|
compile: (o) ->
|
||||||
@@ -538,7 +541,7 @@ exports.Accessor = class Accessor extends Base
|
|||||||
|
|
||||||
children: ['name']
|
children: ['name']
|
||||||
|
|
||||||
(@name, tag) ->
|
constructor: (@name, tag) ->
|
||||||
@proto = if tag is 'proto' then '.prototype' else ''
|
@proto = if tag is 'proto' then '.prototype' else ''
|
||||||
@soak = tag is 'soak'
|
@soak = tag is 'soak'
|
||||||
|
|
||||||
@@ -555,7 +558,7 @@ exports.Index = class Index extends Base
|
|||||||
|
|
||||||
children: ['index']
|
children: ['index']
|
||||||
|
|
||||||
(@index) ->
|
constructor: (@index) ->
|
||||||
|
|
||||||
compile: (o) ->
|
compile: (o) ->
|
||||||
(if @proto then '.prototype' else '') + "[#{ @index.compile o, LEVEL_PAREN }]"
|
(if @proto then '.prototype' else '') + "[#{ @index.compile o, LEVEL_PAREN }]"
|
||||||
@@ -570,7 +573,7 @@ exports.Obj = class Obj extends Base
|
|||||||
|
|
||||||
children: ['properties']
|
children: ['properties']
|
||||||
|
|
||||||
(props) ->
|
constructor: (props, @generated = false) ->
|
||||||
@objects = @properties = props or []
|
@objects = @properties = props or []
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
@@ -634,7 +637,7 @@ exports.Arr = class Arr extends Base
|
|||||||
|
|
||||||
children: ['objects']
|
children: ['objects']
|
||||||
|
|
||||||
(objs) ->
|
constructor: (objs) ->
|
||||||
@objects = objs or []
|
@objects = objs or []
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
@@ -661,12 +664,14 @@ exports.Class = class Class extends Base
|
|||||||
|
|
||||||
# Initialize a **Class** with its name, an optional superclass, and a
|
# Initialize a **Class** with its name, an optional superclass, and a
|
||||||
# list of prototype property assignments.
|
# list of prototype property assignments.
|
||||||
(@variable, @parent, @body = new Expressions) ->
|
constructor: (@variable, @parent, @body = new Expressions) ->
|
||||||
|
|
||||||
# Instead of generating the JavaScript string directly, we build up the
|
# Instead of generating the JavaScript string directly, we build up the
|
||||||
# equivalent syntax tree and compile that, in pieces. You can see the
|
# equivalent syntax tree and compile that, in pieces. You can see the
|
||||||
# constructor, property assignments, and inheritance getting built out below.
|
# constructor, property assignments, and inheritance getting built out below.
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
|
ctor = null
|
||||||
|
|
||||||
if @variable
|
if @variable
|
||||||
decl = if tail = last @variable.properties
|
decl = if tail = last @variable.properties
|
||||||
tail instanceof Accessor and tail.name.value
|
tail instanceof Accessor and tail.name.value
|
||||||
@@ -684,30 +689,34 @@ exports.Class = class Class extends Base
|
|||||||
node.context = name if node.bound
|
node.context = name if node.bound
|
||||||
|
|
||||||
convert = (node) ->
|
convert = (node) ->
|
||||||
for assign in node.base.properties
|
props = node.base.properties.slice 0
|
||||||
|
while assign = props.shift()
|
||||||
if assign instanceof Assign
|
if assign instanceof Assign
|
||||||
base = assign.variable.base
|
base = assign.variable.base
|
||||||
assign.variable = new Value(lname, [new Accessor(base, 'proto')])
|
|
||||||
delete assign.context
|
delete assign.context
|
||||||
func = assign.value
|
func = assign.value
|
||||||
if func instanceof Code and func.bound
|
if base.value is 'constructor'
|
||||||
boundFuncs.push base
|
if ctor
|
||||||
func.bound = no
|
throw new Error 'cannot define more than one constructor in a class'
|
||||||
|
if func.bound
|
||||||
|
throw new Error 'cannot define a constructor as a bound function'
|
||||||
|
if func instanceof Code
|
||||||
|
ctor = func
|
||||||
|
else
|
||||||
|
ctor = new Assign(new Value(lname), func)
|
||||||
|
assign = null
|
||||||
|
else
|
||||||
|
assign.variable = new Value(lname, [new Accessor(base, 'proto')])
|
||||||
|
if func instanceof Code and func.bound
|
||||||
|
boundFuncs.push base
|
||||||
|
func.bound = no
|
||||||
assign
|
assign
|
||||||
|
|
||||||
boundFuncs = []
|
boundFuncs = []
|
||||||
others = []
|
others = []
|
||||||
for node, i in exps = @body.expressions
|
for node, i in exps = @body.expressions
|
||||||
if node instanceof Value and node.isObject()
|
if node instanceof Value and node.isObject(true)
|
||||||
exps[i] = convert node
|
exps[i] = compact convert node
|
||||||
else if node instanceof Code
|
|
||||||
if ctor
|
|
||||||
throw new Error 'cannot define more than one constructor in a class'
|
|
||||||
if node.bound
|
|
||||||
throw new Error 'cannot define a constructor as a bound function'
|
|
||||||
ctor = node
|
|
||||||
exps.splice(i, 1)
|
|
||||||
exps.unshift ctor
|
|
||||||
else
|
else
|
||||||
others.push node
|
others.push node
|
||||||
|
|
||||||
@@ -716,19 +725,20 @@ exports.Class = class Class extends Base
|
|||||||
other.traverseChildren false, (n2) ->
|
other.traverseChildren false, (n2) ->
|
||||||
if n2 instanceof Expressions
|
if n2 instanceof Expressions
|
||||||
for expr2, j in n2.expressions
|
for expr2, j in n2.expressions
|
||||||
if expr2 instanceof Value and expr2.isObject()
|
if expr2 instanceof Value and expr2.isObject(true)
|
||||||
n2.expressions[j] = convert expr2
|
n2.expressions[j] = compact convert expr2
|
||||||
n2.expressions = flatten n2.expressions
|
n2.expressions = flatten n2.expressions
|
||||||
|
|
||||||
@body.expressions = exps = flatten exps
|
@body.expressions = exps = flatten exps
|
||||||
unless ctor
|
unless ctor
|
||||||
exps.unshift ctor = new Code
|
ctor = new Code
|
||||||
if @parent
|
if @parent
|
||||||
ctor.body.push new Call 'super', [new Splat new Literal 'arguments']
|
ctor.body.push new Call 'super', [new Splat new Literal 'arguments']
|
||||||
ctor.ctor = ctor.name = name
|
ctor.ctor = ctor.name = name
|
||||||
ctor.klass = null
|
ctor.klass = null
|
||||||
ctor.noReturn = yes
|
ctor.noReturn = yes
|
||||||
exps.splice 1, 0, new Extends lname, @parent if @parent
|
exps.unshift new Extends lname, @parent if @parent
|
||||||
|
exps.unshift ctor
|
||||||
exps.push lname
|
exps.push lname
|
||||||
|
|
||||||
if boundFuncs.length
|
if boundFuncs.length
|
||||||
@@ -752,7 +762,7 @@ exports.Assign = class Assign extends Base
|
|||||||
|
|
||||||
children: ['variable', 'value']
|
children: ['variable', 'value']
|
||||||
|
|
||||||
(@variable, @value, @context) ->
|
constructor: (@variable, @value, @context) ->
|
||||||
|
|
||||||
assigns: (name) ->
|
assigns: (name) ->
|
||||||
@[if @context is 'object' then 'value' else 'variable'].assigns name
|
@[if @context is 'object' then 'value' else 'variable'].assigns name
|
||||||
@@ -867,7 +877,7 @@ exports.Code = class Code extends Base
|
|||||||
|
|
||||||
children: ['params', 'body']
|
children: ['params', 'body']
|
||||||
|
|
||||||
(params, body, tag) ->
|
constructor: (params, body, tag) ->
|
||||||
@params = params or []
|
@params = params or []
|
||||||
@body = body or new Expressions
|
@body = body or new Expressions
|
||||||
@bound = tag is 'boundfunc'
|
@bound = tag is 'boundfunc'
|
||||||
@@ -934,7 +944,7 @@ exports.Param = class Param extends Base
|
|||||||
|
|
||||||
children: ['name', 'value']
|
children: ['name', 'value']
|
||||||
|
|
||||||
(@name, @value, @splat) ->
|
constructor: (@name, @value, @splat) ->
|
||||||
|
|
||||||
compile: (o) ->
|
compile: (o) ->
|
||||||
@name.compile o, LEVEL_LIST
|
@name.compile o, LEVEL_LIST
|
||||||
@@ -959,7 +969,7 @@ exports.Splat = class Splat extends Base
|
|||||||
|
|
||||||
isAssignable: YES
|
isAssignable: YES
|
||||||
|
|
||||||
(name) ->
|
constructor: (name) ->
|
||||||
@name = if name.compile then name else new Literal name
|
@name = if name.compile then name else new Literal name
|
||||||
|
|
||||||
assigns: (name) ->
|
assigns: (name) ->
|
||||||
@@ -999,7 +1009,7 @@ exports.While = class While extends Base
|
|||||||
|
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
|
|
||||||
(condition, options) ->
|
constructor: (condition, options) ->
|
||||||
@condition = if options?.invert then condition.invert() else condition
|
@condition = if options?.invert then condition.invert() else condition
|
||||||
@guard = options?.guard
|
@guard = options?.guard
|
||||||
|
|
||||||
@@ -1063,7 +1073,7 @@ exports.Op = class Op extends Base
|
|||||||
|
|
||||||
children: ['first', 'second']
|
children: ['first', 'second']
|
||||||
|
|
||||||
(op, first, second, flip) ->
|
constructor: (op, first, second, flip) ->
|
||||||
return new In first, second if op is 'in'
|
return new In first, second if op is 'in'
|
||||||
if op is 'new'
|
if op is 'new'
|
||||||
return first.newInstance() if first instanceof Call
|
return first.newInstance() if first instanceof Call
|
||||||
@@ -1140,7 +1150,7 @@ exports.In = class In extends Base
|
|||||||
|
|
||||||
invert: NEGATE
|
invert: NEGATE
|
||||||
|
|
||||||
(@object, @array) ->
|
constructor: (@object, @array) ->
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
if @array instanceof Value and @array.isArray()
|
if @array instanceof Value and @array.isArray()
|
||||||
@@ -1176,7 +1186,7 @@ exports.Try = class Try extends Base
|
|||||||
|
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
|
|
||||||
(@attempt, @error, @recovery, @ensure) ->
|
constructor: (@attempt, @error, @recovery, @ensure) ->
|
||||||
|
|
||||||
makeReturn: ->
|
makeReturn: ->
|
||||||
@attempt = @attempt .makeReturn() if @attempt
|
@attempt = @attempt .makeReturn() if @attempt
|
||||||
@@ -1207,7 +1217,7 @@ exports.Throw = class Throw extends Base
|
|||||||
|
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
|
|
||||||
(@expression) ->
|
constructor: (@expression) ->
|
||||||
|
|
||||||
# A **Throw** is already a return, of sorts...
|
# A **Throw** is already a return, of sorts...
|
||||||
makeReturn: THIS
|
makeReturn: THIS
|
||||||
@@ -1226,7 +1236,7 @@ exports.Existence = class Existence extends Base
|
|||||||
|
|
||||||
invert: NEGATE
|
invert: NEGATE
|
||||||
|
|
||||||
(@expression) ->
|
constructor: (@expression) ->
|
||||||
|
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
code = @expression.compile o, LEVEL_OP
|
code = @expression.compile o, LEVEL_OP
|
||||||
@@ -1251,7 +1261,7 @@ exports.Parens = class Parens extends Base
|
|||||||
|
|
||||||
children: ['expression']
|
children: ['expression']
|
||||||
|
|
||||||
(@expression) ->
|
constructor: (@expression) ->
|
||||||
|
|
||||||
unwrap : -> @expression
|
unwrap : -> @expression
|
||||||
isComplex : -> @expression.isComplex()
|
isComplex : -> @expression.isComplex()
|
||||||
@@ -1281,7 +1291,7 @@ exports.For = class For extends Base
|
|||||||
|
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
|
|
||||||
(body, head) ->
|
constructor: (body, head) ->
|
||||||
if head.index instanceof Value
|
if head.index instanceof Value
|
||||||
throw SyntaxError 'index cannot be a pattern matching expression'
|
throw SyntaxError 'index cannot be a pattern matching expression'
|
||||||
extend this, head
|
extend this, head
|
||||||
@@ -1415,7 +1425,7 @@ exports.Switch = class Switch extends Base
|
|||||||
|
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
|
|
||||||
(@subject, @cases, @otherwise) ->
|
constructor: (@subject, @cases, @otherwise) ->
|
||||||
|
|
||||||
makeReturn: ->
|
makeReturn: ->
|
||||||
pair[1].makeReturn() for pair in @cases
|
pair[1].makeReturn() for pair in @cases
|
||||||
@@ -1449,7 +1459,7 @@ exports.If = class If extends Base
|
|||||||
|
|
||||||
children: ['condition', 'body', 'elseBody']
|
children: ['condition', 'body', 'elseBody']
|
||||||
|
|
||||||
(condition, @body, options = {}) ->
|
constructor: (condition, @body, options = {}) ->
|
||||||
@condition = if options.invert then condition.invert() else condition
|
@condition = if options.invert then condition.invert() else condition
|
||||||
@elseBody = null
|
@elseBody = null
|
||||||
@isChain = false
|
@isChain = false
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ exports.OptionParser = class OptionParser
|
|||||||
# [short-flag, long-flag, description]
|
# [short-flag, long-flag, description]
|
||||||
#
|
#
|
||||||
# Along with an an optional banner for the usage help.
|
# Along with an an optional banner for the usage help.
|
||||||
(rules, @banner) ->
|
constructor: (rules, @banner) ->
|
||||||
@rules = buildRules rules
|
@rules = buildRules rules
|
||||||
|
|
||||||
# Parse the list of arguments, populating an `options` object with all of the
|
# Parse the list of arguments, populating an `options` object with all of the
|
||||||
|
|||||||
@@ -123,7 +123,9 @@ class exports.Rewriter
|
|||||||
else
|
else
|
||||||
i - 1
|
i - 1
|
||||||
idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
|
idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
|
||||||
tok = ['{', '{', token[2]]
|
value = new String('{')
|
||||||
|
value.generated = yes
|
||||||
|
tok = ['{', value, token[2]]
|
||||||
tok.generated = yes
|
tok.generated = yes
|
||||||
tokens.splice idx, 0, tok
|
tokens.splice idx, 0, tok
|
||||||
@detectEnd i + 2, condition, action
|
@detectEnd i + 2, condition, action
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ exports.Scope = class Scope
|
|||||||
# as well as a reference to the **Expressions** node is belongs to, which is
|
# as well as a reference to the **Expressions** node is belongs to, which is
|
||||||
# where it should declare its variables, and a reference to the function that
|
# where it should declare its variables, and a reference to the function that
|
||||||
# it wraps.
|
# it wraps.
|
||||||
(@parent, @expressions, @method) ->
|
constructor: (@parent, @expressions, @method) ->
|
||||||
@variables = [{name: 'arguments', type: 'arguments'}]
|
@variables = [{name: 'arguments', type: 'arguments'}]
|
||||||
@positions = {}
|
@positions = {}
|
||||||
if @parent
|
if @parent
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ eq context.arg, 3
|
|||||||
eq context.arg.join(' '), '1 2 3'
|
eq context.arg.join(' '), '1 2 3'
|
||||||
|
|
||||||
class Klass
|
class Klass
|
||||||
(@one, @two) ->
|
constructor: (@one, @two) ->
|
||||||
|
|
||||||
obj = new Klass 1, 2
|
obj = new Klass 1, 2
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ thirdCtor = ->
|
|||||||
@array = [1, 2, 3]
|
@array = [1, 2, 3]
|
||||||
|
|
||||||
class ThirdChild extends SecondChild
|
class ThirdChild extends SecondChild
|
||||||
-> thirdCtor.call this
|
constructor: -> thirdCtor.call this
|
||||||
|
|
||||||
# Gratuitous comment for testing.
|
# Gratuitous comment for testing.
|
||||||
func: (string) ->
|
func: (string) ->
|
||||||
@@ -40,15 +40,15 @@ ok (new ThirdChild).array.join(' ') is '1 2 3'
|
|||||||
|
|
||||||
|
|
||||||
class TopClass
|
class TopClass
|
||||||
(arg) ->
|
constructor: (arg) ->
|
||||||
@prop = 'top-' + arg
|
@prop = 'top-' + arg
|
||||||
|
|
||||||
class SuperClass extends TopClass
|
class SuperClass extends TopClass
|
||||||
(arg) ->
|
constructor: (arg) ->
|
||||||
super 'super-' + arg
|
super 'super-' + arg
|
||||||
|
|
||||||
class SubClass extends SuperClass
|
class SubClass extends SuperClass
|
||||||
->
|
constructor: ->
|
||||||
super 'sub'
|
super 'sub'
|
||||||
|
|
||||||
ok (new SubClass).prop is 'top-super-sub'
|
ok (new SubClass).prop is 'top-super-sub'
|
||||||
@@ -57,7 +57,7 @@ ok (new SubClass).prop is 'top-super-sub'
|
|||||||
class OneClass
|
class OneClass
|
||||||
@new = 'new'
|
@new = 'new'
|
||||||
function: 'function'
|
function: 'function'
|
||||||
(name) -> @name = name
|
constructor: (name) -> @name = name
|
||||||
|
|
||||||
class TwoClass extends OneClass
|
class TwoClass extends OneClass
|
||||||
delete TwoClass.new
|
delete TwoClass.new
|
||||||
@@ -131,10 +131,10 @@ ok obj.amI()
|
|||||||
|
|
||||||
# super() calls in constructors of classes that are defined as object properties.
|
# super() calls in constructors of classes that are defined as object properties.
|
||||||
class Hive
|
class Hive
|
||||||
(name) -> @name = name
|
constructor: (name) -> @name = name
|
||||||
|
|
||||||
class Hive.Bee extends Hive
|
class Hive.Bee extends Hive
|
||||||
(name) -> super
|
constructor: (name) -> super
|
||||||
|
|
||||||
maya = new Hive.Bee 'Maya'
|
maya = new Hive.Bee 'Maya'
|
||||||
ok maya.name is 'Maya'
|
ok maya.name is 'Maya'
|
||||||
@@ -154,7 +154,7 @@ ok instance.name() is 'class'
|
|||||||
# ... or statically, to the class.
|
# ... or statically, to the class.
|
||||||
class Dog
|
class Dog
|
||||||
|
|
||||||
(name) ->
|
constructor: (name) ->
|
||||||
@name = name
|
@name = name
|
||||||
|
|
||||||
bark: =>
|
bark: =>
|
||||||
@@ -188,7 +188,7 @@ eq (func() for func in m.generate()).join(' '), '10 10 10'
|
|||||||
|
|
||||||
# Testing a contructor called with varargs.
|
# Testing a contructor called with varargs.
|
||||||
class Connection
|
class Connection
|
||||||
(one, two, three) ->
|
constructor: (one, two, three) ->
|
||||||
[@one, @two, @three] = [one, two, three]
|
[@one, @two, @three] = [one, two, three]
|
||||||
|
|
||||||
out: ->
|
out: ->
|
||||||
@@ -281,12 +281,10 @@ classMaker = ->
|
|||||||
@value = inner
|
@value = inner
|
||||||
|
|
||||||
class One
|
class One
|
||||||
ctor = classMaker()
|
constructor: classMaker()
|
||||||
-> return new ctor
|
|
||||||
|
|
||||||
class Two
|
class Two
|
||||||
ctor = classMaker()
|
constructor: classMaker()
|
||||||
-> return new ctor
|
|
||||||
|
|
||||||
ok (new One).value is 1
|
ok (new One).value is 1
|
||||||
ok (new Two).value is 2
|
ok (new Two).value is 2
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ ok expr(2, 4, 8).join(' ') is '4 16 64'
|
|||||||
|
|
||||||
# Fast object comprehensions over all properties, including prototypal ones.
|
# Fast object comprehensions over all properties, including prototypal ones.
|
||||||
class Cat
|
class Cat
|
||||||
-> @name = 'Whiskers'
|
constructor: -> @name = 'Whiskers'
|
||||||
breed: 'tabby'
|
breed: 'tabby'
|
||||||
hair: 'cream'
|
hair: 'cream'
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ eq ident(non?.existent().method()), undefined, 'soaks inner values'
|
|||||||
# Soaks constructor invocations.
|
# Soaks constructor invocations.
|
||||||
a = 0
|
a = 0
|
||||||
class Foo
|
class Foo
|
||||||
-> a += 1
|
constructor: -> a += 1
|
||||||
bar: "bat"
|
bar: "bat"
|
||||||
|
|
||||||
ok (new Foo())?.bar is 'bat'
|
ok (new Foo())?.bar is 'bat'
|
||||||
|
|||||||
Reference in New Issue
Block a user