unparser 0.2.8 → 0.3.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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +17 -0
  3. data/.rubocop.yml +1 -0
  4. data/Changelog.md +4 -0
  5. data/Gemfile +2 -0
  6. data/Gemfile.lock +70 -64
  7. data/Rakefile +1 -0
  8. data/bin/unparser +2 -0
  9. data/config/devtools.yml +1 -1
  10. data/config/flay.yml +1 -1
  11. data/config/reek.yml +136 -136
  12. data/config/rubocop.yml +14 -1
  13. data/lib/unparser.rb +2 -0
  14. data/lib/unparser/ast.rb +8 -6
  15. data/lib/unparser/ast/local_variable_scope.rb +3 -1
  16. data/lib/unparser/buffer.rb +5 -1
  17. data/lib/unparser/cli.rb +8 -1
  18. data/lib/unparser/cli/color.rb +2 -0
  19. data/lib/unparser/cli/differ.rb +2 -0
  20. data/lib/unparser/cli/source.rb +7 -1
  21. data/lib/unparser/comments.rb +5 -0
  22. data/lib/unparser/constants.rb +8 -6
  23. data/lib/unparser/dsl.rb +2 -0
  24. data/lib/unparser/emitter.rb +18 -9
  25. data/lib/unparser/emitter/alias.rb +2 -0
  26. data/lib/unparser/emitter/argument.rb +3 -0
  27. data/lib/unparser/emitter/assignment.rb +5 -2
  28. data/lib/unparser/emitter/begin.rb +3 -1
  29. data/lib/unparser/emitter/binary.rb +2 -0
  30. data/lib/unparser/emitter/block.rb +3 -0
  31. data/lib/unparser/emitter/case.rb +4 -0
  32. data/lib/unparser/emitter/cbase.rb +2 -0
  33. data/lib/unparser/emitter/class.rb +3 -0
  34. data/lib/unparser/emitter/def.rb +3 -0
  35. data/lib/unparser/emitter/defined.rb +2 -0
  36. data/lib/unparser/emitter/empty.rb +2 -0
  37. data/lib/unparser/emitter/ensure.rb +2 -0
  38. data/lib/unparser/emitter/flipflop.rb +2 -0
  39. data/lib/unparser/emitter/flow_modifier.rb +3 -1
  40. data/lib/unparser/emitter/for.rb +2 -0
  41. data/lib/unparser/emitter/hookexe.rb +2 -0
  42. data/lib/unparser/emitter/if.rb +5 -0
  43. data/lib/unparser/emitter/literal.rb +2 -0
  44. data/lib/unparser/emitter/literal/array.rb +5 -4
  45. data/lib/unparser/emitter/literal/dynamic.rb +2 -0
  46. data/lib/unparser/emitter/literal/dynamic_body.rb +2 -0
  47. data/lib/unparser/emitter/literal/execute_string.rb +2 -0
  48. data/lib/unparser/emitter/literal/hash.rb +3 -2
  49. data/lib/unparser/emitter/literal/primitive.rb +3 -1
  50. data/lib/unparser/emitter/literal/range.rb +2 -0
  51. data/lib/unparser/emitter/literal/regexp.rb +2 -0
  52. data/lib/unparser/emitter/literal/singleton.rb +2 -0
  53. data/lib/unparser/emitter/match.rb +2 -0
  54. data/lib/unparser/emitter/meta.rb +2 -0
  55. data/lib/unparser/emitter/module.rb +2 -0
  56. data/lib/unparser/emitter/op_assign.rb +2 -0
  57. data/lib/unparser/emitter/redo.rb +2 -0
  58. data/lib/unparser/emitter/repetition.rb +4 -1
  59. data/lib/unparser/emitter/resbody.rb +4 -24
  60. data/lib/unparser/emitter/rescue.rb +5 -2
  61. data/lib/unparser/emitter/retry.rb +2 -0
  62. data/lib/unparser/emitter/root.rb +2 -0
  63. data/lib/unparser/emitter/send.rb +3 -0
  64. data/lib/unparser/emitter/send/arguments.rb +2 -0
  65. data/lib/unparser/emitter/send/attribute_assignment.rb +2 -0
  66. data/lib/unparser/emitter/send/binary.rb +2 -0
  67. data/lib/unparser/emitter/send/conditional.rb +2 -0
  68. data/lib/unparser/emitter/send/index.rb +2 -0
  69. data/lib/unparser/emitter/send/regular.rb +3 -0
  70. data/lib/unparser/emitter/send/unary.rb +5 -3
  71. data/lib/unparser/emitter/splat.rb +2 -0
  72. data/lib/unparser/emitter/super.rb +2 -0
  73. data/lib/unparser/emitter/undef.rb +2 -0
  74. data/lib/unparser/emitter/variable.rb +3 -0
  75. data/lib/unparser/emitter/yield.rb +3 -0
  76. data/lib/unparser/finalize.rb +2 -0
  77. data/lib/unparser/node_helpers.rb +6 -0
  78. data/lib/unparser/preprocessor.rb +3 -0
  79. data/spec/integrations.yml +3 -1
  80. data/spec/unit/unparser_spec.rb +3 -7
  81. data/unparser.gemspec +3 -3
  82. metadata +6 -6
  83. data/circle.yml +0 -6
