Skip to content

Commit

Permalink
Implement docstrings
Browse files Browse the repository at this point in the history
Signed-off-by: Kristupas Antanavičius <[email protected]>
  • Loading branch information
arg0d committed Feb 9, 2024
1 parent a2d2500 commit e58c4cf
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 12 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bindgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ camino = "1.0.8"
fs-err = "2.7.0"
paste = "1.0"
serde_json = "1.0.0"
textwrap = "0.16"
8 changes: 8 additions & 0 deletions bindgen/src/gen_go/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,14 @@ pub mod filters {
pub fn enum_variant_name(nm: &str) -> Result<String, askama::Error> {
Ok(oracle().enum_variant_name(nm))
}

/// Get the idiomatic C# rendering of docstring
pub fn docstring(docstring: &str, tabs: &i32) -> Result<String, askama::Error> {
let docstring = textwrap::indent(&textwrap::dedent(docstring), "// ");

let tabs = usize::try_from(*tabs).unwrap_or_default();
Ok(textwrap::indent(&docstring, &"\t".repeat(tabs)))
}
}

/// Renders Go helper code for all types
Expand Down
3 changes: 2 additions & 1 deletion bindgen/templates/CallbackInterfaceTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
{% if self.include_once_check("CallbackInterfaceRuntime.go") %}{% include "CallbackInterfaceRuntime.go" %}{% endif %}
{{- self.add_import("sync") }}

// Declaration and FfiConverters for {{ type_name }} Callback Interface
{%- call go::docstring(cbi, 0) %}
type {{ type_name }} interface {
{% for meth in cbi.methods() -%}
{%- call go::docstring(meth, 1) %}
{{ meth.name()|fn_name }}({% call go::arg_list_decl(meth) %}) {% call go::return_type_decl_cb(meth) %}
{% endfor %}
}
Expand Down
4 changes: 4 additions & 0 deletions bindgen/templates/EnumTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
{% let e = ci.get_enum_definition(name).expect("missing enum") -%}
{%- if e.is_flat() -%}

{%- call go::docstring(e, 0) %}
type {{ type_name }} uint

const (
{%- for variant in e.variants() %}
{%- call go::docstring(variant, 1) %}
{{ type_name }}{{ variant.name()|enum_variant_name }} {{ type_name }} = {{ loop.index }}
{%- endfor %}
)
{%- else %}

{%- call go::docstring(e, 0) %}
type {{ type_name }} interface {
Destroy()
}

