adding '::' as shorthand for '.prototype.'

This commit is contained in:
Jeremy Ashkenas 2010-01-10 16:16:59 -05:00
parent 902febb43a
commit ad18378f7e
10 changed files with 59 additions and 36 deletions

View File

@ -1,16 +1,16 @@
Animal: =>
Animal.prototype.move: meters =>
Animal::move: meters =>
alert(this.name + " moved " + meters + "m.")
Snake: name => this.name: name
Snake extends Animal
Snake.prototype.move: =>
Snake::move: =>
alert("Slithering...")
super(5)
Horse: name => this.name: name
Horse extends Animal
Horse.prototype.move: =>
Horse::move: =>
alert("Galloping...")
super(45)

View File

@ -467,9 +467,9 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
it's awkward to call <b>super</b> (the prototype object's
implementation of the current function), and it's awkward to correctly
set the prototype chain. CoffeeScript provides <tt>extends</tt>
to help with prototype setup, and converts
<tt>super()</tt> calls into calls against the immediate ancestor's
method of the same name.
to help with prototype setup, <tt>::</tt> for quick access to an
object's prototype, and converts <tt>super()</tt> calls into calls against
the immediate ancestor's method of the same name.
</p>
<%= code_for('super', true) %>
@ -575,11 +575,21 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<p>
<b class="header" style="margin-top: 20px;">0.2.2</b>
When performing a comprehension over an object, use <tt>ino</tt>, instead
of <tt>in</tt>, which helps us generate smaller, more efficient code at
compile time.
<br />
Added <tt>::</tt> as a shorthand for saying <tt>.prototype.</tt>
<br />
The "splat" symbol has been changed from a prefix asterisk <tt>*</tt>, to
a postfix ellipsis <tt>...</tt>. Added JavaScript's <tt>in</tt> operator,
a postfix ellipsis <tt>...</tt>
<br />
Added JavaScript's <tt>in</tt> operator,
empty <tt>return</tt> statements, and empty <tt>while</tt> loops.
<br />
Constructor functions that start with capital letters now include a
safety check to make sure that the new instance of the object is returned.
<br />
The <tt>extends</tt> keyword now functions identically to <tt>goog.inherits</tt>
in Google's Closure Library.
</p>

View File

@ -141,18 +141,18 @@ aliquam erat volutpat. Ut wisi enim ad."
# Inheritance and calling super.
Animal: =>
Animal.prototype.move: meters =>
Animal::move: meters =>
alert(this.name + " moved " + meters + "m.")
Snake: name => this.name: name
Snake extends Animal
Snake.prototype.move: =>
Snake::move: =>
alert('Slithering...')
super(5)
Horse: name => this.name: name
Horse extends Animal
Horse.prototype.move: =>
Horse::move: =>
alert('Galloping...')
super(45)

View File

@ -39,11 +39,11 @@
# Create quick reference variables for speed access to core prototypes.
slice: Array.prototype.slice
unshift: Array.prototype.unshift
toString: Object.prototype.toString
hasOwnProperty: Object.prototype.hasOwnProperty
propertyIsEnumerable: Object.prototype.propertyIsEnumerable
slice: Array::slice
unshift: Array::unshift
toString: Object::toString
hasOwnProperty: Object::hasOwnProperty
propertyIsEnumerable: Object::propertyIsEnumerable
# Current version.
@ -585,10 +585,10 @@
# Start chaining a wrapped Underscore object.
wrapper.prototype.chain: =>
wrapper::chain: =>
this._chain: true
this
# Extracts the result from a wrapped and chained object.
wrapper.prototype.value: => this._wrapped
wrapper::value: => this._wrapped

View File

