Giter Site home page Giter Site logo

rhx / gir2swift Goto Github PK

View Code? Open in Web Editor NEW
24.0 24.0 10.0 1.53 MB

A simple GIR parser in Swift for creating Swift types for a .gir file

Home Page: https://rhx.github.io/gir2swift/

License: BSD 2-Clause "Simplified" License

Swift 95.24% XSLT 1.66% Shell 3.11%

gir2swift's People

Contributors

carllusty avatar kabiroberai avatar kiwijane3 avatar mikolasstuchlik avatar rhx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

gir2swift's Issues

Compilation failure with Swift 4

I was trying to build some of your projects (SwiftGtk, SwiftHelloGtkBuilder) and they all fail with the latest Swift:

Swift version 4.0 (swift-4.0-RELEASE)
Target: x86_64-unknown-linux-gnu

Running Ubuntu 16.04 64 bits:

Linux 4.10.0-35-generic #39~16.04.1-Ubuntu SMP Wed Sep 13 09:02:42 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

The error can be reproduced just by cloning any of the repos, cd'ing into them, and then running the enclosed build.sh. I have installed all the library requirements. The error message is in the file attached: error.txt

The compilations of all the aforementioned projects stop when the gir2swift project is building, this is why I post this bug here.

Use element-type for lists/hash tables

From what I've been able to figure out, it appears that GList/GSList are exposed in way that is similar to C, but it doesn't transform the type into a Swift equivalent. If I have a return type with element-type annotation:

/**
 * example_get_list:
 *
 * Returns a list of strings.
 *
 * Returns: (element-type utf8) (transfer container): A list of strings.
 */                                                                             
GList *
example_get_list(void) {
    GList *list = NULL;

    list = g_list_append(list, "foo");
    list = g_list_append(list, "bar");
    list = g_list_append(list, "baz");

    return list;
}                           

then in C, I know I can treat that as:

GList *list = example_get_list();
while(list != NULL) {
    const gchar *value = list->data;
    printf("List value: %s\n", value);
    list = list->next;
}
g_list_free(list);

Depending on the mode in the transfer annotation, I would also know whether to free the list only, its contents as well, or none of it.

In Python for example, said list would be converted to a Python list object with strs, hiding the whole linked-list data structure. All of the freeing stuff is also hidden.

With the Swift binding, I think this ends up being handled in a manual (for Swift) way:

import Example
let list = Example.getList()
while list != nil {
    let value = String(validatingUTF8: l_id!.data!.assumingMemoryBound(to: CChar.self))
    print("List value: \(value)")
    l_id = l_id?.next
}
l_ids?.free()

I don't know if doing full conversion like Python is the best choice in Swift, or whether it can be hidden behind some Protocol, but it would be nice to wrap the element types at least.

An example of one of these in GTK is gtk_application_get_windows. In the best case, the binding for this should be a list of Window objects (or at least something that appears that way in a Swift-like way.)

Note, I've only spent about two days investigating how easy it would be to create Swift bindings for a gir library, and don't actually know any Swift outside of that, so I apologize if my explanations of that side of things do not make any sense.

Module.module/Module.preamble not working

Hi, I'm trying to use this project for the elementary OS Granite library, everything seems to be working fine but at the end I get a lot of errors about missing types etc.

I think I have to import the Gtk libraries because Granite depends on those, so I created the Granite-1.0.preamble etc in the root directory of the project, which is also where I use swift build from.

I'm not sure why, but it's not working for me, nothing is added to the generated files, I opened them to check

Everything is in a github repository here

Includes error

Hello.

I am trying to use your library to parse a .gir to Swift, but am having no success. When running swift run I get the following errors:

