bond 0.6.0.0 → 0.7.0.0
raw patch · 14 files changed
+486/−67 lines, 14 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Language.Bond.Codegen.Templates: comm_h :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text)
+ Language.Bond.Codegen.Templates: types_comm_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text)
Files
- Main.hs +8/−6
- bond.cabal +3/−1
- src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs +13/−13
- src/Language/Bond/Codegen/Cpp/Apply_cpp.hs +1/−1
- src/Language/Bond/Codegen/Cpp/Comm_h.hs +329/−0
- src/Language/Bond/Codegen/Cpp/Reflection_h.hs +12/−12
- src/Language/Bond/Codegen/Cpp/Types_Comm_cpp.hs +34/−0
- src/Language/Bond/Codegen/Cpp/Types_cpp.hs +4/−4
- src/Language/Bond/Codegen/Cpp/Types_h.hs +4/−4
- src/Language/Bond/Codegen/Cpp/Util.hs +41/−19
- src/Language/Bond/Codegen/Templates.hs +5/−0
- src/Language/Bond/Codegen/TypeMapping.hs +6/−6
- tests/Main.hs +16/−1
- tests/Tests/Codegen.hs +10/−0
Main.hs view
@@ -72,21 +72,23 @@ concurrentlyFor_ files $ codeGen options typeMapping $ [ reflection_h , types_cpp + , types_comm_cpp , types_h header enum_header allocator , apply_h applyProto apply_attribute , apply_cpp applyProto + , comm_h ] <> [ enum_h | enum_header] where applyProto = map snd $ filter (enabled apply) protocols enabled a p = null a || fst p `elem` a protocols = - [ (Compact, Protocol "bond::CompactBinaryReader<bond::InputBuffer>" - "bond::CompactBinaryWriter<bond::OutputBuffer>") - , (Fast, Protocol "bond::FastBinaryReader<bond::InputBuffer>" - "bond::FastBinaryWriter<bond::OutputBuffer>") - , (Simple, Protocol "bond::SimpleBinaryReader<bond::InputBuffer>" - "bond::SimpleBinaryWriter<bond::OutputBuffer>") + [ (Compact, Protocol " ::bond::CompactBinaryReader< ::bond::InputBuffer>" + " ::bond::CompactBinaryWriter< ::bond::OutputBuffer>") + , (Fast, Protocol " ::bond::FastBinaryReader< ::bond::InputBuffer>" + " ::bond::FastBinaryWriter< ::bond::OutputBuffer>") + , (Simple, Protocol " ::bond::SimpleBinaryReader< ::bond::InputBuffer>" + " ::bond::SimpleBinaryWriter< ::bond::OutputBuffer>") ] cppCodegen _ = error "cppCodegen: impossible happened."
bond.cabal view
@@ -2,7 +2,7 @@ -- Licensed under the MIT license. See LICENSE file in the project root for full license information. name: bond -version: 0.6.0.0 +version: 0.7.0.0 cabal-version: >= 1.8 tested-with: GHC>=7.4.1 synopsis: Bond schema compiler and code generator @@ -62,7 +62,9 @@ Language.Bond.Codegen.Cpp.Enum_h Language.Bond.Codegen.Cpp.Reflection_h Language.Bond.Codegen.Cpp.Types_cpp + Language.Bond.Codegen.Cpp.Types_Comm_cpp Language.Bond.Codegen.Cpp.Types_h + Language.Bond.Codegen.Cpp.Comm_h Language.Bond.Codegen.Cs.Types_cs Language.Bond.Codegen.Cs.Comm_cs Language.Bond.Codegen.Cpp.ApplyOverloads
src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs view
@@ -28,12 +28,12 @@ // // Overloads of Apply function with common transforms for #{declName}. // These overloads will be selected using argument dependent lookup - // before bond::Apply function templates. + // before ::bond::Apply function templates. // - #{attr}bool Apply(const bond::To< #{qualifiedName}>& transform, - const bond::bonded< #{qualifiedName}>& value)#{body} + #{attr}bool Apply(const ::bond::To< #{qualifiedName}>& transform, + const ::bond::bonded< #{qualifiedName}>& value)#{body} - #{attr}bool Apply(const bond::InitSchemaDef& transform, + #{attr}bool Apply(const ::bond::InitSchemaDef& transform, const #{qualifiedName}& value)#{body} #{newlineSep 1 applyOverloads' protocols}|] where @@ -47,22 +47,22 @@ marshaler = "Marshaler" :: String deserialization Protocol {..} = [lt| - #{attr}bool Apply(const bond::To< #{qualifiedName}>& transform, - const bond::bonded< #{qualifiedName}, #{protocolReader}&>& value)#{body} + #{attr}bool Apply(const ::bond::To< #{qualifiedName}>& transform, + const ::bond::bonded< #{qualifiedName}, #{protocolReader}&>& value)#{body} - #{attr}bool Apply(const bond::To< #{qualifiedName}>& transform, - const bond::bonded<void, #{protocolReader}&>& value)#{body}|] + #{attr}bool Apply(const ::bond::To< #{qualifiedName}>& transform, + const ::bond::bonded<void, #{protocolReader}&>& value)#{body}|] serialization transform Protocol {..} = [lt| - #{attr}bool Apply(const bond::#{transform}<#{protocolWriter} >& transform, + #{attr}bool Apply(const ::bond::#{transform}<#{protocolWriter} >& transform, const #{qualifiedName}& value)#{body} - #{attr}bool Apply(const bond::#{transform}<#{protocolWriter} >& transform, - const bond::bonded< #{qualifiedName}>& value)#{body} + #{attr}bool Apply(const ::bond::#{transform}<#{protocolWriter} >& transform, + const ::bond::bonded< #{qualifiedName}>& value)#{body} #{newlineSep 1 (transcoding transform) protocols}|] where transcoding transform' Protocol {protocolReader = fromReader} = [lt| - #{attr}bool Apply(const bond::#{transform'}<#{protocolWriter} >& transform, - const bond::bonded< #{qualifiedName}, #{fromReader}&>& value)#{body}|] + #{attr}bool Apply(const ::bond::#{transform'}<#{protocolWriter} >& transform, + const ::bond::bonded< #{qualifiedName}, #{fromReader}&>& value)#{body}|] applyOverloads _ _ _ _ _ = mempty
src/Language/Bond/Codegen/Cpp/Apply_cpp.hs view
@@ -28,7 +28,7 @@ where body = [lt| { - return bond::Apply<>(transform, value); + return ::bond::Apply<>(transform, value); }|] attr = [lt||]
+ src/Language/Bond/Codegen/Cpp/Comm_h.hs view
@@ -0,0 +1,329 @@+-- Copyright (c) Microsoft. All rights reserved. +-- Licensed under the MIT license. See LICENSE file in the project root for full license information. + +{-# LANGUAGE QuasiQuotes, OverloadedStrings, RecordWildCards #-} + +module Language.Bond.Codegen.Cpp.Comm_h (comm_h) where + +import System.FilePath +import Data.Monoid +import Prelude +import qualified Data.Text.Lazy as L +import Data.Text.Lazy.Builder +import Text.Shakespeare.Text +import Language.Bond.Syntax.Types +import Language.Bond.Syntax.Util +import Language.Bond.Codegen.Util +import Language.Bond.Codegen.TypeMapping +import qualified Language.Bond.Codegen.Cpp.Util as CPP + + +-- | Codegen template for generating /base_name/_comm.h containing declarations of +-- of service interface and proxy. +comm_h :: MappingContext -> String -> [Import] -> [Declaration] -> (String, L.Text) +comm_h cpp file imports declarations = ("_comm.h", [lt| +#pragma once + +#include <bond/comm/services.h> +#include "#{file}_types.h" +#{newlineSep 0 includeImport imports} + +#{CPP.openNamespace cpp} + #{doubleLineSep 1 comm declarations} + +#{CPP.closeNamespace cpp} +|]) + where + includeImport (Import path) = [lt|#include "#{dropExtension path}_comm.h"|] + + cppType = getTypeName cpp + + request mt = request' (payload mt) + where + payload = maybe "void" cppType + request' params = [lt|::bond::comm::payload<#{padLeft}#{params}>|] + where + paramsText = toLazyText params + padLeft = if L.head paramsText == ':' then [lt| |] else mempty + + response mt = response' (payload mt) + where + payload = maybe "void" cppType + response' params = [lt|::bond::comm::message<#{padLeft}#{params}>|] + where + paramsText = toLazyText params + padLeft = if L.head paramsText == ':' then [lt| |] else mempty + + callback m = [lt|const std::function<void (const #{response m}&)>& callback|] + + comm s@Service {..} = [lt|#{template}class #{declName} + { + public: + virtual ~#{declName}() = default; + + #{doubleLineSep 2 virtualMethod serviceMethods} + + struct Schema; + class Proxy; + + template <template <typename> class Promise> + class Using; + }; + + #{template}struct #{className}::Schema + { + static const ::bond::Metadata metadata; + + #{newlineSep 2 methodMetadata serviceMethods} + + public: struct service + { + #{doubleLineSep 3 methodTemplate serviceMethods} + }; + + private: typedef boost::mpl::list<> methods0; + #{newlineSep 2 pushMethod indexedMethods} + + public: typedef #{typename}methods#{length serviceMethods}::type methods; + #{constructor} + }; + #{onlyTemplate $ CPP.schemaMetadata cpp s} + + #{template}class #{className}::Proxy + : public #{className} + { + public: + template <typename ServiceProxy> + explicit + Proxy(const ServiceProxy& proxy, + const std::string& name = #{className}::Schema::metadata.qualified_name) + : _impl(boost::make_shared<__Impl<ServiceProxy>>(proxy, name)) + {} + + explicit + Proxy(const boost::shared_ptr<#{className}>& service) + : _impl(service) + {} + + Proxy() = default; + + #{doubleLineSep 2 proxyMethod serviceMethods} + + template <template <typename> class Promise> + class Using; + + protected: + boost::shared_ptr<#{className}> _impl; + + template <typename ServiceProxy> + class __Impl + : public #{className} + { + public: + __Impl(const ServiceProxy& proxy, const std::string& name) + : _proxy(proxy), + _name(name) + {} + + virtual ~__Impl() = default; + + #{doubleLineSep 3 implMethod serviceMethods} + + private: + ServiceProxy _proxy; + const std::string _name; + }; + }; + + #{template}template <template <typename> class Promise> + class #{className}::Using + : public #{className} + { + public: + #{doubleLineSep 2 virtualFutureMethod serviceMethods} + + #{doubleLineSep 2 serviceMethod serviceMethods} + }; + + #{template}template <template <typename> class Promise> + class #{className}::Proxy::Using + : public #{className}::Proxy + { + public: + template <typename ServiceProxy> + explicit + Using(const ServiceProxy& proxy, + const std::string& name = #{className}::Schema::metadata.qualified_name) + : #{className}::Proxy(proxy, name) + {} + + explicit + Using(const boost::shared_ptr<#{className}>& service) + : #{className}::Proxy(service) + {} + + Using() = default; + + #{doubleLineSep 2 proxyFutureMethod serviceMethods} + }; + |] + where + className = CPP.className s + template = CPP.template s + onlyTemplate x = if null declParams then mempty else x + typename = onlyTemplate [lt|typename |] + + methodMetadataVar m = [lt|s_#{methodName m}_metadata|] + + methodMetadata m = + [lt|private: static const ::bond::Metadata #{methodMetadataVar m};|] + + -- reversed list of method names zipped with indexes + indexedMethods :: [(String, Int)] + indexedMethods = zipWith ((,) . methodName) (reverse serviceMethods) [0..] + + pushMethod (method, i) = + [lt|private: typedef #{typename}boost::mpl::push_front<methods#{i}, #{typename}service::#{method}>::type methods#{i + 1};|] + + -- constructor, generated only for service templates + constructor = onlyTemplate [lt| + Schema() + { + // Force instantiation of template statics + (void)metadata; + #{newlineSep 4 static serviceMethods} + }|] + where + static m = [lt|(void)#{methodMetadataVar m};|] + + methodTemplate m = [lt|typedef ::bond::reflection::MethodTemplate< + #{className}, + #{request $ methodInput m}, + #{result m}, + &#{className}::#{methodName m}, + &#{methodMetadataVar m} + > #{methodName m};|] + where + result Event{} = "void" + result Function{..} = response methodResult + + methodSignature n m = + [lt|void #{methodName m}(#{commaLineSep n id $ methodParams m})|] + where + methodParams Event{..} = + [ [lt|const #{request methodInput}& input|] + ] + + methodParams Function{..} = + [ [lt|const #{request methodInput}& input|] + , callback methodResult + ] + + resultOf x f = [lt|decltype(std::declval< #{x}>().#{f}())|] + + promiseType result = [lt|Promise< #{response result}>|] + + futureType result = resultOf (promiseType result) get_future + where + get_future = [lt|get_future|] + + methodFutureSignature Function{..} = + [lt|auto #{methodName}(const #{request methodInput}& input) + -> #{futureType methodResult}|] + methodFutureSignature Event{..} = error "No future-based signature for Event methods" + + virtualMethod m = [lt|virtual #{methodSignature 3 m} = 0;|] + + virtualFutureMethod Event{} = mempty + virtualFutureMethod m = [lt|virtual #{methodFutureSignature m} = 0;|] + + serviceMethod Event{} = mempty + serviceMethod m@Function{..} = [lt|#{methodSignature 3 m} override + { + when(#{methodName}(input), ::bond::comm::Continuation(callback)); + }|] + + proxyMethod m@Event{..} = [lt|#{methodSignature 3 m} override + { + _impl->#{methodName}(input); + }#{proxyMethodOverload methodInput}|] + where + proxyMethodOverload Nothing = [lt| + + void #{methodName}() + { + _impl->#{methodName}(::bond::comm::payload<void>()); + }|] + proxyMethodOverload (Just payload) | isStruct payload = [lt| + + void #{methodName}(const #{cppType payload}& input) + { + _impl->#{methodName}(boost::cref(input)); + }|] + proxyMethodOverload _ = mempty + + proxyMethod m@Function{..} = [lt|#{methodSignature 3 m} override + { + _impl->#{methodName}(input, callback); + }#{proxyMethodOverload methodInput}|] + where + proxyMethodOverload Nothing = [lt| + + void #{methodName}( + #{callback methodResult}) + { + _impl->#{methodName}(::bond::comm::payload<void>(), callback); + }|] + proxyMethodOverload (Just payload) | isStruct payload = [lt| + + void #{methodName}(const #{cppType payload}& input, + #{callback methodResult}) + { + _impl->#{methodName}(boost::cref(input), callback); + }|] + proxyMethodOverload _ = mempty + + proxyFutureMethod Event{} = mempty + proxyFutureMethod m@Function{..} = [lt|using #{className}::Proxy::#{methodName}; + + #{methodFutureSignature m} + { + auto promise = boost::make_shared<#{promiseType methodResult}>(); + + _impl->#{methodName}(input, + [=](const #{response methodResult}& result) mutable + { + promise->set_value(result); + }); + + return promise->get_future(); + }#{proxyMethodOverload methodInput}|] + where + proxyMethodOverload Nothing = [lt| + + auto #{methodName}() + -> #{futureType methodResult} + { + return #{methodName}(::bond::comm::payload<void>()); + }|] + proxyMethodOverload (Just payload) | isStruct payload = [lt| + + auto #{methodName}(const #{cppType payload}& input) + -> #{futureType methodResult} + { + return #{methodName}(#{request methodInput}(boost::cref(input))); + } + |] + proxyMethodOverload _ = mempty + + implMethod m@Event{..} = [lt|#{methodSignature 4 m} override + { + _proxy.Send(_name, Schema::service::#{methodName}::metadata.name, input); + }|] + + implMethod m@Function{..} = [lt|#{methodSignature 4 m} override + { + _proxy.Send(_name, Schema::service::#{methodName}::metadata.name, input, callback); + }|] + + comm _ = mempty
src/Language/Bond/Codegen/Cpp/Reflection_h.hs view
@@ -42,11 +42,11 @@ schema s@Struct {..} = [lt|// // #{declName} // - #{CPP.template s}struct #{structName}::Schema + #{CPP.template s}struct #{className}::Schema { typedef #{baseType structBase} base; - static const bond::Metadata metadata; + static const ::bond::Metadata metadata; #{newlineBeginSep 2 fieldMetadata structFields} public: struct var @@ -58,22 +58,22 @@ public: typedef #{typename}fields#{length structFields}::type fields; #{constructor} - static bond::Metadata GetMetadata() + static ::bond::Metadata GetMetadata() { - return bond::reflection::MetadataInit#{metadataInitArgs}("#{declName}", "#{getDeclTypeName idl s}", + return ::bond::reflection::MetadataInit#{metadataInitArgs}("#{declName}", "#{getDeclTypeName idl s}", #{CPP.attributeInit declAttributes} ); } }; #{onlyTemplate $ CPP.schemaMetadata cpp s}|] where - structParams = CPP.structParams s + classParams = CPP.classParams s - structName = CPP.structName s + className = CPP.className s onlyTemplate x = if null declParams then mempty else x - metadataInitArgs = onlyTemplate [lt|<boost::mpl::list#{structParams} >|] + metadataInitArgs = onlyTemplate [lt|<boost::mpl::list#{classParams} >|] typename = onlyTemplate [lt|typename |] @@ -93,22 +93,22 @@ indexedFields = zipWith ((,) . fieldName) (reverse structFields) [0..] baseType (Just base) = cppType base - baseType Nothing = "bond::no_base" + baseType Nothing = "::bond::no_base" pushField (field, i) = [lt|private: typedef #{typename}boost::mpl::push_front<fields#{i}, #{typename}var::#{field}>::type fields#{i + 1};|] fieldMetadata Field {..} = - [lt|private: static const bond::Metadata s_#{fieldName}_metadata;|] + [lt|private: static const ::bond::Metadata s_#{fieldName}_metadata;|] fieldTemplates = F.foldMap $ \ f@Field {..} -> [lt| // #{fieldName} - typedef bond::reflection::FieldTemplate< + typedef ::bond::reflection::FieldTemplate< #{fieldOrdinal}, #{CPP.modifierTag f}, - #{structName}, + #{className}, #{cppType fieldType}, - &#{structName}::#{fieldName}, + &#{className}::#{fieldName}, &s_#{fieldName}_metadata > #{fieldName}; |]
+ src/Language/Bond/Codegen/Cpp/Types_Comm_cpp.hs view
@@ -0,0 +1,34 @@+-- Copyright (c) Microsoft. All rights reserved. +-- Licensed under the MIT license. See LICENSE file in the project root for full license information. + +{-# LANGUAGE QuasiQuotes, OverloadedStrings, RecordWildCards #-} + +module Language.Bond.Codegen.Cpp.Types_Comm_cpp (types_comm_cpp) where + +import Data.Monoid +import Prelude +import Data.Text.Lazy (Text) +import Text.Shakespeare.Text +import Language.Bond.Syntax.Types +import Language.Bond.Codegen.TypeMapping +import Language.Bond.Codegen.Util +import qualified Language.Bond.Codegen.Cpp.Util as CPP + +-- | Codegen template for generating /base_name/_comm_types.cpp containing +-- definitions of helper functions and schema metadata static variables. +types_comm_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text) +types_comm_cpp cpp file _imports declarations = ("_comm.cpp", [lt| +#include "#{file}_reflection.h" +#include "#{file}_comm.h" +#include <bond/core/exception.h> + +#{CPP.openNamespace cpp} + #{doubleLineSepEnd 1 statics declarations} +#{CPP.closeNamespace cpp} +|]) + where + -- definitions of Schema statics for non-generic services + statics s@Service {..} = + if null declParams then CPP.schemaMetadata cpp s else mempty + + statics _ = mempty
src/Language/Bond/Codegen/Cpp/Types_cpp.hs view
@@ -14,7 +14,7 @@ import Language.Bond.Codegen.Util import qualified Language.Bond.Codegen.Cpp.Util as CPP --- | Codegen template for generating /base_name/_type.cpp containing +-- | Codegen template for generating /base_name/_types.cpp containing -- definitions of helper functions and schema metadata static variables. types_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text) types_cpp cpp file _imports declarations = ("_types.cpp", [lt| @@ -47,7 +47,7 @@ const std::map<enum #{declName}, std::string> _value_to_name_#{declName} = - bond::reverse_map(_name_to_value_#{declName}); + ::bond::reverse_map(_name_to_value_#{declName}); const std::string& ToString(enum #{declName} value) { @@ -55,7 +55,7 @@ GetValueToNameMap(value).find(value); if (GetValueToNameMap(value).end() == it) - bond::InvalidEnumValueException(value, "#{declName}"); + ::bond::InvalidEnumValueException(value, "#{declName}"); return it->second; } @@ -63,7 +63,7 @@ void FromString(const std::string& name, enum #{declName}& value) { if (!ToEnum(value, name)) - bond::InvalidEnumValueException(name.c_str(), "#{declName}"); + ::bond::InvalidEnumValueException(name.c_str(), "#{declName}"); } } // namespace #{declName} } // namespace _bond_enumerators|]
src/Language/Bond/Codegen/Cpp/Types_h.hs view
@@ -103,7 +103,7 @@ |] where usesAllocator s@Struct {..} = [lt|template <typename _Alloc#{sepBeginBy ", typename " paramName declParams}> - struct uses_allocator<#{typename} #{getDeclTypeName cpp s}#{CPP.structParams s}, _Alloc> + struct uses_allocator<#{typename} #{getDeclTypeName cpp s}#{CPP.classParams s}, _Alloc> : is_convertible<_Alloc, #{allocParam}> {};|] where @@ -146,13 +146,13 @@ #{initMetadata} }; - #{template}inline void swap(#{qualifiedStructName}& left, #{qualifiedStructName}& right) + #{template}inline void swap(#{qualifiedClassName}& left, #{qualifiedClassName}& right) { left.swap(right); }|] where template = CPP.template s - qualifiedStructName = [lt|#{getDeclTypeName cpp s}#{CPP.structParams s}|] + qualifiedClassName = CPP.qualifiedClassName cpp s otherParam = if hasOnlyMetaFields then mempty else [lt| other|] hasOnlyMetaFields = not (any (not . getAny . metaField) structFields) && isNothing structBase @@ -339,7 +339,7 @@ } inline - const char* GetTypeName(enum #{declName}, const bond::qualified_name_tag&) + const char* GetTypeName(enum #{declName}, const ::bond::qualified_name_tag&) { return "#{getDeclTypeName idl e}"; }
src/Language/Bond/Codegen/Cpp/Util.hs view
@@ -7,8 +7,9 @@ module Language.Bond.Codegen.Cpp.Util ( openNamespace , closeNamespace - , structName - , structParams + , className + , classParams + , qualifiedClassName , template , modifierTag , defaultValue @@ -23,7 +24,8 @@ import Data.Monoid import Prelude -import Data.Text.Lazy (Text) +import Data.Text.Lazy (Text, unpack) +import Data.Text.Lazy.Builder (toLazyText) import Text.Shakespeare.Text import Language.Bond.Syntax.Types import Language.Bond.Syntax.Util @@ -44,14 +46,18 @@ where close n = [lt|} // namespace #{n}|] -structName :: Declaration -> String -structName s@Struct {..} = declName <> structParams s -structName _ = error "structName: impossible happened." +className :: Declaration -> String +className decl = declName decl <> classParams decl -structParams :: Declaration -> String -structParams Struct {..} = angles $ sepBy ", " paramName declParams -structParams _ = error "structName: impossible happened." +classParams :: Declaration -> String +classParams = angles . sepBy ", " paramName . declParams +qualifiedClassName :: MappingContext -> Declaration -> String +qualifiedClassName cpp s@Struct {..} = qualifiedName <> classParams s + where + qualifiedName = unpack $ toLazyText $ getDeclTypeName cpp s +qualifiedClassName _ _ = error "qualifiedClassName: impossible happened." + template :: Declaration -> Text template d = if null $ declParams d then mempty else [lt|template <typename #{params}> |] @@ -60,7 +66,7 @@ -- attribute initializer attributeInit :: [Attribute] -> Text -attributeInit [] = "bond::reflection::Attributes()" +attributeInit [] = "::bond::reflection::Attributes()" attributeInit xs = [lt|boost::assign::map_list_of<std::string, std::string>#{newlineBeginSep 5 attrNameValue xs}|] where idl = MappingContext idlTypeMapping [] [] [] @@ -69,7 +75,7 @@ -- modifier tag type for a field modifierTag :: Field -> Text -modifierTag Field {..} = [lt|bond::reflection::#{modifier fieldType fieldModifier}_field_modifier|] +modifierTag Field {..} = [lt|::bond::reflection::#{modifier fieldType fieldModifier}_field_modifier|] where modifier BT_MetaName _ = [lt|required_optional|] modifier BT_MetaFullName _ = [lt|required_optional|] @@ -102,26 +108,42 @@ -- schema metadata static member definitions schemaMetadata :: MappingContext -> Declaration -> Text schemaMetadata cpp s@Struct {..} = [lt| - #{template s}const bond::Metadata #{structName s}::Schema::metadata - = #{structName s}::Schema::GetMetadata();#{newlineBeginSep 1 staticDef structFields}|] + #{template s}const ::bond::Metadata #{className s}::Schema::metadata + = #{className s}::Schema::GetMetadata();#{newlineBeginSep 1 staticDef structFields}|] where -- static member definition for field metadata staticDef f@Field {..} | fieldModifier == Optional && null fieldAttributes = [lt| - #{template s}const bond::Metadata #{structName s}::Schema::s_#{fieldName}_metadata - = bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}");|] + #{template s}const ::bond::Metadata #{className s}::Schema::s_#{fieldName}_metadata + = ::bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}");|] | otherwise = [lt| - #{template s}const bond::Metadata #{structName s}::Schema::s_#{fieldName}_metadata - = bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}", #{modifierTag f}::value, - #{attributeInit fieldAttributes});|] + #{template s}const ::bond::Metadata #{className s}::Schema::s_#{fieldName}_metadata + = ::bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}", #{modifierTag f}::value, + #{attributeInit fieldAttributes});|] where defaultInit Field {fieldDefault = (Just def)} = [lt|#{explicitDefault def}, |] defaultInit _ = mempty - explicitDefault (DefaultNothing) = "bond::nothing" + explicitDefault (DefaultNothing) = "::bond::nothing" explicitDefault d@(DefaultInteger _) = staticCast d explicitDefault d@(DefaultFloat _) = staticCast d explicitDefault d = defaultValue cpp fieldType d staticCast d = [lt|static_cast<#{getTypeName cpp fieldType}>(#{defaultValue cpp fieldType d})|] +schemaMetadata _ s@Service {..} = [lt| + #{template s}const ::bond::Metadata #{className s}::Schema::metadata + = ::bond::reflection::MetadataInit#{metadataInitArgs}("#{declName}", "#{idlNamespace}", + #{attributeInit declAttributes});#{newlineBeginSep 1 staticDef serviceMethods}|] + where + idl = MappingContext idlTypeMapping [] [] [] + idlNamespace = getDeclTypeName idl s + metadataInitArgs = if null declParams then mempty else [lt|<boost::mpl::list#{classParams s} >|] + -- static member definition for method metadata + staticDef m = [lt| + #{template s}const ::bond::Metadata #{className s}::Schema::s_#{methodName m}_metadata + = ::bond::reflection::MetadataInit("#{methodName m}"#{attributes $ methodAttributes m}|] + where + attributes [] = [lt|);|] + attributes a = [lt|, + #{attributeInit a});|] schemaMetadata _ _ = error "schemaMetadata: impossible happened." defaultedFunctions, defaultedMoveCtors, rvalueReferences :: Text
src/Language/Bond/Codegen/Templates.hs view
@@ -36,11 +36,14 @@ -- ** C++ types_h , types_cpp + , types_comm_cpp , reflection_h , enum_h , apply_h , apply_cpp , Protocol(..) + -- ** C++ Comm + , comm_h -- ** C# , FieldMapping(..) , StructMapping(..) @@ -57,7 +60,9 @@ import Language.Bond.Codegen.Cpp.Enum_h import Language.Bond.Codegen.Cpp.Reflection_h import Language.Bond.Codegen.Cpp.Types_cpp +import Language.Bond.Codegen.Cpp.Types_Comm_cpp import Language.Bond.Codegen.Cpp.Types_h +import Language.Bond.Codegen.Cpp.Comm_h import Language.Bond.Codegen.Cs.Types_cs import Language.Bond.Codegen.Cs.Comm_cs -- redundant imports for haddock
src/Language/Bond/Codegen/TypeMapping.hs view
@@ -350,15 +350,15 @@ cppType BT_WString = pure "std::wstring" cppType BT_MetaName = pure "std::string" cppType BT_MetaFullName = pure "std::string" -cppType BT_Blob = pure "bond::blob" +cppType BT_Blob = pure "::bond::blob" cppType (BT_IntTypeArg x) = pureText x -cppType (BT_Maybe type_) = "bond::maybe<" <>> elementTypeName type_ <<> ">" +cppType (BT_Maybe type_) = "::bond::maybe<" <>> elementTypeName type_ <<> ">" cppType (BT_List element) = "std::list<" <>> elementTypeName element <<> ">" -cppType (BT_Nullable element) = "bond::nullable<" <>> elementTypeName element <<> ">" +cppType (BT_Nullable element) = "::bond::nullable<" <>> elementTypeName element <<> ">" cppType (BT_Vector element) = "std::vector<" <>> elementTypeName element <<> ">" cppType (BT_Set element) = "std::set<" <>> elementTypeName element <<> ">" cppType (BT_Map key value) = "std::map<" <>> elementTypeName key <<>> ", " <>> elementTypeName value <<> ">" -cppType (BT_Bonded type_) = "bond::bonded<" <>> elementTypeName type_ <<> ">" +cppType (BT_Bonded type_) = "::bond::bonded<" <>> elementTypeName type_ <<> ">" cppType (BT_TypeParam param) = pureText $ paramName param cppType (BT_UserDefined a@Alias {..} args) = aliasTypeName a args cppType (BT_UserDefined decl args) = declQualifiedTypeName decl <<>> (angles <$> commaSepTypeNames args) @@ -370,8 +370,8 @@ cppTypeCustomAlloc alloc BT_MetaName = cppTypeCustomAlloc alloc BT_String cppTypeCustomAlloc alloc BT_MetaFullName = cppTypeCustomAlloc alloc BT_String cppTypeCustomAlloc alloc (BT_List element) = "std::list<" <>> elementTypeName element <<>> ", " <>> allocator alloc element <<> ">" -cppTypeCustomAlloc alloc (BT_Nullable element) | isStruct element = "bond::nullable<" <>> elementTypeName element <<> ", " <> alloc <> ">" -cppTypeCustomAlloc _lloc (BT_Nullable element) = "bond::nullable<" <>> elementTypeName element <<> ">" +cppTypeCustomAlloc alloc (BT_Nullable element) | isStruct element = "::bond::nullable<" <>> elementTypeName element <<> ", " <> alloc <> ">" +cppTypeCustomAlloc _lloc (BT_Nullable element) = "::bond::nullable<" <>> elementTypeName element <<> ">" cppTypeCustomAlloc alloc (BT_Vector element) = "std::vector<" <>> elementTypeName element <<>> ", " <>> allocator alloc element <<> ">" cppTypeCustomAlloc alloc (BT_Set element) = "std::set<" <>> elementTypeName element <<>> comparer element <<>> allocator alloc element <<> ">" cppTypeCustomAlloc alloc (BT_Map key value) = "std::map<" <>> elementTypeName key <<>> ", " <>> elementTypeName value <<>> comparer key <<>> pairAllocator alloc key value <<> ">"
tests/Main.hs view
@@ -10,7 +10,7 @@ tests :: TestTree tests = testGroup "Compiler tests" [ testGroup "AST" - [ localOption (QuickCheckMaxSize 15) $ + [ localOption (QuickCheckMaxSize 6) $ testProperty "roundtrip" roundtripAST , testGroup "Compare .bond and .json" [ testCase "attributes" $ compareAST "attributes" @@ -27,6 +27,7 @@ , testCase "simple service syntax" $ compareAST "service" , testCase "service attributes" $ compareAST "service_attributes" , testCase "generic service" $ compareAST "generic_service" + , testCase "documentation example" $ compareAST "example" ] ] , testGroup "SchemaDef" @@ -97,6 +98,20 @@ ] "basic_types" ] + , testGroup "Comm" + [ verifyCppCommCodegen + [ "c++" + ] + "service" + , verifyCppCommCodegen + [ "c++" + ] + "generic_service" + , verifyCppCommCodegen + [ "c++" + ] + "service_attributes" + ] , testGroup "C#" [ verifyCsCodegen "attributes" , verifyCsCodegen "basic_types"
tests/Tests/Codegen.hs view
@@ -7,6 +7,7 @@ module Tests.Codegen ( verifyCodegen , verifyCppCodegen + , verifyCppCommCodegen , verifyApplyCodegen , verifyCsCodegen , verifyCsCommCodegen @@ -61,6 +62,14 @@ "bond::SimpleBinaryWriter<bond::OutputBuffer>" ] +verifyCppCommCodegen :: [String] -> FilePath -> TestTree +verifyCppCommCodegen args baseName = + testGroup baseName $ + map (verifyFile (processOptions args) baseName cppTypeMapping "") + [ comm_h + , types_cpp + , types_comm_cpp + ] verifyCsCommCodegen :: [String] -> FilePath -> TestTree verifyCsCommCodegen args baseName = @@ -95,6 +104,7 @@ templates Cpp {..} = [ reflection_h , types_cpp + , types_comm_cpp , types_h header enum_header allocator ] templates Cs {..} =