js2 0.3.4 → 0.3.5
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/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
|