@@ -2,10 +2,11 @@ inherit_from: ../.rubocop.yml
2
2
 
3
3
  AllCops:
4
4
  Include:
5
+ - 'lib/unparser.rb'
6
+ - 'lib/unparser/**/*.rb'
5
7
  - '**/*.rake'
6
8
  - 'Gemfile'
7
9
  - 'Gemfile.triage'
8
- TargetRubyVersion: 2.1
9
10
 
10
11
  # Avoid parameter lists longer than five parameters.
11
12
  ParameterLists:
@@ -103,3 +104,15 @@ EmptyLinesAroundModuleBody:
103
104
  # I like my style more
104
105
  AccessModifierIndentation:
105
106
  Enabled: false
107
+
108
+ Style/CommentedKeyword:
109
+ Enabled: false
110
+
111
+ Style/MixinGrouping:
112
+ Enabled: false
113
+
114
+ Lint/BooleanSymbol:
115
+ Enabled: false
116
+
117
+ Style/AccessModifierDeclarations:
118
+ Enabled: false
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
  require 'abstract_type'
3
5
  require 'procto'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  # Namespace for AST processing tools
3
5
  # :reek:TooManyConstants
@@ -6,7 +8,7 @@ module Unparser
6
8
  FIRST_CHILD = ->(node) { node.children.first }.freeze
7
9
  TAUTOLOGY = ->(_node) { true }.freeze
8
10
 
9
- RESET_NODES = [:module, :class, :sclass, :def, :defs].freeze
11
+ RESET_NODES = %i[module class sclass def defs].freeze
10
12
  INHERIT_NODES = [:block].freeze
11
13
  CLOSE_NODES = (RESET_NODES + INHERIT_NODES).freeze
12
14
 
@@ -14,7 +16,7 @@ module Unparser
14
16
  #
15
17
  # FIXME: Kwargs are missing.
16
18
  #
17
- ASSIGN_NODES = [:lvasgn, :arg, :optarg, :restarg].freeze
19
+ ASSIGN_NODES = %i[lvasgn arg optarg restarg].freeze
18
20
 
19
21
  # Test for local variable inherited scope reset
20
22
  #
@@ -98,7 +100,6 @@ module Unparser
98
100
  # @api private
99
101
  #
100
102
  def each(&block)
101
- return to_enum unless block_given?
102
103
  Walker.call(node, controller, &block)
103
104
  end
104
105
 
@@ -176,18 +177,19 @@ module Unparser
176
177
  #
177
178
  # @param [Parser::AST::Node] node
178
179
  #
179
- # @return [self]
180
+ # @return [undefined]
180
181
  #
181
182
  # @api private
182
183
  #
