prettyrb 0.4.0 → 0.5.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: cfaf933924416b3773afaed63ee03ca8c2ddaa9a3e36147c3db453f24245e375
4
- data.tar.gz: b5fcfe41b9738e7bd628501b1aff497e7083cb7f6e061fa7e5821719c7c86bcf
3
+ metadata.gz: f3ca66d3c436cf92ecaeef327cd56e32380eb956c844cafcc605e471f80e5a9d
4
+ data.tar.gz: 6a88f83ea9a52c7cebcb0c70d72a8f599c8480e0a628c2eba016ce506ef99996
5
5
  SHA512:
6
- metadata.gz: de542dd1e0f5999aa4aec410a8329e387944e1ce370805c2c4aaa805f5020034287fb7db8e0bfe4d3c2627b722c6b0d3a3cfa0024dbc4255fba9e3161cea0a9f
7
- data.tar.gz: 953349398a0107c7012336a3a69dd0ae5c700cde330fced7db07cd96876178cfe87457273fc4440b48caabd2f050b26f79b26e0ec8f2c40af279fe2c3246ab4a
6
+ metadata.gz: 3fb301879d8c8905aa82268ac2d04944fc02eb4a3e9d28466b80a70dd3e3b2e1ad93dba3a4916736e5c5533c067eb69b869a610f12ee6746d61ec5165e43d128
7
+ data.tar.gz: 3a2894fd21b9493aec14b1d85a08e3be929e356ad7dd2dee013409f2ec3dcd47f914ab15d6028146e769533812abb786bbce415d449edcaefd679093c06d5af5
@@ -1 +1 @@
1
- 2.7.0
1
+ 2.6.0
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prettyrb (0.3.1)
4
+ prettyrb (0.5.0)
5
5
  parser (~> 2.7.0.5)
6
6
  thor
7
7
 
@@ -1,17 +1,29 @@
1
+ require "forwardable"
2
+
1
3
  require "parser/current"
2
4
  require "prettyrb/version"
3
5
 
4
6
  require "prettyrb/nodes/base_node"
5
7
  require "prettyrb/nodes/if_node"
6
8
  require "prettyrb/nodes/string_helper"
9
+ require "prettyrb/nodes/logical_operator_helper"
7
10
  require "prettyrb/nodes/str_node"
8
11
  require "prettyrb/nodes/dstr_node"
12
+ require "prettyrb/nodes/def_node"
13
+ require "prettyrb/nodes/and_node"
14
+ require "prettyrb/nodes/or_node"
15
+ require "prettyrb/nodes/regexp_node"
16
+ require "prettyrb/nodes/send_node"
17
+
18
+ require "prettyrb/document"
9
19
  require "prettyrb/builder"
10
20
  require "prettyrb/formatter"
11
21
  require "prettyrb/visitor"
22
+ require "prettyrb/writer"
12
23
 
13
24
  require "prettyrb/cli"
14
25
 
15
26
  module Prettyrb
27
+ MAX_LINE_LENGTH = 100
16
28
  class Error < StandardError; end
17
29
  end
@@ -1,9 +1,14 @@
1
1
  module Prettyrb
2
2
  class Builder < Parser::Builders::Default
3
3
  NODE_TYPES = {
4
+ and: Prettyrb::Nodes::AndNode,
5
+ dstr: Prettyrb::Nodes::DstrNode,
4
6
  if: Prettyrb::Nodes::IfNode,
7
+ or: Prettyrb::Nodes::OrNode,
8
+ regexp: Prettyrb::Nodes::RegexpNode,
9
+ send: Prettyrb::Nodes::SendNode,
5
10
  str: Prettyrb::Nodes::StrNode,
6
- dstr: Prettyrb::Nodes::DstrNode,
11
+ def: Prettyrb::Nodes::DefNode,
7
12
  }.freeze
8
13
 
9
14
  def n(type, children, source_map)
@@ -3,18 +3,27 @@ require "thor"
3
3
  module Prettyrb
4
4
  class CLI < Thor
5
5
  desc "format [FILE]", "Ruby file to prettify"
6
- option :write, type: :boolean
7
- method_option :files, type: :array
8
- def format(*files)
6
+ def format(file)
9
7
  content = File.read(file)
10
8
  formatted_content = Prettyrb::Formatter.new(content).format
11
9
 
