Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate typescript definitions & documentation for common GIR libraries #24

Open
romgrk opened this issue Jun 15, 2018 · 24 comments
Open

Comments

@romgrk
Copy link
Owner

romgrk commented Jun 15, 2018

No description provided.

@WebReflection
Copy link
Contributor

not sure if it helps, but I have created a GJS based CommonJS env called cgjs which brings in also a gir namespace scanner called cgjs-about

cgjs-about gi.Gio.File

# output as json format
cgjs-about gi.Gio.File --json

It provides all things it understands per each class, including optional arguments. Maybe from that JSON it's easy to create the .ts definition.

@benwaffle
Copy link
Contributor

Looks like there's a couple of projects that already try to do this:

https://github.com/darkoverlordofdata/gir2dts
https://github.com/niagr/GIR2TS
https://github.com/Place1/gir-dts-generator

@romgrk
Copy link
Owner Author

romgrk commented Jun 15, 2018

Looks interesting! Although those are aimed at GJS bindings, which means the naming conventions are not the same as the ones we're using here.
Btw, we also don't have documentation about our naming conventions, so I'll need to review the code to check how we're naming constants, enums, interfaces and some other things. I know in some cases, we're not respecting JS standards, example:

const win = new Gtk.Window({
  window_position: Gtk.WindowPosition.CENTER // should be windowPosition
})

There is already lib/inspect.js, which would be a good starting point. It implements functions for exploring the GIR namespaces through javascript. E.g.:

const inspect = require('./lib/inspect')
const gtk = inspect.parseNamespace('Gtk')
console.log(gtk.init)
// => FunctionInfo { type: 'function', ... }

@WebReflection
Copy link
Contributor

@romgrk the result would be the same, 'cause AFAIK the GIR namespace is the same in GJS or whatever Node.js is doing here, it's standard 🤷‍♂️

in cgjs I convert at runtime through proxies the accessor, mapping that to equivalent snake_case counterpart, for the simple reason every documentation you have about Gtk+ online is pretty much Python Gtk+ based so it's sneak_case, and I wanted cgjs developers to be free to use both.

And yet, this has nothing to do with .ts files generation, right?

@cancerberoSgx
Copy link

cancerberoSgx commented Oct 3, 2019

Hello, I'm interesting on generating TypeScript type definitions using ./lib/inspect . I have very basic knowledge of GTK and I?m not an expert on C++ but have plenty experience with TypeScript and in particular TypeScript type definitions for libraries. My plan is to start with lib/inspect.js, and when I see I can reach somewhere, start researching how to support also the jsdocs. I wonder know if someone is planning / working on this or if the project has any plan to support TS descriptions at all ? Thanks

I see this project https://github.com/niagr/gjs-ts/blob/master/Gtk-3.0.d.ts has what's seems to be a complete type definitions for gtk+3 although I think the member camel/case conventions does not match this project's. It would be easy for build a small program to refactor these names to support this project's API, but I wonder what't the opinion on that take - or if it would be better to build a solution from scratch (that also considers jsdoc descriptions ?)

@romgrk
Copy link
Owner Author

romgrk commented Oct 4, 2019

As far as I know, no one is actively working on generating typedefs at the moment. Having TS descriptions would be SO awesome, I just haven't had enough time to do it myself :) If you want to take the task, you're more than welcome.

lib/inspect.js is a good starting point because I've translated some C++ behaviors in JS (eg C++ and JS). And it makes sense to build from scratch because there are various details that can differ between implementations. Also because if we want to generate correct bindings we need to take in account the overrides.

The naming is handled in lib/index.js, so that part is quite easy to use. It could be imported in lib/inspect.js.

Another thing to be mindful of is that event handlers don't have the self parameter as other GIR implementation have.
Other bindings are usually in the format

widget.on('key-press-event', (self: Gtk.Widget, event: Gdk.EventKey) => {...}) 
// where widget === self

in node-gtk, the self parameter is elided:

widget.on('key-press-event', (event: Gdk.EventKey) => {...})

If you open a PR, I can try to list all the gotchas that I can think of.

@cancerberoSgx
Copy link

cancerberoSgx commented Oct 4, 2019

Working on it and this is more or less my plan :

  • First: add typings for node-gtk API itself . Add simple usage snippets using import instead require() .Question: seems like the intention is _GIRepository and _c to be private right ? Do you mind if I nevertheless document and export _GIRepository as an internal namespace making explicitly that is private @internal - since some utilities there are pretty useful ? Or should users figure out a way of implementing equivalent code with Gobject and never use those ? Or do you think type names/information regarding signatures can be extracted with a public API i'm missing ?