183
184
  def call(node)
184
185
  return unless controller.call(node)
186
+
185
187
  block.call(node)
186
188
  node.children.each do |child|
187
- next unless child.is_a?(Parser::AST::Node)
189
+ break unless child.instance_of?(Parser::AST::Node)
190
+
188
191
  call(child)
189
192
  end
190
- self
191
193
  end
192
194
 
193
195
  end # Walker
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  module AST
3
5
 
@@ -130,7 +132,6 @@ module Unparser
130
132
  # @api private
131
133
  #
132
134
  def each(node, &block)
133
- return to_enum(__method__, node) unless block_given?
134
135
  visit(node, &block)
135
136
  end
136
137
 
@@ -154,6 +155,7 @@ module Unparser
154
155
  #
155
156
  # @api private
156
157
  #
158
+ # ignore :reek:LongYieldList
157
159
  def visit(node, &block)
158
160
  before = current.dup
159
161
  enter(node)
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
 
3
5
  # Buffer used to emit into
6
+ #
7
+ # ignore :reek:TooManyMethods
4
8
  class Buffer
5
9
 
6
10
  NL = "\n".freeze
@@ -12,7 +16,7 @@ module Unparser
12
16
  # @api private
13
17
  #
14
18
  def initialize
15
- @content = ''
19
+ @content = +''
16
20
  @indent = 0
17
21
  end
18
22
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'unparser'
2
4
  require 'optparse'
3
5
  require 'diff/lcs'
@@ -11,6 +13,7 @@ module Unparser
11
13
  # Unparser CLI implementation
12
14
  #
13
15
  # :reek:InstanceVariableAssumption
16
+ # :reek:TooManyInstanceVariables
14
17
  class CLI
15
18
 
16
19
  EXIT_SUCCESS = 0
@@ -37,6 +40,7 @@ module Unparser
37
40
  #
38
41
  # @api private
39
42
  #
43
+ # ignore :reek:TooManyStatements
40
44
  def initialize(arguments)
41
45
  @sources = []
42
46
  @ignore = Set.new
@@ -56,12 +60,13 @@ module Unparser
56
60
 
57
61
  # Add options
58
62
  #
59
- # @param [Optparse::Builder] builder
63
+ # @param [OptionParser] builder
60
64
  #
61
65
  # @return [undefined]
62
66
  #
63
67
  # @api private
64
68
  #
69
+ # ignore :reek:TooManyStatements
65
70
  def add_options(builder)
66
71
  builder.banner = 'usage: unparse [options] FILE [FILE]'
67
72
  builder.separator('')
@@ -91,6 +96,7 @@ module Unparser
91
96
  def exit_status
92
97
  effective_sources.each do |source|
93
98
  next if @ignore.include?(source)
99
+
94
100
  process_source(source)
95
101
  break if @fail_fast && !@success
96
102
  end
@@ -148,6 +154,7 @@ module Unparser
148
154
  #
149
155
  # @api private
150
156
  #
157
+ # ignore :reek:UtilityFunction
151
158
  def sources(file_name)
152
159
  files =
153
160
  if File.directory?(file_name)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  # Class to colorize strings
3
5
  class Color
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  class CLI
3
5
  # Class to create diffs from source code
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  class CLI
3
5
  # Source representation for CLI sources
6
+ #
7
+ # ignore :reek:TooManyMethods
4
8
  class Source
5
9
  include AbstractType, Adamantium::Flat, NodeHelpers
6
10
 
@@ -27,7 +31,7 @@ module Unparser
27
31
  def self.build(ast)
28
32
  source = Unparser.unparse(ast)
29
33
  new(source, ast, nil)
30
- rescue => exception
34
+ rescue StandardError => exception
31
35
  new(nil, ast, exception)
32
36
  end
33
37
  end
@@ -84,6 +88,7 @@ module Unparser
84
88
  #
85
89
  # @api private
86
90
  #
91
+ # ignore :reek:UtilityFunction
87
92
  def strip(source)