@ -973,23 +973,23 @@ globals = ((function() {
it's awkward to call <b>super</b> (the prototype object's
implementation of the current function), and it's awkward to correctly
set the prototype chain. CoffeeScript provides <tt>extends</tt>
to help with prototype setup, and converts
<tt>super()</tt> calls into calls against the immediate ancestor's
method of the same name.
to help with prototype setup, <tt>::</tt> for quick access to an
object's prototype, and converts <tt>super()</tt> calls into calls against
the immediate ancestor's method of the same name.
</p>
<div class='code'><pre class="idle"><span class="FunctionName">Animal</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
<span class="FunctionName">Animal.prototype.move</span><span class="Keyword">:</span> <span class="FunctionArgument">meters</span> <span class="Storage">=&gt;</span>
Animal<span class="Keyword">:</span><span class="Keyword">:</span><span class="FunctionName">move</span><span class="Keyword">:</span> <span class="FunctionArgument">meters</span> <span class="Storage">=&gt;</span>
alert(<span class="Variable">this</span>.name <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> moved <span class="String">&quot;</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>m.<span class="String">&quot;</span></span>)
<span class="FunctionName">Snake</span><span class="Keyword">:</span> <span class="FunctionArgument">name</span> <span class="Storage">=&gt;</span> <span class="Variable">this</span>.name<span class="Keyword">:</span> name
Snake <span class="Variable">extends</span> Animal
<span class="FunctionName">Snake.prototype.move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
Snake<span class="Keyword">:</span><span class="Keyword">:</span><span class="FunctionName">move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
alert(<span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>)
<span class="Variable">super</span>(<span class="Number">5</span>)
<span class="FunctionName">Horse</span><span class="Keyword">:</span> <span class="FunctionArgument">name</span> <span class="Storage">=&gt;</span> <span class="Variable">this</span>.name<span class="Keyword">:</span> name
Horse <span class="Variable">extends</span> Animal
<span class="FunctionName">Horse.prototype.move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
Horse<span class="Keyword">:</span><span class="Keyword">:</span><span class="FunctionName">move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
alert(<span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>)
<span class="Variable">super</span>(<span class="Number">45</span>)
@ -1265,11 +1265,21 @@ world...";
<p>
<b class="header" style="margin-top: 20px;">0.2.2</b>
When performing a comprehension over an object, use <tt>ino</tt>, instead
of <tt>in</tt>, which helps us generate smaller, more efficient code at
compile time.
<br />
Added <tt>::</tt> as a shorthand for saying <tt>.prototype.</tt>
<br />
The "splat" symbol has been changed from a prefix asterisk <tt>*</tt>, to
a postfix ellipsis <tt>...</tt>. Added JavaScript's <tt>in</tt> operator,
a postfix ellipsis <tt>...</tt>
<br />
Added JavaScript's <tt>in</tt> operator,
empty <tt>return</tt> statements, and empty <tt>while</tt> loops.
<br />
Constructor functions that start with capital letters now include a
safety check to make sure that the new instance of the object is returned.
<br />
The <tt>extends</tt> keyword now functions identically to <tt>goog.inherits</tt>
in Google's Closure Library.
</p>

View File

@ -43,7 +43,7 @@
<key>comment</key>
<string>match stuff like: funcName: =&gt; … </string>
<key>match</key>
<string>([a-zA-Z0-9_?.$*]*)\s*(=|:)\s*([\w,\s]*?)\s*(=&gt;)</string>
<string>([a-zA-Z0-9_?.$:*]*)\s*(=|:)\s*([\w,\s]*?)\s*(=&gt;)</string>
<key>name</key>
<string>meta.function.coffee</string>
</dict>
@ -64,7 +64,7 @@
<key>comment</key>
<string>match stuff like: a =&gt; … </string>
<key>match</key>
<string>([a-zA-Z0-9_?., $*]*)\s*(=&gt;)</string>
<string>([a-zA-Z0-9_?., $:*]*)\s*(=&gt;)</string>
<key>name</key>
<string>meta.inline.function.coffee</string>
</dict>
@ -214,7 +214,7 @@
</dict>
<dict>
<key>match</key>
<string>\b([a-zA-Z$_](\w|\$)*)(\:)\s</string>
<string>\b([a-zA-Z$_](\w|\$|:)*)(\:)\s</string>
<key>name</key>
<string>variable.assignment.coffee</string>
<key>captures</key>

View File

@ -4,7 +4,7 @@ class Parser
token IF ELSE UNLESS
token NUMBER STRING REGEX
token TRUE FALSE YES NO ON OFF
token IDENTIFIER PROPERTY_ACCESS
token IDENTIFIER PROPERTY_ACCESS PROTOTYPE_ACCESS
token CODE PARAM NEW RETURN
token TRY CATCH FINALLY THROW
token BREAK CONTINUE
@ -234,6 +234,7 @@ rule
# Accessing into an object or array, through dot or index notation.
Accessor:
PROPERTY_ACCESS IDENTIFIER { result = AccessorNode.new(val[1]) }
| PROTOTYPE_ACCESS IDENTIFIER { result = AccessorNode.new(val[1], true) }
| Index { result = val[0] }
| Range { result = SliceNode.new(val[0]) }
;

View File

@ -88,6 +88,7 @@ module CoffeeScript
tag = KEYWORDS.include?(identifier) ? identifier.upcase.to_sym : :IDENTIFIER
tag = :LEADING_WHEN if tag == :WHEN && [:OUTDENT, :INDENT, "\n"].include?(last_tag)
@tokens[-1][0] = :PROPERTY_ACCESS if tag == :IDENTIFIER && last_value == '.' && !(@tokens[-2][1] == '.')
@tokens[-1][0] = :PROTOTYPE_ACCESS if tag == :IDENTIFIER && last_value == '::'
token(tag, identifier)
@i += identifier.length
end

View File

@ -324,12 +324,13 @@ module CoffeeScript
class AccessorNode < Node
attr_reader :name
def initialize(name)
@name = name
def initialize(name, prototype=false)
@name, @prototype = name, prototype
end
def compile_node(o)
write(".#{@name}")
proto = @prototype ? "prototype." : ''
write(".#{proto}#{@name}")
end
end
@ -416,7 +417,7 @@ module CoffeeScript
# Setting the value of a local variable, or the value of an object property.
class AssignNode < Node
PROTO_ASSIGN = /\A(\S+)\.prototype/
LEADING_DOT = /\A\./
LEADING_DOT = /\A\.(prototype\.)?/
attr_reader :variable, :value, :context

View File

@ -1,21 +1,21 @@
Base: =>
Base.prototype.func: string =>
Base::func: string =>
'zero/' + string
FirstChild: =>
FirstChild extends Base
FirstChild.prototype.func: string =>
FirstChild::func: string =>
super('one/') + string
SecondChild: =>
SecondChild extends FirstChild
SecondChild.prototype.func: string =>
SecondChild::func: string =>
super('two/') + string
ThirdChild: =>
this.array: [1, 2, 3]
ThirdChild extends SecondChild
ThirdChild.prototype.func: string =>
ThirdChild::func: string =>
super('three/') + string
result: (new ThirdChild()).func('four')