prettyrb 0.4.0 → 0.5.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: 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