88
93
  source = source.rstrip
89
94
  indent = source.scan(/^\s*/).first
@@ -204,6 +209,7 @@ module Unparser
204
209
  #
205
210
  # @api private
206
211
  #
212
+ # ignore :reek:UtilityFunction
207
213
  def parse(source)
208
214
  Parser::CurrentRuby.parse(source)
209
215
  end
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
 
3
5
  # Holds the comments that remain to be emitted
6
+ #
7
+ # ignore :reek:RepeatedConditional
4
8
  class Comments
5
9
 
6
10
  # Proxy to singleton
@@ -52,6 +56,7 @@ module Unparser
52
56
  #
53
57
  def take_eol_comments
54
58
  return EMPTY_ARRAY unless @last_range_consumed
59
+
55
60
  comments = take_up_to_line(@last_range_consumed.end.line)
56
61
  unshift_documents(comments)
57
62
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  # All unparser constants maybe included in other libraries.
3
5
  #
4
- # rubocop:disable MutableConstant
5
6
  # False positive since constants are frozen dynamically
6
7
  # to avoid duplication of `.freeze` calls
7
8
  #
@@ -22,16 +23,16 @@ module Unparser
22
23
  private_class_method :symbol_set
23
24
 
24
25
  # All unary operators of the ruby language
25
- UNARY_OPERATORS = symbol_set %w(
26
+ UNARY_OPERATORS = symbol_set %w[
26
27
  ! ~ -@ +@
27
- )
28
+ ]
28
29
 
29
30
  # All binary operators of the ruby language
30
- BINARY_OPERATORS = symbol_set %w(
31
+ BINARY_OPERATORS = symbol_set %w[
31
32
  + - * / & | && || << >> ==
32
33
  === != <= < <=> > >= =~ !~ ^
33
34
  ** %
34
- )
35
+ ]
35
36
 
36
37
  COMMENT = '#'
37
38
 
@@ -104,11 +105,12 @@ module Unparser
104
105
 
105
106
  DEFAULT_DELIMITER = ', '.freeze
106
107
 
107
- CURLY_BRACKETS = IceNine.deep_freeze(%w({ }))
108
+ CURLY_BRACKETS = IceNine.deep_freeze(%w[{ }])
108
109
 
109
110
  KEYWORDS = constants.each_with_object([]) do |name, keywords|
110
111
  value = const_get(name).freeze
111
112
  next unless name.to_s.start_with?('K_')
113
+
112
114
  keywords << value.to_sym
113
115
  end.to_set.freeze
114
116
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  # DSL to help defining emitters
3
5
  module DSL
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
 
3
5
  # Emitter base class
4
6
  #
5
7
  # buggy, argument values are sends to self
6
- # rubocop:disable CircularArgumentReference
8
+ #
9
+ # ignore :reek:TooManyMethods
7
10
  class Emitter
8
11
  include Adamantium::Flat, AbstractType, Constants, NodeHelpers
9
12
  include Concord.new(:node, :parent)
@@ -12,11 +15,11 @@ module Unparser
12
15
  # Registry for node emitters
13
16
  REGISTRY = {} # rubocop:disable MutableConstant
14
17
 
15
- NOINDENT = [:rescue, :ensure].to_set.freeze
18
+ NOINDENT = %i[rescue ensure].to_set.freeze
16
19
 
17
20
  DEFAULT_DELIMITER = ', '.freeze
18
21
 
19
- CURLY_BRACKETS = IceNine.deep_freeze(%w({ }))
22
+ CURLY_BRACKETS = IceNine.deep_freeze(%w[{ }])
20
23
 
21
24
  module Unterminated
22
25
  def terminated?
@@ -236,6 +239,7 @@ module Unparser
236
239
  #
237
240
  # @api private
238
241
  #
242
+ # ignore :reek:ControlParameter
239
243
  def conditional_parentheses(flag)
240
244
  if flag
241
245
  parentheses { yield }
@@ -265,8 +269,8 @@ module Unparser
265
269
  #