{%- for variant in e.variants() %}
{%- call go::docstring(variant, 0) %}
type {{ type_name }}{{ variant.name()|class_name }} struct {
{%- for field in variant.fields() %}
{{ field.name()|field_name }} {{ field|type_name}}
Expand Down
3 changes: 3 additions & 0 deletions bindgen/templates/ErrorTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

{%- call go::docstring(e, 0) %}
type {{ type_name|class_name }} struct {
err error
}
Expand All @@ -23,6 +24,7 @@ var Err{{ variant_class_name }} = fmt.Errorf("{{ variant_class_name }}")
// Variant structs
{%- for variant in e.variants() %}
{%- let variant_class_name = (type_name.clone() + variant.name())|class_name %}
{%- call go::docstring(variant, 0) %}
type {{ variant_class_name }} struct {
{%- if e.is_flat() %}
message string
Expand All @@ -33,6 +35,7 @@ type {{ variant_class_name }} struct {
{%- endif %}
}

{%- call go::docstring(variant, 0) %}
func New{{ variant_class_name }}(
{%- if !e.is_flat() %}
{%- for field in variant.fields() %}
Expand Down
4 changes: 4 additions & 0 deletions bindgen/templates/ObjectTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,29 @@
{%- let obj_name = obj.name()|class_name %}
{%- if self.include_once_check("ObjectRuntime.go") %}{% include "ObjectRuntime.go" %}{% endif %}

{%- call go::docstring(obj, 0) %}
type {{ obj_name }} struct {
ffiObject FfiObject
}

{%- match obj.primary_constructor() %}
{%- when Some with (cons) %}
{%- call go::docstring(cons, 0) %}
func New{{ obj_name }}({% call go::arg_list_decl(cons) -%}) {% call go::return_type_decl(cons) %} {
{% call go::ffi_call_binding(func, "") %}
}
{%- when None %}
{%- endmatch %}

{% for cons in obj.alternate_constructors() -%}
{%- call go::docstring(cons, 0) %}
func {{ obj_name }}{{ cons.name()|fn_name }}({% call go::arg_list_decl(cons) %}) {% call go::return_type_decl(cons) %} {
{% call go::ffi_call_binding(func, "") %}
}
{% endfor %}

{% for func in obj.methods() -%}
{%- call go::docstring(func, 0) %}
func (_self {{ type_name }}){{ func.name()|fn_name }}({%- call go::arg_list_decl(func) -%}) {% call go::return_type_decl(func) %} {
_pointer := _self.ffiObject.incrementPointer("{{ type_name }}")
defer _self.ffiObject.decrementPointer()
Expand Down
2 changes: 2 additions & 0 deletions bindgen/templates/RecordTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

{%- let rec = ci.get_record_definition(name).expect("missing record") %}

{%- call go::docstring(rec, 0) %}
type {{ type_name }} struct {
{%- for field in rec.fields() %}
{%- call go::docstring(field, 1) %}
{{ field.name()|field_name }} {{ field|type_name -}}
{%- endfor %}
}
Expand Down
2 changes: 2 additions & 0 deletions bindgen/templates/TopLevelFunctionTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

{%- if func.is_async() %}
{%- call go::docstring(func, 0) %}
func {{ func.name()|fn_name}}({%- call go::arg_list_decl(func) -%}) {% call go::return_type_decl(func) %} {
{% call go::async_ffi_call_binding(func, "") %}
}
{%- else %}
{%- call go::docstring(func, 0) %}
func {{ func.name()|fn_name}}({%- call go::arg_list_decl(func) -%}) {% call go::return_type_decl(func) %} {
{% call go::ffi_call_binding(func, "") %}
}
Expand Down
8 changes: 7 additions & 1 deletion bindgen/templates/macros.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,10 @@ RustBufferFromExternal({{ arg|lower_fn }}({{ arg.name()|var_name }}))
{%- endmatch -%}
{%- endmacro -%}


{%- macro docstring(defn, indent_tabs) %}
{%- match defn.docstring() %}
{%- when Some(docstring) %}
{{ docstring|docstring(indent_tabs) }}
{%- else %}
{%- endmatch %}
{%- endmacro %}
1 change: 1 addition & 0 deletions bindgen/templates/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

{%- call go::docstring(ci.namespace_definition(), 0) %}
package {{ ci.namespace() }}

// #include <{{ config.header_filename() }}>
Expand Down
6 changes: 3 additions & 3 deletions binding_tests/callbacks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestCallbackRegistrationIsNotAffectedByGC(t *testing.T) {
func TestCallbackReferenceIsDropped(t *testing.T) {
telephone := callbacks.NewTelephone()
dropped := false
done := make(chan struct{})
done := make(chan struct{})
func() {
callback := &OnCallAnswerImpl{}
runtime.SetFinalizer(callback, func(cb *OnCallAnswerImpl) {
Expand All @@ -71,9 +71,9 @@ func TestCallbackReferenceIsDropped(t *testing.T) {
runtime.GC()
// runtime.GC() is not a fully blocking call
select {
case <- time.After(time.Millisecond * 100):
case <-time.After(time.Millisecond * 100):
panic("timed out")
case <- done:
case <-done:
assert.Equal(t, true, dropped)
}
}
4 changes: 2 additions & 2 deletions binding_tests/custom_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"net/url"
"testing"

"github.com/NordSecurity/uniffi-bindgen-go/binding_tests/generated/custom_types"
"github.com/NordSecurity/uniffi-bindgen-go/binding_tests/generated/custom_types"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
)

func unwrap[T any](value T, err error) T {
Expand Down
93 changes: 93 additions & 0 deletions binding_tests/docstring_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package binding_tests

import (
"testing"

docstrings "github.com/NordSecurity/uniffi-bindgen-go/binding_tests/generated/uniffi_docstring"

"fmt"
"github.com/stretchr/testify/assert"
"io"
"os"
"regexp"
"strings"
)

type ExampleCallback struct{}

func (_ ExampleCallback) Test() {
}

// Make sure symbols are not accidentally commented out by docstrings
func TestSymbolsWithDocstringsExist(t *testing.T) {
docstrings.Test()

_ = docstrings.EnumTestOne
_ = docstrings.EnumTestTwo

_ = docstrings.AssociatedEnumTestTest{0}
_ = docstrings.AssociatedEnumTestTest2{0}

_ = docstrings.ErrErrorTestOne
_ = docstrings.ErrErrorTestTwo

_ = docstrings.NewAssociatedErrorTestTest(0)
_ = docstrings.NewAssociatedErrorTestTest2(0)

obj := docstrings.NewObjectTest()
obj = docstrings.ObjectTestNewAlternate()
obj.Test()

record := docstrings.RecordTest{0}
_ = record.Test

var callback docstrings.CallbackTest
callback = ExampleCallback{}
callback.Test()
}

func TestDocstringsAppearInBindings(t *testing.T) {
bindingsContent := readDocstringBindingsFile(t)
expectedDocstrings := getExpectedDocstrings(t)

var missingDocstrings []string

for _, docstring := range expectedDocstrings {
if !strings.Contains(bindingsContent, docstring) {
missingDocstrings = append(missingDocstrings, docstring)
}
}

assert.Empty(t, missingDocstrings)
}

func readDocstringBindingsFile(t *testing.T) string {
cwd, err := os.Getwd()
assert.NoError(t, err)

file, err := os.Open(fmt.Sprintf("%s/generated/uniffi_docstring/uniffi_docstring.go", cwd))
assert.NoError(t, err)
defer file.Close()

bytes, err := io.ReadAll(file)
assert.NoError(t, err)

return string(bytes)
}

func getExpectedDocstrings(t *testing.T) []string {
cwd, err := os.Getwd()
assert.NoError(t, err)

file, err := os.Open(fmt.Sprintf("%s/../3rd-party/uniffi-rs/fixtures/docstring/tests/test_generated_bindings.rs", cwd))
assert.NoError(t, err)
defer file.Close()

bytes, err := io.ReadAll(file)
assert.NoError(t, err)

re, err := regexp.Compile(`<docstring-.*>`)
assert.NoError(t, err)

return re.FindAllString(string(bytes), -1)
}
6 changes: 3 additions & 3 deletions binding_tests/fixture_callbacks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ func (getters) GetList(v []int32, arg2 bool) ([]int32, *fixture_callbacks.Simple
func (getters) GetNothing(v string) *fixture_callbacks.SimpleError {
if v == "bad-argument" {
return fixture_callbacks.NewSimpleErrorBadArgument()
}
if v == "unexpected-error" {
}
if v == "unexpected-error" {
return fixture_callbacks.NewSimpleErrorUnexpectedError()
}
}
return nil
}

Expand Down
3 changes: 1 addition & 2 deletions fixtures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ uniffi-example-todolist = { path = "../3rd-party/uniffi-rs/examples/todolist" }
# Fixtures
uniffi-fixture-callbacks = { path = "../3rd-party/uniffi-rs/fixtures/callbacks" }
uniffi-fixture-coverall = { path = "../3rd-party/uniffi-rs/fixtures/coverall" }
# ext types
uniffi-fixture-docstring = { path = "../3rd-party/uniffi-rs/fixtures/docstring" }
uniffi-fixture-ext-types = { path = "../3rd-party/uniffi-rs/fixtures/ext-types/lib" }
uniffi-fixture-ext-types-proc-macro = { path = "../3rd-party/uniffi-rs/fixtures/ext-types/proc-macro-lib" }
uniffi-fixture-ext-types-lib-one = { path = "../3rd-party/uniffi-rs/fixtures/ext-types/uniffi-one" }
uniffi-fixture-ext-types-guid = { path = "../3rd-party/uniffi-rs/fixtures/ext-types/guid" }

uniffi-fixture-foreign-executor = { path = "../3rd-party/uniffi-rs/fixtures/foreign-executor" }
uniffi-fixture-futures = { path = "../3rd-party/uniffi-rs/fixtures/futures" }
uniffi-fixture-large-enum = { package = "large-enum", path = "../3rd-party/uniffi-rs/fixtures/large-enum" }
Expand Down
1 change: 1 addition & 0 deletions fixtures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod uniffi_fixtures {

// Fixtures

uniffi_fixture_docstring::uniffi_reexport_scaffolding!();
uniffi_fixture_callbacks::uniffi_reexport_scaffolding!();
uniffi_chronological::uniffi_reexport_scaffolding!();
uniffi_coverall::uniffi_reexport_scaffolding!();
Expand Down

0 comments on commit e58c4cf

Please sign in to comment.