unparser 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
  #