js2 0.0.10 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/Manifest +42 -0
  2. data/README.md +65 -0
  3. data/Rakefile +19 -35
  4. data/bin/js2 +80 -66
  5. data/config/js2.yml +2 -0
  6. data/js2.gemspec +33 -0
  7. data/lib/js2/{haml_parser.rb → parser/haml.rb} +2 -2
  8. data/lib/js2/{haml_engine.rb → parser/haml_engine.rb} +1 -1
  9. data/lib/js2/parser/lexer.rb +37 -0
  10. data/lib/js2/{parser.rb → parser/tokenizer.rb} +157 -143
  11. data/lib/js2/{replace.rb → ragel/helper.rb} +16 -5
  12. data/lib/js2/ragel/tokenizer.rl +561 -0
  13. data/lib/js2/{tokenizer.rl.erb → ragel/tokenizer.rl.erb} +12 -19
  14. data/lib/js2/standard/factory.rb +289 -0
  15. data/lib/js2/standard/node.rb +75 -0
  16. data/lib/js2/util/compilation.rb +77 -0
  17. data/lib/js2/util/config.rb +84 -0
  18. data/lib/js2/util/exec.rb +34 -0
  19. data/lib/js2/util/file_handler.rb +73 -0
  20. data/lib/js2/{js2bootstrap.js2 → util/js2bootstrap.js2} +12 -68
  21. data/lib/js2/util/processor.rb +88 -0
  22. data/lib/js2/util/rdoc.rb +35 -0
  23. data/lib/js2/{sel_decorator.rb → util/sel_decorator.rb} +11 -1
  24. data/lib/js2.rb +22 -45
  25. data/test/compiled/bar.js +3 -0
  26. data/test/compiled/basic.comp.js +31 -0
  27. data/test/compiled/basic.js +27 -0
  28. data/test/compiled/foo.js +3 -0
  29. data/test/fixtures/bar.js2 +3 -0
  30. data/test/fixtures/basic.js2 +27 -0
  31. data/test/fixtures/basic.js2.haml +4 -0
  32. data/test/fixtures/basic.js2.yml +5 -0
  33. data/test/fixtures/curry.js2 +5 -0
  34. data/test/fixtures/foo.js2 +3 -0
  35. data/test/fixtures/member.js2 +14 -0
  36. data/test/fixtures/private.js2 +5 -0
  37. data/test/fixtures/property.js2 +4 -0
  38. data/test/test_helper.rb +25 -0
  39. data/test/test_js2.rb +43 -0
  40. data/wiki/features.md +106 -0
  41. data/wiki/installation.md +53 -0
  42. metadata +89 -83
  43. data/Changelog +0 -33
  44. data/History.txt +0 -4
  45. data/Manifest.txt +0 -35
  46. data/PostInstall.txt +0 -7
  47. data/README +0 -69
  48. data/README.rdoc +0 -69
  49. data/README.txt +0 -69
  50. data/examples/js2.yml +0 -8
  51. data/examples/test.yml +0 -5
  52. data/lib/javascript/sel_marker.js2 +0 -150
  53. data/lib/javascript/test.js2 +0 -73
  54. data/lib/js2/config.rb +0 -39
  55. data/lib/js2/daemon.rb +0 -35
  56. data/lib/js2/file_handler.rb +0 -91
  57. data/lib/js2/foo.js2.haml +0 -3
  58. data/lib/js2/js2.js +0 -110
  59. data/lib/js2/processor.rb +0 -112
  60. data/lib/js2/test/selenium.rb +0 -119
  61. data/lib/js2/test/selenium_element.rb +0 -234
  62. data/lib/js2/test/selenium_helper.rb +0 -27
  63. data/lib/js2/tree.rb +0 -351
  64. data/lib/js2/universe.rb +0 -123
  65. data/lib/tasks/js2.rake +0 -9
  66. data/website/index.txt +0 -86
  67. /data/{LICENSE → lib/js2/standard/class_node.rb} +0 -0
