js2 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +12 -2
- data/lib/js2/js2.js +135 -22
- metadata +17 -7
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.3.5
|
2
|
+
* Added scope and binding support to shorthand functions
|
3
|
+
* Added support for modules
|
4
|
+
|
5
|
+
0.3.4
|
6
|
+
* coded reduce to clojure spec
|
7
|
+
* fixed collect and some other iterators
|
8
|
+
|
1
9
|
0.3.3
|
2
|
-
|
3
|
-
|
10
|
+
* using closure for classes instead of hashes
|
11
|
+
* adding static methods
|
12
|
+
|
13
|
+
|
data/lib/js2/js2.js
CHANGED
@@ -14,6 +14,7 @@ function mainFunction (arg) {
|
|
14
14
|
|
15
15
|
var JS2 = root.JS2 = mainFunction;
|
16
16
|
var js2 = root.js2 = JS2;
|
17
|
+
js2.VERSION = "0.3.5";
|
17
18
|
|
18
19
|
JS2.ROOT = JS2;
|
19
20
|
|
@@ -24,22 +25,39 @@ function mainFunction (arg) {
|
|
24
25
|
this.klass = klass;
|
25
26
|
this.par = par;
|
26
27
|
|
27
|
-
this
|
28
|
-
|
29
|
-
members: {},
|
30
|
-
};
|
31
|
-
|
32
|
-
this.methods = {};
|
33
|
-
this.members = {};
|
28
|
+
this.members = {};
|
29
|
+
this.staticMembers = {};
|
34
30
|
this.children = [];
|
31
|
+
this.included = [];
|
35
32
|
|
36
|
-
if (this.par) this.par.
|
33
|
+
if (this.par) this.par.OO.children.push(klass);
|
37
34
|
};
|
38
35
|
|
39
36
|
OO.prototype = {
|
40
37
|
forbiddenMembers: {
|
41
38
|
'prototype': undefined,
|
42
|
-
'
|
39
|
+
'OO': undefined
|
40
|
+
},
|
41
|
+
|
42
|
+
include: function(module) {
|
43
|
+
this.included.push(module);
|
44
|
+
var members = module.OO.members;
|
45
|
+
for (var name in members) {
|
46
|
+
if (members.hasOwnProperty(name)) {
|
47
|
+
this.addMember(name, members[name]);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
var staticMembers = module.OO.staticMembers;
|
52
|
+
for (var name in staticMembers) {
|
53
|
+
if (staticMembers.hasOwnProperty(name)) {
|
54
|
+
this.addStaticMember(name, staticMembers[name]);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
if (typeof staticMembers['included'] == 'function') {
|
59
|
+
staticMembers['included'](this.klass);
|
60
|
+
}
|
43
61
|
},
|
44
62
|
|
45
63
|
createNamespace: function(name) {
|
@@ -74,6 +92,7 @@ function mainFunction (arg) {
|
|
74
92
|
}
|
75
93
|
|
76
94
|
proto[name] = member;
|
95
|
+
this.members[name] = member;
|
77
96
|
},
|
78
97
|
|
79
98
|
addStaticMember: function(name, member) {
|
@@ -86,14 +105,15 @@ function mainFunction (arg) {
|
|
86
105
|
}
|
87
106
|
|
88
107
|
this.klass[name] = member;
|
108
|
+
this.staticMembers[name] = member;
|
89
109
|
}
|
90
110
|
};
|
91
111
|
|
92
112
|
JS2.Class = function() { this.initialize.apply(this, arguments); };
|
93
|
-
JS2.Class.
|
113
|
+
JS2.Class.OO = new OO(JS2.Class);
|
94
114
|
JS2.Class.prototype = {
|
95
115
|
initialize: function () {},
|
96
|
-
oo: JS2.Class.
|
116
|
+
oo: JS2.Class.OO
|
97
117
|
};
|
98
118
|
|
99
119
|
var namedClasses = {};
|
@@ -104,13 +124,13 @@ function mainFunction (arg) {
|
|
104
124
|
var noInit = false;
|
105
125
|
JS2.Class.extend = function(name, klassDef) {
|
106
126
|
var klass = function() { if (!noInit) this.initialize.apply(this, arguments); };
|
107
|
-
klass.
|
127
|
+
klass.OO = new OO(klass, this);
|
108
128
|
|
109
129
|
if (typeof name != 'string') {
|
110
130
|
klassDef = name;
|
111
131
|
} else {
|
112
132
|
namedClasses[name] = klass;
|
113
|
-
var namespace = this.
|
133
|
+
var namespace = this.OO.createNamespace(name);
|
114
134
|
namespace[0][namespace[1]] = klass;
|
115
135
|
}
|
116
136
|
|
@@ -120,8 +140,8 @@ function mainFunction (arg) {
|
|
120
140
|
noInit = false;
|
121
141
|
|
122
142
|
klass.prototype = proto;
|
123
|
-
var oo = klass.
|
124
|
-
proto.
|
143
|
+
var oo = klass.OO;
|
144
|
+
proto.OO = oo;
|
125
145
|
|
126
146
|
for (var name in this) {
|
127
147
|
oo.addStaticMember(name, this[name]);
|
@@ -138,6 +158,8 @@ function mainFunction (arg) {
|
|
138
158
|
return klass;
|
139
159
|
};
|
140
160
|
|
161
|
+
JS2.Module = JS2.Class;
|
162
|
+
|
141
163
|
var assert = {
|
142
164
|
'eq': function(expected, actual) { if (expected != actual) console.log("Expected "+expected+", but got "+actual+".") },
|
143
165
|
'isFalse': function(val) { if (val) console.log("Expected false, but got "+val+".") },
|
@@ -159,7 +181,9 @@ function mainFunction (arg) {
|
|
159
181
|
[ 'SPACE', "\\s+" ],
|
160
182
|
[ 'REGEX', "\\/" ],
|
161
183
|
[ 'CLASS', "class" ],
|
184
|
+
[ 'MODULE', "module" ],
|
162
185
|
[ 'STATIC', "static" ],
|
186
|
+
[ 'include', "include" ],
|
163
187
|
[ 'SHORT_FUNCT', "#\\{|#\\(" ],
|
164
188
|
[ 'FOREACH', "foreach" ],
|
165
189
|
[ 'CURRY', "curry" ],
|
@@ -437,6 +461,7 @@ function mainFunction (arg) {
|
|
437
461
|
this.index = 0;
|
438
462
|
this.str = str;
|
439
463
|
this.orig = str;
|
464
|
+
this.before = [];
|
440
465
|
},
|
441
466
|
|
442
467
|
toArray: function() {
|
@@ -478,7 +503,9 @@ function mainFunction (arg) {
|
|
478
503
|
},
|
479
504
|
|
480
505
|
pop: function() {
|
481
|
-
|
506
|
+
var ret = this.tokens.pop();
|
507
|
+
this.before.push(ret);
|
508
|
+
return ret;
|
482
509
|
},
|
483
510
|
|
484
511
|
peek: function() {
|
@@ -494,6 +521,7 @@ function mainFunction (arg) {
|
|
494
521
|
case '(': this.braceCount++; break;
|
495
522
|
case ')': this.braceCount--; break;
|
496
523
|
}
|
524
|
+
this.before.unshift(token);
|
497
525
|
return token;
|
498
526
|
},
|
499
527
|
|
@@ -539,7 +567,7 @@ function mainFunction (arg) {
|
|
539
567
|
}
|
540
568
|
};
|
541
569
|
|
542
|
-
var KEYWORDS = { 'var': null, 'class': null, 'function': null, 'in': null, 'with': null, 'curry': null, 'static': null };
|
570
|
+
var KEYWORDS = { 'var': null, 'class': null, 'function': null, 'in': null, 'with': null, 'curry': null, 'static': null, 'module':null };
|
543
571
|
var IDS = JS2.Lexer.IDS;
|
544
572
|
IDS['NODE'] = -1;
|
545
573
|
|
@@ -655,6 +683,7 @@ function mainFunction (arg) {
|
|
655
683
|
handOff: function(token) {
|
656
684
|
switch (token[1]) {
|
657
685
|
case IDS.CLASS: return Klass;
|
686
|
+
case IDS.MODULE: return Module;
|
658
687
|
case IDS.FOREACH: return Foreach;
|
659
688
|
case IDS.SHORT_FUNCT: return ShortFunct;
|
660
689
|
case IDS.CURRY: return Curry;
|
@@ -692,6 +721,23 @@ function mainFunction (arg) {
|
|
692
721
|
}
|
693
722
|
});
|
694
723
|
|
724
|
+
var Module = Klass.extend({
|
725
|
+
name: 'Module',
|
726
|
+
toString: function() {
|
727
|
+
var v = this.validate(/(module)(\s+)/);
|
728
|
+
var last = v.last;
|
729
|
+
var m = last.match(/^([\w$]+(\.[\w$]+)*)/);
|
730
|
+
if (m) {
|
731
|
+
var name = m[1];
|
732
|
+
var source = last.substr(name.length);
|
733
|
+
return JS2.DECORATOR.createModule(name, source);
|
734
|
+
} else {
|
735
|
+
// raise error
|
736
|
+
}
|
737
|
+
}
|
738
|
+
});
|
739
|
+
|
740
|
+
|
695
741
|
var Block = Content.extend({
|
696
742
|
name: 'Block',
|
697
743
|
handleToken: function(token) {
|
@@ -708,6 +754,7 @@ function mainFunction (arg) {
|
|
708
754
|
case 'var': return Member;
|
709
755
|
case 'function': return Method;
|
710
756
|
case 'static': return StaticMember;
|
757
|
+
case 'include': return Include;
|
711
758
|
}
|
712
759
|
},
|
713
760
|
|
@@ -719,10 +766,23 @@ function mainFunction (arg) {
|
|
719
766
|
|
720
767
|
toString: function() {
|
721
768
|
var str = this.$super();
|
722
|
-
return str.replace(/^{/, 'function(KLASS, OO){')
|
769
|
+
return str.replace(/^{/, 'function(KLASS, OO){');
|
723
770
|
}
|
724
771
|
});
|
725
772
|
|
773
|
+
var Include = Content.extend({
|
774
|
+
name: 'Include',
|
775
|
+
handleToken: function(token) {
|
776
|
+
if (token[0] == ';') this.closed = true;
|
777
|
+
},
|
778
|
+
|
779
|
+
toString: function() {
|
780
|
+
var v = this.validate(/^(include)(\s+)/);
|
781
|
+
return "OO.include(" + v.last.replace(/;$/, ');');
|
782
|
+
}
|
783
|
+
|
784
|
+
});
|
785
|
+
|
726
786
|
var StaticMember = Content.extend({
|
727
787
|
name: 'StaticMember',
|
728
788
|
handOff: function(token) {
|
@@ -829,9 +889,8 @@ function mainFunction (arg) {
|
|
829
889
|
handOff: function(token) {
|
830
890
|
if (this.started) {
|
831
891
|
this.closed = true;
|
832
|
-
var foo = (new Validator(this.tokens.toArray())).getString(2);
|
833
892
|
this.semi = (new Validator(this.tokens.toArray())).validate(/^(\s*)([^\s\w$])/, 2) ? '' : ';';
|
834
|
-
}
|
893
|
+
}
|
835
894
|
|
836
895
|
switch (token[0]) {
|
837
896
|
case '(': return Braces;
|
@@ -839,9 +898,50 @@ function mainFunction (arg) {
|
|
839
898
|
}
|
840
899
|
},
|
841
900
|
|
901
|
+
parseArgs: function(str) {
|
902
|
+
// (arg1, arg2 with scope1, scope2 binds bindingVar)
|
903
|
+
var m = str.match(/^\((\s*([\w\$]+)(\s*,\s*[\w\$]+)*)?(\s*with\s+(([\w\$]+)(\s*,\s*[\w\$]+)*))?(\s*binds\s+(.+))?\)/);
|
904
|
+
if (!m) {} // raise error
|
905
|
+
|
906
|
+
return {
|
907
|
+
braces: '(' + (m[1] || '') + ')',
|
908
|
+
scope: m[5],
|
909
|
+
binds: m[9]
|
910
|
+
};
|
911
|
+
},
|
912
|
+
|
842
913
|
toString: function() {
|
843
|
-
var
|
844
|
-
|
914
|
+
var scopes = null;
|
915
|
+
var inScopes = null;
|
916
|
+
|
917
|
+
var v = this.validate(/(#)(Braces)?(\s*)(Block)/);
|
918
|
+
var args = this.parseArgs(v[2] ? v[2].toString() : '($1,$2,$3)');
|
919
|
+
var body = v[4];
|
920
|
+
|
921
|
+
// we need a function within a function
|
922
|
+
if (args.binds || args.scope) {
|
923
|
+
var scope = args.scope || '';
|
924
|
+
var inScope = scope;
|
925
|
+
|
926
|
+
// need to pass in __self and bind to __self
|
927
|
+
if (args.binds) {
|
928
|
+
var comma = scope == '' ? '' : ',';
|
929
|
+
inScope = scope.replace(/^/, '__self' + comma);
|
930
|
+
scope = scope.replace(/^/, args.binds + comma);
|
931
|
+
|
932
|
+
return '(function(' + inScope + '){' + 'var f = function' + args.braces + body + ';' + ' return function() { return f.apply(__self, arguments)};})(' + scope + ')' + this.semi;
|
933
|
+
}
|
934
|
+
|
935
|
+
// no binding, just use scoping
|
936
|
+
else {
|
937
|
+
return '(function(' + inScope + '){' + 'return function' + args.braces + body + ';' + '})(' + scope + ')' + this.semi;
|
938
|
+
}
|
939
|
+
}
|
940
|
+
|
941
|
+
// just a normal function
|
942
|
+
else {
|
943
|
+
return "function" + args.braces + body + this.semi;
|
944
|
+
}
|
845
945
|
}
|
846
946
|
});
|
847
947
|
|
@@ -1208,6 +1308,7 @@ JS2.Class.extend('Config', function(KLASS, OO){
|
|
1208
1308
|
|
1209
1309
|
JS2.Class.extend('Commander', function(KLASS, OO){
|
1210
1310
|
OO.addMember("BANNER","js2 <command> [options] <arguments>\n" +
|
1311
|
+
"VERSION: " + js2.VERSION + "\n" +
|
1211
1312
|
"Commands:\n" +
|
1212
1313
|
" * run <file> -- Executes file\n" +
|
1213
1314
|
" * render <file> -- Shows JS2 compiled output\n" +
|
@@ -1297,6 +1398,10 @@ JS2.Class.extend('BrowserDecorator', function(KLASS, OO){
|
|
1297
1398
|
OO.addMember("klass",function (name, par, source) {
|
1298
1399
|
return par+".extend('"+name+"',"+source+");";
|
1299
1400
|
});
|
1401
|
+
|
1402
|
+
OO.addMember("createModule",function (name, source) {
|
1403
|
+
return "JS2.Module.extend('"+name+"',"+source+");";
|
1404
|
+
});
|
1300
1405
|
});
|
1301
1406
|
|
1302
1407
|
JS2.Class.extend('NodeDecorator', function(KLASS, OO){
|
@@ -1307,6 +1412,10 @@ JS2.Class.extend('NodeDecorator', function(KLASS, OO){
|
|
1307
1412
|
OO.addMember("klass",function (name, par, source) {
|
1308
1413
|
return "var "+name+"=exports['"+name+"']="+par+".extend("+source+");";
|
1309
1414
|
});
|
1415
|
+
|
1416
|
+
OO.addMember("createModule",function (name, source) {
|
1417
|
+
return "var "+name+"=exports['"+name+"']=JS2.Module.extend("+source+");";
|
1418
|
+
});
|
1310
1419
|
});
|
1311
1420
|
|
1312
1421
|
JS2.Class.extend('RingoDecorator', function(KLASS, OO){
|
@@ -1317,6 +1426,10 @@ JS2.Class.extend('RingoDecorator', function(KLASS, OO){
|
|
1317
1426
|
OO.addMember("klass",function (name, par, source) {
|
1318
1427
|
return "var "+name+"=exports['"+name+"']="+par+".extend("+source+");";
|
1319
1428
|
});
|
1429
|
+
|
1430
|
+
OO.addMember("createModule",function (name, source) {
|
1431
|
+
return "var "+name+"=exports['"+name+"']=JS2.Module.extend("+source+");";
|
1432
|
+
});
|
1320
1433
|
});
|
1321
1434
|
|
1322
1435
|
JS2.DECORATOR = JS2.DECORATOR || new JS2.BrowserDecorator();
|
metadata
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: js2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 5
|
9
|
+
version: 0.3.5
|
6
10
|
platform: ruby
|
7
11
|
authors:
|
8
12
|
- Jeff Su
|
@@ -10,7 +14,7 @@ autorequire:
|
|
10
14
|
bindir: bin
|
11
15
|
cert_chain: []
|
12
16
|
|
13
|
-
date: 2011-03-
|
17
|
+
date: 2011-03-14 00:00:00 -07:00
|
14
18
|
default_executable:
|
15
19
|
dependencies:
|
16
20
|
- !ruby/object:Gem::Dependency
|
@@ -21,6 +25,8 @@ dependencies:
|
|
21
25
|
requirements:
|
22
26
|
- - ">="
|
23
27
|
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
24
30
|
version: "0"
|
25
31
|
type: :runtime
|
26
32
|
version_requirements: *id001
|
@@ -36,11 +42,11 @@ extra_rdoc_files: []
|
|
36
42
|
files:
|
37
43
|
- bin/js2
|
38
44
|
- bin/js2-ruby
|
39
|
-
- lib/js2.rb
|
40
|
-
- lib/js2/context.rb
|
41
|
-
- lib/js2/rack.rb
|
42
45
|
- lib/js2/command.rb
|
46
|
+
- lib/js2/context.rb
|
43
47
|
- lib/js2/fs.rb
|
48
|
+
- lib/js2/rack.rb
|
49
|
+
- lib/js2.rb
|
44
50
|
- lib/js2/js2.js
|
45
51
|
- CHANGELOG
|
46
52
|
has_rdoc: true
|
@@ -57,17 +63,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
63
|
requirements:
|
58
64
|
- - ">="
|
59
65
|
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
60
68
|
version: "0"
|
61
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
70
|
none: false
|
63
71
|
requirements:
|
64
72
|
- - ">="
|
65
73
|
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
66
76
|
version: "0"
|
67
77
|
requirements: []
|
68
78
|
|
69
79
|
rubyforge_project:
|
70
|
-
rubygems_version: 1.
|
80
|
+
rubygems_version: 1.3.7
|
71
81
|
signing_key:
|
72
82
|
specification_version: 3
|
73
83
|
summary: Javascript Syntactic Sugar
|