coffee-script 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +3 -0
- data/coffee-script.gemspec +2 -2
- data/examples/code.coffee +3 -3
- data/examples/poignant.coffee +3 -3
- data/examples/underscore.coffee +16 -15
- data/lib/coffee-script.rb +1 -1
- data/lib/coffee_script/CoffeeScript.tmbundle/Syntaxes/CoffeeScript.tmLanguage +9 -5
- data/lib/coffee_script/command_line.rb +12 -2
- data/lib/coffee_script/grammar.y +30 -19
- data/lib/coffee_script/lexer.rb +11 -9
- data/lib/coffee_script/narwhal/coffee-script.coffee +5 -5
- data/lib/coffee_script/narwhal/lib/coffee-script.js +15 -15
- data/lib/coffee_script/narwhal/lib/coffee-script/loader.js +2 -2
- data/lib/coffee_script/nodes.rb +114 -72
- data/lib/coffee_script/parser.rb +1128 -1063
- data/lib/coffee_script/rewriter.rb +4 -0
- data/lib/coffee_script/value.rb +1 -1
- data/package.json +1 -1
- metadata +2 -3
- data/lib/coffee_script/parser.output +0 -11407
data/README
CHANGED
data/coffee-script.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'coffee-script'
|
3
|
-
s.version = '0.2.
|
4
|
-
s.date = '2010-1-
|
3
|
+
s.version = '0.2.2' # Keep version in sync with coffee-script.rb
|
4
|
+
s.date = '2010-1-10'
|
5
5
|
|
6
6
|
s.homepage = "http://jashkenas.github.com/coffee-script/"
|
7
7
|
s.summary = "The CoffeeScript Compiler"
|
data/examples/code.coffee
CHANGED
@@ -141,18 +141,18 @@ aliquam erat volutpat. Ut wisi enim ad."
|
|
141
141
|
|
142
142
|
# Inheritance and calling super.
|
143
143
|
Animal: =>
|
144
|
-
Animal
|
144
|
+
Animal::move: meters =>
|
145
145
|
alert(this.name + " moved " + meters + "m.")
|
146
146
|
|
147
147
|
Snake: name => this.name: name
|
148
148
|
Snake extends Animal
|
149
|
-
Snake
|
149
|
+
Snake::move: =>
|
150
150
|
alert('Slithering...')
|
151
151
|
super(5)
|
152
152
|
|
153
153
|
Horse: name => this.name: name
|
154
154
|
Horse extends Animal
|
155
|
-
Horse
|
155
|
+
Horse::move: =>
|
156
156
|
alert('Galloping...')
|
157
157
|
super(45)
|
158
158
|
|
data/examples/poignant.coffee
CHANGED
@@ -14,9 +14,9 @@
|
|
14
14
|
# end
|
15
15
|
|
16
16
|
LotteryTicket: {
|
17
|
-
get_picks:
|
18
|
-
set_picks:
|
19
|
-
get_purchase:
|
17
|
+
get_picks: => this.picks
|
18
|
+
set_picks: nums => this.picks: nums
|
19
|
+
get_purchase: => this.purchase
|
20
20
|
set_purchase: amount => this.purchase: amount
|
21
21
|
}
|
22
22
|
|
data/examples/underscore.coffee
CHANGED
@@ -30,7 +30,7 @@
|
|
30
30
|
breaker: if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
|
31
31
|
|
32
32
|
|
33
|
-
# Create a safe reference to the Underscore object
|
33
|
+
# Create a safe reference to the Underscore object forreference below.
|
34
34
|
_: root._: obj => new wrapper(obj)
|
35
35
|
|
36
36
|
|
@@ -39,15 +39,15 @@
|
|
39
39
|
|
40
40
|
|
41
41
|
# Create quick reference variables for speed access to core prototypes.
|
42
|
-
slice: Array
|
43
|
-
unshift: Array
|
44
|
-
toString: Object
|
45
|
-
hasOwnProperty: Object
|
46
|
-
propertyIsEnumerable: Object
|
42
|
+
slice: Array::slice
|
43
|
+
unshift: Array::unshift
|
44
|
+
toString: Object::toString
|
45
|
+
hasOwnProperty: Object::hasOwnProperty
|
46
|
+
propertyIsEnumerable: Object::propertyIsEnumerable
|
47
47
|
|
48
48
|
|
49
49
|
# Current version.
|
50
|
-
_.VERSION: '0.5.
|
50
|
+
_.VERSION: '0.5.5'
|
51
51
|
|
52
52
|
|
53
53
|
# ------------------------ Collection Functions: ---------------------------
|
@@ -60,7 +60,7 @@
|
|
60
60
|
return obj.forEach(iterator, context) if obj.forEach
|
61
61
|
if _.isArray(obj) or _.isArguments(obj)
|
62
62
|
return iterator.call(context, obj[i], i, obj) for i in [0...obj.length]
|
63
|
-
iterator.call(context, val, key, obj) for
|
63
|
+
iterator.call(context, val, key, obj) for key, val ino obj
|
64
64
|
catch e
|
65
65
|
throw e if e isnt breaker
|
66
66
|
obj
|
@@ -148,7 +148,7 @@
|
|
148
148
|
# based on '==='.
|
149
149
|
_.include: obj, target =>
|
150
150
|
return _.indexOf(obj, target) isnt -1 if _.isArray(obj)
|
151
|
-
for val
|
151
|
+
for key, val ino obj
|
152
152
|
return true if val is target
|
153
153
|
false
|
154
154
|
|
@@ -380,7 +380,7 @@
|
|
380
380
|
# Retrieve the names of an object's properties.
|
381
381
|
_.keys: obj =>
|
382
382
|
return _.range(0, obj.length) if _.isArray(obj)
|
383
|
-
key for
|
383
|
+
key for key, val ino obj
|
384
384
|
|
385
385
|
|
386
386
|
# Retrieve the values of an object's properties.
|
@@ -395,7 +395,7 @@
|
|
395
395
|
|
396
396
|
# Extend a given object with all of the properties in a source object.
|
397
397
|
_.extend: destination, source =>
|
398
|
-
for
|
398
|
+
for key, val ino source
|
399
399
|
destination[key]: val
|
400
400
|
destination
|
401
401
|
|
@@ -564,8 +564,9 @@
|
|
564
564
|
_.each(_.functions(_)) name =>
|
565
565
|
method: _[name]
|
566
566
|
wrapper.prototype[name]: =>
|
567
|
-
|
568
|
-
|
567
|
+
args: _.toArray(arguments)
|
568
|
+
unshift.call(args, this._wrapped)
|
569
|
+
result(method.apply(_, args), this._chain)
|
569
570
|
|
570
571
|
|
571
572
|
# Add all mutator Array functions to the wrapper.
|
@@ -584,10 +585,10 @@
|
|
584
585
|
|
585
586
|
|
586
587
|
# Start chaining a wrapped Underscore object.
|
587
|
-
wrapper
|
588
|
+
wrapper::chain: =>
|
588
589
|
this._chain: true
|
589
590
|
this
|
590
591
|
|
591
592
|
|
592
593
|
# Extracts the result from a wrapped and chained object.
|
593
|
-
wrapper
|
594
|
+
wrapper::value: => this._wrapped
|
data/lib/coffee-script.rb
CHANGED
@@ -10,7 +10,7 @@ require "coffee_script/parse_error"
|
|
10
10
|
# Namespace for all CoffeeScript internal classes.
|
11
11
|
module CoffeeScript
|
12
12
|
|
13
|
-
VERSION = '0.2.
|
13
|
+
VERSION = '0.2.2' # Keep in sync with the gemspec.
|
14
14
|
|
15
15
|
# Compile a script (String or IO) to JavaScript.
|
16
16
|
def self.compile(script, options={})
|
@@ -10,6 +10,10 @@
|
|
10
10
|
</array>
|
11
11
|
<key>name</key>
|
12
12
|
<string>CoffeeScript</string>
|
13
|
+
<key>foldingStartMarker</key>
|
14
|
+
<string>^.*[:=] \{[^\}]*$</string>
|
15
|
+
<key>foldingStopMarker</key>
|
16
|
+
<string>\s*\}</string>
|
13
17
|
<key>patterns</key>
|
14
18
|
<array>
|
15
19
|
<dict>
|
@@ -39,7 +43,7 @@
|
|
39
43
|
<key>comment</key>
|
40
44
|
<string>match stuff like: funcName: => … </string>
|
41
45
|
<key>match</key>
|
42
|
-
<string>([a-zA-Z0-9_
|
46
|
+
<string>([a-zA-Z0-9_?.$:*]*)\s*(=|:)\s*([\w,\s]*?)\s*(=>)</string>
|
43
47
|
<key>name</key>
|
44
48
|
<string>meta.function.coffee</string>
|
45
49
|
</dict>
|
@@ -60,7 +64,7 @@
|
|
60
64
|
<key>comment</key>
|
61
65
|
<string>match stuff like: a => … </string>
|
62
66
|
<key>match</key>
|
63
|
-
<string>([a-zA-Z0-9_?.,
|
67
|
+
<string>([a-zA-Z0-9_?., $:*]*)\s*(=>)</string>
|
64
68
|
<key>name</key>
|
65
69
|
<string>meta.inline.function.coffee</string>
|
66
70
|
</dict>
|
@@ -210,7 +214,7 @@
|
|
210
214
|
</dict>
|
211
215
|
<dict>
|
212
216
|
<key>match</key>
|
213
|
-
<string>\b([a-zA-Z$_]\w*)(\:)\s</string>
|
217
|
+
<string>\b([a-zA-Z$_](\w|\$|:)*)(\:)\s</string>
|
214
218
|
<key>name</key>
|
215
219
|
<string>variable.assignment.coffee</string>
|
216
220
|
<key>captures</key>
|
@@ -220,7 +224,7 @@
|
|
220
224
|
<key>name</key>
|
221
225
|
<string>entity.name.function.coffee</string>
|
222
226
|
</dict>
|
223
|
-
<key>
|
227
|
+
<key>3</key>
|
224
228
|
<dict>
|
225
229
|
<key>name</key>
|
226
230
|
<string>keyword.operator.coffee</string>
|
@@ -259,7 +263,7 @@
|
|
259
263
|
</dict>
|
260
264
|
<dict>
|
261
265
|
<key>match</key>
|
262
|
-
<string
|
266
|
+
<string>!|%|&|\*|\/|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\?|\|\||\:|\*=|(?<!\()/=|%=|\+=|\-=|&=|\^=|\b(in|ino|instanceof|new|delete|typeof|and|or|is|isnt|not)\b</string>
|
263
267
|
<key>name</key>
|
264
268
|
<string>keyword.operator.coffee</string>
|
265
269
|
</dict>
|
@@ -1,7 +1,13 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'open3'
|
4
|
-
|
4
|
+
begin
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/../coffee-script')
|
6
|
+
rescue LoadError => e
|
7
|
+
puts(e.message)
|
8
|
+
puts("use \"rake build:parser\" to regenerate parser.rb")
|
9
|
+
exit(1)
|
10
|
+
end
|
5
11
|
|
6
12
|
module CoffeeScript
|
7
13
|
|
@@ -133,6 +139,7 @@ Usage:
|
|
133
139
|
begin
|
134
140
|
options = {}
|
135
141
|
options[:no_wrap] = true if @options[:no_wrap]
|
142
|
+
options[:globals] = true if @options[:globals]
|
136
143
|
CoffeeScript.compile(script, options)
|
137
144
|
rescue CoffeeScript::ParseError, SyntaxError => e
|
138
145
|
STDERR.puts "#{source}: #{e.message}"
|
@@ -187,9 +194,12 @@ Usage:
|
|
187
194
|
opts.on('-v', '--verbose', 'print at every step of code generation') do |v|
|
188
195
|
ENV['VERBOSE'] = 'true'
|
189
196
|
end
|
190
|
-
opts.on('-n', '--no-wrap', 'raw output, no safety wrapper
|
197
|
+
opts.on('-n', '--no-wrap', 'raw output, no function safety wrapper') do |n|
|
191
198
|
@options[:no_wrap] = true
|
192
199
|
end
|
200
|
+
opts.on('-g', '--globals', 'attach all top-level variable as globals') do |n|
|
201
|
+
@options[:globals] = true
|
202
|
+
end
|
193
203
|
opts.on_tail('--install-bundle', 'install the CoffeeScript TextMate bundle') do |i|
|
194
204
|
install_bundle
|
195
205
|
exit
|
data/lib/coffee_script/grammar.y
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
class Parser
|
2
2
|
|
3
|
-
# Declare tokens produced by the lexer
|
3
|
+
# Declare terminal tokens produced by the lexer.
|
4
4
|
token IF ELSE UNLESS
|
5
5
|
token NUMBER STRING REGEX
|
6
6
|
token TRUE FALSE YES NO ON OFF
|
7
|
-
token IDENTIFIER PROPERTY_ACCESS
|
8
|
-
token CODE PARAM
|
7
|
+
token IDENTIFIER PROPERTY_ACCESS PROTOTYPE_ACCESS
|
8
|
+
token CODE PARAM NEW RETURN
|
9
9
|
token TRY CATCH FINALLY THROW
|
10
10
|
token BREAK CONTINUE
|
11
|
-
token FOR IN BY WHEN WHILE
|
11
|
+
token FOR IN INO BY WHEN WHILE
|
12
12
|
token SWITCH LEADING_WHEN
|
13
13
|
token DELETE INSTANCEOF TYPEOF
|
14
14
|
token SUPER EXTENDS
|
@@ -21,7 +21,7 @@ token INDENT OUTDENT
|
|
21
21
|
# Declare order of operations.
|
22
22
|
prechigh
|
23
23
|
left '?'
|
24
|
-
nonassoc UMINUS
|
24
|
+
nonassoc UMINUS NOT '!' '!!' '~' '++' '--'
|
25
25
|
left '*' '/' '%'
|
26
26
|
left '+' '-'
|
27
27
|
left '<<' '>>' '>>>'
|
@@ -34,11 +34,12 @@ prechigh
|
|
34
34
|
left '.'
|
35
35
|
right INDENT
|
36
36
|
left OUTDENT
|
37
|
-
right WHEN LEADING_WHEN IN BY
|
37
|
+
right WHEN LEADING_WHEN IN INO BY
|
38
38
|
right THROW FOR NEW SUPER
|
39
39
|
left EXTENDS
|
40
40
|
left ASSIGN '||=' '&&='
|
41
|
-
right RETURN
|
41
|
+
right RETURN
|
42
|
+
right '=>' UNLESS IF ELSE WHILE
|
42
43
|
preclow
|
43
44
|
|
44
45
|
rule
|
@@ -58,13 +59,13 @@ rule
|
|
58
59
|
| Expressions Terminator { result = val[0] }
|
59
60
|
;
|
60
61
|
|
61
|
-
# All types of expressions in our language.
|
62
|
+
# All types of expressions in our language. The basic unit of CoffeeScript
|
63
|
+
# is the expression.
|
62
64
|
Expression:
|
63
65
|
Value
|
64
66
|
| Call
|
65
67
|
| Code
|
66
68
|
| Operation
|
67
|
-
| Range
|
68
69
|
| Assign
|
69
70
|
| If
|
70
71
|
| Try
|
@@ -79,18 +80,20 @@ rule
|
|
79
80
|
| Comment
|
80
81
|
;
|
81
82
|
|
83
|
+
# A block of expressions. Note that the Rewriter will convert some postfix
|
84
|
+
# forms into blocks for us, by altering the token stream.
|
82
85
|
Block:
|
83
86
|
INDENT Expressions OUTDENT { result = val[1] }
|
84
87
|
| INDENT OUTDENT { result = Expressions.new }
|
85
88
|
;
|
86
89
|
|
87
|
-
#
|
90
|
+
# Tokens that can terminate an expression.
|
88
91
|
Terminator:
|
89
92
|
"\n"
|
90
93
|
| ";"
|
91
94
|
;
|
92
95
|
|
93
|
-
# All hard-coded values.
|
96
|
+
# All hard-coded values. These can be printed straight to JavaScript.
|
94
97
|
Literal:
|
95
98
|
NUMBER { result = LiteralNode.new(val[0]) }
|
96
99
|
| STRING { result = LiteralNode.new(val[0]) }
|
@@ -107,12 +110,12 @@ rule
|
|
107
110
|
| OFF { result = LiteralNode.new(false) }
|
108
111
|
;
|
109
112
|
|
110
|
-
# Assignment to a variable.
|
113
|
+
# Assignment to a variable (or index).
|
111
114
|
Assign:
|
112
115
|
Value ASSIGN Expression { result = AssignNode.new(val[0], val[2]) }
|
113
116
|
;
|
114
117
|
|
115
|
-
# Assignment within an object literal.
|
118
|
+
# Assignment within an object literal (can be quoted).
|
116
119
|
AssignObj:
|
117
120
|
IDENTIFIER ASSIGN Expression { result = AssignNode.new(ValueNode.new(val[0]), val[2], :object) }
|
118
121
|
| STRING ASSIGN Expression { result = AssignNode.new(ValueNode.new(LiteralNode.new(val[0])), val[2], :object) }
|
@@ -122,6 +125,7 @@ rule
|
|
122
125
|
# A return statement.
|
123
126
|
Return:
|
124
127
|
RETURN Expression { result = ReturnNode.new(val[1]) }
|
128
|
+
| RETURN { result = ReturnNode.new(ValueNode.new(Value.new('null'))) }
|
125
129
|
;
|
126
130
|
|
127
131
|
# A comment.
|
@@ -184,8 +188,10 @@ rule
|
|
184
188
|
| Expression '&&=' Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
185
189
|
|
186
190
|
| Expression INSTANCEOF Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
191
|
+
| Expression IN Expression { result = OpNode.new(val[1], val[0], val[2]) }
|
187
192
|
;
|
188
193
|
|
194
|
+
# The existence operator.
|
189
195
|
Existence:
|
190
196
|
Expression '?' { result = ExistenceNode.new(val[0]) }
|
191
197
|
;
|
@@ -202,13 +208,15 @@ rule
|
|
202
208
|
| ParamList "," Param { result = val[0] << val[2] }
|
203
209
|
;
|
204
210
|
|
211
|
+
# A Parameter (or ParamSplat) in a function definition.
|
205
212
|
Param:
|
206
213
|
PARAM
|
207
|
-
|
|
214
|
+
| PARAM "." "." "." { result = ParamSplatNode.new(val[0]) }
|
208
215
|
;
|
209
216
|
|
217
|
+
# A regular splat.
|
210
218
|
Splat:
|
211
|
-
|
219
|
+
Expression "." "." "." { result = ArgSplatNode.new(val[0])}
|
212
220
|
;
|
213
221
|
|
214
222
|
# Expressions that can be treated as values.
|
@@ -218,6 +226,7 @@ rule
|
|
218
226
|
| Array { result = ValueNode.new(val[0]) }
|
219
227
|
| Object { result = ValueNode.new(val[0]) }
|
220
228
|
| Parenthetical { result = ValueNode.new(val[0]) }
|
229
|
+
| Range { result = ValueNode.new(val[0]) }
|
221
230
|
| Value Accessor { result = val[0] << val[1] }
|
222
231
|
| Invocation Accessor { result = ValueNode.new(val[0], [val[1]]) }
|
223
232
|
;
|
@@ -225,6 +234,7 @@ rule
|
|
225
234
|
# Accessing into an object or array, through dot or index notation.
|
226
235
|
Accessor:
|
227
236
|
PROPERTY_ACCESS IDENTIFIER { result = AccessorNode.new(val[1]) }
|
237
|
+
| PROTOTYPE_ACCESS IDENTIFIER { result = AccessorNode.new(val[1], true) }
|
228
238
|
| Index { result = val[0] }
|
229
239
|
| Range { result = SliceNode.new(val[0]) }
|
230
240
|
;
|
@@ -269,6 +279,7 @@ rule
|
|
269
279
|
# | Invocation Code { result = val[0] << val[1] }
|
270
280
|
;
|
271
281
|
|
282
|
+
# The list of arguments to a function invocation.
|
272
283
|
Arguments:
|
273
284
|
"(" ArgList ")" { result = val[1] }
|
274
285
|
| "(" ArgList ")" Code { result = val[1] << val[3] }
|
@@ -330,6 +341,7 @@ rule
|
|
330
341
|
# The while loop. (there is no do..while).
|
331
342
|
While:
|
332
343
|
WHILE Expression Block { result = WhileNode.new(val[1], val[2]) }
|
344
|
+
| WHILE Expression { result = WhileNode.new(val[1], nil) }
|
333
345
|
;
|
334
346
|
|
335
347
|
# Array comprehensions, including guard and current index.
|
@@ -349,6 +361,7 @@ rule
|
|
349
361
|
# The source of the array comprehension can optionally be filtered.
|
350
362
|
ForSource:
|
351
363
|
IN Expression { result = {:source => val[1]} }
|
364
|
+
| INO Expression { result = {:source => val[1], :object => true} }
|
352
365
|
| ForSource
|
353
366
|
WHEN Expression { result = val[0].merge(:filter => val[2]) }
|
354
367
|
| ForSource
|
@@ -374,12 +387,10 @@ rule
|
|
374
387
|
LEADING_WHEN Expression Block { result = IfNode.new(val[1], val[2], nil, {:statement => true}) }
|
375
388
|
| LEADING_WHEN Expression Block
|
376
389
|
Terminator { result = IfNode.new(val[1], val[2], nil, {:statement => true}) }
|
377
|
-
| Comment
|
390
|
+
| Comment Terminator When { result = val[2].add_comment(val[0]) }
|
378
391
|
;
|
379
392
|
|
380
|
-
#
|
381
|
-
# grammar expand unambiguously.
|
382
|
-
|
393
|
+
# The most basic form of "if".
|
383
394
|
IfBlock:
|
384
395
|
IF Expression Block { result = IfNode.new(val[1], val[2]) }
|
385
396
|
;
|
data/lib/coffee_script/lexer.rb
CHANGED
@@ -12,23 +12,23 @@ module CoffeeScript
|
|
12
12
|
"new", "return",
|
13
13
|
"try", "catch", "finally", "throw",
|
14
14
|
"break", "continue",
|
15
|
-
"for", "in", "by", "where", "while",
|
15
|
+
"for", "in", "ino", "by", "where", "while",
|
16
16
|
"switch", "when",
|
17
17
|
"super", "extends",
|
18
18
|
"arguments",
|
19
19
|
"delete", "instanceof", "typeof"]
|
20
20
|
|
21
21
|
# Token matching regexes.
|
22
|
-
IDENTIFIER = /\A([a-zA-Z$_]\w*)/
|
22
|
+
IDENTIFIER = /\A([a-zA-Z$_](\w|\$)*)/
|
23
23
|
NUMBER = /\A(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i
|
24
|
-
STRING = /\A(""|''|"(.*?)[^\\]"|'(.*?)[^\\]')/m
|
25
|
-
JS = /\A(``|`(.*?)[^\\]`)/m
|
24
|
+
STRING = /\A(""|''|"(.*?)([^\\]|\\\\)"|'(.*?)([^\\]|\\\\)')/m
|
25
|
+
JS = /\A(``|`(.*?)([^\\]|\\\\)`)/m
|
26
26
|
OPERATOR = /\A([+\*&|\/\-%=<>:!]+)/
|
27
27
|
WHITESPACE = /\A([ \t]+)/
|
28
28
|
COMMENT = /\A(((\n?[ \t]*)?#.*$)+)/
|
29
29
|
CODE = /\A(=>)/
|
30
|
-
REGEX = /\A(\/(.*?)[^\\]\/[imgy]{0,4})/
|
31
|
-
MULTI_DENT = /\A((\n([ \t]*)
|
30
|
+
REGEX = /\A(\/(.*?)([^\\]|\\\\)\/[imgy]{0,4})/
|
31
|
+
MULTI_DENT = /\A((\n([ \t]*))+)(\.)?/
|
32
32
|
LAST_DENT = /\n([ \t]*)/
|
33
33
|
ASSIGNMENT = /\A(:|=)\Z/
|
34
34
|
|
@@ -88,6 +88,7 @@ module CoffeeScript
|
|
88
88
|
tag = KEYWORDS.include?(identifier) ? identifier.upcase.to_sym : :IDENTIFIER
|
89
89
|
tag = :LEADING_WHEN if tag == :WHEN && [:OUTDENT, :INDENT, "\n"].include?(last_tag)
|
90
90
|
@tokens[-1][0] = :PROPERTY_ACCESS if tag == :IDENTIFIER && last_value == '.' && !(@tokens[-2][1] == '.')
|
91
|
+
@tokens[-1][0] = :PROTOTYPE_ACCESS if tag == :IDENTIFIER && last_value == '::'
|
91
92
|
token(tag, identifier)
|
92
93
|
@i += identifier.length
|
93
94
|
end
|
@@ -139,7 +140,9 @@ module CoffeeScript
|
|
139
140
|
return false unless indent = @chunk[MULTI_DENT, 1]
|
140
141
|
@line += indent.scan(MULTILINER).size
|
141
142
|
@i += indent.size
|
142
|
-
|
143
|
+
next_character = @chunk[MULTI_DENT, 4]
|
144
|
+
no_newlines = next_character == '.' || (last_value.to_s.match(NO_NEWLINE) && last_value != "=>")
|
145
|
+
return suppress_newlines(indent) if no_newlines
|
143
146
|
size = indent.scan(LAST_DENT).last.last.length
|
144
147
|
return newline_token(indent) if size == @indent
|
145
148
|
if size > @indent
|
@@ -221,8 +224,7 @@ module CoffeeScript
|
|
221
224
|
i -= 1
|
222
225
|
tok = @tokens[i]
|
223
226
|
return if !tok
|
224
|
-
next if
|
225
|
-
next tok[0] = :PARAM_SPLAT if tok[0] == '*'
|
227
|
+
next if ['.', ','].include?(tok[0])
|
226
228
|
return if tok[0] != :IDENTIFIER
|
227
229
|
tok[0] = :PARAM
|
228
230
|
end
|