starlark_compiler 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 +4 -4
- data/Gemfile.lock +2 -2
- data/lib/starlark_compiler.rb +1 -0
- data/lib/starlark_compiler/ast.rb +25 -22
- data/lib/starlark_compiler/build_file.rb +85 -0
- data/lib/starlark_compiler/version.rb +1 -1
- data/lib/starlark_compiler/writer.rb +54 -44
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 663c6958d605dfe906b15293619e97fff4040f4fa57568b88c5d76a343a04083
|
4
|
+
data.tar.gz: c04c32107df5dfd72be317e48f3f6b96683a21c02b648c8e1f8932859c9b8072
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cfa2e574e4a1be840990253089e61680d58232e9370af894e1cbb502ff8ba1aa145961c2161dd157e0c5d49cdf9bbdf1e2618cbb2c4b0ee18ee146a5dc2e59a
|
7
|
+
data.tar.gz: d12126d5aecf51ff166c650372620b6171791df5704aea2cf7a8e8e5d5cb68730cd2d0a42c892ec7b58a9c82128893fbc0b51f89cebc1e0f3835f92d3bd96d95
|
data/Gemfile.lock
CHANGED
data/lib/starlark_compiler.rb
CHANGED
@@ -12,34 +12,37 @@ module StarlarkCompiler
|
|
12
12
|
@toplevel << node
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
return str if str !~ /_/ && str =~ /[A-Z]+.*/
|
15
|
+
class Builder
|
16
|
+
def const_name_for(str)
|
17
|
+
str = str.to_s
|
18
|
+
return str if str !~ /_/ && str =~ /[A-Z]+.*/
|
20
19
|
|
21
|
-
|
22
|
-
|
20
|
+
str.split('_').map(&:capitalize).join.to_sym
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def respond_to_missing?(name)
|
24
|
+
AST.constants.include?(const_name_for(name))
|
25
|
+
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
def method_missing(name, *args, **kwargs)
|
28
|
+
const_name = const_name_for(name)
|
29
|
+
begin
|
30
|
+
v = AST.const_get(const_name)
|
31
|
+
rescue NameError
|
32
|
+
super
|
33
|
+
else
|
34
|
+
if kwargs.empty?
|
35
|
+
v.new(*args)
|
34
36
|
else
|
35
|
-
|
36
|
-
v.new(*args)
|
37
|
-
else
|
38
|
-
v.new(*args, **kwargs)
|
39
|
-
end
|
37
|
+
v.new(*args, **kwargs)
|
40
38
|
end
|
41
39
|
end
|
42
|
-
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
private_constant :Builder
|
43
|
+
|
44
|
+
def self.build(&blk)
|
45
|
+
Builder.new.instance_exec(&blk)
|
43
46
|
end
|
44
47
|
|
45
48
|
class Node
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'starlark_compiler/ast'
|
4
|
+
require 'starlark_compiler/writer'
|
5
|
+
|
6
|
+
module StarlarkCompiler
|
7
|
+
class BuildFile
|
8
|
+
def initialize(package:, workspace: Dir.pwd)
|
9
|
+
@loads = Hash.new { |h, k| h[k] = Set.new }
|
10
|
+
@targets = {}
|
11
|
+
@package = package
|
12
|
+
@workspace = workspace
|
13
|
+
@path = File.join(@workspace, @package, 'BUILD.bazel')
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_load(from:, of:) # rubocop:disable Naming/MethodParameterName
|
17
|
+
@loads[from] |= Array(of)
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_target(function_call)
|
21
|
+
name = function_call.kwargs.fetch(:name)
|
22
|
+
if @targets[name]
|
23
|
+
raise Error, "Target named #{name.inspect} already exists in #{package}"
|
24
|
+
end
|
25
|
+
|
26
|
+
@targets[name] = function_call
|
27
|
+
end
|
28
|
+
|
29
|
+
def save!
|
30
|
+
File.open(@path, 'w') do |f|
|
31
|
+
Writer.write(ast: to_starlark, io: f)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_starlark
|
36
|
+
loads = @loads
|
37
|
+
.sort_by { |k, _| k }
|
38
|
+
.map { |f, fn| AST.build { function_call('load', f, *fn.sort) } }
|
39
|
+
targets = @targets
|
40
|
+
.sort_by { |k, _| k }
|
41
|
+
.map { |_f, fn| normalize_function_call_kwargs(fn) }
|
42
|
+
AST.new(toplevel: loads + targets)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# from https://github.com/bazelbuild/buildtools/blob/90de5e7001fbdfec29d4128bb508e01169f46950/tables/tables.go#L171-L202
|
48
|
+
KWARG_NAME_PRIORITY = {
|
49
|
+
name: -99,
|
50
|
+
gwt_name: -98,
|
51
|
+
package_name: -97,
|
52
|
+
visible_node_name: -96,
|
53
|
+
size: -95,
|
54
|
+
timeout: -94,
|
55
|
+
testonly: -93,
|
56
|
+
src: -92,
|
57
|
+
srcdir: -91,
|
58
|
+
srcs: -90,
|
59
|
+
out: -89,
|
60
|
+
outs: -88,
|
61
|
+
hdrs: -87,
|
62
|
+
has_services: -86,
|
63
|
+
include: -85,
|
64
|
+
of: -84,
|
65
|
+
baseline: -83,
|
66
|
+
# All others sort here, at 0.
|
67
|
+
destdir: 1,
|
68
|
+
exports: 2,
|
69
|
+
runtime_deps: 3,
|
70
|
+
deps: 4,
|
71
|
+
implementation: 5,
|
72
|
+
implements: 6,
|
73
|
+
alwayslink: 7
|
74
|
+
}.freeze
|
75
|
+
private_constant :KWARG_NAME_PRIORITY
|
76
|
+
|
77
|
+
def normalize_function_call_kwargs(func)
|
78
|
+
kwargs = func.kwargs.sort_by do |k, _v|
|
79
|
+
[KWARG_NAME_PRIORITY.fetch(k, 0), k]
|
80
|
+
end.to_h
|
81
|
+
func.kwargs.replace(kwargs)
|
82
|
+
func
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -24,7 +24,10 @@ module StarlarkCompiler
|
|
24
24
|
case ast
|
25
25
|
when AST
|
26
26
|
ast.toplevel.each_with_index do |o, i|
|
27
|
-
|
27
|
+
unless i.zero?
|
28
|
+
write_newline
|
29
|
+
write_newline unless o.is_a?(AST::FunctionCall) && o.name == 'load'
|
30
|
+
end
|
28
31
|
write_node(o)
|
29
32
|
end
|
30
33
|
when AST::Node
|
@@ -32,16 +35,16 @@ module StarlarkCompiler
|
|
32
35
|
else
|
33
36
|
raise Error, "Trying to write unknown object #{ast.inspect}"
|
34
37
|
end
|
35
|
-
|
38
|
+
write_newline
|
36
39
|
end
|
37
40
|
|
38
|
-
def write_node(node
|
39
|
-
write_start_of_line if start_of_line
|
41
|
+
def write_node(node)
|
40
42
|
delegate('write_%s', node)
|
41
43
|
end
|
42
44
|
|
43
|
-
def
|
44
|
-
io <<
|
45
|
+
def write_newline
|
46
|
+
io << "\n"
|
47
|
+
io << ' ' * indent
|
45
48
|
end
|
46
49
|
|
47
50
|
def write_string(str)
|
@@ -73,65 +76,63 @@ module StarlarkCompiler
|
|
73
76
|
def write_function_call(call)
|
74
77
|
single_line = single_line?(call)
|
75
78
|
io << call.name << '('
|
76
|
-
io << "\n" unless single_line
|
77
79
|
final_index = single_line && call.kwargs.empty? && call.args.size.pred
|
78
80
|
call.args.each_with_index do |arg, idx|
|
79
|
-
indented do
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
io << (single_line ? ' ' : "\n")
|
84
|
-
end
|
81
|
+
indented(single_line: single_line) do |indenter|
|
82
|
+
indenter.write_newline
|
83
|
+
write_node(arg)
|
84
|
+
indenter.write_comma unless final_index == idx
|
85
85
|
end
|
86
86
|
end
|
87
87
|
final_index = single_line && call.kwargs.size.pred
|
88
88
|
call.kwargs.each_with_index do |(k, v), idx|
|
89
|
-
indented do
|
90
|
-
|
89
|
+
indented(single_line: single_line) do |indenter|
|
90
|
+
indenter.write_newline
|
91
91
|
io << "#{k} = "
|
92
|
-
write_node(v
|
93
|
-
unless final_index == idx
|
94
|
-
io << ','
|
95
|
-
io << (single_line ? ' ' : "\n")
|
96
|
-
end
|
92
|
+
write_node(v)
|
93
|
+
indenter.write_comma unless final_index == idx
|
97
94
|
end
|
98
95
|
end
|
99
|
-
|
96
|
+
write_newline unless single_line
|
100
97
|
io << ')'
|
101
98
|
end
|
102
99
|
|
103
100
|
def write_array(array)
|
104
101
|
single_line = single_line?(array)
|
105
102
|
io << '['
|
103
|
+
end_index = array.elements.size.pred
|
106
104
|
array.elements.each_with_index do |node, i|
|
107
|
-
|
108
|
-
|
109
|
-
|
105
|
+
indented(single_line: single_line) do |indenter|
|
106
|
+
indenter.write_newline
|
107
|
+
write_node(node)
|
108
|
+
indenter.write_comma unless i == end_index && single_line
|
110
109
|
end
|
111
|
-
write_node(node, start_of_line: !single_line)
|
112
110
|
end
|
111
|
+
write_newline unless single_line
|
113
112
|
io << ']'
|
114
113
|
end
|
115
114
|
|
116
115
|
def write_dictionary(dictionary)
|
117
116
|
single_line = single_line?(dictionary)
|
118
117
|
io << '{'
|
118
|
+
end_index = dictionary.elements.size.pred
|
119
119
|
dictionary.elements.each_with_index do |(key, value), i|
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
indented(single_line: single_line) do |indenter|
|
121
|
+
indenter.write_newline
|
122
|
+
write_node(key)
|
123
|
+
io << ': '
|
124
|
+
write_node(value)
|
125
|
+
indenter.write_comma unless i == end_index && single_line
|
123
126
|
end
|
124
|
-
write_node(key, start_of_line: !single_line)
|
125
|
-
io << ': '
|
126
|
-
write_node(value, start_of_line: false)
|
127
127
|
end
|
128
|
+
write_newline unless single_line
|
128
129
|
io << '}'
|
129
130
|
end
|
130
131
|
|
131
132
|
def write_binary_operator(operator)
|
132
|
-
write_node(operator.lhs
|
133
|
+
write_node(operator.lhs)
|
133
134
|
io << " #{operator.operator} "
|
134
|
-
write_node(operator.rhs
|
135
|
+
write_node(operator.rhs)
|
135
136
|
end
|
136
137
|
|
137
138
|
def write_none(_none)
|
@@ -143,14 +144,26 @@ module StarlarkCompiler
|
|
143
144
|
end
|
144
145
|
|
145
146
|
def write_false(_none)
|
146
|
-
io << '
|
147
|
+
io << 'False'
|
147
148
|
end
|
148
149
|
|
149
|
-
|
150
|
-
|
151
|
-
|
150
|
+
Indenter = Struct.new(:writer, :should_indent) do
|
151
|
+
def write_newline
|
152
|
+
writer.write_newline if should_indent
|
153
|
+
end
|
154
|
+
|
155
|
+
def write_comma
|
156
|
+
writer.io << (should_indent ? ',' : ', ')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
private_constant :Indenter
|
160
|
+
|
161
|
+
def indented(single_line:)
|
162
|
+
should_indent = !single_line
|
163
|
+
@indent += 1 if should_indent
|
164
|
+
yield Indenter.new(self, should_indent)
|
152
165
|
ensure
|
153
|
-
@indent -= 1
|
166
|
+
@indent -= 1 if should_indent
|
154
167
|
end
|
155
168
|
|
156
169
|
def single_line?(node)
|
@@ -182,16 +195,13 @@ module StarlarkCompiler
|
|
182
195
|
end
|
183
196
|
|
184
197
|
def single_line_array?(array)
|
185
|
-
|
186
|
-
array.elements.
|
187
|
-
else
|
188
|
-
array.elements.size <= 1 && array.elements.all?(&method(:single_line?))
|
189
|
-
end
|
198
|
+
array.elements.size <= 1 &&
|
199
|
+
array.elements.all?(&method(:single_line?))
|
190
200
|
end
|
191
201
|
|
192
202
|
def single_line_dictionary?(dictionary)
|
193
203
|
dictionary.elements.size <= 1 &&
|
194
|
-
dictionary.elements.
|
204
|
+
dictionary.elements.each_key.all?(&method(:single_line?))
|
195
205
|
end
|
196
206
|
end
|
197
207
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: starlark_compiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Giddins
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- bin/setup
|
46
46
|
- lib/starlark_compiler.rb
|
47
47
|
- lib/starlark_compiler/ast.rb
|
48
|
+
- lib/starlark_compiler/build_file.rb
|
48
49
|
- lib/starlark_compiler/version.rb
|
49
50
|
- lib/starlark_compiler/writer.rb
|
50
51
|
- starlark_compiler.gemspec
|