Class: CrystalRuby::Types::Type
Constant Summary
collapse
- ARC_MUTEX =
TODO: Replace with pthread primitives and share with Crystal
CrystalRuby::ArcMutex.new
CrystalRuby::Typemaps::CRYSTAL_TYPE_MAP, CrystalRuby::Typemaps::C_TYPE_CONVERSIONS, CrystalRuby::Typemaps::C_TYPE_MAP, CrystalRuby::Typemaps::ERROR_VALUE, CrystalRuby::Typemaps::FFI_TYPE_MAP
Class Attribute Summary collapse
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
build_type_map, convert_crystal_to_lib_type, convert_lib_to_crystal_type, crystal_type, error_value, ffi_type, lib_type
Methods included from Allocator
included
Constructor Details
#initialize(_rbval) ⇒ Type
Returns a new instance of Type.
52
53
54
55
|
# File 'lib/crystalruby/types/type.rb', line 52
def initialize(_rbval)
@class = self.class
raise error if error
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
# File 'lib/crystalruby/types/type.rb', line 199
def method_missing(method, *args, &block)
v = begin
native
rescue StandardError
super
end
if v.respond_to?(method)
hash_before = v.hash
result = v.send(method, *args, &block)
if v.hash != hash_before
self.value = v
v.equal?(result) ? self : result
else
result
end
else
super
end
end
|
Class Attribute Details
.convert_if ⇒ Object
Returns the value of attribute convert_if.
42
43
44
|
# File 'lib/crystalruby/types/type.rb', line 42
def convert_if
@convert_if
end
|
.ffi_type ⇒ Object
Returns the value of attribute ffi_type.
42
43
44
|
# File 'lib/crystalruby/types/type.rb', line 42
def ffi_type
@ffi_type
end
|
.inner_types ⇒ Object
Returns the value of attribute inner_types.
42
43
44
|
# File 'lib/crystalruby/types/type.rb', line 42
def inner_types
@inner_types
end
|
.memsize ⇒ Object
Returns the value of attribute memsize.
42
43
44
|
# File 'lib/crystalruby/types/type.rb', line 42
def memsize
@memsize
end
|
.typename ⇒ Object
Returns the value of attribute typename.
42
43
44
|
# File 'lib/crystalruby/types/type.rb', line 42
def typename
@typename
end
|
Instance Attribute Details
#memory ⇒ Object
Returns the value of attribute memory.
50
51
52
|
# File 'lib/crystalruby/types/type.rb', line 50
def memory
@memory
end
|
#value(native: false) ⇒ Object
Returns the value of attribute value.
50
51
52
|
# File 'lib/crystalruby/types/type.rb', line 50
def value
@value
end
|
Class Method Details
.[](*value) ⇒ Object
87
88
89
90
|
# File 'lib/crystalruby/types/type.rb', line 87
def self.[](*value)
is_list_type = ancestors.any? { |a| a < CrystalRuby::Types::Array || a < CrystalRuby::Types::Tuple }
new(is_list_type ? value : value.first)
end
|
.anonymous? ⇒ Boolean
92
93
94
|
# File 'lib/crystalruby/types/type.rb', line 92
def self.anonymous?
name.nil? || name.start_with?("CrystalRuby::Types::")
end
|
.base_crystal_class_name ⇒ Object
105
106
107
|
# File 'lib/crystalruby/types/type.rb', line 105
def self.base_crystal_class_name
crystal_class_name.split("::").last
end
|
.bind_local_vars!(variable_names, binding) ⇒ Object
219
220
221
222
223
224
225
226
227
228
|
# File 'lib/crystalruby/types/type.rb', line 219
def self.bind_local_vars!(variable_names, binding)
variable_names.each do |name|
define_singleton_method(name) do
binding.local_variable_get("#{name}")
end
define_method(name) do
binding.local_variable_get("#{name}")
end
end
end
|
.cast!(value) ⇒ Object
161
162
163
|
# File 'lib/crystalruby/types/type.rb', line 161
def self.cast!(value)
value.is_a?(Type) ? value.value : value
end
|
.crystal_class_name ⇒ Object
96
97
98
99
100
101
102
103
|
# File 'lib/crystalruby/types/type.rb', line 96
def self.crystal_class_name
name || native_type_expr.split(",").join("_and_")
.split("|").join("_or_")
.split("(").join("_of_")
.gsub(/[^a-zA-Z0-9_]/, "")
.split("_")
.map(&:capitalize).join << "_#{type_digest[0..6]}"
end
|
.crystal_type ⇒ Object
236
237
238
|
# File 'lib/crystalruby/types/type.rb', line 236
def self.crystal_type
lib_type(ffi_type)
end
|
.crystal_type_to_pointer_type_conversion(expr) ⇒ Object
129
130
131
|
# File 'lib/crystalruby/types/type.rb', line 129
def self.crystal_type_to_pointer_type_conversion(expr)
anonymous? ? "#{crystal_class_name}.new(#{expr}).return_value" : "#{expr}.return_value"
end
|
.each_child_address(pointer) ⇒ Object
230
|
# File 'lib/crystalruby/types/type.rb', line 230
def self.each_child_address(pointer); end
|
.finalize(_memory) ⇒ Object
57
58
59
|
# File 'lib/crystalruby/types/type.rb', line 57
def self.finalize(_memory)
->(_) {}
end
|
.fixed_width? ⇒ Boolean
157
158
159
|
# File 'lib/crystalruby/types/type.rb', line 157
def self.fixed_width?
false
end
|
.from_ffi_array_repr(value) ⇒ Object
181
182
183
|
# File 'lib/crystalruby/types/type.rb', line 181
def self.from_ffi_array_repr(value)
anonymous? ? new(value).value : new(value)
end
|
.inner_type ⇒ Object
254
255
256
|
# File 'lib/crystalruby/types/type.rb', line 254
def self.inner_type
inner_types.first
end
|
.inspect ⇒ Object
270
271
272
|
# File 'lib/crystalruby/types/type.rb', line 270
def self.inspect
type_expr
end
|
.inspect_name ⇒ Object
61
62
63
|
# File 'lib/crystalruby/types/type.rb', line 61
def self.inspect_name
(name || "#{typename}").to_s.gsub(/^CrystalRuby::Types::[^::]+::/, "")
end
|
.native_type_expr ⇒ Object
73
74
75
76
77
78
79
80
81
|
# File 'lib/crystalruby/types/type.rb', line 73
def self.native_type_expr
if !inner_types
"::#{typename}"
elsif !inner_keys
"::#{typename}(#{inner_types.map(&:native_type_expr).join(", ")})"
else
"::#{typename}(#{inner_keys.zip(inner_types).map { |k, v| "#{k}: #{v.native_type_expr}" }.join(", ")})"
end
end
|
.nested_types ⇒ Object
121
122
123
|
# File 'lib/crystalruby/types/type.rb', line 121
def self.nested_types
[self, *(inner_types || []).map(&:nested_types)].flatten.uniq
end
|
.numeric? ⇒ Boolean
145
146
147
|
# File 'lib/crystalruby/types/type.rb', line 145
def self.numeric?
false
end
|
.pointer_to_crystal_type_conversion(expr) ⇒ Object
125
126
127
|
# File 'lib/crystalruby/types/type.rb', line 125
def self.pointer_to_crystal_type_conversion(expr)
anonymous? ? "#{crystal_class_name}.new(#{expr}).native" : "#{crystal_class_name}.new(#{expr})"
end
|
.primitive? ⇒ Boolean
149
150
151
|
# File 'lib/crystalruby/types/type.rb', line 149
def self.primitive?
false
end
|
.template_name ⇒ Object
133
134
135
|
# File 'lib/crystalruby/types/type.rb', line 133
def self.template_name
typename || superclass.template_name
end
|
.type_defn ⇒ Object
137
138
139
140
141
142
143
|
# File 'lib/crystalruby/types/type.rb', line 137
def self.type_defn
unless Template.const_defined?(template_name) && Template.const_get(template_name).is_a?(Template::Renderer)
raise "Template not found for #{template_name}"
end
Template.const_get(template_name).render(binding)
end
|
.type_digest ⇒ Object
117
118
119
|
# File 'lib/crystalruby/types/type.rb', line 117
def self.type_digest
Digest::MD5.hexdigest(native_type_expr.to_s)
end
|
.type_expr ⇒ Object
258
259
260
261
262
263
264
265
266
267
268
|
# File 'lib/crystalruby/types/type.rb', line 258
def self.type_expr
if !inner_types
inspect_name
elsif !anonymous?
name
elsif inner_keys
"#{inspect_name}(#{inner_keys.zip(inner_types).map { |k, v| "#{k}: #{v.inspect}" }.join(", ")})"
else
"#{inspect_name}(#{inner_types.map(&:inspect).join(", ")})"
end
end
|
.union_types ⇒ Object
65
66
67
|
# File 'lib/crystalruby/types/type.rb', line 65
def self.union_types
[self]
end
|
.valid? ⇒ Boolean
69
70
71
|
# File 'lib/crystalruby/types/type.rb', line 69
def self.valid?
true
end
|
.valid_cast?(raw) ⇒ Boolean
83
84
85
|
# File 'lib/crystalruby/types/type.rb', line 83
def self.valid_cast?(raw)
raw.is_a?(self) || convert_if.any? { |type| raw.is_a?(type) }
end
|
.validate!(type) ⇒ Object
246
247
248
249
250
251
252
|
# File 'lib/crystalruby/types/type.rb', line 246
def self.validate!(type)
unless type.is_a?(Class) && type.ancestors.include?(Types::Type)
raise "Result #{type} is not a valid CrystalRuby type"
end
raise "Invalid type: #{type.error}" unless type.valid?
end
|
.variable_width? ⇒ Boolean
153
154
155
|
# File 'lib/crystalruby/types/type.rb', line 153
def self.variable_width?
false
end
|
.|(other) ⇒ Object
240
241
242
243
244
|
# File 'lib/crystalruby/types/type.rb', line 240
def self.|(other)
raise "Cannot union non-crystal type #{other}" unless other.is_a?(Class) && other.ancestors.include?(Type)
CrystalRuby::Types::TaggedUnion(*union_types, *other.union_types)
end
|
Instance Method Details
#==(other) ⇒ Object
165
166
167
|
# File 'lib/crystalruby/types/type.rb', line 165
def ==(other)
value(native: true) == (other.is_a?(Type) ? other.value(native: true) : other)
end
|
#coerce(other) ⇒ Object
173
174
175
|
# File 'lib/crystalruby/types/type.rb', line 173
def coerce(other)
[other, value]
end
|
#deep_dup ⇒ Object
Create a brand new copy of this object
190
191
192
|
# File 'lib/crystalruby/types/type.rb', line 190
def deep_dup
self.class.new(native)
end
|
#dup ⇒ Object
Create a new reference to this object.
195
196
197
|
# File 'lib/crystalruby/types/type.rb', line 195
def dup
self.class.new(@memory)
end
|
#inner_value ⇒ Object
185
186
187
|
# File 'lib/crystalruby/types/type.rb', line 185
def inner_value
@value
end
|
#inspect ⇒ Object
177
178
179
|
# File 'lib/crystalruby/types/type.rb', line 177
def inspect
value.inspect
end
|
#item_size ⇒ Object
232
233
234
|
# File 'lib/crystalruby/types/type.rb', line 232
def item_size
inner_types.map(&:memsize).sum
end
|
#native ⇒ Object
113
114
115
|
# File 'lib/crystalruby/types/type.rb', line 113
def native
value(native: true)
end
|
#nil? ⇒ Boolean
169
170
171
|
# File 'lib/crystalruby/types/type.rb', line 169
def nil?
value.nil?
end
|