Skip to content

Commit

Permalink
Use Crystal Char for gunichar.
Browse files Browse the repository at this point in the history
Properties were not tested but they should work.
  • Loading branch information
hugopl committed Oct 8, 2023
1 parent 2b83ac8 commit e20a45a
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 31 deletions.
4 changes: 4 additions & 0 deletions spec/libtest/test_subject.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,10 @@ TestSubject* test_subject_may_return_null(TestSubject* self, gboolean return_nil
return return_nil ? NULL : self;
}

gunichar test_subject_return_char(TestSubject* self, gunichar character) {
return character;
}

void test_subject_transfer_full_param(GObject* subject) {
}

Expand Down
7 changes: 7 additions & 0 deletions spec/libtest/test_subject.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ gboolean test_subject_call_simple_func(TestSubject* self, int number);
*/
TestSubject* test_subject_may_return_null(TestSubject* self, gboolean return_nil);

/**
* test_subject_return_char:
* @character: The very same character that will be returned.
* Returns: The very same character parameter.
*/
gunichar test_subject_return_char(TestSubject* self, gunichar character);

/**
* test_subject_transfer_full_param:
* @subject: (transfer full):
Expand Down
65 changes: 36 additions & 29 deletions src/generator/arg_strategy.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ module Generator
end

abstract def match?(strategy : ArgStrategy, direction : ArgStrategy::Direction) : Bool
abstract def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
abstract def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
abstract def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
abstract def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
end

class ArgStrategy
Expand Down Expand Up @@ -90,8 +90,8 @@ module Generator
io = @implementation ||= IO::Memory.new
io << "# " << arg_plan.class.name << LF
case direction
in .c_to_crystal? then arg_plan.generate_lib_implementation(io, self)
in .crystal_to_c? then arg_plan.generate_crystal_implementation(io, self)
in .c_to_crystal? then arg_plan.generate_c_to_crystal_implementation(io, self)
in .crystal_to_c? then arg_plan.generate_crystal_to_c_implementation(io, self)
end
end

Expand All @@ -113,14 +113,14 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_type = strategy.arg_type
io << to_identifier(strategies[arg_type.array_length].arg.name) << " = " << to_identifier(arg.name)
io << (arg.nullable? ? ".try(&.size) || 0" : ".size")
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
end
end

Expand All @@ -136,7 +136,7 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_name = to_identifier(arg.name)
arg_type = arg.type_info
Expand All @@ -151,7 +151,7 @@ module Generator
generate_array_to_unsafe(io, arg_name, arg.type_info)
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_name = to_identifier(arg.name)
arg_type = arg.type_info
Expand Down Expand Up @@ -196,7 +196,7 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_type = arg.type_info
arg_name = to_identifier(arg.name)
Expand All @@ -210,7 +210,7 @@ module Generator
end
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_name = arg.name
var = "lib_#{to_identifier(arg_name)}"
Expand All @@ -230,7 +230,7 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg

io << to_identifier(arg.name) << " = "
Expand All @@ -243,7 +243,7 @@ module Generator
end
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
end

private def arg_used_in_return_type?(method, arg) : Bool
Expand All @@ -262,12 +262,12 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
io << to_identifier(arg.name) << "=" << to_crystal_type(arg.type_info) << ".new"
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
end
end

Expand All @@ -281,7 +281,7 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_type = strategy.arg_type
type = to_crystal_type(arg_type)
Expand All @@ -300,7 +300,7 @@ module Generator
io << "end\n"
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_type = strategy.arg_type
type = to_crystal_type(arg_type)
Expand All @@ -326,15 +326,15 @@ module Generator
end
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
obj = arg.type_info.interface.as(RegisteredTypeInfo)

var = to_identifier(arg.name)
io << "GICrystal.ref(" << var << ")\n"
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
end
end

Expand All @@ -349,10 +349,10 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_name = to_identifier(arg.name)
namespace = to_type_name(strategy.method.namespace.name)
Expand All @@ -364,28 +364,35 @@ module Generator

struct BuiltInTypeArgPlan < ArgPlan
def match?(strategy : ArgStrategy, direction : ArgStrategy::Direction) : Bool
return false if direction.crystal_to_c?
return false if strategy.remove_from_declaration?

arg_type = strategy.arg.type_info
return false if handmade_type?(arg_type)
type_info = strategy.arg.type_info
return false if handmade_type?(type_info)

case arg_type.tag
tag = type_info.tag
return tag.unichar? if direction.crystal_to_c?

case tag
when .interface?, .utf8?, .filename?, .boolean?
true
else
false
end
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_name = to_identifier(arg.name)
type_info = arg.type_info
return unless type_info.tag.unichar?
io << arg_name << '=' << convert_to_lib(arg_name, type_info, :none, arg.nullable?) << LF
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
arg_name = to_identifier(arg.name)
type_info = arg.type_info

arg_name = to_identifier(arg.name)
io << arg_name << '=' << convert_to_crystal("lib_#{arg_name}", type_info, nil, arg.ownership_transfer)
io << " unless lib_" << arg_name << ".null?" if arg.nullable?
io << LF
Expand Down Expand Up @@ -414,7 +421,7 @@ module Generator
true
end

def generate_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_crystal_to_c_implementation(io : IO, strategy : ArgStrategy) : Nil
arg = strategy.arg
type_info = arg.type_info
callback = type_info.interface.as(CallbackInfo)
Expand All @@ -436,7 +443,7 @@ module Generator
io << "end\n"
end

def generate_lib_implementation(io : IO, strategy : ArgStrategy) : Nil
def generate_c_to_crystal_implementation(io : IO, strategy : ArgStrategy) : Nil
end
end
end
8 changes: 6 additions & 2 deletions src/generator/helpers.cr
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ module Generator::Helpers
end
when .boolean?
"GICrystal.to_c_bool(#{var})"
when .unichar?
"#{var}.ord.to_u32"
when .interface?
iface = type.interface.not_nil!
if iface.is_a?(EnumInfo)
Expand Down Expand Up @@ -244,7 +246,7 @@ module Generator::Helpers
when .g_list? then "GLib::List"
when .gs_list? then "GLib::SList"
when .g_hash? then "Void"
when .unichar? then "UInt32"
when .unichar? then "Char"
when .error? then "GLib::Error"
else
raise Error.new("Unknown Crystal representation for #{tag}")
Expand Down Expand Up @@ -311,7 +313,7 @@ module Generator::Helpers
case tag
when .boolean?
"GICrystal.to_bool(#{var})"
when .int8?, .u_int8?, .int16?, .u_int16?, .int32?, .u_int32?, .int64?, .u_int64?, .float?, .double?, .unichar?, .gtype?
when .int8?, .u_int8?, .int16?, .u_int16?, .int32?, .u_int32?, .int64?, .u_int64?, .float?, .double?, .gtype?
var
when .utf8?, .filename?
expr = if transfer.full?
Expand All @@ -320,6 +322,8 @@ module Generator::Helpers
"::String.new(#{var})"
end
tag.filename? ? "::Path.new(#{expr})" : expr
when .unichar?
"#{var}.chr"
when .interface?
iface = type.interface.not_nil!
convert_to_crystal(var, iface, args, transfer)
Expand Down

0 comments on commit e20a45a

Please sign in to comment.