<module-includes>:1:9: note: in file included from <module-includes>:1: #import "libxml/HTMLparser.h" ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/libxml2/libxml/HTMLparser.h:15:10: error: 'libxml/xmlversion.h' file not found #include <libxml/xmlversion.h> ^ /Users/roadmaps/arrow-apache-arrow-0.13.0/c_glib/gir2swift/.build/checkouts/SwiftLibXML/Sources/SwiftLibXML/XMLAttribute.swift:13:12: error: could not build Objective-C module 'libxml2' import libxml2 ^ <module-includes>:1:9: note: in file included from <module-includes>:1: #import "libxml/HTMLparser.h" ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/libxml2/libxml/HTMLparser.h:15:10: error: 'libxml/xmlversion.h' file not found #include <libxml/xmlversion.h> ^ /Users/roadmaps/arrow-apache-arrow-0.13.0/c_glib/gir2swift/.build/checkouts/SwiftLibXML/Sources/SwiftLibXML/XMLAttribute.swift:13:12: error: could not build Objective-C module 'libxml2' import libxml2 ^ <module-includes>:1:9: note: in file included from <module-includes>:1: #import "libxml/HTMLparser.h" ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/libxml2/libxml/HTMLparser.h:15:10: error: 'libxml/xmlversion.h' file not found #include <libxml/xmlversion.h> ^ /Users/roadmaps/arrow-apache-arrow-0.13.0/c_glib/gir2swift/.build/checkouts/SwiftLibXML/Sources/SwiftLibXML/XMLAttribute.swift:13:12: error: could not build Objective-C module 'libxml2' import libxml2 ^ <module-includes>:1:9: note: in file included from <module-includes>:1: #import "libxml/HTMLparser.h" ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/libxml2/libxml/HTMLparser.h:15:10: error: 'libxml/xmlversion.h' file not found #include <libxml/xmlversion.h> ^ /Users/roadmaps/arrow-apache-arrow-0.13.0/c_glib/gir2swift/.build/checkouts/SwiftLibXML/Sources/SwiftLibXML/XMLAttribute.swift:13:12: error: could not build Objective-C module 'libxml2' import libxml2 ^

Redundant protocol conformance warnings

Currently gir2swift just blindly translates .gir file interface implementations into protocol conformances, leading to redundant conformance warnings, e.g.:

Gtk-3.0-TearoffMenuItem-UIManager.swift:25726:128: warning: redundant conformance constraint 'Self': 'TreeModelProtocol'
public protocol TreeStoreProtocol: GLibObject.ObjectProtocol, BuildableProtocol, TreeDragDestProtocol, TreeDragSourceProtocol, TreeModelProtocol, TreeSortableProtocol {
                                                                                                                               ^
Gtk-3.0-TearoffMenuItem-UIManager.swift:25726:147: note: conformance constraint 'Self': 'TreeModelProtocol' implied here
public protocol TreeStoreProtocol: GLibObject.ObjectProtocol, BuildableProtocol, TreeDragDestProtocol, TreeDragSourceProtocol, TreeModelProtocol, TreeSortableProtocol {

Expanding the `.yaml` manifest capabilities

With introduction of the .yaml manifest, we have the opportunity to reduce the number of gir2swift files in each repository.

I would like to see following files being part of the .yaml manifest:

