unparser 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96674256a364b20d34279b13821b1885615189db24c4ec229405b8305936fa4d
4
- data.tar.gz: 1c5484ef44c86310837ad8626635228e56bf3227e11e3d4190f0159cb52dfc58
3
+ metadata.gz: 52e96163f8fc7a9a3da3464e326997c9dc5a094225806e0f2fc72e0474a97026
4
+ data.tar.gz: 719ac295c33e15c44cbe9bff91920536367b37409e71fb407f1fecef2cd69dbf
5
5
  SHA512:
6
- metadata.gz: f5784148f66b8283b4b56a48f7b93c116b069a947ee3196012444bade8f02a67fb080cd52d6011068c8cdcf7ac82efe07bf1b3c2e7aa7215d66313369aa5e469
7
- data.tar.gz: ce7223635f503a065e8d4826d6967817d9165adf76c424105bfc690f9c1b5dfee6c87dbb320c4ccb72af9ebcb78eb4b3fa2319977d89f0eb892e940bfd6b5eb6
6
+ metadata.gz: 661ff992d06f1c3f1ff05e66ecd789c08fc91432af9e082a036309a6d74bec83e99b58026f1e85080c86f2b8ab8d01de08bb8e743225e5204690670c9d0f280e
7
+ data.tar.gz: 338124c08c6e241f70f587db3e149da9562dfd18550bae2e1f4d6afaa76f9e3b9d39dae37ca1d81e7ff97d50e246a2a56faa984edb4988c05e9e69d6880d12ba
@@ -1,17 +1,41 @@
1
1
  defaults: &defaults
2
2
  working_directory: ~/unparser
3
- steps:
4
- - checkout
5
- - run: bundle install
6
- - run: bundle exec rake ci
3
+ docker:
4
+ - image: circleci/ruby:2.5.3
7
5
  version: 2
8
6
  jobs:
9
- ruby_2_5:
7
+ unit_specs:
10
8
  <<: *defaults
11
- docker:
12
- - image: circleci/ruby:2.5.3
9
+ steps:
10
+ - checkout
11
+ - run: bundle install
12
+ - run: bundle exec rspec spec/unit
13
+ integration_specs:
14
+ <<: *defaults
15
+ steps:
16
+ - checkout
17
+ - run: bundle install
18
+ - run: bundle exec rspec spec/integration
19
+ metrics:
20
+ <<: *defaults
21
+ steps:
22
+ - checkout
23
+ - run: bundle install
24
+ - run: bundle exec rake metrics:rubocop
25
+ - run: bundle exec rake metrics:reek
26
+ - run: bundle exec rake metrics:flay
27
+ - run: bundle exec rake metrics:flog
28
+ mutant:
29
+ <<: *defaults
30
+ steps:
31
+ - checkout
32
+ - run: bundle install
33
+ - run: bundle exec rake metrics:mutant
13
34
  workflows:
14
35
  version: 2
15
36
  test:
16
37
  jobs:
17
- - ruby_2_5
38
+ - unit_specs
39
+ - integration_specs
40
+ - metrics
41
+ - mutant
@@ -1,3 +1,8 @@
1
+ # v0.4.0 2018-12-01
2
+
3
+ * Change to modern AST format.
4
+ * Add experimental `Unparser.{parser,parse,parse_with_comments}`
5
+
1
6
  # v0.3.0 2018-11-16
2
7
 
3
8
  * Drop support for Ruby < 2.5
