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.
- data/History.txt +4 -0
- data/esprima.gemspec +1 -0
- data/lib/esprima.rb +11 -0
- data/lib/esprima/ast.rb +60 -0
- data/lib/esprima/parser.rb +5 -7
- data/lib/esprima/version.rb +1 -1
- data/spec/ast_spec.rb +78 -0
- data/spec/esprima_spec.rb +8 -1
- data/spec/parser_spec.rb +5 -2
- data/spec/spec_helper.rb +2 -0
- metadata +70 -80
data/History.txt
CHANGED
data/esprima.gemspec
CHANGED
@@ -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'
|
data/lib/esprima.rb
CHANGED
@@ -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
|
data/lib/esprima/ast.rb
ADDED
@@ -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
|
data/lib/esprima/parser.rb
CHANGED
@@ -3,13 +3,11 @@
|
|
3
3
|
module Esprima
|
4
4
|
class Parser
|
5
5
|
def initialize
|
6
|
-
@
|
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
|
-
|
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
|
24
|
+
def to_ruby_hash(obj)
|
27
25
|
if obj.is_a?(V8::Array)
|
28
|
-
obj.map { |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] =
|
28
|
+
obj.inject({}) { |ret, (key, val)| ret[key.to_sym] = to_ruby_hash(val); ret }
|
31
29
|
else
|
32
30
|
obj
|
33
31
|
end
|
data/lib/esprima/version.rb
CHANGED
data/spec/ast_spec.rb
ADDED
@@ -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
|
data/spec/esprima_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
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
|
data/spec/parser_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require
|
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")
|
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
|
data/spec/spec_helper.rb
CHANGED
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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
32
28
|
name: commonjs
|
33
|
-
|
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
|
-
|
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.
|
47
|
-
|
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
|
-
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
58
53
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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:
|
129
|
-
|
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:
|
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.
|
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
|
+
|