From 54df6f1181698db02487fb32517dc37e99d66d32 Mon Sep 17 00:00:00 2001 From: Andrew Twyman Date: Mon, 18 Apr 2016 20:37:23 -0700 Subject: [PATCH] Test const methods Added a test to prove that const methods for C++ work, and documented rules for const & static methods. --- README.md | 13 +++++++++++++ src/source/resolver.scala | 6 ++++-- test-suite/djinni/client_interface.djinni | 2 +- .../generated-src/cpp/reverse_client_interface.hpp | 2 +- .../cpp/reverse_client_interface_impl.cpp | 2 +- .../cpp/reverse_client_interface_impl.hpp | 2 +- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 247ac1252..b33f1e18e 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,7 @@ methods. Djinni is capable of generating equality and order comparators, impleme as operator overloading in C++ and standard comparison functions in Java / Objective-C. Things to note: + - All fields in the record are compared in the order they appear in the record declaration. If you need to add a field later, make sure the order is correct. - Ordering comparison is not supported for collection types, optionals, and booleans. @@ -232,6 +233,18 @@ Things to note: types of comparators as the outer record. ### Interface + +#### Special Methods for C++ Only +`+c` interfaces (implementable only in C++) can have methods flagged with the special keywords const and static which have special effects in C++: + + special_methods = interface +c { + const accessor_method(); + static factory_method(); + } + +- `const` methods will be declared as const in C++, though this cannot be enforced on callers in other languages, which lack this feature. +- `static` methods will become a static method of the C++ class, which can be called from other languages without an object. This is often useful for factory methods to act as a cross-language constructor. + #### Exception Handling When an interface implemented in C++ throws a `std::exception`, it will be translated to a `java.lang.RuntimeException` in Java or an `NSException` in Objective-C. The `what()` message diff --git a/src/source/resolver.scala b/src/source/resolver.scala index f5d41c708..aac986b1e 100644 --- a/src/source/resolver.scala +++ b/src/source/resolver.scala @@ -264,15 +264,17 @@ private def resolveRecord(scope: Scope, r: Record) { } private def resolveInterface(scope: Scope, i: Interface) { - // Check for static methods in Java or Objective-C; not allowed + // Const and static methods are only allowed on +c (only) interfaces if (i.ext.java || i.ext.objc) { for (m <- i.methods) { if (m.static) throw Error(m.ident.loc, "static not allowed for +j or +o interfaces").toException if (m.const) - throw Error(m.ident.loc, "const method not allowed for +j or +o interfaces").toException + throw Error(m.ident.loc, "const method not allowed for +j or +o +p interfaces").toException } } + + // Static+const isn't valid if (i.ext.cpp) { for (m <- i.methods) { if (m.static && m.const) diff --git a/test-suite/djinni/client_interface.djinni b/test-suite/djinni/client_interface.djinni index dd7d97d0a..10c5e8657 100644 --- a/test-suite/djinni/client_interface.djinni +++ b/test-suite/djinni/client_interface.djinni @@ -17,7 +17,7 @@ client_interface = interface +j +o { } reverse_client_interface = interface +c { - return_str(): string; + const return_str(): string; meth_taking_interface(i: reverse_client_interface): string; meth_taking_optional_interface(i: optional): string; diff --git a/test-suite/generated-src/cpp/reverse_client_interface.hpp b/test-suite/generated-src/cpp/reverse_client_interface.hpp index 95bb4f8b8..372af04b4 100644 --- a/test-suite/generated-src/cpp/reverse_client_interface.hpp +++ b/test-suite/generated-src/cpp/reverse_client_interface.hpp @@ -13,7 +13,7 @@ class ReverseClientInterface { public: virtual ~ReverseClientInterface() {} - virtual std::string return_str() = 0; + virtual std::string return_str() const = 0; virtual std::string meth_taking_interface(const std::shared_ptr & i) = 0; diff --git a/test-suite/handwritten-src/cpp/reverse_client_interface_impl.cpp b/test-suite/handwritten-src/cpp/reverse_client_interface_impl.cpp index dacb059d2..fab277e4a 100644 --- a/test-suite/handwritten-src/cpp/reverse_client_interface_impl.cpp +++ b/test-suite/handwritten-src/cpp/reverse_client_interface_impl.cpp @@ -2,7 +2,7 @@ namespace testsuite { -std::string ReverseClientInterfaceImpl::return_str() { +std::string ReverseClientInterfaceImpl::return_str() const { return "test"; } diff --git a/test-suite/handwritten-src/cpp/reverse_client_interface_impl.hpp b/test-suite/handwritten-src/cpp/reverse_client_interface_impl.hpp index 8359b871a..1d962b9b6 100644 --- a/test-suite/handwritten-src/cpp/reverse_client_interface_impl.hpp +++ b/test-suite/handwritten-src/cpp/reverse_client_interface_impl.hpp @@ -7,7 +7,7 @@ class ReverseClientInterfaceImpl : public ReverseClientInterface { ReverseClientInterfaceImpl() {} virtual ~ReverseClientInterfaceImpl() {} - virtual std::string return_str() override; + virtual std::string return_str() const override; virtual std::string meth_taking_interface(const std::shared_ptr & i) override;