1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

adding class methods to class definition syntax, using '@'

This commit is contained in:
Jeremy Ashkenas 2010-03-29 21:43:12 -04:00
parent 711dacae5f
commit 177ec92c39
7 changed files with 180 additions and 167 deletions

View file

@ -127,6 +127,8 @@
return new AssignNode(new ValueNode($1), $3, 'object'); return new AssignNode(new ValueNode($1), $3, 'object');
}), o("AlphaNumeric ASSIGN Expression", function() { }), o("AlphaNumeric ASSIGN Expression", function() {
return new AssignNode(new ValueNode($1), $3, 'object'); return new AssignNode(new ValueNode($1), $3, 'object');
}), o("ThisProperty ASSIGN Expression", function() {
return new AssignNode(new ValueNode($1), $3, 'this');
}), o("Comment") }), o("Comment")
], ],
// A return statement from a function body. // A return statement from a function body.

View file

@ -833,7 +833,7 @@
// 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.
ClassNode.prototype.compile_node = function compile_node(o) { ClassNode.prototype.compile_node = function compile_node(o) {
var _a, _b, _c, applied, construct, extension, func, prop, props, returns, val; var _a, _b, _c, access, applied, construct, extension, func, prop, props, pvar, returns, val;
extension = this.parent && new ExtendsNode(this.variable, this.parent); extension = this.parent && new ExtendsNode(this.variable, this.parent);
constructor = null; constructor = null;
props = new Expressions(); props = new Expressions();
@ -841,13 +841,15 @@
_b = this.properties; _b = this.properties;
for (_a = 0, _c = _b.length; _a < _c; _a++) { for (_a = 0, _c = _b.length; _a < _c; _a++) {
prop = _b[_a]; prop = _b[_a];
if (prop.variable && prop.variable.base.value === 'constructor') { pvar = prop.variable;
if (pvar && pvar.base.value === 'constructor') {
func = prop.value; func = prop.value;
func.body.push(new ReturnNode(literal('this'))); func.body.push(new ReturnNode(literal('this')));
constructor = new AssignNode(this.variable, func); constructor = new AssignNode(this.variable, func);
} else { } else {
if (prop.variable) { if (pvar) {
val = new ValueNode(this.variable, [new AccessorNode(prop.variable, 'prototype')]); access = prop.context === 'this' ? pvar.base.properties[0] : new AccessorNode(pvar, 'prototype');
val = new ValueNode(this.variable, [access]);
prop = new AssignNode(val, prop.value); prop = new AssignNode(val, prop.value);
} }
props.push(prop); props.push(prop);

File diff suppressed because one or more lines are too long

View file

@ -304,10 +304,10 @@
// In order to accomplish this, move outdents that follow closing parens // In order to accomplish this, move outdents that follow closing parens
// inwards, safely. The steps to accomplish this are: // inwards, safely. The steps to accomplish this are:
// 1. Check that all paired tokens are balanced and in order. // 1. Check that all paired tokens are balanced and in order.
// 2. Rewrite the stream with a stack: if you see an '(' or INDENT, add it // 2. Rewrite the stream with a stack: if you see an `EXPRESSION_START`, add it
// to the stack. If you see an ')' or OUTDENT, pop the stack and replace // to the stack. If you see an `EXPRESSION_END`, pop the stack and replace
// it with the inverse of what we've just popped. // it with the inverse of what we've just popped.
// 3. Keep track of "debt" for tokens that we fake, to make sure we end // 3. Keep track of "debt" for tokens that we manufacture, to make sure we end
// up balanced in the end. // up balanced in the end.
Rewriter.prototype.rewrite_closing_parens = function rewrite_closing_parens() { Rewriter.prototype.rewrite_closing_parens = function rewrite_closing_parens() {
var _a, debt, key, stack, val; var _a, debt, key, stack, val;

View file

@ -140,6 +140,7 @@ grammar: {
AssignObj: [ AssignObj: [
o "Identifier ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object' o "Identifier ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object'
o "AlphaNumeric ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object' o "AlphaNumeric ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object'
o "ThisProperty ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'this'
o "Comment" o "Comment"
] ]

View file

@ -628,14 +628,16 @@ exports.ClassNode: class ClassNode extends BaseNode
o.top: true o.top: true
for prop in @properties for prop in @properties
if prop.variable and prop.variable.base.value is 'constructor' pvar: prop.variable
if pvar and pvar.base.value is 'constructor'
func: prop.value func: prop.value
func.body.push(new ReturnNode(literal('this'))) func.body.push(new ReturnNode(literal('this')))
constructor: new AssignNode(@variable, func) constructor: new AssignNode(@variable, func)
else else
if prop.variable if pvar
val: new ValueNode(@variable, [new AccessorNode(prop.variable, 'prototype')]) access: if prop.context is 'this' then pvar.base.properties[0] else new AccessorNode(pvar, 'prototype')
prop: new AssignNode(val, prop.value) val: new ValueNode(@variable, [access])
prop: new AssignNode(val, prop.value)
props.push prop props.push prop
if not constructor if not constructor

View file

@ -1,6 +1,9 @@
class Base class Base
func: (string) -> func: (string) ->
'zero/' + string "zero/$string"
@static: (string) ->
"static/$string"
class FirstChild extends Base class FirstChild extends Base
func: (string) -> func: (string) ->
@ -21,6 +24,7 @@ class ThirdChild extends SecondChild
result: (new ThirdChild()).func 'four' result: (new ThirdChild()).func 'four'
ok result is 'zero/one/two/three/four' ok result is 'zero/one/two/three/four'
ok Base.static('word') is 'static/word'
class TopClass class TopClass