266
270
  # @api private
267
271
  #
268
- def delimited_plain(nodes, delimiter = DEFAULT_DELIMITER)
269
- delimited(nodes, delimiter, &method(:visit_plain))
272
+ def delimited_plain(nodes)
273
+ delimited(nodes, &method(:visit_plain))
270
274
  end
271
275
 
272
276
  # Emit delimited body
@@ -278,13 +282,14 @@ module Unparser
278
282
  #
279
283
  # @api private
280
284
  #
281
- def delimited(nodes, delimiter = DEFAULT_DELIMITER, &block)
285
+ def delimited(nodes, &block)
282
286
  return if nodes.empty?
287
+
283
288
  block ||= method(:visit)
284
289
  head, *tail = nodes
285
290
  block.call(head)
286
291
  tail.each do |node|
287
- write(delimiter)
292
+ write(DEFAULT_DELIMITER)
288
293
  block.call(node)
289
294
  end
290
295
  end
@@ -321,6 +326,7 @@ module Unparser
321
326
  def emit_comments_before(source_part = :expression)
322
327
  comments_before = comments.take_before(node, source_part)
323
328
  return if comments_before.empty?
329
+
324
330
  emit_comments(comments_before)
325
331
  buffer.nl
326
332
  end
@@ -347,6 +353,7 @@ module Unparser
347
353
  emit_eol_comments
348
354
  comments_left = comments.take_all
349
355
  return if comments_left.empty?
356
+
350
357
  buffer.nl
351
358
  emit_comments(comments_left)
352
359
  end
@@ -428,8 +435,6 @@ module Unparser
428
435
  #
429
436
  # False positive:
430
437
  #
431
- # rubocop:disable MethodCallWithoutArgsParentheses
432
- #
433
438
  def indented
434
439
  buffer = buffer()
435
440
  buffer.indent
@@ -447,6 +452,7 @@ module Unparser
447
452
  #
448
453
  # @api private
449
454
  #
455
+ # rubocop:disable MethodCallWithoutArgsParentheses
450
456
  def emit_body(body = body())
451
457
  unless body
452
458
  buffer.indent
@@ -456,6 +462,7 @@ module Unparser
456
462
  end
457
463
  visit_indented(body)
458
464
  end
465
+ # rubocop:enable MethodCallWithoutArgsParentheses
459
466
 
460
467
  # Visit indented node
461
468
  #
@@ -495,9 +502,11 @@ module Unparser
495
502
  #
496
503
  # @api private
497
504
  #
505
+ # rubocop:disable MethodCallWithoutArgsParentheses
498
506
  def run(emitter, node = node())
499
507
  emitter.new(node, self).write_to_buffer
500
508
  end
509
+ # rubocop:enable MethodCallWithoutArgsParentheses
501
510
 
502
511
  end # Emitter
503
512
  end # Unparser
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  class Emitter
3
5
  # Emitter for alias nodes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  class Emitter
3
5
 
@@ -40,6 +42,7 @@ module Unparser
40
42
  def dispatch
41
43
  delimited(normal_arguments)
42
44
  return if shadowargs.empty?
45
+
43
46
  write('; ')
44
47
  delimited(shadowargs)
45
48
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Unparser
2
4
  class Emitter
3
5
 
@@ -41,6 +43,7 @@ module Unparser
41
43
  def emit_right
42
44
  right = right_node
43
45
  return unless right
46
+
44
47
  write(WS, T_ASN, WS)
45
48
  visit(right)
46
49
  end
@@ -144,8 +147,8 @@ module Unparser
144
147
 
145
148
  private
146
149
 
147
- NO_COMMA = [:splat, :restarg].to_set.freeze
148
- PARENT_MLHS = [:mlhs, :masgn].freeze
150
+ NO_COMMA = %i[splat restarg].to_set.freeze
151
+ PARENT_MLHS = %i[mlhs masgn].freeze
149
152
 
150
153
  # Perform dispatch
151
154
  #