esprima 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ === 1.2.0
2
+
3
+ * Added intermediate AST class that offers a few convenience methods like `each`.
4
+
1
5
  === 1.1.0
2
6
 
3
7
  * Fix the require path for the parser.
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.add_dependency 'therubyracer', '~> 0.9.10'
17
17
  s.add_dependency 'commonjs', '~> 0.2.6'
18
+ s.add_dependency 'escodegen', '~> 1.0.0'
18
19
 
19
20
  s.add_development_dependency 'rake'
20
21
  s.add_development_dependency 'rspec', '~> 2.11.0'
@@ -2,11 +2,22 @@
2
2
 
3
3
  require 'v8'
4
4
  require 'commonjs'
5
+ require 'escodegen'
5
6
 
6
7
  require 'esprima/parser'
8
+ require 'esprima/ast'
9
+
10
+ # hack for inconsistency between Ruby 1.8 and 1.9
11
+ Enumerator = Enumerable::Enumerator unless defined?(Enumerator)
7
12
 
8
13
  module Esprima
9
14
  def self.load_path
10
15
  @load_path ||= File.expand_path(File.join(File.dirname(__FILE__), "../vendor"))
11
16
  end
17
+
18
+ def self.new_environment
19
+ context = V8::Context.new
20
+ env = CommonJS::Environment.new(context, :path => Esprima.load_path)
21
+ env.require("esprima")
22
+ end
12
23
  end
@@ -0,0 +1,60 @@
1
+ # encoding: UTF-8
2
+
3
+ module Esprima
4
+ class AST
5
+ include Enumerable
6
+
7
+ attr_reader :tree, :esprima
8
+
9
+ def initialize(tree, environment = nil)
10
+ @esprima = @environment || Esprima.new_environment
11
+ @tree = tree
12
+ end
13
+
14
+ def to_ecma(options = {})
15
+ Escodegen::Generator.new.generate(@tree, options)
16
+ end
17
+
18
+ def is_list?
19
+ @tree.is_a?(Array)
20
+ end
21
+
22
+ def is_hash?
23
+ @tree.is_a?(Hash)
24
+ end
25
+
26
+ def [](key)
27
+ @tree[key]
28
+ end
29
+
30
+ def each
31
+ if block_given?
32
+ each_node { |node| yield Esprima::AST.new(node, @esprima) }
33
+ else
34
+ nodes = []
35
+ each_node { |node| nodes << Esprima::AST.new(node, @esprima) }
36
+ nodes.to_enum
37
+ end
38
+ end
39
+
40
+ protected
41
+
42
+ def each_node
43
+ if tree.is_a?(Array)
44
+ tree.each do |t|
45
+ yield t if yieldable?(t)
46
+ Esprima::AST.new(t, @esprima).each_node { |sub_t| yield sub_t if yieldable?(sub_t) }
47
+ end
48
+ elsif tree.is_a?(Hash)
49
+ tree.each_pair do |_, t|
50
+ yield t if yieldable?(t)
51
+ Esprima::AST.new(t, @esprima).each_node { |sub_t| yield sub_t if yieldable?(sub_t) }
52
+ end
53
+ end
54
+ end
55
+
56
+ def yieldable?(obj)
57
+ obj.is_a?(Hash) || obj.is_a?(Array)
58
+ end
59
+ end
60
+ end
@@ -3,13 +3,11 @@
3
3
  module Esprima
4
4
  class Parser
5
5
  def initialize
6
- @context = V8::Context.new
7
- @env = CommonJS::Environment.new(@context, :path => Esprima.load_path)
8
- @esprima = @env.require("esprima")
6
+ @esprima = Esprima.new_environment
9
7
  end
10
8
 
11
9
  def parse(code)
12
- to_ruby(@esprima.parse(code))
10
+ Esprima::AST.new(to_ruby_hash(@esprima.parse(code)), @esprima)
13
11
  end
14
12
 
15
13
  def parse_file(file)
@@ -23,11 +21,11 @@ module Esprima
23
21
  File.read(file)
24
22
  end
25
23
 
26
- def to_ruby(obj)
24
+ def to_ruby_hash(obj)
27
25
  if obj.is_a?(V8::Array)
28
- obj.map { |val| to_ruby(val) }
26
+ obj.map { |val| to_ruby_hash(val) }
29
27
  elsif obj.is_a?(V8::Object)
30
- obj.inject({}) { |ret, (key, val)| ret[key.to_sym] = to_ruby(val); ret }
28
+ obj.inject({}) { |ret, (key, val)| ret[key.to_sym] = to_ruby_hash(val); ret }
31
29
  else
32
30
  obj