  • .blacklist
  • .module
  • .override
  • .preamble
  • .verbatim
  • .whitelist

What is your opinion on the issue. Is this desirable, and if so, are there any issues that would need to be solved?

Raspberry Pi 4 CI for the project

Hello,

I have a Raspberry Pi 4 (4GB) model which I use as a CI.
It runs 64-bit Ubuntu 21.04 (or Ubuntu MATE 20.10). The CI services are provided by Jenkins.

I'm willing to make the Raspberry accessible from the Internet and maintain it as a CI for this project. Let me know whether you are interested or not.

I don't mind using any other software for the automation, I just happen to know Jenkins the most. The Github Actions are not recommended for a public repository.

Generated files not building with Swift 5.2

Swift 5.2 was released a few days ago.
Generated Swift sources do not compile anymore.

The following error is thrown a bunch of times:

/Users/lschmierer/Master Thesis/HealthEnclave/HealthEnclaveTerminal/.build/checkouts/
SwiftGObject/Sources/GLibObject/GObject-2.0-ParamSpecBoolean.swift:87:24:
error: overridden method 'init' has generic signature <T where T : ParamSpecBooleanProtocol>
which is incompatible with base method's generic signature <T where T : ParamSpecProtocol>;
expected generic signature to be <T where T : ParamSpecProtocol>
    public convenience init<T: ParamSpecBooleanProtocol>(_ other: T) {
                       ^
/Users/lschmierer/Master Thesis/HealthEnclave/HealthEnclaveTerminal/.build/checkouts/
SwiftGObject/Sources/GLibObject/GObject-2.0-ParamSpec.swift:142:24:
note: overridden declaration is here
    public convenience init<T: ParamSpecProtocol>(_ other: T) {

Tested using the Swift compiler shipped with Xcode 11.4

Advice needed: on the way to remove postprocessing

One major challange for new users and developers of the SwiftGtk project is the wrapper generation itself. The wrapper generation does three major tasks (in cases of both rhx's and mikolasstuchlik's scripts):

  1. a script needs to be able to execute generation at all packages (this is currenly done either by recursive execution or dumping swift package)
  2. a script needs to call gir2swift with correct prerequisities (this is currently done by either hand writing prerequisities, trusting the correctness of Swift package dependencies, but it alco can be done in the process of generation automatically, since .gir contains references to it's prerequisities)
  3. running postprocessing on generated files which eliminates edge-cases and other wrongly generated code.

The third step (postprocessing) is a major component. A lot of work and research was put into developing and maintaining it. At the same time, the postprocessing has a lot of weak spots:

  • the intent is not clear since the postprocessing is not documented, nobody but the person who created a certain correction knows what was the original intention and whether it is even needed
  • the postprocessing is the sole reason for maintaining the scripts at all otherwise we would be able to handle generation by fairly simple script or even gir2swift itself
  • awk and sed are yet another prerequisity for already complicated project a developer already needs to have above average understanding of Swift, C, GLib/GObject, .gir/g-ir, bash, the structure of gir2swift itself, etc.

I would like to integrate the work done by postprocessing into the gir2swift and replace the awk, sed and gir2swift-manifest.sh by one gir2swift-manifest.json file, that would contain all the required information.

I would like to initiate the dicussion about the structure of such json file and I would like to ask following questions.

  • What kinds of postprocessing is being performed? Example: renaming swift types, renaming c types, adding annotations to specific function arguments, removing specified substrings etc...
  • Are the tasks platform dependent? Do we need an expression system? Example: { "platform": "Linux", "distributionContains": "Ubuntu" }, {"pkg-cofig-library": "glib", "until-version": "2.0.0"} etc...
  • Could be the edgecases summarized? For example some .gir files do not use "priv" attribute on private properties, some .gir files fail to fill correct type getter (refer to GirRecord.swift:96) - I would like to handle cases like this in the json files too instead of gir2swift. (This could be fixed by "preprocessing" the XML file)

Discussion: Additional sources of truth for wrapper generation

Abstract

This issue aims to open a discussion about adopting a second source of truth for wrapper generation. The aim of introducing a second source of truth is the elimination of all post-processing. The second source of truth is the C and Swift API itself.

The current state

Currently, the gir2swift generates wrappers based on input files in the Swift wrapper repository (excluding .awk and .sed files) and .gir files located in the filesystem. The input files in the repository are common for all platforms, whereas the .gir files are expected to reflect the API present on a given platform.

Unfortunately, .gir files are not always a correct reflection of the API present on a given platform[1]. Therefore we need postprocessing and other patches that make the generated Swift code compile.

Interacting with the C API

The Clang compiler used as a part of Swift compiler[2] provides a small API called libclang[3]. The libclang may be used to "parse" the C APIs for us, but we would need to mimic the Clang Importer[4]. At the same time, I could not find any such API for the Swift compiler[5].

One of the most important tools of an IDE is to perform semantic analysis of the program written and provide a user with additional information, like suggestions, warnings, and whether the code is correct. For that purpose, the Swift developers provide a tool called sourcekit-lsp[6]. The sourcekit-lsp can read the C and Swift API and provide an IDE with the aforementioned services.

Taking advantage of the sourcekit-lsp

It would be unreasonable to work with the sourcekit-lsp in the same manner as the IDE (i.e., use the JSON RPC to query the LSP daemon for information.) I have focused on the libraries that serve as the source of truth for the LSP daemon itself.

One such library is indexstore-db[7]. The indexstore-db can interpret the output of the Swift compiler (which creates an index during the compilation)[8]. I have been able to modify a SwiftGLib repository and create a demo project, which prints the list of symbols. https://github.com/mikolasstuchlik/GLibISDemo

I was able to tap only to the surface of the information sourcekit-lsp (at this moment, I am only able to get the list of symbols and their kind), but it should be possible to get things like argument types of a function, the fields of a structure, etc.

Incorporating into the gir2swift

Incorporating the indexstore-db itself (or any other tool used by the sourcekit-lsp) into the gir2swift as a dependency may be tricky. The indexstore-db may depend on a specific version of the Swift compiler and is a rather big dependency.

We could also develop the C API reading part of gir2swift in a separate repository (let's call it a c-api-index) that would run before gir2swift. After it's finished, it would store a metadata file containing all the information we would need to verify the validity of a .gir file. Information such as a list of existing symbols and their kind.

Summary

If the proposed tool is implemented, it will effectively replace the post-processing with a pre-processing. However, the promise of having such a tool is that there would be less need for a manual configuration (and thus maintenance). What other features should such a tool have?

[1] https://discord.com/channels/791751777598570606/791751778092711941/870776594329915505
[2] Clang compiler is distributed with the Swift compiler as a part of the Swift toolchain.
[3] https://clang.llvm.org/doxygen/group__CINDEX.html
[4] https://swift.org/swift-compiler/
[5] I have found libswift https://github.com/apple/swift/tree/286d22b2e6e282ef08dc810580c1ea94aac9ab08/libswift but this module represents a part of the Swift compiler written in Swift.
[6] https://github.com/apple/sourcekit-lsp
[7] https://github.com/apple/indexstore-db
[8] Therefore we need to run the compiler before the wrapper generation process even starts.

gir2swift creates duplicate labels for some (template) methods

When compiling SwiftGtk, numerous labels show up as unnecessary duplicates, e.g.:

Gtk-3.0-PadControllerClass-RadioActionClass.swift:1821:53: warning: extraneous duplicate parameter name; 'keyFile' already has an argument label
    @inlinable init<KeyFileT: GLib.KeyFileProtocol>(keyFile keyFile: KeyFileT, groupName: UnsafePointer<gchar>? = nil) throws {
                                                    ^~~~~~~~
                                                    
Gtk-3.0-PadControllerClass-RadioActionClass.swift:1865:68: warning: extraneous duplicate parameter name; 'keyFile' already has an argument label
    @inlinable static func newFrom<KeyFileT: GLib.KeyFileProtocol>(keyFile keyFile: KeyFileT, groupName: UnsafePointer<gchar>? = nil) throws -> PaperSizeRef! {
                                                                   ^~~~~~~~
Gtk-3.0-ScaleAccessible-Table.swift:35495:21: warning: extraneous duplicate parameter name; 'iconName' already has an argument label
    @inlinable init(iconName iconName: UnsafePointer<gchar>!) {
                    ^~~~~~~~~
Gtk-3.0-IMContextSimple-Label.swift:6430:21: warning: extraneous duplicate parameter name; 'iconName' already has an argument label
    @inlinable init(iconName iconName: UnsafePointer<gchar>? = nil, size: GtkIconSize) {
                    ^~~~~~~~~
                    
Gtk-3.0-IMContextSimple-Label.swift:6450:48: warning: extraneous duplicate parameter name; 'iconSet' already has an argument label
    @inlinable init<IconSetT: IconSetProtocol>(iconSet iconSet: IconSetT, size: GtkIconSize) {
                                               ^~~~~~~~

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.