dead_code_terminator 0.2.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0594405128f563ed209b13acac45f6d1dcfebb56c36f51bee071cab04e208ecf'
4
- data.tar.gz: 3c16615d8ed48a12d1284908a35e580d90c008eb85ec4e7c3aa94a133fe0e775
3
+ metadata.gz: 30f177ea46b025d82a1647deb392a82ea79bf7d188180b01db1d3b7c9914772f
4
+ data.tar.gz: a1e654d7c848fea862cf3c3fdbf07e42096457e4994beb76f7b8c0fe6b83580a
5
5
  SHA512:
6
- metadata.gz: 215e88c2977706899fb2d312b483cd46e8d9311f1cb411f62d9cce8a3d64fce29891ebdaf02497fb9e200efc805830af06104840a9e9da0bdc825f3a2085933b
7
- data.tar.gz: aeb91248beb05727ae810e98833a70c19df8e6b34f6641a40d477a3f71773943453cdcf8aa706387002ba04db471acdb33c15afcf234b3a93f6aadac4d845c19
6
+ metadata.gz: 01d433228fbd4f63be908d7b0841d42514442f6fdf4d5c1ba54c241b4746284a430594d19061eb2a4926c0e7639cdc5694cdf12b16a498f41bb131ce2ff0bdc4
7
+ data.tar.gz: 4405404ec2c1e561177c7a3780d8b8511fbae3a1545d02231bc5b261845d4eb1925e081f1a1f439d482314785868ee9b2b7dacd8a472e9e9b698f855d13f26b5
data/.rubocop.yml CHANGED
@@ -26,3 +26,7 @@ Lint/BooleanSymbol:
26
26
  Metrics/BlockLength:
27
27
  Exclude:
28
28
  - spec/**/*rb
29
+
30
+ Naming/VariableNumber:
31
+ Exclude:
32
+ - spec/**/*rb
data/README.md CHANGED
@@ -27,8 +27,6 @@ So if you have hotfix patches from upstream - they'll be applied without conflic
27
27
 
28
28
  ## TODO
29
29
 
30
- - `unless`
31
- - `x ? a : b`
32
30
  - builtin file tree processing
33
31
  ## License
34
32
 
@@ -14,6 +14,24 @@ module DeadCodeTerminator
14
14
  class Error < StandardError; end
15
15
 
16
16
  def self.strip(io, env: {})
17
- Ast.new(env: env, ast: Unparser.parse(io)).process
17
+ replaces = on_node(Unparser.parse(io)) do |ast|
18
+ Ast.new(env: env, ast: ast).process if ast.type == :if
19
+ end
20
+
21
+ rewrite(Parser::Source::Buffer.new("buffer-or-filename", source: io), replaces)
22
+ end
23
+
24
+ def self.rewrite(buffer, replaces)
25
+ Parser::Source::TreeRewriter.new(buffer).tap do |rewriter|
26
+ replaces.each do |replace|
27
+ rewriter.replace(*replace)
28
+ end
29
+ end.process
30
+ end
31
+
32
+ def self.on_node(node, &block)
33
+ Array(yield(node)) + node.children.flat_map do |elem|
34
+ on_node(elem, &block) if elem.is_a?(Parser::AST::Node)
35
+ end.compact
18
36
  end
19
37
  end
@@ -2,35 +2,46 @@
2
2
 
3
3
  module DeadCodeTerminator
4
4
  class Ast
5
- attr_reader :env, :ast
5
+ attr_reader :env, :ast, :buf, :cond, :then_branch, :else_branch
6
6
 
7
7
  def initialize(env:, ast:)
8
8
  @env = env
9
9
  @ast = ast
10
+ @buf = @ast.loc.expression.source_buffer
11
+ @cond, @then_branch, @else_branch = @ast.children
12
+
13
+ # handle single brackets around: `if (ENV['X'])`
14
+ @cond = @cond.children[0] if (@cond.type == :begin) && (@cond.children.size == 1)
10
15
  end
11
16
 
12
17
  def process
13
- erase_before!
14
- erase_after!
15
- rewriter.process
18
+ static_if_branch ? [erase_before_args, erase_after_args] : []
16
19
  end
17
20
 
18
21
  private
19
22
 
