Skip to content

Commit

Permalink
Add nn header and reference for cppcli generator (#128)
Browse files Browse the repository at this point in the history
* fix: cppcli generator nn header and references
* Fixed the missing nn headers in generated code
* Added ref class to solve the issue of syntax
  not found when interfaces depend on each other
* fix: add .bat extension to binary on Windows
* test: add C++/CLI tests for circular dependencies

Also: fix the issue of comparing strings on Windows
  • Loading branch information
FanglinIfolor authored Mar 16, 2022
1 parent 649763f commit 1d5fbcb
Show file tree
Hide file tree
Showing 23 changed files with 670 additions and 37 deletions.
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import sbtassembly.AssemblyPlugin.defaultUniversalScript
ThisBuild / scalaVersion := "2.13.6"
ThisBuild / organization := "com.github.cross-language-cpp"

val binExt = if (System.getProperty("os.name").startsWith("Windows")) ".bat" else ""
lazy val djinni = (project in file("."))
.configs(IntegrationTest)
.settings(
Expand All @@ -14,7 +15,7 @@ lazy val djinni = (project in file("."))
libraryDependencies += "org.yaml" % "snakeyaml" % "1.29",
libraryDependencies += "com.github.scopt" %% "scopt" % "4.0.1",
libraryDependencies += "commons-io" % "commons-io" % "2.11.0",
assembly / assemblyOutputPath := { file("target/bin") / (assembly / assemblyJarName).value },
assembly / assemblyOutputPath := { file("target/bin") / s"${(assembly / assemblyJarName).value}${binExt}" },
assembly / assemblyJarName := s"${name.value}",
assembly / assemblyOption := (assembly / assemblyOption).value.copy(prependShellScript = Some(defaultUniversalScript(shebang = false))),
assembly / test := {}
Expand Down
2 changes: 0 additions & 2 deletions docs/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ You can run the jar like this:
./djinni --help
```

On Windows the file must be renamed to `djinni.bat` to make it executable.

!!! attention

The resulting binary still requires Java to be able to run! [Details on how the self-executing jar works](https://github.com/sbt/sbt-assembly#prepending-a-launch-script).
Expand Down
13 changes: 13 additions & 0 deletions src/it/resources/cppcli_circular_dependent_interface.djinni
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
one_interface = interface +c {
method_taking_another_interface(dep: another_interface);
method_taking_optional_another_interface(dep: optional<another_interface>);
method_returning_another_interface(): another_interface;
method_returning_optional_another_interface(): optional<another_interface>;
}

another_interface = interface +c {
method_taking_one_interface(dep: one_interface);
method_taking_optional_one_interface(dep: optional<one_interface>);
method_returning_one_interface(): one_interface;
method_returning_optional_one_interface(): optional<one_interface>;
}
8 changes: 8 additions & 0 deletions src/it/resources/cppcli_extern_dependent_interface.djinni
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@extern "cpp_interface_dependency.yml"

dependent_interface = interface +c {
method_taking_interface_dependency(dep: interface_dependency);
method_taking_optional_interface_dependency(dep: optional<interface_dependency>);
method_returning_interface_dependency(): interface_dependency;
method_returning_optional_interface_dependency(): optional<interface_dependency>;
}
11 changes: 11 additions & 0 deletions src/it/resources/cppcli_interface_nonnull.djinni
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# interface comment
my_cpp_interface = interface +c {
# method comment
method_returning_nothing(value: i32);
method_returning_some_type(key: string): i32;
const method_changing_nothing(): i32;
static get_version(): i32;

# Interfaces can also have constants
const version: i32 = 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file was generated by Djinni from cppcli_circular_dependent_interface.djinni

#include "AnotherInterface.hpp" // my header
#include "djinni/cppcli/Error.hpp"
#include "djinni/cppcli/Marshal.hpp"
#include "djinni/cppcli/WrapperCache.hpp"
#include "one_interface.hpp"

ref class AnotherInterfaceCppProxy : public AnotherInterface {
using CppType = std::shared_ptr<::AnotherInterface>;
using HandleType = ::djinni::CppProxyCache::Handle<CppType>;
public:
AnotherInterfaceCppProxy(const CppType& cppRef) : _cppRefHandle(new HandleType(cppRef)) {}

void MethodTakingOneInterface(OneInterface^ dep) override {
try {
_cppRefHandle->get()->method_taking_one_interface(::OneInterface::ToCpp(dep));
} DJINNI_TRANSLATE_EXCEPTIONS()
}

void MethodTakingOptionalOneInterface(OneInterface^ dep) override {
try {
_cppRefHandle->get()->method_taking_optional_one_interface(::djinni::Optional<std::optional, ::OneInterface>::ToCpp(dep));
} DJINNI_TRANSLATE_EXCEPTIONS()
}

OneInterface^ MethodReturningOneInterface() override {
try {
auto cs_result = _cppRefHandle->get()->method_returning_one_interface();
return ::OneInterface::FromCpp(cs_result);
} DJINNI_TRANSLATE_EXCEPTIONS()
return nullptr; // Unreachable! (Silencing compiler warnings.)
}

OneInterface^ MethodReturningOptionalOneInterface() override {
try {
auto cs_result = _cppRefHandle->get()->method_returning_optional_one_interface();
return ::djinni::Optional<std::optional, ::OneInterface>::FromCpp(cs_result);
} DJINNI_TRANSLATE_EXCEPTIONS()
return nullptr; // Unreachable! (Silencing compiler warnings.)
}

CppType djinni_private_get_proxied_cpp_object() {
return _cppRefHandle->get();
}

private:
AutoPtr<HandleType> _cppRefHandle;
};

AnotherInterface::CppType AnotherInterface::ToCpp(AnotherInterface::CsType cs)
{
if (!cs) {
return nullptr;
}
return dynamic_cast<AnotherInterfaceCppProxy^>(cs)->djinni_private_get_proxied_cpp_object();
}

AnotherInterface::CsType AnotherInterface::FromCppOpt(const AnotherInterface::CppOptType& cpp)
{
if (!cpp) {
return nullptr;
}
return ::djinni::get_cpp_proxy<AnotherInterfaceCppProxy^>(cpp);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file was generated by Djinni from cppcli_circular_dependent_interface.djinni

#pragma once

#include "../cpp-headers/another_interface.hpp"
#include "OneInterface.hpp"
#include <memory>

ref class OneInterface;

public ref class AnotherInterface abstract {
public:
virtual void MethodTakingOneInterface(OneInterface^ dep) abstract;

virtual void MethodTakingOptionalOneInterface(OneInterface^ dep) abstract;

virtual OneInterface^ MethodReturningOneInterface() abstract;

virtual OneInterface^ MethodReturningOptionalOneInterface() abstract;

internal:
using CppType = std::shared_ptr<::AnotherInterface>;
using CppOptType = std::shared_ptr<::AnotherInterface>;
using CsType = AnotherInterface^;

static CppType ToCpp(CsType cs);
static CsType FromCppOpt(const CppOptType& cpp);
static CsType FromCpp(const CppType& cpp) { return FromCppOpt(cpp); }
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file was generated by Djinni from cppcli_circular_dependent_interface.djinni

#include "OneInterface.hpp" // my header
#include "another_interface.hpp"
#include "djinni/cppcli/Error.hpp"
#include "djinni/cppcli/Marshal.hpp"
#include "djinni/cppcli/WrapperCache.hpp"

ref class OneInterfaceCppProxy : public OneInterface {
using CppType = std::shared_ptr<::OneInterface>;
using HandleType = ::djinni::CppProxyCache::Handle<CppType>;
public:
OneInterfaceCppProxy(const CppType& cppRef) : _cppRefHandle(new HandleType(cppRef)) {}

void MethodTakingAnotherInterface(AnotherInterface^ dep) override {
try {
_cppRefHandle->get()->method_taking_another_interface(::AnotherInterface::ToCpp(dep));
} DJINNI_TRANSLATE_EXCEPTIONS()
}

void MethodTakingOptionalAnotherInterface(AnotherInterface^ dep) override {
try {
_cppRefHandle->get()->method_taking_optional_another_interface(::djinni::Optional<std::optional, ::AnotherInterface>::ToCpp(dep));
} DJINNI_TRANSLATE_EXCEPTIONS()
}

AnotherInterface^ MethodReturningAnotherInterface() override {
try {
auto cs_result = _cppRefHandle->get()->method_returning_another_interface();
return ::AnotherInterface::FromCpp(cs_result);
} DJINNI_TRANSLATE_EXCEPTIONS()
return nullptr; // Unreachable! (Silencing compiler warnings.)
}

AnotherInterface^ MethodReturningOptionalAnotherInterface() override {
try {
auto cs_result = _cppRefHandle->get()->method_returning_optional_another_interface();
return ::djinni::Optional<std::optional, ::AnotherInterface>::FromCpp(cs_result);
} DJINNI_TRANSLATE_EXCEPTIONS()
return nullptr; // Unreachable! (Silencing compiler warnings.)
}

CppType djinni_private_get_proxied_cpp_object() {
return _cppRefHandle->get();
}

private:
AutoPtr<HandleType> _cppRefHandle;
};

OneInterface::CppType OneInterface::ToCpp(OneInterface::CsType cs)
{
if (!cs) {
return nullptr;
}
return dynamic_cast<OneInterfaceCppProxy^>(cs)->djinni_private_get_proxied_cpp_object();
}

OneInterface::CsType OneInterface::FromCppOpt(const OneInterface::CppOptType& cpp)
{
if (!cpp) {
return nullptr;
}
return ::djinni::get_cpp_proxy<OneInterfaceCppProxy^>(cpp);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file was generated by Djinni from cppcli_circular_dependent_interface.djinni

#pragma once

#include "../cpp-headers/one_interface.hpp"
#include "AnotherInterface.hpp"
#include <memory>

ref class AnotherInterface;

public ref class OneInterface abstract {
public:
virtual void MethodTakingAnotherInterface(AnotherInterface^ dep) abstract;

virtual void MethodTakingOptionalAnotherInterface(AnotherInterface^ dep) abstract;

virtual AnotherInterface^ MethodReturningAnotherInterface() abstract;

virtual AnotherInterface^ MethodReturningOptionalAnotherInterface() abstract;

internal:
using CppType = std::shared_ptr<::OneInterface>;
using CppOptType = std::shared_ptr<::OneInterface>;
using CsType = OneInterface^;

static CppType ToCpp(CsType cs);
static CsType FromCppOpt(const CppOptType& cpp);
static CsType FromCpp(const CppType& cpp) { return FromCppOpt(cpp); }
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
src/it/resources/result/cppcli_circular_dependent_interface/cppcli/OneInterface.hpp
src/it/resources/result/cppcli_circular_dependent_interface/cppcli/OneInterface.cpp
src/it/resources/result/cppcli_circular_dependent_interface/cppcli/AnotherInterface.hpp
src/it/resources/result/cppcli_circular_dependent_interface/cppcli/AnotherInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file was generated by Djinni from cppcli_extern_dependent_interface.djinni

#include "DependentInterface.hpp" // my header
#include "djinni/cppcli/Error.hpp"
#include "djinni/cppcli/Marshal.hpp"
#include "djinni/cppcli/WrapperCache.hpp"

ref class DependentInterfaceCppProxy : public DependentInterface {
using CppType = std::shared_ptr<::DependentInterface>;
using HandleType = ::djinni::CppProxyCache::Handle<CppType>;
public:
DependentInterfaceCppProxy(const CppType& cppRef) : _cppRefHandle(new HandleType(cppRef)) {}

void MethodTakingInterfaceDependency(InterfaceDependency^ dep) override {
try {
_cppRefHandle->get()->method_taking_interface_dependency(::InterfaceDependency::ToCpp(dep));
} DJINNI_TRANSLATE_EXCEPTIONS()
}

void MethodTakingOptionalInterfaceDependency(InterfaceDependency^ dep) override {
try {
_cppRefHandle->get()->method_taking_optional_interface_dependency(::djinni::Optional<std::optional, ::InterfaceDependency>::ToCpp(dep));
} DJINNI_TRANSLATE_EXCEPTIONS()
}

InterfaceDependency^ MethodReturningInterfaceDependency() override {
try {
auto cs_result = _cppRefHandle->get()->method_returning_interface_dependency();
return ::InterfaceDependency::FromCpp(cs_result);
} DJINNI_TRANSLATE_EXCEPTIONS()
return nullptr; // Unreachable! (Silencing compiler warnings.)
}

InterfaceDependency^ MethodReturningOptionalInterfaceDependency() override {
try {
auto cs_result = _cppRefHandle->get()->method_returning_optional_interface_dependency();
return ::djinni::Optional<std::optional, ::InterfaceDependency>::FromCpp(cs_result);
} DJINNI_TRANSLATE_EXCEPTIONS()
return nullptr; // Unreachable! (Silencing compiler warnings.)
}

CppType djinni_private_get_proxied_cpp_object() {
return _cppRefHandle->get();
}

private:
AutoPtr<HandleType> _cppRefHandle;
};

DependentInterface::CppType DependentInterface::ToCpp(DependentInterface::CsType cs)
{
if (!cs) {
return nullptr;
}
return dynamic_cast<DependentInterfaceCppProxy^>(cs)->djinni_private_get_proxied_cpp_object();
}

DependentInterface::CsType DependentInterface::FromCppOpt(const DependentInterface::CppOptType& cpp)
{
if (!cpp) {
return nullptr;
}
return ::djinni::get_cpp_proxy<DependentInterfaceCppProxy^>(cpp);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file was generated by Djinni from cppcli_extern_dependent_interface.djinni

#pragma once

#include "../cpp-headers/dependent_interface.hpp"
#include "InterfaceDependency.hpp"
#include <memory>

public ref class DependentInterface abstract {
public:
virtual void MethodTakingInterfaceDependency(InterfaceDependency^ dep) abstract;

virtual void MethodTakingOptionalInterfaceDependency(InterfaceDependency^ dep) abstract;

virtual InterfaceDependency^ MethodReturningInterfaceDependency() abstract;

virtual InterfaceDependency^ MethodReturningOptionalInterfaceDependency() abstract;

internal:
using CppType = std::shared_ptr<::DependentInterface>;
using CppOptType = std::shared_ptr<::DependentInterface>;
using CsType = DependentInterface^;

static CppType ToCpp(CsType cs);
static CsType FromCppOpt(const CppOptType& cpp);
static CsType FromCpp(const CppType& cpp) { return FromCppOpt(cpp); }
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src/it/resources/result/cppcli_extern_dependent_interface/cppcli/DependentInterface.hpp
src/it/resources/result/cppcli_extern_dependent_interface/cppcli/DependentInterface.cpp
Loading

0 comments on commit 1d5fbcb

Please sign in to comment.