33
31
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Esprima
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
@@ -0,0 +1,78 @@
1
+ # encoding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ AST = [{
6
+ :type => "ExpressionStatement",
7
+ :expression => {
8
+ :left => {
9
+ :type => "Literal",
10
+ :value => 7
11
+ },
12
+ :type => "BinaryExpression",
13
+ :right => {
14
+ :type => "Literal",
15
+ :value => 8
16
+ },
17
+ :operator => "+"
18
+ }
19
+ }]
20
+
21
+ describe Esprima::AST do
22
+ describe "#yieldable?" do
23
+ it "esprima parser should only yield arrays and hashes" do
24
+ ast = Esprima::AST.new({})
25
+ ast.send(:'yieldable?', {}).should be_true
26
+ ast.send(:'yieldable?', []).should be_true
27
+ ast.send(:'yieldable?', "").should be_false
28
+ end
29
+ end
30
+
31
+ context "with an ast" do
32
+ before(:each) do
33
+ @ast = Esprima::Parser.new.parse("7 + 8;")
34
+ end
35
+
36
+ describe "#each" do
37
+ it "yields if a block is given" do
38
+ @ast.each { |a| a.should be_a(Esprima::AST) }
39
+ end
40
+
41
+ it "returns an array of parse nodes" do
42
+ result = @ast.each.map(&:tree)
43
+ result.size.should == 5
44
+ result.should include(AST)
45
+ result.should include(AST.first)
46
+ result.should include(AST.first[:expression])
47
+ result.should include(AST.first[:expression][:left])
48
+ result.should include(AST.first[:expression][:right])
49
+ end
50
+ end
51
+
52
+ describe "#[]" do
53
+ it "allows access to the internal tree with [] syntax" do
54
+ @ast[:body][0][:type].should == "ExpressionStatement"
55
+ end
56
+ end
57
+
58
+ describe "#is_hash?" do
59
+ it "should return true if the underlying tree is a hash, false otherwise" do
60
+ @ast.is_hash?.should be_true
61
+ Esprima::AST.new(@ast.tree[:body], @ast.esprima).is_hash?.should be_false
62
+ end
63
+ end
64
+
65
+ describe "#is_list?" do
66
+ it "should return true if the underlying tree is an array, false otherwise" do
67
+ @ast.is_list?.should be_false
68
+ Esprima::AST.new(@ast.tree[:body], @ast.esprima).is_list?.should be_true
69
+ end
70
+ end
71
+
72
+ describe "#to_ecma" do
73
+ it "should build JavaScript code from the AST" do
74
+ @ast.to_ecma.should == "7 + 8;"
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.join(File.dirname(__FILE__), "spec_helper")
3
+ require "spec_helper"
4
4
 
5
5
  describe Esprima do
6
6
  describe "#load_path" do
@@ -8,4 +8,11 @@ describe Esprima do
8
8
  File.should exist(File.join(Esprima.load_path, "esprima.js"))
9
9
  end
10
10
  end
11
+
12
+ describe "#new_environment" do
13
+ it "creates a new environment that can be used to parse javascript code" do
14
+ env = Esprima.new_environment
15
+ env.parse("1 + 1").should_not be_nil
16
+ end
17
+ end
11
18
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.join(File.dirname(__FILE__), "spec_helper")
3
+ require "spec_helper"
4
4
 
5
5
  EXPRESSION = "7 + 8"