data/Manifest ADDED
@@ -0,0 +1,42 @@
1
+ Manifest
2
+ README.md
3
+ Rakefile
4
+ bin/js2
5
+ config/js2.yml
6
+ js2.gemspec
7
+ lib/js2.rb
8
+ lib/js2/parser/haml.rb
9
+ lib/js2/parser/haml_engine.rb
10
+ lib/js2/parser/lexer.rb
11
+ lib/js2/parser/tokenizer.rb
12
+ lib/js2/ragel/helper.rb
13
+ lib/js2/ragel/tokenizer.rl
14
+ lib/js2/ragel/tokenizer.rl.erb
15
+ lib/js2/standard/class_node.rb
16
+ lib/js2/standard/factory.rb
17
+ lib/js2/standard/node.rb
18
+ lib/js2/util/compilation.rb
19
+ lib/js2/util/config.rb
20
+ lib/js2/util/exec.rb
21
+ lib/js2/util/file_handler.rb
22
+ lib/js2/util/js2bootstrap.js2
23
+ lib/js2/util/processor.rb
24
+ lib/js2/util/rdoc.rb
25
+ lib/js2/util/sel_decorator.rb
26
+ test/compiled/bar.js
27
+ test/compiled/basic.comp.js
28
+ test/compiled/basic.js
29
+ test/compiled/foo.js
30
+ test/fixtures/bar.js2
31
+ test/fixtures/basic.js2
32
+ test/fixtures/basic.js2.haml
33
+ test/fixtures/basic.js2.yml
34
+ test/fixtures/curry.js2
35
+ test/fixtures/foo.js2
36
+ test/fixtures/member.js2
37
+ test/fixtures/private.js2
38
+ test/fixtures/property.js2
39
+ test/test_helper.rb
40
+ test/test_js2.rb
41
+ wiki/features.md
42
+ wiki/installation.md
data/README.md ADDED
@@ -0,0 +1,65 @@
1
+ * [Features](http://github.com/jeffsu/js2/blob/master/wiki/features.md) (simple documentation)
2
+ * [Installation](http://github.com/jeffsu/js2/blob/master/wiki/installation.md)
3
+ * [Source Code](http://github.com/jeffsu/js2)
4
+
5
+ ## OO Javascript
6
+
7
+ For every Javascript developer that has ever wanted to create a library for his/her project, there comes a time when an Object Oriented approach is necessary (or extremely desired). Fortunately, there are a plethora of options to choose from:
8
+
9
+ > using prototype (not the framework) and hashes:
10
+ > var MyClass = function () {
11
+ > this.member1 = "member";
12
+ > };
13
+ > MyClass.prototype = {
14
+ > method1: function () { alert('method1 called'); }
15
+ > }
16
+ > embedding functions right in the instantiator:
17
+ > function MyClass () {
18
+ > this.member1 = "member1";
19
+ > function method1 () {
20
+ > alert("method1 called");
21
+ > }
22
+ > }
23
+ > using jQuery (or any of the js OO frameworks) by passing in hashes:
24
+ > var MyClass = Class.create({
25
+ > member1: "member1",
26
+ > method1: function(){ alert("method1 called") },
27
+ > });
28
+ Unfortunately, these solutions are dissimilar to Java, Ruby, and C-based languages.
29
+
30
+ ## JS2 Solution
31
+
32
+ JS2 language that is a superset of Javascript and the problem it tries to solve is bringing "natural" OO syntax to Javascript by adding a compilation layer.
33
+
34
+ So in myClass.js2 one could write:
35
+
36
+ class MyClass {
37
+ var member1 = "member1";
38
+
39
+ function method1 () {
40
+ alert("method1 called");
41
+ }
42
+ }
43
+
44
+ And after compilation myClass.js (notice the .js extension vs the .js2) would be:
45
+
46
+ var MyClass = function () { };
47
+ MyClass.prototype = {
48
+ member1: "member1",
49
+ method1: function () { alert("method1 called"); }
50
+ }
51
+
52
+ One of the nice things about this solution is that it allows us to "calculate" things like mixins and inheritance at compile time rather than runtime. This compilation layer opens the doors for features such as:
53
+
54
+ * Inheritance
55
+ * Mixins (Ruby's multiple inheritance solution)
56
+ * getters and setters
57
+ * IoC (Dependency Injection)
58
+ * AOP (Aspect Oriented Programming)
59
+ * foreach
60
+ * currying
61
+ * More Features
62
+
63
+ ## Inspiration
64
+
65
+ HAML, SASS, Ruby, Perl, jQuery, Prototype.js
data/Rakefile CHANGED
@@ -1,41 +1,25 @@
1
1
  require 'rubygems'
2
- gem 'hoe', '>= 2.1.0'
3
- require 'hoe'
4
- require 'fileutils'
5
- require './lib/js2'
2
+ require 'rake'
3
+ require 'echoe'
6
4
 
7
- Hoe.plugin :newgem
8
- # Hoe.plugin :website
9
- # Hoe.plugin :cucumberfeatures
10
-
11
- # Generate all the Rake tasks
12
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
- $hoe = Hoe.spec 'js2' do
14
- self.developer 'Jeff Su', 'me@jeffsu.com'
15
- self.rubyforge_name = self.name
16
- self.extra_deps = [['haml','>= 2.2.6'], [ 'RubyInline', '>= 3.8.3']]
5
+ JS2_VERSION = '0.1.1'
6
+ Echoe.new('js2', JS2_VERSION) do |p|
7
+ p.description = ""
8
+ p.url = "http://github.com/jeffsu/js2"
9
+ p.author = "Jeff Su"
10
+ p.email = "me@jeffsu.com"
11
+ p.ignore_pattern = ["tmp/*", "script/*", "test/out" ]
12
+ p.development_dependencies = []
17
13
  end
18
14
 
19
- require 'newgem/tasks'
20
- Dir['tasks/**/*.rake'].each { |t| load t }
15
+ namespace :js2 do
16
+ task :compile do
17
+ system("pushd lib/js2/ragel/; ruby helper.rb; ragel -C tokenizer.rl; mv tokenizer.c ../parser/tokenizer.rb")
18
+ end
21
19
 
20
+ task :install do
21
+ Rake::Task['gem'].invoke
22
+ system("sudo gem install ./pkg/js2-#{JS2_VERSION}.gem")
23
+ end
24
+ end
22
25
 
23
- #task :default => [ :build_ragel, :test ] do
24
- #end
25
- #
26
- #task :build_ragel do
27
- # puts "build_ragel"
28
- # system("cd meta/; ruby replace.rb; cd ../; ragel -C meta/final_tokenizer.rl; mv meta/final_tokenizer.c lib/js2/parser/fast.rb")
29
- #end
30
- #
31
- #task :test do
32
- # puts "run test"
33
- # system("ruby test/test.rb")
34
- #end
35
- #
36
- #namespace :js2 => :envionment do
37
- # task :build do
38
- # p = JS2::Processor.processor_from_file(RAILS_ROOT + '/config/js2.yml', RAILS_ENV)
39
- # p.write_files
40
- # end
41
- #end
data/bin/js2 CHANGED
@@ -1,108 +1,122 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'optparse'
4
+ require 'ostruct'
4
5
 
5
6
  require 'rubygems'
6
7
  require 'js2'
7
8
 
8
- options = Hash.new
9
9
 
10
- dir = nil
10
+ options = OpenStruct.new
11
+ options.rails = false
12
+ options.sleep_time = 1
11
13
 
12
14
 
13
- usage = "Usage: js2 [options] <dir-with-js2>"
14
15
  op = OptionParser.new do |opts|
15
- opts.banner = usage
16
+ opts.banner = "Usage: js2 <daemon|compile|rdoc|help|config> [options]"
16
17
 
17
- opts.on("--js2-haml-dir DIR", "Directory with js2.haml files") do |haml|
18
- options[:js2_haml_dir] = haml
18
+ opts.on('-r', '--rails', "Rails (out_dir: ./public/javascript js2_dir: ./app/js2)") do |r|
19
+ options.rails = true
19
20
  end
20
21
 
21
- opts.on("--out-dir DIR", "Directory of js2 -> js output") do |out|
22
- options[:write_dir] = out
22
+ opts.on('-e', '--environment ENV', "Mostly for use with rails or a yml file with multiple configurations.") do |env|
23
+ options.env = env
23
24
  end
24
25
 
25
- opts.on("--vars VARS", "Example: var1=val1;var2=val2") do |out|
26
- vars = Hash.new
27
- out.split(/;/).each do |str|
28
- pair = str.split(/=/)
29
- vars[pair[0]] = pair[1]
30
- end
31
- options[:var] = vars
26
+ opts.on('-c', '--config FILE', "Use js2.yml config file (run: js2 config to generate a config file)") do |file|
27
+ options.yml = YAML.load_file(file)
32
28
  end
33
29
 
34
- opts.on("-d", "--daemonize") do |d|
35
- options[:daemonize] = true
30
+ opts.on('-i', '--include-rails', "Mostly for use with rails or a yml file with multiple configurations.") do |env|
31
+ options.include_rails = true
36
32
  end
37
33
 
38
- opts.on("-y YAML_FILE", "--yml YAML_FILE", "Use yml config") do |f|
39
- options[:yml] = f
34
+ opts.on('-s', '--sleep N', "Defines the wait time in between directory checks. This is only applicable to daemon mode.") do |t|
35
+ options.sleep_time = t.to_i
40
36
  end
41
37
 
42
- opts.on('-h', "--help", "Help Screen") do
43
- puts opts
44
- exit
38
+
39
+ opts.on('-j', '--js2-dir DIR', "Directory where js2 files reside. Defaults to current directory.") do |d|
40
+ options.js2_dir = d
41
+ end
42
+
43
+ opts.on('-o', '--out-dir DIR', "Output directory where javascript is written to. Defaults to current directory.") do |d|
44
+ options.out_dir = d
45
+ end
46
+
47
+ opts.on('-h', '--haml-dir DIR', "Direcotry where js2.haml files reside. Defaults to current directory.") do |d|
48
+ options.haml_dir = d
45
49
  end
46
50
  end
47
51
 
48
- # assume rails
49
- if ! options[:write_dir] && File.directory?('public') && File.directory?('app') && File.directory?('vendor') && File.directory?('config')
50
- puts "Detected Rails setup: using auto config"
52
+ main_action = ARGV.first
53
+ if [ 'daemon', 'compile', 'rdoc', 'help', 'config' ].include?(main_action)
51
54
 
52
- options[:js2_dir] = File.directory?('app/js2') ? './app/js2' : './js2'
55
+ else
56
+ main_action = nil
57
+ end
53
58
 
54
- options[:write_dir] ||= './public/javascripts'
59
+ if main_action == 'help' || ! main_action
60
+ puts op
61
+ exit
62
+ end
55
63
 
56
- options[:daemonize] = true
64
+ if ! main_action
65
+ main_action = 'daemon'
66
+ end
57
67
 
58
- options[:js2_haml_dir] = dir
68
+ op.parse!
69
+
70
+ if options.yml && options.env
71
+ options.yml = options.yml[options.env]
59
72
  end
60
73
 
74
+ if options.yml
75
+ options.yml.each_pair do |k,v|
76
+ options.send(k +'=', v) if options.send(k) == nil
77
+ end
78
+ end
61
79
 
62
- begin
63
- op.parse!(ARGV)
64
- rescue OptionParser::ParseError => e
65
- puts op
80
+ puts options.inspect
81
+ puts options.include_rails.inspect
82
+
83
+ if options.include_rails
84
+ puts "loading rails environment..."
85
+ ENV['RAILS_ENV'] = options.env if options.env
86
+ require './config/environment'
66
87
  end
67
88
 
68
- if !dir && File.directory?("./public/javascripts")
69
- dir = "./public/javascripts"
89
+ config = JS2::Util::Config.new
90
+
91
+ if options.rails
92
+ config.rails!
70
93
  end
71
94
 
72
- if options[:yml]
73
- d = JS2::Processor.daemon_from_yaml(options[:yml])
74
- d.run do
75
- puts "Recompiled: " + Time.now.to_s
76
- sleep 0.5
77
- end
95
+ config.out_dir = options.out_dir if options.out_dir
96
+ config.js2_dir = options.js2_dir if options.js2_dir
97
+ config.haml_dir = options.haml_dir if options.haml_dir
98
+ config.haml_engine = eval('::' + options.haml_engine_class + '.new') if options.haml_engine_class
78
99
 
100
+ puts config
101
+
102
+ if main_action == 'config'
103
+ puts "# run: js2 config > js2.yml to create a config file"
104
+ puts config.example_yml
79
105
  exit
80
106
  end
81
107
 
82
- options[:js2_dir] ||= '.'
83
- options[:js2_haml_dir] ||= '.'
84
- options[:write_dir] ||= '.'
85
- options[:vars] ||= {}
86
-
87
- puts "Using js2 dir: #{options[:dir]}"
88
- puts "Writing to: #{options[:write_dir]}"
89
- puts "HAML dir (optional): #{options[:js2_haml_dir]}"
90
-
91
- config = JS2::Config.new
92
-
93
- config.js2_dir = options[:js2_dir]
94
- config.js2_haml_dir = options[:js2_haml_dir]
95
- config.write_dir = options[:write_dir]
96
- config.vars = options[:vars]
97
-
98
- p = JS2::Processor.get(config)
99
- if options[:daemonize]
100
- puts "Daemonizing..."
101
- d = JS2::Daemon.new(p)
102
- d.run do
103
- puts "Recompiled at #{Time.now}"
104
- sleep 0.5
108
+ processor = JS2::Util::Processor.new(config)
109
+
110
+ if main_action == 'daemon'
111
+ puts "running in daemon mode..."
112
+ while 1
113
+ res = processor.process!
114
+ puts "Compiling #{Time.now}..." if res[:changed].any?
115
+ sleep options.sleep_time
105
116
  end
106
- else
107
- p.write_files
117
+ elsif main_action == 'compile'
118
+ puts "compiling once! use daemon to monitor changes and compile automatically."
119
+ elsif main_action == 'rdoc'
120
+ res = processor.process!
121
+ JS2::Util::Rdoc.build(res[:klasses])
108
122
  end
data/config/js2.yml ADDED
@@ -0,0 +1,2 @@
1
+ js2_dir: './test/fixtures'
2
+ out_dir: './test/out'
data/js2.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{js2}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jeff Su"]
9
+ s.date = %q{2010-04-19}
10
+ s.default_executable = %q{js2}
11
+ s.description = %q{}
12
+ s.email = %q{me@jeffsu.com}
13
+ s.executables = ["js2"]
14
+ s.extra_rdoc_files = ["README.md", "bin/js2", "lib/js2.rb", "lib/js2/parser/haml.rb", "lib/js2/parser/haml_engine.rb", "lib/js2/parser/lexer.rb", "lib/js2/parser/tokenizer.rb", "lib/js2/ragel/helper.rb", "lib/js2/ragel/tokenizer.rl", "lib/js2/ragel/tokenizer.rl.erb", "lib/js2/standard/class_node.rb", "lib/js2/standard/factory.rb", "lib/js2/standard/node.rb", "lib/js2/util/compilation.rb", "lib/js2/util/config.rb", "lib/js2/util/exec.rb", "lib/js2/util/file_handler.rb", "lib/js2/util/js2bootstrap.js2", "lib/js2/util/processor.rb", "lib/js2/util/rdoc.rb", "lib/js2/util/sel_decorator.rb"]
15
+ s.files = ["Manifest", "README.md", "Rakefile", "bin/js2", "config/js2.yml", "js2.gemspec", "lib/js2.rb", "lib/js2/parser/haml.rb", "lib/js2/parser/haml_engine.rb", "lib/js2/parser/lexer.rb", "lib/js2/parser/tokenizer.rb", "lib/js2/ragel/helper.rb", "lib/js2/ragel/tokenizer.rl", "lib/js2/ragel/tokenizer.rl.erb", "lib/js2/standard/class_node.rb", "lib/js2/standard/factory.rb", "lib/js2/standard/node.rb", "lib/js2/util/compilation.rb", "lib/js2/util/config.rb", "lib/js2/util/exec.rb", "lib/js2/util/file_handler.rb", "lib/js2/util/js2bootstrap.js2", "lib/js2/util/processor.rb", "lib/js2/util/rdoc.rb", "lib/js2/util/sel_decorator.rb", "test/compiled/bar.js", "test/compiled/basic.comp.js", "test/compiled/basic.js", "test/compiled/foo.js", "test/fixtures/bar.js2", "test/fixtures/basic.js2", "test/fixtures/basic.js2.haml", "test/fixtures/basic.js2.yml", "test/fixtures/curry.js2", "test/fixtures/foo.js2", "test/fixtures/member.js2", "test/fixtures/private.js2", "test/fixtures/property.js2", "test/test_helper.rb", "test/test_js2.rb", "wiki/features.md", "wiki/installation.md"]
16
+ s.homepage = %q{http://github.com/jeffsu/js2}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Js2", "--main", "README.md"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{js2}
20
+ s.rubygems_version = %q{1.3.6}
21
+ s.summary = %q{}
22
+ s.test_files = ["test/test_helper.rb", "test/test_js2.rb"]
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 3
27
+
28
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
+ else
30
+ end
31
+ else
32
+ end
33
+ end
@@ -4,11 +4,11 @@ begin
4
4
  require 'erb'
5
5
  require 'json'
6
6
 
7
- class JS2::HamlParser
7
+ class JS2::Parser::Haml
8
8
  attr_accessor :vars
9
9
 
10
10
  def initialize (haml_engine = nil, vars = nil)
11
- @haml_engine = haml_engine || JS2::HamlEngine.new
11
+ @haml_engine = haml_engine || JS2::Parser::HamlEngine.new
12
12
  @vars = vars || Hash.new
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ rescue Exception
8
8
  end
9
9
 
10
10
 
11
- class JS2::HamlEngine
11
+ class JS2::Parser::HamlEngine
12
12
  def hamlize (string)
13
13
  return Haml::Engine.new(string, { :ugly => true }).render(self).gsub(/\n/, '')
14
14
  end
@@ -0,0 +1,37 @@
1
+ class JS2::Parser::Lexer
2
+ def initialize
3
+ @tokenizer = JS2::Parser::Tokenizer.new
4
+ end
5
+
6
+ def start_node (type, idx, is_static = false)
7
+ child = @stack.last.add_child(type, idx)
8
+ @stack.push(child)
9
+ end
10
+
11
+ def stop_node (idx)
12
+ @last_idx = idx
13
+ last = @stack.pop()
14
+ last.stop(idx)
15
+ end
16
+
17
+ def parse (string, factory, file = nil)
18
+ @string = string
19
+ @page = factory.page_node(string, file)
20
+ @stack = [ @page ]
21
+ @last_idx = 0
22
+
23
+ @tokenizer.tokenize!(@string, self)
24
+
25
+ @page.children.each do |c|
26
+ c.stop(@last_idx) unless c.stop_idx
27
+ end
28
+
29
+ @page.stop(@last_idx)
30
+ end
31
+
32
+ def parse_file (file, factory)
33
+ parse(File.read(file), factory, file)
34
+ return @page
35
+ end
36
+ end
37
+