esprima 1.1.0 → 1.2.0

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.
@@ -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
+