12
- if options[:write]
10
+ puts formatted_content
11
+ end
12
+
13
+ desc "write [FILES]", "Write prettified Ruby files"
14
+ def write(*files)
15
+ files.each do |file|
16
+ content = File.read(file)
17
+ begin
18
+ formatted_content = Prettyrb::Formatter.new(content).format
19
+ rescue Exception => e
20
+ puts "Failed to write #{file}"
21
+ throw e
22
+ end
23
+
13
24
  File.open(file, 'w') do |f|
14
25
  f.write(formatted_content)
15
26
  end
16
- else
17
- puts formatted_content
18
27
  end
19
28
  end
20
29
  end
@@ -0,0 +1,164 @@
1
+ module Prettyrb
2
+ module Document
3
+ module DSL
4
+ def concat(*args)
5
+ Document::Concat.new(*args)
6
+ end
7
+
8
+ def join(*args)
9
+ Document::Join.new(*args)
10
+ end
11
+
12
+ def group(*args)
13
+ Document::Group.new(*args)
14
+ end
15
+
16
+ def if_break(*args)
17
+ Document::IfBreak.new(*args)
18
+ end
19
+
20
+ def indent(*args)
21
+ Document::Indent.new(*args)
22
+ end
23
+
24
+ def dedent(*args)
25
+ Document::Dedent.new(*args)
26
+ end
27
+
28
+ def hardline(*args)
29
+ Document::Hardline.new(*args)
30
+ end
31
+
32
+ def softline(*args)
33
+ Document::Softline.new(*args)
34
+ end
35
+ end
36
+
37
+ class Builder
38
+ attr_reader :parts
39
+
40
+ include Enumerable
41
+
42
+ def initialize(*args)
43
+ @parts = args
44
+ end
45
+
46
+ def each
47
+ @parts.each
48
+ end
49
+
50
+ def inspect
51
+ inspect_children(self, indent_level: 0)
52
+ end
53
+
54
+ def has_group_part?
55
+ parts.any? { |p| p.is_a?(Group) }
56
+ end
57
+
58
+ def groups
59
+ parts.select { |p| p.is_a?(Group) } + parts.flat_map do |p|
60
+ p.groups if p.respond_to?(:groups)
61
+ end.compact
62
+ end
63
+
64
+ def max_group_depth
65
+ return 0 if !parts
66
+ return @max_group_depth if defined?(@max_group_depth)
67
+
68
+ has_groups = parts.any? { |p| p.is_a?(Group) }
69
+
70
+ total = if has_groups
71
+ 1
72
+ else
73
+ 0
74
+ end
75
+
76
+ # TODO swap filter/flat_map for single iteration
77
+ nested_total = parts.
78
+ filter { |p| p.respond_to?(:max_group_depth) }.
79
+ flat_map { |p| p.max_group_depth }.
80
+ max
81
+
82
+ @max_group_depth = total + (nested_total || 0)
83
+ end
84
+
85
+ private
86
+
87
+ def inspect_children(builder, indent_level:)
88
+ if builder.respond_to?(:parts)
89
+ children = if builder.parts
90
+ builder.parts.map do |p|
91
+ inspect_children(p, indent_level: indent_level + 1)
92
+ end.join("\n")
93
+ end
94
+
95
+ " " * indent_level + "(#{builder.class}\n#{" "*indent_level}#{children}\n #{" " * indent_level})"
96
+ else
97
+ " " * indent_level + builder.inspect
98
+ end
99
+ end
100
+ end
101
+
102
+ class Concat < Builder
103
+ end
104
+
105
+ class Group < Builder
106
+ attr_reader :joiner
107
+
108
+ def initialize(*args, joiner: "")
109
+ super(*args)
110
+ @joiner = joiner
111
+ end
112
+ end
113
+
114
+ class Join < Builder
115
+ attr_reader :separator
116
+
117
+ def initialize(separator: ",", parts:)
118
+ if parts.is_a?(Array)
119
+ super(*parts)
120
+ else
121
+ super(parts)
122
+ end
123
+ @separator = separator
124
+ end
125
+ end
126
+
127
+ class IfBreak
128
+ attr_reader :without_break, :with_break
129
+ def initialize(without_break:, with_break: )
130
+ @without_break = without_break
131
+ @with_break = with_break
132
+ end
133
+ end
134
+
135
+ class Indent < Builder
136
+ attr_reader :only_when_break
137
+
138
+ def initialize(*args, only_when_break: false)
139
+ @only_when_break = only_when_break
140
+ super(*args)
141
+ end
142
+ end
143
+
144
+ class Dedent < Builder
145
+ end
146
+
147
+ class Hardline < Builder
148
+ attr_reader :count, :skip_indent
149
+ def initialize(count: 1, skip_indent: false)
150
+ @count = count
151
+ @skip_indent = skip_indent
152
+ end
153
+ end
154
+
155
+ class Softline < Builder
156
+ attr_reader :fallback
157
+
158
+ def initialize(*args, fallback: nil)
159
+ super(args)
160
+ @fallback = fallback
161
+ end
162
+ end
163
+ end
164
+ end
@@ -20,7 +20,7 @@ module Prettyrb
20
20
  Parser::CurrentRuby.send(:setup_source_buffer, "file='(string)'", 1, @code, parser.default_encoding)