6
6
  AST_RESULT = [{
@@ -23,6 +23,7 @@ describe Esprima::Parser do
23
23
  describe "#parse" do
24
24
  it "should parse a basic js expression" do
25
25
  result = Esprima::Parser.new.parse(EXPRESSION)
26
+ result.should be_a(Esprima::AST)
26
27
  result[:body].should == AST_RESULT
27
28
  end
28
29
  end
@@ -31,7 +32,9 @@ describe Esprima::Parser do
31
32
  it "should parse a basic js file" do
32
33
  parser = Esprima::Parser.new
33
34
  mock(parser).read_file("my_file.js") { EXPRESSION }
34
- parser.parse_file("my_file.js")[:body].should == AST_RESULT
35
+ result = parser.parse_file("my_file.js")
36
+ result.should be_a(Esprima::AST)
37
+ result[:body].should == AST_RESULT
35
38
  end
36
39
  end
37
40
  end
@@ -1,5 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ $:.push(File.dirname(__FILE__))
4
+
3
5
  require 'rspec'
4
6
  require 'esprima'
5
7
 
metadata CHANGED
@@ -1,108 +1,100 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: esprima
3
- version: !ruby/object:Gem::Version
4
- version: 1.1.0
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 1.2.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Cameron Dutro
9
9
  - Ariya Hidayat
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-09-17 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
13
+
14
+ date: 2012-11-15 00:00:00 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
16
17
  name: therubyracer
17
- requirement: !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ~>
21
- - !ruby/object:Gem::Version
22
- version: 0.9.10
23
- type: :runtime
24
18
  prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
19
+ requirement: &id001 !ruby/object:Gem::Requirement
26
20
  none: false
27
- requirements:
21
+ requirements:
28
22
  - - ~>
29
- - !ruby/object:Gem::Version
23
+ - !ruby/object:Gem::Version
30
24
  version: 0.9.10
31
- - !ruby/object:Gem::Dependency
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
32
28
  name: commonjs
33
- requirement: !ruby/object:Gem::Requirement
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
34
31
  none: false
35
- requirements:
32
+ requirements:
36
33
  - - ~>
37
- - !ruby/object:Gem::Version
34
+ - !ruby/object:Gem::Version
38
35
  version: 0.2.6
39
36
  type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: escodegen
40
40
  prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
42
  none: false
43
- requirements:
43
+ requirements:
44
44
  - - ~>
45
- - !ruby/object:Gem::Version
46
- version: 0.2.6
47
- - !ruby/object:Gem::Dependency
45
+ - !ruby/object:Gem::Version
46
+ version: 1.0.0
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
48
50
  name: rake
49
- requirement: !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
56
51
  prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
52
+ requirement: &id004 !ruby/object:Gem::Requirement
58
53
  none: false
59
- requirements:
60
- - - ! '>='
61
- - !ruby/object:Gem::Version
62
- version: '0'
63
- - !ruby/object:Gem::Dependency
64
- name: rspec
65
- requirement: !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
- - - ~>
69
- - !ruby/object:Gem::Version
70
- version: 2.11.0
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
71
58
  type: :development
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: rspec
72
62
  prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
63
+ requirement: &id005 !ruby/object:Gem::Requirement
74
64
  none: false
75
- requirements:
65
+ requirements:
76
66
  - - ~>
77
- - !ruby/object:Gem::Version
67
+ - !ruby/object:Gem::Version
78
68
  version: 2.11.0
79
- - !ruby/object:Gem::Dependency
80
- name: rr
81
- requirement: !ruby/object:Gem::Requirement
82
- none: false
83
- requirements:
84
- - - ~>
85
- - !ruby/object:Gem::Version
86
- version: 1.0.4
87
69
  type: :development
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: rr
88
73
  prerelease: false
89
- version_requirements: !ruby/object:Gem::Requirement
74
+ requirement: &id006 !ruby/object:Gem::Requirement
90
75
  none: false
91
- requirements:
76
+ requirements:
92
77
  - - ~>
93
- - !ruby/object:Gem::Version
78
+ - !ruby/object:Gem::Version
94
79
  version: 1.0.4
80
+ type: :development
81
+ version_requirements: *id006
95
82
  description: Ruby wrapper around the Esprima static code analyzer for JavaScript.
96
- email:
83
+ email:
97
84
  - cdutro@twitter.com
98
85
  - ariya.hidayat@gmail.com
99
86
  executables: []
87
+
100
88
  extensions: []
89
+
101
90
  extra_rdoc_files: []
102
- files:
91
+
92
+ files:
93
+ - lib/esprima/ast.rb
103
94
  - lib/esprima/parser.rb
104
95
  - lib/esprima/version.rb
105
96
  - lib/esprima.rb
97
+ - spec/ast_spec.rb
106
98
  - spec/esprima_spec.rb
107
99
  - spec/parser_spec.rb
108
100
  - spec/spec_helper.rb
@@ -116,32 +108,30 @@ files:
116
108
  - esprima.gemspec
117
109
  homepage: http://esprima.org
118
110
  licenses: []
111
+
119
112
  post_install_message:
120
113
  rdoc_options: []
121
- require_paths:
114
+
115
+ require_paths:
122
116
  - lib
123
- required_ruby_version: !ruby/object:Gem::Requirement
117
+ required_ruby_version: !ruby/object:Gem::Requirement
124
118
  none: false
125
- requirements:
126
- - - ! '>='
127
- - !ruby/object:Gem::Version
128
- version: '0'
129
- segments:
130
- - 0
131
- hash: -4557661203188248061
132
- required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: "0"
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
124
  none: false
134
- requirements:
135
- - - ! '>='
136
- - !ruby/object:Gem::Version
137
- version: '0'
138
- segments:
139
- - 0
140
- hash: -4557661203188248061
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: "0"
141
129
  requirements: []
130
+
142
131
  rubyforge_project:
143
- rubygems_version: 1.8.24
132
+ rubygems_version: 1.8.17
144
133
  signing_key:
145
134
  specification_version: 3
146
135
  summary: Ruby wrapper around the Esprima static code analyzer for JavaScript.
147
136
  test_files: []
137
+