data/Gemfile CHANGED
@@ -3,3 +3,5 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
+
7
+ gem 'mutant', git: 'https://github.com/mbj/mutant', branch: 'change/to-modern-ast'
@@ -1,7 +1,31 @@
1
+ GIT
2
+ remote: https://github.com/mbj/mutant
3
+ revision: 6b36372385ec1bedc0d170470e65d7d33740769e
4
+ branch: change/to-modern-ast
5
+ specs:
6
+ mutant (0.8.20)
7
+ abstract_type (~> 0.0.7)
8
+ adamantium (~> 0.2.0)
9
+ anima (~> 0.3.0)
10
+ ast (~> 2.2)
11
+ concord (~> 0.1.5)
12
+ diff-lcs (~> 1.3)
13
+ equalizer (~> 0.0.9)
14
+ ice_nine (~> 0.11.1)
15
+ memoizable (~> 0.4.2)
16
+ morpher (~> 0.2.6)
17
+ parser (~> 2.5.1)
18
+ procto (~> 0.0.2)
19
+ regexp_parser (~> 1.2)
20
+ unparser (~> 0.3.0)
21
+ mutant-rspec (0.8.20)
22
+ mutant (~> 0.8.20)
23
+ rspec-core (>= 3.4.0, < 4.0.0)
24
+
1
25
  PATH
2
26
  remote: .
3
27
  specs:
4
- unparser (0.2.9)
28
+ unparser (0.4.0)
5
29
  abstract_type (~> 0.0.7)
6
30
  adamantium (~> 0.2.0)
7
31
  concord (~> 0.1.5)
@@ -82,25 +106,6 @@ GEM
82
106
  equalizer (~> 0.0.9)
83
107
  ice_nine (~> 0.11.0)
84
108
  procto (~> 0.0.2)
85
- mutant (0.8.19)
86
- abstract_type (~> 0.0.7)
87
- adamantium (~> 0.2.0)
88
- anima (~> 0.3.0)
89
- ast (~> 2.2)
90
- concord (~> 0.1.5)
91
- diff-lcs (~> 1.3)
92
- equalizer (~> 0.0.9)
93
- ice_nine (~> 0.11.1)
94
- memoizable (~> 0.4.2)
95
- morpher (~> 0.2.6)
96
- parallel (~> 1.3)
97
- parser (~> 2.5.1)
98
- procto (~> 0.0.2)
99
- regexp_parser (~> 1.2)
100
- unparser (~> 0.2.5)
101
- mutant-rspec (0.8.19)
102
- mutant (~> 0.8.19)
103
- rspec-core (>= 3.4.0, < 4.0.0)
104
109
  parallel (1.12.1)
105
110
  parser (2.5.3.0)
106
111
  ast (~> 2.4.0)
@@ -166,6 +171,7 @@ DEPENDENCIES
166
171
  anima (~> 0.3.0)
167
172
  devtools (~> 0.1.21)
168
173
  morpher (~> 0.2.6)
174
+ mutant!
169
175
  unparser!
170
176
 
171
177
  BUNDLED WITH