21
21
  )
22
22
 
23
- visitor = Visitor.new
23
+ visitor = Visitor.new(root_node)
24
24
  visitor.visit(root_node)
25
25
 
26
26
  visitor.output
@@ -28,15 +28,6 @@ module Prettyrb
28
28
 
29
29
  private
30
30
 
31
- def format_type(node, indentation)
32
- case node.node_type
33
- when :if
34
- IfFormatter.new(node, indentation).format
35
- else
36
- raise "can't handle #{node}"
37
- end
38
- end
39
-
40
31
  attr_reader :code
41
32
  end
42
33
  end
@@ -0,0 +1,11 @@
1
+ module Prettyrb
2
+ module Nodes
3
+ class AndNode < BaseNode
4
+ include LogicalOperatorHelper
5
+
6
+ def operator
7
+ "&&"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -8,7 +8,7 @@ module Prettyrb
8
8
 
9
9
  super
10
10
 
11
- children.each do |child|
11
+ children&.each do |child|
12
12
  next unless child.is_a?(BaseNode)
13
13
  child.parent = self
14
14
  end
@@ -20,6 +20,10 @@ module Prettyrb
20
20
  @mutable[:parent]
21
21
  end
22
22
 
23
+ def string?
24
+ type == :str || type == :dstr
25
+ end
26
+
23
27
  protected
24
28
 
25
29
  def parent=(parent)
@@ -0,0 +1,17 @@
1
+ module Prettyrb
2
+ module Nodes
3
+ class DefNode < BaseNode
4
+ def name
5
+ children[0]
6
+ end
7
+
8
+ def args
9
+ children[1]
10
+ end
11
+
12
+ def body
13
+ children[2]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -11,7 +11,7 @@ module Prettyrb
11
11
  end
12
12
  end
13
13
 
14
- def conditions_node
14
+ def conditions
15
15
  children[0]
16
16
  end
17
17
 
@@ -42,6 +42,22 @@ module Prettyrb
42
42
  def unless_node?
43
43
  children[1].nil? && children[2] != :if
44
44
  end
45
+
46
+ def elsif_branches
47
+ if has_elsif?
48
+ [else_body_node] + else_body_node.elsif_branches
49
+ else
50
+ []
51
+ end
52
+ end
53
+
54
+ def else_branch
55
+ if has_elsif?
56
+ elsif_branches.last.children[2]
57
+ else
58
+ else_body_node
59
+ end
60
+ end
45
61
  end
46
62
  end
47
63
  end
@@ -0,0 +1,13 @@
1
+ module Prettyrb
2
+ module Nodes
3
+ module LogicalOperatorHelper
4
+ def left
5
+ children[0]
6
+ end
7
+
8
+ def right
9
+ children[1]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Prettyrb
2
+ module Nodes
3
+ class OrNode < BaseNode
4
+ include LogicalOperatorHelper
5
+
6
+ def operator
7
+ "||"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ module Prettyrb
2
+ module Nodes
3
+ class RegexpNode < BaseNode
4
+ include StringHelper
5
+
6
+ PERCENT_PAIRS = {
7
+ "{" => "}",
8
+ "[" => "]",
9
+ "(" => ")",
10
+ "<" => ">",
11
+ }
12
+
13
+ def percent?
14
+ loc.expression.source.start_with?("%")
15
+ end
16
+
17
+ def percent_type
18
+ loc.expression.source[1]
19
+ end
20
+
21
+ def start_delimiter
22
+ loc.expression.source[2]
23
+ end
24
+
25
+ def end_delimiter
26
+ PERCENT_PAIRS.fetch(start_delimiter, start_delimiter)
27
+ end
28
+
29
+ def format
30
+ raw_content = loc.expression.source
31
+ content = raw_content[1...-1]
32
+
33
+ if raw_content[0] == "'"
34
+ content.gsub('"', '\\"').gsub('#{', '\\#{')
35
+ else
36
+ content.gsub("\\", "\\\\")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end