crystalruby 0.1.13 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +10 -0
- data/README.md +49 -26
- data/exe/crystalruby +15 -14
- data/lib/crystalruby/adapter.rb +98 -70
- data/lib/crystalruby/compilation.rb +13 -83
- data/lib/crystalruby/config.rb +14 -17
- data/lib/crystalruby/function.rb +234 -0
- data/lib/crystalruby/library.rb +191 -0
- data/lib/crystalruby/reactor.rb +30 -62
- data/lib/crystalruby/template.rb +0 -1
- data/lib/crystalruby/templates/index.cr +33 -12
- data/lib/crystalruby/typebuilder.rb +2 -0
- data/lib/crystalruby/typemaps.rb +87 -1
- data/lib/crystalruby/types/array.rb +4 -3
- data/lib/crystalruby/types/hash.rb +5 -3
- data/lib/crystalruby/types/named_tuple.rb +6 -3
- data/lib/crystalruby/types/time.rb +3 -1
- data/lib/crystalruby/types/tuple.rb +3 -1
- data/lib/crystalruby/types/type_serializer/json.rb +3 -2
- data/lib/crystalruby/types/typedef.rb +3 -1
- data/lib/crystalruby/types/union_type.rb +8 -6
- data/lib/crystalruby/version.rb +1 -1
- data/lib/crystalruby.rb +24 -253
- metadata +5 -2
data/lib/crystalruby/typemaps.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CrystalRuby
|
2
4
|
module Typemaps
|
3
5
|
CRYSTAL_TYPE_MAP = {
|
@@ -66,6 +68,90 @@ module CrystalRuby
|
|
66
68
|
void: {
|
67
69
|
to: "nil"
|
68
70
|
}
|
69
|
-
|
71
|
+
}.tap do |hash|
|
72
|
+
hash.define_singleton_method(:convert) do |type, dir, expr|
|
73
|
+
if hash.key?(type)
|
74
|
+
conversion_string = hash[type][dir]
|
75
|
+
conversion_string =~ /%/ ? conversion_string % expr : conversion_string
|
76
|
+
else
|
77
|
+
expr
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def build_type_map(crystalruby_type)
|
83
|
+
{
|
84
|
+
ffi_type: ffi_type(crystalruby_type),
|
85
|
+
ffi_ret_type: ffi_type(crystalruby_type),
|
86
|
+
crystal_type: crystal_type(crystalruby_type),
|
87
|
+
lib_type: lib_type(crystalruby_type),
|
88
|
+
error_value: error_value(crystalruby_type),
|
89
|
+
arg_mapper: if crystalruby_type.is_a?(Types::TypeSerializer)
|
90
|
+
lambda { |arg|
|
91
|
+
crystalruby_type.prepare_argument(arg)
|
92
|
+
}
|
93
|
+
end,
|
94
|
+
retval_mapper: if crystalruby_type.is_a?(Types::TypeSerializer)
|
95
|
+
lambda { |arg|
|
96
|
+
crystalruby_type.prepare_retval(arg)
|
97
|
+
}
|
98
|
+
end,
|
99
|
+
convert_crystal_to_lib_type: ->(expr) { convert_crystal_to_lib_type(expr, crystalruby_type) },
|
100
|
+
convert_lib_to_crystal_type: ->(expr) { convert_lib_to_crystal_type(expr, crystalruby_type) }
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
def ffi_type(type)
|
105
|
+
case type
|
106
|
+
when Symbol then type
|
107
|
+
when Types::TypeSerializer then type.ffi_type
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def lib_type(type)
|
112
|
+
if type.is_a?(Types::TypeSerializer)
|
113
|
+
type.lib_type
|
114
|
+
else
|
115
|
+
C_TYPE_MAP.fetch(type)
|
116
|
+
end
|
117
|
+
rescue StandardError
|
118
|
+
raise "Unsupported type #{type}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def error_value(type)
|
122
|
+
if type.is_a?(Types::TypeSerializer)
|
123
|
+
type.error_value
|
124
|
+
else
|
125
|
+
ERROR_VALUE.fetch(type)
|
126
|
+
end
|
127
|
+
rescue StandardError
|
128
|
+
raise "Unsupported type #{type}"
|
129
|
+
end
|
130
|
+
|
131
|
+
def crystal_type(type)
|
132
|
+
if type.is_a?(Types::TypeSerializer)
|
133
|
+
type.crystal_type
|
134
|
+
else
|
135
|
+
CRYSTAL_TYPE_MAP.fetch(type)
|
136
|
+
end
|
137
|
+
rescue StandardError
|
138
|
+
raise "Unsupported type #{type}"
|
139
|
+
end
|
140
|
+
|
141
|
+
def convert_lib_to_crystal_type(expr, type)
|
142
|
+
if type.is_a?(Types::TypeSerializer)
|
143
|
+
type.lib_to_crystal_type_expr(expr)
|
144
|
+
else
|
145
|
+
C_TYPE_CONVERSIONS.convert(type, :from, expr)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def convert_crystal_to_lib_type(expr, type)
|
150
|
+
if type.is_a?(Types::TypeSerializer)
|
151
|
+
type.crystal_to_lib_type_expr(expr)
|
152
|
+
else
|
153
|
+
C_TYPE_CONVERSIONS.convert(type, :to, expr)
|
154
|
+
end
|
155
|
+
end
|
70
156
|
end
|
71
157
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CrystalRuby::Types
|
2
4
|
Array = Type.new(
|
3
5
|
:Array,
|
@@ -6,9 +8,8 @@ module CrystalRuby::Types
|
|
6
8
|
|
7
9
|
def self.Array(type)
|
8
10
|
Type.validate!(type)
|
9
|
-
Type.new("Array", inner_types: [type], accept_if: [::Array]
|
10
|
-
|
11
|
-
a.map!{|v| type.interpret!(v) }
|
11
|
+
Type.new("Array", inner_types: [type], accept_if: [::Array]) do |a|
|
12
|
+
a.map! { |v| type.interpret!(v) }
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CrystalRuby::Types
|
2
4
|
Hash = Type.new(
|
3
5
|
:Hash,
|
4
|
-
error: "Hash type must have 2 type parameters. E.g. Hash(Float64, String)"
|
6
|
+
error: "Hash type must have 2 type parameters. E.g. Hash(Float64, String)"
|
5
7
|
)
|
6
8
|
|
7
9
|
def self.Hash(key_type, value_type)
|
8
10
|
Type.validate!(key_type)
|
9
11
|
Type.validate!(value_type)
|
10
12
|
Type.new("Hash", inner_types: [key_type, value_type], accept_if: [::Hash]) do |h|
|
11
|
-
h.transform_keys!{|k| key_type.interpret!(k) }
|
12
|
-
h.transform_values!{|v| value_type.interpret!(v) }
|
13
|
+
h.transform_keys! { |k| key_type.interpret!(k) }
|
14
|
+
h.transform_values! { |v| value_type.interpret!(v) }
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CrystalRuby::Types
|
2
4
|
NamedTuple = Type.new(
|
3
5
|
:NamedTuple,
|
@@ -6,7 +8,7 @@ module CrystalRuby::Types
|
|
6
8
|
|
7
9
|
def self.NamedTuple(types_hash)
|
8
10
|
types_hash.keys.each do |key|
|
9
|
-
raise "NamedTuple keys must be symbols" unless key.
|
11
|
+
raise "NamedTuple keys must be symbols" unless key.is_a?(::Symbol) || key.respond_to?(:to_sym)
|
10
12
|
end
|
11
13
|
types_hash.values.each do |value_type|
|
12
14
|
Type.validate!(value_type)
|
@@ -14,9 +16,10 @@ module CrystalRuby::Types
|
|
14
16
|
keys = types_hash.keys.map(&:to_sym)
|
15
17
|
values = types_hash.values
|
16
18
|
Type.new("NamedTuple", inner_types: values, inner_keys: keys, accept_if: [::Hash]) do |h|
|
17
|
-
h.transform_keys!{|k| k.to_sym }
|
19
|
+
h.transform_keys! { |k| k.to_sym }
|
18
20
|
raise "Invalid keys for named tuple" unless h.keys.length == keys.length
|
19
|
-
raise "Invalid keys for named tuple" unless h.keys.all?{|k| keys.include?(k)}
|
21
|
+
raise "Invalid keys for named tuple" unless h.keys.all? { |k| keys.include?(k) }
|
22
|
+
|
20
23
|
h.each do |key, value|
|
21
24
|
h[key] = values[keys.index(key)].interpret!(value)
|
22
25
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CrystalRuby::Types
|
2
4
|
Tuple = Type.new(
|
3
5
|
:Tuple,
|
@@ -9,7 +11,7 @@ module CrystalRuby::Types
|
|
9
11
|
Type.validate!(value_type)
|
10
12
|
end
|
11
13
|
Type.new("Tuple", inner_types: types, accept_if: [::Array]) do |a|
|
12
|
-
a.map!.with_index{|v, i|
|
14
|
+
a.map!.with_index { |v, i| inner_types[i].interpret!(v) }
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "type_serializer"
|
2
4
|
|
3
5
|
module CrystalRuby
|
@@ -5,7 +7,7 @@ module CrystalRuby
|
|
5
7
|
class Typedef; end
|
6
8
|
|
7
9
|
def self.Typedef(type)
|
8
|
-
return type if type.
|
10
|
+
return type if type.is_a?(Class) && type < Typedef
|
9
11
|
|
10
12
|
Class.new(Typedef) do
|
11
13
|
define_singleton_method(:union_types) do
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CrystalRuby
|
2
4
|
module Types
|
3
5
|
class UnionType < Type
|
@@ -26,12 +28,12 @@ module CrystalRuby
|
|
26
28
|
|
27
29
|
def interpret!(raw)
|
28
30
|
union_types.each do |type|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
next unless type.interprets?(raw)
|
32
|
+
|
33
|
+
begin
|
34
|
+
return type.interpret!(raw)
|
35
|
+
rescue StandardError
|
36
|
+
# Pass
|
35
37
|
end
|
36
38
|
end
|
37
39
|
raise "Invalid deserialized value #{raw} for type #{inspect}"
|
data/lib/crystalruby/version.rb
CHANGED
data/lib/crystalruby.rb
CHANGED
@@ -15,277 +15,48 @@ require_relative "crystalruby/template"
|
|
15
15
|
require_relative "crystalruby/compilation"
|
16
16
|
require_relative "crystalruby/adapter"
|
17
17
|
require_relative "crystalruby/reactor"
|
18
|
+
require_relative "crystalruby/library"
|
19
|
+
require_relative "crystalruby/function"
|
20
|
+
require_relative "module"
|
18
21
|
|
19
22
|
module CrystalRuby
|
20
|
-
CR_SRC_FILES_PATTERN = "./**/*.cr"
|
21
|
-
CR_COMPILE_MUX = Mutex.new
|
22
|
-
|
23
23
|
module_function
|
24
24
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
arg_types = args.transform_values(&method(:build_type_map))
|
29
|
-
return_type = build_type_map(returns)
|
30
|
-
lib_fn_args = arg_types.map { |k, arg_type| "_#{k} : #{arg_type[:lib_type]}" }.join(",")
|
31
|
-
lib_fn_args += ", " unless lib_fn_args.empty?
|
32
|
-
lib_fn_arg_names = arg_types.map { |k, _arg_type| "_#{k}" }.join(",")
|
33
|
-
lib_fn_arg_names += ", " unless lib_fn_args.empty?
|
34
|
-
|
35
|
-
function_body = Template::Function.render(
|
36
|
-
{
|
37
|
-
module_name: owner.name,
|
38
|
-
lib_fn_name: lib_fn_name,
|
39
|
-
fn_name: name,
|
40
|
-
fn_body: body,
|
41
|
-
callback_call: returns == :void ? "callback.call(thread_id)" : "callback.call(thread_id, converted)",
|
42
|
-
callback_type: return_type[:ffi_type] == :void ? "UInt32 -> Void" : " UInt32, #{return_type[:lib_type]} -> Void",
|
43
|
-
fn_args: arg_types.map { |k, arg_type| "#{k} : #{arg_type[:crystal_type]}" }.join(","),
|
44
|
-
fn_ret_type: return_type[:crystal_type],
|
45
|
-
lib_fn_args: lib_fn_args,
|
46
|
-
lib_fn_arg_names: lib_fn_arg_names,
|
47
|
-
lib_fn_ret_type: return_type[:lib_type],
|
48
|
-
convert_lib_args: arg_types.map do |k, arg_type|
|
49
|
-
"#{k} = #{arg_type[:convert_lib_to_crystal_type]["_#{k}"]}"
|
50
|
-
end.join("\n "),
|
51
|
-
arg_names: args.keys.join(","),
|
52
|
-
convert_return_type: return_type[:convert_crystal_to_lib_type]["return_value"],
|
53
|
-
error_value: return_type[:error_value]
|
54
|
-
}
|
55
|
-
)
|
56
|
-
{
|
57
|
-
name: name,
|
58
|
-
body: function_body,
|
59
|
-
retval_map: returns.is_a?(Types::TypeSerializer) ? ->(rv) { returns.prepare_retval(rv) } : nil,
|
60
|
-
ffi_types: arg_types.map { |_k, arg_type| arg_type[:ffi_type] },
|
61
|
-
arg_maps: arg_types.map { |_k, arg_type| arg_type[:mapper] },
|
62
|
-
ffi_ret_type: return_type[:ffi_ret_type]
|
63
|
-
}
|
64
|
-
end
|
65
|
-
|
66
|
-
def build_type_map(crystalruby_type)
|
67
|
-
if crystalruby_type.is_a?(Types::TypeSerializer) && !crystalruby_type.anonymous?
|
68
|
-
CrystalRuby.register_type!(crystalruby_type)
|
69
|
-
end
|
70
|
-
|
71
|
-
{
|
72
|
-
ffi_type: ffi_type(crystalruby_type),
|
73
|
-
ffi_ret_type: ffi_type(crystalruby_type),
|
74
|
-
crystal_type: crystal_type(crystalruby_type),
|
75
|
-
lib_type: lib_type(crystalruby_type),
|
76
|
-
error_value: error_value(crystalruby_type),
|
77
|
-
mapper: crystalruby_type.is_a?(Types::TypeSerializer) ? ->(arg) { crystalruby_type.prepare_argument(arg) } : nil,
|
78
|
-
convert_crystal_to_lib_type: ->(expr) { convert_crystal_to_lib_type(expr, crystalruby_type) },
|
79
|
-
convert_lib_to_crystal_type: ->(expr) { convert_lib_to_crystal_type(expr, crystalruby_type) }
|
80
|
-
}
|
81
|
-
end
|
82
|
-
|
83
|
-
def ffi_type(type)
|
84
|
-
case type
|
85
|
-
when Symbol then type
|
86
|
-
when Types::TypeSerializer then type.ffi_type
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def lib_type(type)
|
91
|
-
if type.is_a?(Types::TypeSerializer)
|
92
|
-
type.lib_type
|
93
|
-
else
|
94
|
-
Typemaps::C_TYPE_MAP.fetch(type)
|
95
|
-
end
|
96
|
-
rescue StandardError => e
|
97
|
-
raise "Unsupported type #{type}"
|
98
|
-
end
|
99
|
-
|
100
|
-
def error_value(type)
|
101
|
-
if type.is_a?(Types::TypeSerializer)
|
102
|
-
type.error_value
|
103
|
-
else
|
104
|
-
Typemaps::ERROR_VALUE.fetch(type)
|
105
|
-
end
|
106
|
-
rescue StandardError => e
|
107
|
-
raise "Unsupported type #{type}"
|
108
|
-
end
|
109
|
-
|
110
|
-
def crystal_type(type)
|
111
|
-
if type.is_a?(Types::TypeSerializer)
|
112
|
-
type.crystal_type
|
113
|
-
else
|
114
|
-
Typemaps::CRYSTAL_TYPE_MAP.fetch(type)
|
115
|
-
end
|
116
|
-
rescue StandardError => e
|
117
|
-
raise "Unsupported type #{type}"
|
118
|
-
end
|
119
|
-
|
120
|
-
def convert_lib_to_crystal_type(expr, type)
|
121
|
-
if type.is_a?(Types::TypeSerializer)
|
122
|
-
type.lib_to_crystal_type_expr(expr)
|
123
|
-
else
|
124
|
-
Typemaps::C_TYPE_CONVERSIONS[type] ? Typemaps::C_TYPE_CONVERSIONS[type][:from] % expr : expr
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def convert_crystal_to_lib_type(expr, type)
|
129
|
-
if type.is_a?(Types::TypeSerializer)
|
130
|
-
type.crystal_to_lib_type_expr(expr)
|
131
|
-
else
|
132
|
-
Typemaps::C_TYPE_CONVERSIONS[type] ? Typemaps::C_TYPE_CONVERSIONS[type][:to] % expr : expr
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def self.instantiate_crystal_ruby!
|
137
|
-
unless system("which crystal > /dev/null 2>&1")
|
138
|
-
raise "Crystal executable not found. Please ensure Crystal is installed and in your PATH."
|
139
|
-
end
|
140
|
-
|
141
|
-
@instantiated = true
|
142
|
-
%w[crystal_lib_dir crystal_main_file crystal_src_dir crystal_lib_name].each do |config_key|
|
143
|
-
unless config.send(config_key)
|
144
|
-
raise "Missing config option `#{config_key}`. \nProvide this inside crystalruby.yaml (run `bundle exec crystalruby init` to generate this file with detaults)"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
FileUtils.mkdir_p config.crystal_codegen_dir_abs
|
148
|
-
FileUtils.mkdir_p config.crystal_lib_dir_abs
|
149
|
-
FileUtils.mkdir_p config.crystal_src_dir_abs
|
150
|
-
unless File.exist?(config.crystal_src_dir_abs / config.crystal_main_file)
|
151
|
-
IO.write(
|
152
|
-
config.crystal_src_dir_abs / config.crystal_main_file,
|
153
|
-
"require \"./#{config.crystal_codegen_dir}/index\"\n"
|
154
|
-
)
|
155
|
-
end
|
156
|
-
|
157
|
-
return if File.exist?(config.crystal_src_dir / "shard.yml")
|
158
|
-
|
159
|
-
IO.write("#{config.crystal_src_dir}/shard.yml", <<~YAML)
|
160
|
-
name: src
|
161
|
-
version: 0.1.0
|
162
|
-
YAML
|
25
|
+
def initialized?
|
26
|
+
!!@initialized
|
163
27
|
end
|
164
28
|
|
165
|
-
def
|
166
|
-
|
167
|
-
end
|
29
|
+
def initialize_crystal_ruby!
|
30
|
+
return if initialized?
|
168
31
|
|
169
|
-
|
170
|
-
|
171
|
-
@
|
32
|
+
check_crystal_ruby!
|
33
|
+
check_config!
|
34
|
+
@initialized = true
|
172
35
|
end
|
173
36
|
|
174
|
-
def
|
175
|
-
|
176
|
-
end
|
37
|
+
def check_crystal_ruby!
|
38
|
+
return if system("which crystal > /dev/null 2>&1")
|
177
39
|
|
178
|
-
|
179
|
-
|
180
|
-
@types_cache[type.name] = type.type_defn
|
40
|
+
raise "Crystal executable not found. Please ensure Crystal is installed and in your PATH." \
|
41
|
+
"See https://crystal-lang.org/install/"
|
181
42
|
end
|
182
43
|
|
183
|
-
def
|
184
|
-
|
185
|
-
parts = type_name.split("::")
|
186
|
-
typedef = parts[0...-1].each_with_index.reduce("") do |acc, (part, index)|
|
187
|
-
acc + "#{" " * index}module #{part}\n"
|
188
|
-
end
|
189
|
-
typedef += "#{" " * (parts.size - 1)}alias #{parts.last} = #{expr}\n"
|
190
|
-
typedef + parts[0...-1].reverse.each_with_index.reduce("") do |acc, (_part, index)|
|
191
|
-
acc + "#{" " * (parts.size - 2 - index)}end\n"
|
192
|
-
end
|
193
|
-
end.join("\n")
|
194
|
-
end
|
44
|
+
def check_config!
|
45
|
+
return if config.crystal_src_dir
|
195
46
|
|
196
|
-
|
197
|
-
|
198
|
-
function_data = function[:body]
|
199
|
-
file_digest = Digest::MD5.hexdigest function_data
|
200
|
-
fname = function[:name]
|
201
|
-
"require \"./#{function[:owner].name}/#{fname}_#{file_digest}.cr\"\n"
|
202
|
-
end.join("\n")
|
47
|
+
raise "Missing config option `crystal_src_dir`. \nProvide this inside crystalruby.yaml "\
|
48
|
+
"(run `bundle exec crystalruby init` to generate this file with detaults)"
|
203
49
|
end
|
204
50
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
CR_COMPILE_MUX.synchronize do
|
209
|
-
return if @compiled
|
51
|
+
%w[debug info warn error].each do |level|
|
52
|
+
define_method("log_#{level}") do |*msg|
|
53
|
+
prefix = config.colorize_log_output ? "\e[33mcrystalruby\e[0m\e[90m [#{Thread.current.object_id}]\e[0m" : "[crystalruby] #{Thread.current.object_id}"
|
210
54
|
|
211
|
-
|
212
|
-
type_modules: type_modules,
|
213
|
-
requires: requires
|
214
|
-
)
|
215
|
-
if @compiled = CrystalRuby::Compilation.compile!(
|
216
|
-
verbose: config.verbose,
|
217
|
-
debug: config.debug
|
218
|
-
)
|
219
|
-
IO.write(digest_file_name, get_cr_src_files_digest)
|
220
|
-
else
|
221
|
-
File.delete(digest_file_name) if File.exist?(digest_file_name)
|
222
|
-
raise "Error compiling crystal code"
|
223
|
-
end
|
55
|
+
config.logger.send(level, "#{prefix} #{msg.join(", ")}")
|
224
56
|
end
|
225
57
|
end
|
226
58
|
|
227
|
-
def
|
228
|
-
|
229
|
-
@chunk_store.each do |function|
|
230
|
-
function[:compile_callback]&.call
|
231
|
-
end
|
232
|
-
log_debug(".attach_crystal_ruby_lib. Single thread mode: #{config.single_thread_mode}")
|
233
|
-
if config.single_thread_mode
|
234
|
-
Reactor.init_single_thread_mode!
|
235
|
-
else
|
236
|
-
Reactor.start!
|
237
|
-
end
|
238
|
-
@attached = true
|
239
|
-
end
|
240
|
-
|
241
|
-
def self.get_cr_src_files_digest
|
242
|
-
file_digests = Dir.glob(CR_SRC_FILES_PATTERN).sort.map do |file_path|
|
243
|
-
content = File.read(file_path)
|
244
|
-
Digest::MD5.hexdigest(content)
|
245
|
-
end.join
|
246
|
-
Digest::MD5.hexdigest(file_digests)
|
247
|
-
end
|
248
|
-
|
249
|
-
def self.digest_file_name
|
250
|
-
@digest_file_name ||= config.crystal_lib_dir_abs / "#{config.crystal_lib_name}.digest"
|
251
|
-
end
|
252
|
-
|
253
|
-
def self.chunk_store
|
254
|
-
@chunk_store ||= []
|
255
|
-
end
|
256
|
-
|
257
|
-
def self.get_current_crystal_lib_digest
|
258
|
-
File.read(digest_file_name) if File.exist?(digest_file_name)
|
259
|
-
end
|
260
|
-
|
261
|
-
def self.write_chunk(owner, body:, name: Digest::MD5.hexdigest(body), &compile_callback)
|
262
|
-
log_debug(".write_chunk!")
|
263
|
-
chunk_store.delete_if { |chnk| chnk[:owner].name == owner.name && chnk[:name] == name }
|
264
|
-
chunk_store << { owner: owner, name: name, body: body, compile_callback: compile_callback }
|
265
|
-
FileUtils.mkdir_p(config.crystal_codegen_dir_abs)
|
266
|
-
existing = Dir.glob("#{config.crystal_codegen_dir_abs}/**/*.cr")
|
267
|
-
chunk_store.each do |function|
|
268
|
-
log_debug(".processing_chunk", function[0..60])
|
269
|
-
owner_name = function[:owner].name
|
270
|
-
FileUtils.mkdir_p(config.crystal_codegen_dir_abs / owner_name)
|
271
|
-
function_data = function[:body]
|
272
|
-
fname = function[:name]
|
273
|
-
file_digest = Digest::MD5.hexdigest function_data
|
274
|
-
filename = config.crystal_codegen_dir_abs / owner_name / "#{fname}_#{file_digest}.cr"
|
275
|
-
|
276
|
-
unless existing.delete(filename.to_s)
|
277
|
-
log_debug("Chunk invalidated", filename.to_s)
|
278
|
-
@attached = false
|
279
|
-
@compiled = false
|
280
|
-
File.write(filename, function_data)
|
281
|
-
end
|
282
|
-
existing.select do |f|
|
283
|
-
f =~ /#{config.crystal_codegen_dir / owner_name / "#{fname}_[a-f0-9]{32}\.cr"}/
|
284
|
-
end.each do |fl|
|
285
|
-
File.delete(fl) unless fl.eql?(filename.to_s)
|
286
|
-
end
|
287
|
-
end
|
59
|
+
def compile!
|
60
|
+
CrystalRuby::Library.all.each(&:build!)
|
288
61
|
end
|
289
62
|
end
|
290
|
-
|
291
|
-
require_relative "module"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crystalruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wouter Coppieters
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: digest
|
@@ -74,6 +74,7 @@ executables:
|
|
74
74
|
extensions: []
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
|
+
- ".dockerignore"
|
77
78
|
- ".rubocop.yml"
|
78
79
|
- CHANGELOG.md
|
79
80
|
- CODE_OF_CONDUCT.md
|
@@ -88,6 +89,8 @@ files:
|
|
88
89
|
- lib/crystalruby/adapter.rb
|
89
90
|
- lib/crystalruby/compilation.rb
|
90
91
|
- lib/crystalruby/config.rb
|
92
|
+
- lib/crystalruby/function.rb
|
93
|
+
- lib/crystalruby/library.rb
|
91
94
|
- lib/crystalruby/reactor.rb
|
92
95
|
- lib/crystalruby/template.rb
|
93
96
|
- lib/crystalruby/templates/function.cr
|