data/README.md CHANGED
@@ -7,12 +7,12 @@ unparser
7
7
  [![Gem Version](https://img.shields.io/gem/v/unparser.svg)](https://rubygems.org/gems/unparser)
8
8
 
9
9
  Generate equivalent source for ASTs from whitequarks [parser](https://github.com/whitequark/parser).
10
- Excluding the macruby extensions the parser gem implemnents on top of ruby syntax.
11
10
 
12
- Excluding the MacRuby / RubyMotion extensions the parser gem implemenents on top of MRI Ruby
13
- syntax starting with parser release 2.3. If you feel the need to get them supported, contact me.
11
+ The following constraints apply:
14
12
 
15
- This library is able to reproduce 100% of Ruby 2.1 - 2.3 syntax. Including its own source code.
13
+ * No support for macruby extensions
14
+ * Only support for the [modern AST](https://github.com/whitequark/parser/#usage) format
15
+ * Only support for Ruby >= 2.5
16
16
 
17
17
  It serves well for [mutant](https://github.com/mbj/mutant) mutators and the in-memory vendoring for self hosting,
18
18
  and other tooling.
@@ -20,15 +20,19 @@ and other tooling.
20
20
  Public API:
21
21
  -----------
22
22
 
23
- While unparser is in the `0.x` versions its public API can change any moment. I recommend to use `~> 0.x.y` style
24
- version constraints that should give the best mileage.
23
+ While unparser is in the `0.x` versions its public API can change any moment.
24
+ I recommend to use `~> 0.x.y` style version constraints that should give the best mileage.
25
25
 
26
26
  Usage
27
27
  -----
28
28
 
29
29
  ```ruby
30
+ require 'parser/current'
30
31
  require 'unparser'
31
- Unparser.unparse(your_ast) # => "the code"
32
+
33
+ ast = Unpaser.parse('your(ruby(code))')
34
+
35
+ Unparser.unparse(ast) # => 'your(ruby(code))'
32
36
  ```
33
37
 
34
38
  To preserve the comments from the source:
@@ -36,8 +40,10 @@ To preserve the comments from the source:
36
40
  ```ruby
37
41
  require 'parser/current'
38
42
  require 'unparser'
39
- ast, comments = Parser::CurrentRuby.parse_with_comments(your_source)
40
- Unparser.unparse(ast, comments) # => "the code # with comments"
43
+
44
+ ast, comments = Unpaser.parse_with_comments('your(ruby(code)) # with comments')
45
+
46
+ Unparser.unparse(ast, comments) # => 'your(ruby(code)) # with comments'
41
47
  ```
42
48
 
43
49
  Passing in manually constructed AST:
@@ -71,22 +77,19 @@ Unparser.unparse(node) # => "def foo(x)\n x + 3\nend"
71
77
  Note: DO NOT attempt to pass in nodes generated via `AST::Sexp#s`, these ones return
72
78
  API incompatible `AST::Node` instances, unparser needs `Parser::AST::Node` instances.
73
79
 
74
-
75
80
  Equivalent vs identical:
76
81
 
77
82
  ```ruby
78
83
  require 'unparser'
79
84
 
80
- code = <<-RUBY
81
- %w(foo bar)
85
+ node = Unparser.parse(<<~'RUBY')
86
+ %w[foo bar]
82
87
  RUBY
83
88
 
84
- node = Parser::CurrentRuby.parse(code)
85
-
86
- generated = Unparser.unparse(node) # ["foo", "bar"], NOT %w(foo bar) !
89
+ generated = Unparser.unparse(node) # ["foo", "bar"], NOT %w[foo bar] !
87
90
 
88
91
  code == generated # false, not identical code
89
- Parser::CurrentRuby.parse(generated) == node # true, but identical AST
92
+ Unparser.parse(generated) == node # true, but identical AST
90
93
  ```
91
94
 
92
95
  Summary: unparser does not reproduce your source! It produces equivalent source.
@@ -94,7 +97,7 @@ Summary: unparser does not reproduce your source! It produces equivalent source.
94
97
  Testing:
95
98
  --------
96
99
 
97
- Unparser currently successfully round trips almost all ruby code around. Using MRI-2.0.0.
100
+ Unparser currently successfully round trips almost all ruby code around. Using MRI-2.5.x.
98
101
  If there is a non round trippable example that is NOT subjected to known [Limitations](#limitations).
99
102
  please report a bug.
100
103
 
@@ -106,10 +109,7 @@ Limitations:
106
109
  Source parsed with magic encoding headers other than UTF-8 and that have literal strings.
107
110
  where parts can be represented in UTF-8 will fail to get reproduced.
108
111
 
109
- Please note: If you are on 1.9.3 or any 1.9 mode ruby and use UTF-8 encoded source via the magic encoding header:
110
- Unparser does not reproduce these.
111
-
112
- A fix might be possible and requires some guessing or parser metadata the raw AST does not carry.
112
+ A fix is possible as with latest updates the parser gem carries the information.
113
113
 
114
114
  Example:
115
115
 
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 13
3
- total_score: 632
3
+ total_score: 640
@@ -11,8 +11,7 @@ detectors:
11
11
  exclude: []
12
12
  ControlParameter:
13
13
  enabled: true
14
- exclude:
15
- - Mutant::Expression#match_length
14
+ exclude: []
16
15
  DataClump:
17
16
  enabled: true
18
17
  exclude: []
@@ -31,9 +30,7 @@ detectors:
31
30
  exclude: []
32
31
  LongParameterList:
33
32
  enabled: true
34
- exclude:
35
- - Mutant::Matcher::Method::Instance#self.build
36
- - Mutant::Meta::Example::DSL # 3 vars
33
+ exclude: []
37
34
  max_params: 2
38
35
  LongYieldList:
39
36
  enabled: true
@@ -41,55 +38,30 @@ detectors:
41
38
  max_params: 2
42
39
  NestedIterators:
43
40
  enabled: true
44
- exclude:
45
- - Mutant#self.singleton_subclass_instance
46
- - Mutant::CLI#parse
47
- - Mutant::Mutator::Node::Arguments#emit_argument_mutations
48
- - Mutant::Mutator::Node::Resbody#mutate_captures
49
- - Mutant::Mutator::Util::Array::Element#dispatch
50
- - Mutant::Parallel::Master#run
51
- - Mutant::RequireHighjack#self.call
52
- - Mutant::Selector::Expression#call
53
- - Parser::Lexer#self.new
41
+ exclude: []
54
42
  max_allowed_nesting: 1
55
43
  ignore_iterators: []
56
44
  NilCheck:
57
45
  enabled: false
58
46
  RepeatedConditional:
59
47
  enabled: true
60
- exclude:
61
- - Mutant::Mutator
62
- - Mutant::Meta::Example::DSL
48
+ exclude: []
63
49
  max_ifs: 1
64
50
  TooManyInstanceVariables:
65
51
  enabled: true
66
- exclude:
67
- - Mutant::Mutator # 4 vars
68
- - Mutant::Parallel::Master # 4 vars
69
- - Mutant::Meta::Example::DSL # 4 vars
52
+ exclude: []
70
53
  max_instance_variables: 3
71
54
  TooManyMethods:
72
55
  enabled: true
73
- exclude:
74
- - Mutant::CLI
75
- - Mutant::Mutator::Node
76
- - Mutant::Parallel::Master
56
+ exclude: []
77
57
  max_methods: 10
78
58
  TooManyStatements:
79
59
  enabled: true
80
- exclude:
81
- - Mutant::CLI#add_debug_options
82
- - Mutant::CLI#add_environment_options
83
- - Mutant::Reporter::CLI::Printer::Config#run
84
- - Mutant::Reporter::CLI::Printer::EnvProgress#run
85
- - Mutant::Runner#run_driver
86
- - Mutant::Zombifier::File#self.find
60
+ exclude: []
87
61
  max_statements: 7
88
62
  UncommunicativeMethodName:
89
63
  enabled: true
90
- exclude:
91
- - Mutant::AST::Sexp#s
92
- - Mutant::Mutation#sha1
64
+ exclude: []
93
65
  reject:
94
66
  - '/^[a-z]$/'
95
67
  - '/[0-9]$/'
@@ -123,15 +95,4 @@ detectors:
123
95
  exclude: []
124
96
  UtilityFunction:
125
97
  enabled: true
126
- exclude:
127
- - Mutant::AST::Sexp#s
128
- - Mutant::Actor::Env#new_mailbox
129
- - Mutant::CLI#reporter
130
- - Mutant::Integration::Null#call
131
- - Mutant::Integration::Rspec#parse_example
132
- - Mutant::Integration::Rspec#parse_expression # intentional, private
133
- - Mutant::Meta::Example::Verification#format_mutations # intentional, private
134
- - Mutant::Reporter::CLI::Format::Progressive#new_buffer
135
- - Mutant::Reporter::CLI::Printer::StatusProgressive#object # False positive calls super
136
- - Mutant::Repository::Diff#tracks? # intentional, private
137
- - Mutant::Repository::Diff#within_working_directory? # intentional, private
98
+ exclude: []
@@ -8,10 +8,15 @@ require 'parser/current'
8
8
 
9
9
  # Library namespace
10
10
  module Unparser
11
+ # Unparser specific AST builder defaulting to modern AST format
12
+ class Builder < Parser::Builders::Default
13
+ modernize
14
+ end
11
15
 
12
16
  EMPTY_STRING = ''.freeze
17
+ EMPTY_ARRAY = [].freeze
13
18
 
14
- EMPTY_ARRAY = [].freeze
19
+ private_constant(*constants(false))
15
20
 
16
21
  # Unparse an AST (and, optionally, comments) into a string
17
22
  #
@@ -31,6 +36,60 @@ module Unparser
31
36
  buffer.content
32
37
  end
33
38
 
39
+ # Parse string into AST
40
+ #
41
+ # @param [String] source
42
+ #
43
+ # @return [Parser::AST::Node]
44
+ def self.parse(source)
45
+ parser.parse(buffer(source))
46
+ end
47
+
48
+ # Parse string into AST, with comments
49
+ #
50
+ # @param [String] source
51
+ #
52
+ # @return [Parser::AST::Node]
53
+ def self.parse_with_comments(source)
54
+ parser.parse_with_comments(buffer(source))
55
+ end
56
+
57
+ # Parser instance that produces AST unparser understands
58
+ #
59
+ # @return [Parser::Base]
60
+ #
61
+ # @api private
62
+ #
63
+ # ignore :reek:NestedIterators
64
+ def self.parser
65
+ Parser::CurrentRuby.new(Builder.new).tap do |parser|
66
+ parser.diagnostics.tap do |diagnostics|
67
+ diagnostics.all_errors_are_fatal = true
68
+ diagnostics.consumer = method(:consume_diagnostic)
69
+ end
70
+ end
71
+ end
72
+
73
+ # Consume diagnostic
74
+ #
75
+ # @param [Parser::Diagnostic] diagnostic
76
+ #
77
+ # @return [undefined]
78
+ def self.consume_diagnostic(diagnostic)
79
+ Kernel.warn(diagnostic.render)
80
+ end
81
+ private_class_method :consume_diagnostic
82
+
83
+ # Construct a parser buffer from string
84
+ #
85
+ # @param [String] source
86
+ #
87
+ # @return [Parser::Source::Buffer]
88
+ def self.buffer(source)
89
+ Parser::Source::Buffer.new('(string)').tap do |buffer|
90
+ buffer.source = source
91
+ end
92
+ end
34
93
  end # Unparser
35
94
 
36
95
  require 'unparser/buffer'
@@ -56,7 +115,6 @@ require 'unparser/emitter/meta'
56
115
  require 'unparser/emitter/send'
57
116
  require 'unparser/emitter/send/unary'
58
117
  require 'unparser/emitter/send/binary'
59
- require 'unparser/emitter/send/index'
60
118
  require 'unparser/emitter/send/regular'
61
119
  require 'unparser/emitter/send/conditional'
62
120
  require 'unparser/emitter/send/arguments'
@@ -93,5 +151,7 @@ require 'unparser/emitter/flipflop'
93
151
  require 'unparser/emitter/rescue'
94
152
  require 'unparser/emitter/resbody'
95
153
  require 'unparser/emitter/ensure'
154
+ require 'unparser/emitter/index'
155
+ require 'unparser/emitter/lambda'
96
156
  # make it easy for zombie
97
157
  require 'unparser/finalize'
@@ -16,7 +16,7 @@ module Unparser
16
16
  #
17
17
  # FIXME: Kwargs are missing.
18
18
  #
19
- ASSIGN_NODES = %i[lvasgn arg optarg restarg].freeze
19
+ ASSIGN_NODES = %i[arg lvasgn optarg procarg0 restarg].freeze
20
20
 
21
21
  # Test for local variable inherited scope reset
22
22
  #