20
- def erase_before!
21
- rewriter.replace(range(end_pos, (total_end - end_pos)), "\n" * (total_lines - to_line))
23
+ def erase_before_args
24
+ [range(total_begin, begin_pos_before_spaces), "\n" * (from_line - total_first_line)]
25
+ end
26
+
27
+ def erase_after_args
28
+ [range(end_pos, total_end), "\n" * (total_lines - to_line)]
22
29
  end
23
30
 
24
- def erase_after!
25
- rewriter.replace(range(0, begin_pos), "\n" * (from_line - 1))
31
+ def begin_pos_before_spaces
32
+ begin_pos - count_spaces_before_first_line_of_static_if_branch
26
33
  end
27
34
 
28
35
  def begin_pos
29
- new_ast.loc.expression.begin_pos
36
+ static_if_branch.loc.expression.begin_pos
30
37
  end
31
38
 
32
39
  def end_pos
33
- new_ast.loc.expression.end_pos
40
+ static_if_branch.loc.expression.end_pos
41
+ end
42
+
43
+ def total_begin
44
+ ast.loc.expression.begin_pos
34
45
  end
35
46
 
36
47
  def total_end
@@ -38,47 +49,47 @@ module DeadCodeTerminator
38
49
  end
39
50
 
40
51
  def from_line
41
- new_ast.loc.expression.source_buffer.line_for_position(begin_pos)
52
+ @from_line ||= line_for_position_of_static_if_branch(begin_pos)
42
53
  end
43
54
 
44
55
  def to_line
45
- new_ast.loc.expression.source_buffer.line_for_position(end_pos)
56
+ line_for_position_of_static_if_branch(end_pos)
46
57
  end
47
58
 
48
59
  def total_lines
49
60
  ast.loc.last_line
50
61
  end
51
62
 
52
- def rewriter
53
- @rewriter ||= Parser::Source::TreeRewriter.new(buf)
63
+ def total_first_line
64
+ ast.loc.first_line
54
65
  end
55
66
 
56
- def range(from, len)
57
- Parser::Source::Range.new(buf, from, from + len)
67
+ def range(from, to)
68
+ Parser::Source::Range.new(buf, from, to)
58
69
  end
59
70
 
60
- def buf
61
- @buf ||= ast.loc.expression.source_buffer
71
+ # :(
72
+ def count_spaces_before_first_line_of_static_if_branch
73
+ (begin_pos - 1).downto(0).take_while do |pos|
74
+ line_for_position_of_static_if_branch(pos) == from_line
75
+ end.size
62
76
  end
63
77
 
64
- def new_ast
65
- @new_ast ||= case ast.type
66
- when :if then if_ast
67
- else ast
68
- end
78
+ def line_for_position_of_static_if_branch(pos)
79
+ static_if_branch.loc.expression.source_buffer.line_for_position(pos)
69
80
  end
70
81
 
71
- def if_ast
72
- cond, then_branch, else_branch = ast.children
82
+ def static_if_branch
83
+ return @static_if_branch if defined? @static_if_branch
73
84
 
74
85
  Cond.nodes.each do |klass|
75
86
  if (value = klass.new(env: env, ast: cond).value)
76
- return then_branch if value == Cond::Base::THEN
77
- return else_branch if value == Cond::Base::ELSE
87
+ return (@static_if_branch = then_branch) if value == Cond::Base::THEN
88
+ return (@static_if_branch = else_branch) if value == Cond::Base::ELSE
78
89
  end
79
90
  end
80
91
 
81
- ast
92
+ @static_if_branch = nil
82
93
  end
83
94
  end
84
95
  end
@@ -3,6 +3,8 @@
3
3
  module DeadCodeTerminator
4
4
  module Cond
5
5
  class Base
6
+ include ::AST::Sexp
7
+
6
8
  THEN = :then
7
9
  ELSE = :else
8
10
 
@@ -14,12 +16,6 @@ module DeadCodeTerminator
14
16
  end
15
17
 
16
18
  def value; end
17
-
18
- private
19
-
20
- def s(type, *children)
21
- Parser::AST::Node.new(type, children)
22
- end
23
19
  end
24
20
  end
25
21
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeadCodeTerminator
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dead_code_terminator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vlad Bokov