types generation

  • My plan is 0% implementation 100% types - with the exception of the generation tooling and some tests.
  • For types generation, I've started with inspect.js, and have something working - but still need to understand a couple of GObject-instrospection concepts (in particular the semantic difference between Method and Field and if they are related with other node kinds like Properties, ad vfuncs and prerequisistes but that's my homework) -
  • first objective is being able to generate all types/names in a library - `generate({target: [{library: 'Gtk', version: '3.0', dest: 'types/gtk+-3.0.d.ts'}]}) - then I can focus on a CLI or refining and generate only given names and its dependencies or on separate files, etc.
    • for inter-libray type dependencies will use /// triple-slash imports assuming they are all in the same folder.We can plan then the best distribution approach
    • for C types utf8, gboolean, char, int, gfloat, I will probably create type alias for them in a separate file (?) Or do you think it's better to reference / translate just to JS types automatically if applies?
    • for events/signals I plan to use the general approach, just like @types/node EventEmitter - overloading on() method by name using literal string types - not having self makes it easy and more familiar to node.js users - I think gobject-instrospection will give me all the info I need between event name and listener signatures
  • What I would also love to do it to autogenerate jsdoc descriptions . I was able to extract most of them from https://valadoc.org/ by downloading/extracting .zip and using cheerio (jquery for node) to extract the description section. It was simple but if we go this way I probably need to use some tools to formatting so markdown indentation is correct. Do you have some other ideas regarding this? Would be perfect just being able to parse/extract from .h but I'm not really a C++ expert... perhaps gtk-doc ?
  • Finally I would like to write some TypeScript tests, just to types matches OK and I would like them to run not only compile. I'm assuming I could add a couple along existing tests?

Will keep you updated, thanks for the project, btw: do you know / have a working gdk-cairo test ? with time would be awesome to build a playground app with an editor on one side and the running app on the other and a list of examples - just compile and eval() the code on edit to reload the app - That should be an awesome gtk/cairo playground not so easy to implement with C I think.

Thanks

@dhonx
Copy link
Contributor

dhonx commented Oct 4, 2019

@cancerberoSgx Actually I want to do it ... but I'm not very good with typescript. It's great if you can help with that. I'm ready to help if you need. ✌️

@dhonx
Copy link
Contributor

dhonx commented Oct 4, 2019

@cancerberoSgx dont forget to join us on discord for discussion. 🙂

@benwaffle
Copy link
Contributor

@cancerberoSgx gir has the docs/descriptions

@cancerberoSgx
Copy link

Hi im sorry but currenlty my desktop is mac which is not my favorite technology and until a moment everything was fine but now listLibs() is showing gtk+ version 2.0 (not 3.0) and is failing

  [ 'Atk-1.0', 'Atk', '1.0' ],
  [ 'DBus-1.0', 'DBus', '1.0' ],
  [ 'DBusGLib-1.0', 'DBusGLib', '1.0' ],
  [ 'GIRepository-2.0', 'GIRepository', '2.0' ],
  [ 'GL-1.0', 'GL', '1.0' ],
  [ 'GLib-2.0', 'GLib', '2.0' ],
  [ 'GModule-2.0', 'GModule', '2.0' ],
  [ 'GObject-2.0', 'GObject', '2.0' ],
  [ 'Gdk-2.0', 'Gdk', '2.0' ],
  [ 'GdkPixbuf-2.0', 'GdkPixbuf', '2.0' ],
  [ 'GdkX11-2.0', 'GdkX11', '2.0' ],
  [ 'Gio-2.0', 'Gio', '2.0' ],
  [ 'Gtk-2.0', 'Gtk', '2.0' ],
  [ 'Pango-1.0', 'Pango', '1.0' ],
  [ 'PangoCairo-1.0', 'PangoCairo', '1.0' ],
  [ 'PangoFT2-1.0', 'PangoFT2', '1.0' ],
  [ 'PangoXft-1.0', 'PangoXft', '1.0' ],
  [ 'cairo-1.0', 'cairo', '1.0' ],
  [ 'fontconfig-2.0', 'fontconfig', '2.0' ],
  [ 'freetype2-2.0', 'freetype2', '2.0' ],
  [ 'libxml2-2.0', 'libxml2', '2.0' ],
  [ 'win32-1.0', 'win32', '1.0' ],
  [ 'xfixes-4.0', 'xfixes', '4.0' ],
  [ 'xft-2.0', 'xft', '2.0' ],
  [ 'xlib-2.0', 'xlib', '2.0' ],
  [ 'xrandr-1.3', 'xrandr', '1.3' ]

I'm using this brew thing, and tried to remove everything and installing it again, but no luck - restarting.... Perhaps somebody knows some trick ? will try again but in the meanwhile perhaps somebody had the same trouble ?
thanks

@cancerberoSgx
Copy link

@benwaffle oh, nice to know - I read about that files(?) will research how to generated from the sources - will try with an old ones I imagine are easy to generate from latest sources right ? thanks! good tip

@cancerberoSgx
Copy link

@benwaffle form your repo https://github.com/nemequ/vala-girs/tree/master/gir-1.0 !! sorry I'm kind of rusty in native desktop technologies -... thanks

@cancerberoSgx
Copy link

cancerberoSgx commented Oct 4, 2019

@benwaffle Thanks for this - accessing this data from files will make my job much more easy. I'm assuming the rest of the metadata (not only descriptions) will comply with this project (with the exception of mentioned overrides signal syntax) ?

Congratulations , you saved my day - Don't know why I didn't see these technologies before - Nice to see an initiative building on top of formal object descriptions and documentation! - https://valadoc.org/ and the value there is amazing - all those technologies ruled with the same ring... one little suggestion, from a total outsider - adding a link to download the .gir file that sourced each project could make sense. Congrats and thanks again!

@romgrk
Copy link
Owner Author

romgrk commented Oct 4, 2019

Lots of questions and I don't have much time for personal projects today ^^

I'll start with these two:

  • about _GIRepository and `c: this is private and I don't wish it to be documented for external projects. We (you included) can use it as much as you want but I don't see any external use-case for it.
  • about C types: these are translated by node-gtk into JS types, the translation rules are the code in src/value.cc: here and here.

