hugopl / gi-crystal

Tool to generate Crystal bindings for gobject-based libraries (i.e. GTK)
BSD 3-Clause "New" or "Revised" License
45 stars 3 forks source link

syntax error generating bindings? #84

Closed elder-n00b closed 1 year ago

elder-n00b commented 1 year ago

Very first time I try to use this, I may well be doing something wrong.

fish❯ crystal init app cr_gtk4
    create  /.mnt/data/experiments/cr_gtk4/.gitignore
    create  /.mnt/data/experiments/cr_gtk4/.editorconfig
    create  /.mnt/data/experiments/cr_gtk4/LICENSE
    create  /.mnt/data/experiments/cr_gtk4/README.md
    create  /.mnt/data/experiments/cr_gtk4/shard.yml
    create  /.mnt/data/experiments/cr_gtk4/src/cr_gtk4.cr
    create  /.mnt/data/experiments/cr_gtk4/spec/spec_helper.cr
    create  /.mnt/data/experiments/cr_gtk4/spec/cr_gtk4_spec.cr
Initialized empty Git repository in /.mnt/data/experiments/cr_gtk4/.git/

...

fish❯ cat shard.yml
name: cr_gtk4
version: 0.1.0

authors:
  - your-name-here <your-email-here>

targets:
  cr_gtk4:
    main: src/cr_gtk4.cr

dependencies:
  gtk4:
    github: hugopl/gtk4.cr

crystal: 1.7.3

license: MIT
fish❯ shards install
Resolving dependencies
Fetching https://github.com/hugopl/gtk4.cr.git
Fetching https://github.com/hugopl/gi-crystal.git
Fetching https://github.com/hugopl/version_from_shard.git
Installing version_from_shard (1.2.5)
Installing gi-crystal (0.14.0)
Postinstall of gi-crystal: shards build
Installing gtk4 (0.12.0)
Writing shard.lock
fish❯ ./bin/gi-crystal
info - Starting at 2023-03-30 11:39:02 +02:00, project dir: /.mnt/data/experiments/cr_gtk4
info - Generating bindings at /.mnt/data/experiments/cr_gtk4/lib/gi-crystal/src/auto
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gi-crystal/src/bindings/g_object/binding.yml
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gi-crystal/src/bindings/g_lib/binding.yml
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gtk4/src/bindings/gio/binding.yml
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gtk4/src/bindings/harfbuzz/binding.yml
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gtk4/src/bindings/gsk/binding.yml
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gtk4/src/bindings/gtk/binding.yml
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gtk4/src/bindings/gdk/binding.yml
info - Using binding config at /.mnt/data/experiments/cr_gtk4/lib/gtk4/src/bindings/pango/binding.yml
warn - g_cancellable_connect - Callback without user_data!
warn - Gio::ActionEntry padding field - Unknown conversion to crystal for fixed size array.
warn - Gio::DBusInterfaceVTable padding field - Unknown conversion to crystal for fixed size array.
warn - Gio::DBusSubtreeVTable padding field - Unknown conversion to crystal for fixed size array.
info - HarfBuzz - No binding config found for freetype2-2.0.
warn - HarfBuzz - Interface constant not supported.
info - Gsk - No binding config found for Graphene-1.0.
warn - gsk_border_node_get_widths - Unknown conversion to crystal for fixed size array.
info - gsk_render_node_draw - No binding config found for cairo-1.0.
info - Gdk - No binding config found for PangoCairo-1.0.
info - Gdk - No binding config found for GdkPixbuf-2.0.
warn - Gdk - SeatCapabilities::All (0xf) doesn't have all possible bits set (0x1f).
warn - Gdk::TimeCoord axes field - Unknown conversion to crystal for fixed size array.
info - GdkPixbuf - No binding config found for GModule-2.0.
warn - gdk_pixbuf_get_options - Unknown conversion to crystal for GHash
warn - Boxed not working for enums
warn - Gtk::BuildableParser padding field - Unknown conversion to crystal for fixed size array.
syntax error in './harf_buzz-0.0/harf_buzz.cr:3371:15': can't use variable name 'unicodes' inside assignment to variable 'unicodes'
fatal - Error formating generated files at '/.mnt/data/experiments/cr_gtk4/lib/gi-crystal/src/auto'.

The syntax error code is this (in ./lib/gi-crystal/src/auto/harf_buzz-0.0/harf_buzz.cr):

3361   │ def self.face_collect_nominal_glyph_mapping(face : HarfBuzz::FaceT,) : HarfBuzz::MapT
3362   │   # hb_face_collect_nominal_glyph_mapping: (None)
3363   │ # @face:
3364   │ # @mapping: (out) (caller-allocates)
3365   │ # @unicodes: (out) (nullable) (caller-allocates)
3366   │ # Returns: (transfer none)
3367   │
3368   │
3369   │   # Generator::CallerAllocatesPlan
3370   │ mapping=HarfBuzz::MapT.new# Generator::NullableArrayPlan
3371   │ unicodes = if unicodes.nil?
3372   │ Void.null
3373   │ else
3374   │ unicodes.to_unsafe
3375   │ end
3376   │ # Generator::CallerAllocatesPlan
3377   │ unicodes=HarfBuzz::SetT.new
3378   │   # C call
3379   │   LibHarfBuzz.hb_face_collect_nominal_glyph_mapping(face, mapping, unicodes)
3380   │
3381   │
3382   │
3383   │   # Return value handling
3384   │
3385   │   mapping
3386   │
3387   │ end

but it looks correct to me, and I could not reproduce the syntax error with similar code by itself. Let me know if I should provide more info or do some tests, it's all a bit over my head but I want this to work and I have time on my hands.

edit: looks like it may be related to #53

BlobCodes commented 1 year ago

The issue in the generated code is that the variable unicodes uses itself during the initial definition:

# variable a does not exist yet
a = if a
  1
end

The underlying issue is that gi-crystal does not really support (out) arguments.

The function face_collect_nominal_glyph_mapping actually wants three arguments face, mapping and unicodes. But the last two arguments are (out) arguments. That means that the arguments should be pointers to variables in which the resulting objects will be stores. In the case of unicodes, you can even pass a null pointer to indicate that you do not want this object.

All this is quite complicated and not yet mapped to crystal world. So this issue probably won't be solved soon.

elder-n00b commented 1 year ago

Well then, for now I put hb_face_collect_nominal_glyph_mapping under lib_ignore in ./lib/gtk4/src/bindings/harfbuzz/binding.yml, that works around the error.

In case I want to try something about it, I start looking in ./src/generator/arg_strategy.cr and method_gen.cr right?

hugopl commented 1 year ago

BTW I noticed that this function is already ignored in https://github.com/hugopl/harfbuzz.cr/blob/main/src/bindings/harfbuzz/binding.yml so it's already fixed in master branch.

I just need to do a release then 😅

hugopl commented 1 year ago

And yes, it's a duplicate of https://github.com/hugopl/gi-crystal/issues/53.

Anyway, thanks for trying the bindings and report the issue.