Do not hesitate if you have questions about GObject concepts. I've found it a bit hard to understand them sometimes so it helps to have someone who can explain them.

@JumpLink
Copy link
Contributor

Here is a fork from me of ts-for-gjs to add type definition generation support for node-gtk (including two examples).

Btw here is also an interesting conversation about type definitions for node-gtk: clayrisser/ts-gir#1

@JumpLink
Copy link
Contributor

JumpLink commented Apr 7, 2020

The ts-for-gjs fork with initial support for node-gtk is merged (including examples) now, help for improvement is very welcome

@romgrk
Copy link
Owner Author

romgrk commented Apr 9, 2020

I've found a few issues that I've listed here. Thanks for your contribution!

@padcom
Copy link

padcom commented Jun 14, 2022

Guys, anything happening it that department?

@JumpLink
Copy link
Contributor

@padcom You can use ts-for-gir which has already very good results

@romgrk
Copy link
Owner Author

romgrk commented Jun 14, 2022

Nothing new here, ts-for-gir has a node-gtk mode. There were some issues but I think it was at least somewhat usable.

@JumpLink
Copy link
Contributor

JumpLink commented Jun 19, 2022

There is quite news there, because there were a few code contributions to further improve the types for node-gtk on ts-for-gir. So please test them again and give me feedback.

It is important not to use the package from NPM as this is not from us and is unfortunately heavily deprecated (but I will be releasing it officially on NPM under a different name soon), more about how to use ts-for-gjs in die README.

Bug reports and other contributions are welcome. Currently I'm working on a big pull request gjsify/ts-for-gir#63 where I'm working on introducing real inheritance in the types. This is already working very well but I still need to fix some type conflicts. I would also be happy about contributions to this PR because it's not easy to fix this conflicts and maybe a new way of thinking will also help.

The master branch currently does not use inheritance and simply copies all inherited methods, this has the advantage that it avoids the type conflicts, but has the disadvantage that the generated types become very large.

By the way, I'm also working on another project in parallel to generate API documentation from this generated Typescript types: https://node-gtk-docs.gjsify.org/

As soon as my PR is finished I will improve the generated documentation as well.

@JumpLink
Copy link
Contributor

Okay now real inheritance and implementations are merged to ts-for-gir, I would be very happy if someone would test the types for node-gtk again :)

@romgrk
Copy link
Owner Author

romgrk commented Jun 30, 2022

I did a quick overview, here are a few notes:

  1. GObject classes have $gtype, but node-gtk has __gtype__: BigInt

  2. There are some events missing, e.g. on Gtk 3.0

    • DrawingArea#on('draw', (context) => { ... }), context is typed as any
    • Window#on(...) doesn't list events show, destroy, delete-event (which are kinda important)
  3. We've added support for virtual functions, they're also kinda important in Gtk-4.0 to create custom widgets. They're exposed without a prefix, the best test is the gtk_widget_measure example along with docs for gtk_widget_measure.
    Note that the return value of virtual functions is similar to that of native functions, here is the logic:

    • Sum all of the out arguments, plus 1 if the return value is non-void
    • If the sum is equal to 1, the JS-retval is the simply the C-retval or the C-out-argument that needs to be returned
    • If the sum is more than 1, the JS-retval is an array that contains first the C-retval, if any, then the C-out-args in order of declaration.

That's it for the issues, I also wanted to say great work for the rest! It's really nice to be able to just switch the extension to .ts and get full autocompletion. It makes it much easier to discover the APIs.

Screenshot from 2022-06-30 01-41-24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants