bond 0.12.1.0 → 0.13.0.0
raw patch · 12 files changed
+30/−614 lines, 12 filesnew-uploader
Files
- Main.hs +4/−9
- Options.hs +0/−4
- bond.cabal +7/−12
- src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs +1/−2
- src/Language/Bond/Codegen/Cpp/Grpc_cpp.hs +0/−33
- src/Language/Bond/Codegen/Cpp/Grpc_h.hs +0/−237
- src/Language/Bond/Codegen/Cpp/Types_h.hs +1/−1
- src/Language/Bond/Codegen/Cs/Grpc_cs.hs +0/−241
- src/Language/Bond/Codegen/Cs/Util.hs +7/−1
- src/Language/Bond/Codegen/Templates.hs +0/−6
- tests/TestMain.hs +10/−37
- tests/Tests/Codegen.hs +0/−31
Main.hs view
@@ -94,9 +94,7 @@ , (Simple, ProtocolWriter " ::bond::SimpleBinaryWriter<::bond::OutputBuffer>") ] templates = concat $ map snd $ filter fst codegen_templates - codegen_templates = [ (core_enabled, core_files) - , (grpc_enabled, [grpc_h export_attribute, grpc_cpp]) - ] + codegen_templates = [ (core_enabled, core_files) ] core_files = [ reflection_h export_attribute , types_h export_attribute header enum_header allocator alloc_ctors_enabled type_aliases_enabled scoped_alloc_enabled @@ -123,9 +121,7 @@ then ConstructorParameters else DefaultWithProtectedBase templates = concat $ map snd $ filter fst codegen_templates - codegen_templates = [ (structs_enabled, [types_cs Class fieldMapping constructorOptions]) - , (grpc_enabled, [grpc_cs]) - ] + codegen_templates = [ (structs_enabled, [types_cs Class fieldMapping constructorOptions]) ] csCodegen _ = error "csCodegen: impossible happened." anyServiceInheritance :: [Declaration] -> Bool @@ -142,9 +138,8 @@ namespaceMapping <- parseNamespaceMappings $ namespace options (Bond imports namespaces declarations) <- parseFile (import_dir options) file let mappingContext = MappingContext typeMapping aliasMapping namespaceMapping namespaces - case (anyServiceInheritance declarations, service_inheritance_enabled options, grpc_enabled options) of - (True, False, _) -> fail "Use --enable-service-inheritance to enable service inheritance syntax." - (True, True, True) -> fail "Service inheritance is not supported in gRPC codegen." + case (anyServiceInheritance declarations, service_inheritance_enabled options) of + (True, False) -> fail "Use --enable-service-inheritance to enable service inheritance syntax." _ -> forM_ templates $ \template -> do let (suffix, code) = template mappingContext baseName imports declarations let fileName = baseName ++ suffix
Options.hs view
@@ -40,7 +40,6 @@ , jobs :: Maybe Int , no_banner :: Bool , core_enabled :: Bool - , grpc_enabled :: Bool , alloc_ctors_enabled :: Bool , type_aliases_enabled :: Bool , scoped_alloc_enabled :: Bool @@ -58,7 +57,6 @@ , jobs :: Maybe Int , no_banner :: Bool , structs_enabled :: Bool - , grpc_enabled :: Bool , service_inheritance_enabled :: Bool , constructor_parameters :: Bool } @@ -96,7 +94,6 @@ , jobs = def &= opt "0" &= typ "NUM" &= name "j" &= help "Run NUM jobs simultaneously (or '$ncpus' if no NUM is not given)" , no_banner = def &= help "Omit the banner at the top of generated files" , core_enabled = True &= explicit &= name "core" &= help "Generate core serialization definitions (true by default, --core=false to disable)" - , grpc_enabled = False &= explicit &= name "grpc" &= help "Generate gRPC definitions" , alloc_ctors_enabled = False &= explicit &= name "alloc-ctors" &= help "Generate constructors with allocator argument" , type_aliases_enabled = False &= explicit &= name "type-aliases" &= help "Generate type aliases" , scoped_alloc_enabled = False &= explicit &= name "scoped-alloc" &= help "Use std::scoped_allocator_adaptor for strings and containers" @@ -111,7 +108,6 @@ , readonly_properties = def &= name "r" &= help "Generate private property setters" , fields = def &= name "f" &= help "Generate public fields rather than properties" , structs_enabled = True &= explicit &= name "structs" &= help "Generate C# types for Bond structs and enums (true by default, use \"--structs=false\" to disable)" - , grpc_enabled = False &= explicit &= name "grpc" &= help "Generate C# services and proxies for gRPC" , constructor_parameters = def &= explicit &= name "preview-constructor-parameters" &= help "PREVIEW FEATURE: Generate a constructor that takes all the fields as parameters. Typically used with readonly-properties." } &= name "c#" &=
bond.cabal view
@@ -1,13 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0. +-- This file has been generated from package.yaml by hpack version 0.35.0. -- -- see: https://github.com/sol/hpack --- --- hash: 5f829cf187d9630385924b752fae193c51da82b2d9bfc0ef8f38f23a638fc604 name: bond -version: 0.12.1.0 +version: 0.13.0.0 synopsis: Bond schema compiler and code generator description: Bond is a cross-platform framework for handling schematized data. It supports cross-language de/serialization and powerful generic mechanisms for efficiently manipulating data. . This package contains a library for parsing the Bond schema definition language and performing template-based code generation. The library includes built-in templates for generating standard Bond C++ and C# code, as well as utilities for writing custom codegen templates. . The package also contains a command-line compiler/codegen tool, named gbc, which is primarily used to generate code for C++ and C# programs using Bond. category: Language, Compiler, Code Generation @@ -35,13 +33,10 @@ Language.Bond.Codegen.Cpp.Apply_h Language.Bond.Codegen.Cpp.ApplyOverloads Language.Bond.Codegen.Cpp.Enum_h - Language.Bond.Codegen.Cpp.Grpc_cpp - Language.Bond.Codegen.Cpp.Grpc_h Language.Bond.Codegen.Cpp.Reflection_h Language.Bond.Codegen.Cpp.Types_cpp Language.Bond.Codegen.Cpp.Types_h Language.Bond.Codegen.Cpp.Util - Language.Bond.Codegen.Cs.Grpc_cs Language.Bond.Codegen.Cs.Types_cs Language.Bond.Codegen.Cs.Util Language.Bond.Codegen.CustomMapping @@ -74,13 +69,13 @@ , shakespeare , text , unordered-containers + default-language: Haskell2010 if os(windows) && arch(i386) ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware if os(windows) && arch(x86_64) ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va if flag(warningsAsErrors) ghc-options: -Wall -Werror - default-language: Haskell2010 executable gbc main-is: Main.hs @@ -89,7 +84,7 @@ Options Paths_bond hs-source-dirs: - ./. + ./ build-depends: aeson , async @@ -107,6 +102,7 @@ , shakespeare , text , unordered-containers + default-language: Haskell2010 if os(windows) && arch(i386) ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware if os(windows) && arch(x86_64) @@ -115,7 +111,6 @@ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Werror else ghc-options: -threaded -rtsopts -with-rtsopts=-N - default-language: Haskell2010 test-suite gbc-tests type: exitcode-stdio-1.0 @@ -130,7 +125,7 @@ Options hs-source-dirs: tests - ./. + ./ build-depends: Diff , HUnit @@ -156,6 +151,7 @@ , tasty-quickcheck , text , unordered-containers + default-language: Haskell2010 if os(windows) && arch(i386) ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware if os(windows) && arch(x86_64) @@ -164,4 +160,3 @@ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Werror else ghc-options: -threaded -rtsopts -with-rtsopts=-N - default-language: Haskell2010
src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs view
@@ -33,8 +33,7 @@ const ::bond::bonded< #{qualifiedName}>& value); #{extern}template #{attr} - bool Apply(const ::bond::InitSchemaDef& transform, - const #{qualifiedName}& value); + bool Apply< #{qualifiedName}>(const ::bond::InitSchemaDef& transform); #{extern}template #{attr} bool Apply(const ::bond::Null& transform,
− src/Language/Bond/Codegen/Cpp/Grpc_cpp.hs
@@ -1,33 +0,0 @@--- 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.Grpc_cpp (grpc_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/_grpc.cpp containing --- definitions of helper functions and schema metadata static variables. -grpc_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text) -grpc_cpp cpp file _imports declarations = ("_grpc.cpp", [lt| -#include "#{file}_reflection.h" -#include "#{file}_grpc.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/Grpc_h.hs
@@ -1,237 +0,0 @@--- 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.Grpc_h (grpc_h) where - -import System.FilePath -import Data.Maybe (isNothing) -import Data.Monoid -import Prelude -import qualified Data.Text.Lazy as L -import Data.Text.Lazy.Builder -import Text.Shakespeare.Text -import Language.Bond.Util -import Language.Bond.Syntax.Types -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/_grpc.h containing declarations of --- of service interface and proxy. -grpc_h :: Maybe String -> MappingContext -> String -> [Import] -> [Declaration] -> (String, L.Text) -grpc_h export_attribute cpp file imports declarations = ("_grpc.h", [lt| -#pragma once - -#include "#{file}_reflection.h" -#include "#{file}_types.h" -#{newlineSep 0 includeImport imports} -#{includeBondReflection} -#include <bond/core/bonded.h> -#include <bond/ext/grpc/reflection.h> -#include <bond/ext/grpc/detail/client.h> -#include <bond/ext/grpc/detail/service.h> - -#include <boost/optional/optional.hpp> -#include <functional> -#include <memory> - -#{CPP.openNamespace cpp} -#{doubleLineSep 1 grpc declarations} - -#{CPP.closeNamespace cpp} - -|]) - where - includeImport (Import path) = [lt|#include "#{dropExtension (slashForward path)}_grpc.h"|] - - idl = MappingContext idlTypeMapping [] [] [] - - cppType = getTypeName cpp - - payload = maybe "void" cppType - - bonded mt = bonded' (payload mt) - where - bonded' params = [lt|::bond::bonded<#{padLeft}#{params}>|] - where - paramsText = toLazyText params - padLeft = if L.head paramsText == ':' then [lt| |] else mempty - - includeBondReflection = - if usesBondVoid then [lt|#include <bond/core/bond_reflection.h>|] else mempty - where usesBondVoid = any declUses declarations - declUses Service {serviceMethods = methods} = any methodUses methods - declUses _ = False - methodUses Function {methodInput = input} = isNothing (methodTypeToMaybe input) - methodUses Event {} = True - - grpc s@Service{..} = [lt| -#{template}struct #{declName} final -{ - struct Schema - { - #{export_attr}static const ::bond::Metadata metadata; - - #{newlineSep 2 methodMetadata serviceMethods} - - public: struct service - { - #{newlineSep 3 (uncurry methodTemplate) (zip serviceMethods uniqueMethodTemplateStructNames)} - }; - - private: typedef boost::mpl::list<> methods0; - #{newlineSep 2 pushMethod indexedMethods} - - public: typedef #{typename}methods#{length serviceMethods}::type methods; - - #{constructor} - }; - - class #{proxyName} : public ::bond::ext::grpc::detail::client - { - public: - using ::bond::ext::grpc::detail::client::client; - - #{doubleLineSep 2 publicProxyMethodDecl serviceMethods} - - private: - #{newlineSep 2 privateProxyMethodDecl serviceMethods} - }; - - class #{serviceName} : public ::bond::ext::grpc::detail::service - { - public: - explicit #{serviceName}(const ::bond::ext::grpc::Scheduler& scheduler) - : ::bond::ext::grpc::detail::service( - scheduler, - { - #{commaLineSep 5 serviceMethodName serviceMethods} - }) - {} - - #{newlineSep 2 serviceVirtualMethod serviceMethods} - - private: - void start() override - { - _data.emplace(*this); - } - - struct data - { - explicit data(#{serviceName}& s) - : _s(s) - {} - - #{serviceName}& _s; - #{newlineSep 3 serviceDataMember serviceMethodsWithIndex} - }; - - ::boost::optional<data> _data; - }; -}; - -#{onlyTemplate $ CPP.schemaMetadata cpp s} -|] - where - template = CPP.template s - onlyTemplate x = if null declParams then mempty else x - onlyNonTemplate x = if null declParams then x else mempty - typename = onlyTemplate [lt|typename |] - - export_attr = onlyNonTemplate $ optional (\a -> [lt|#{a} - |]) export_attribute - - methodMetadataVar m = [lt|s_#{methodName m}_metadata|] - - methodMetadata m = - [lt|private: #{export_attr}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 3 static serviceMethods} - }|] - where - static m = [lt|(void)#{methodMetadataVar m};|] - - -- unique names for each of the MethodTemplate derived structs that - -- we need to generate in the same order as serviceMethods. - uniqueMethodTemplateStructNames :: [String] - uniqueMethodTemplateStructNames = uniqueNames (map (\n -> n ++ "_type") methodNames) reservedNames - where - methodNames = map methodName serviceMethods - reservedNames = methodTemplateReservedNames ++ methodNames - -- methodTemplateReservedNames are names used in ::bond::reflection::MethodTemplate<> - methodTemplateReservedNames = ["MethodTemplate", "service_type", "input_type", "result_type", "metadata", "method"] - - methodTemplate :: Method -> String -> L.Text - methodTemplate m methodTemplateStructName = [lt|typedef struct #{methodTemplateStructName} : ::bond::ext::grpc::reflection::MethodTemplate<#{declName}, #{payload $ methodTypeToMaybe (methodInput m)}, #{resultType m}, &#{methodMetadataVar m}> {} #{methodName m};|] - - proxyName = "Client" :: String - serviceName = "Service" :: String - - serviceMethodsWithIndex :: [(Integer,Method)] - serviceMethodsWithIndex = zip [0..] serviceMethods - - publicProxyMethodDecl Function{methodInput = Void, ..} = [lt|void Async#{methodName}(const ::std::function<void(::bond::ext::grpc::unary_call_result<#{payload (methodTypeToMaybe methodResult)}>)>& cb, ::std::shared_ptr<::grpc::ClientContext> context = {}) - { - ::bond::ext::grpc::detail::client::dispatch(_m#{methodName}, std::move(context), cb); - } - ::std::future<::bond::ext::grpc::unary_call_result<#{payload (methodTypeToMaybe methodResult)}>> Async#{methodName}(::std::shared_ptr<::grpc::ClientContext> context = {}) - { - return ::bond::ext::grpc::detail::client::dispatch<#{payload (methodTypeToMaybe methodResult)}>(_m#{methodName}, std::move(context)); - }|] - publicProxyMethodDecl Function{..} = [lt|void Async#{methodName}(const #{bonded (methodTypeToMaybe methodInput)}& request, const ::std::function<void(::bond::ext::grpc::unary_call_result<#{payload (methodTypeToMaybe methodResult)}>)>& cb, ::std::shared_ptr<::grpc::ClientContext> context = {}) - { - ::bond::ext::grpc::detail::client::dispatch(_m#{methodName}, std::move(context), cb, request); - } - std::future<::bond::ext::grpc::unary_call_result<#{payload (methodTypeToMaybe methodResult)}>> Async#{methodName}(const #{bonded (methodTypeToMaybe methodInput)}& request, ::std::shared_ptr<::grpc::ClientContext> context = {}) - { - return ::bond::ext::grpc::detail::client::dispatch<#{payload (methodTypeToMaybe methodResult)}>(_m#{methodName}, std::move(context), request); - } - void Async#{methodName}(const #{payload (methodTypeToMaybe methodInput)}& request, const ::std::function<void(::bond::ext::grpc::unary_call_result<#{payload (methodTypeToMaybe methodResult)}>)>& cb, ::std::shared_ptr<::grpc::ClientContext> context = {}) - { - ::bond::ext::grpc::detail::client::dispatch(_m#{methodName}, std::move(context), cb, request); - } - ::std::future<::bond::ext::grpc::unary_call_result<#{payload (methodTypeToMaybe methodResult)}>> Async#{methodName}(const #{payload (methodTypeToMaybe methodInput)}& request, ::std::shared_ptr<::grpc::ClientContext> context = {}) - { - return ::bond::ext::grpc::detail::client::dispatch<#{payload (methodTypeToMaybe methodResult)}>(_m#{methodName}, std::move(context), request); - }|] - publicProxyMethodDecl Event{methodInput = Void, ..} = [lt|void Async#{methodName}(::std::shared_ptr<::grpc::ClientContext> context = {}) - { - ::bond::ext::grpc::detail::client::dispatch(_m#{methodName}, std::move(context), {}); - }|] - publicProxyMethodDecl Event{..} = [lt|void Async#{methodName}(const #{bonded (methodTypeToMaybe methodInput)}& request, ::std::shared_ptr<::grpc::ClientContext> context = {}) - { - ::bond::ext::grpc::detail::client::dispatch(_m#{methodName}, std::move(context), {}, request); - } - void Async#{methodName}(const #{payload (methodTypeToMaybe methodInput)}& request, ::std::shared_ptr<::grpc::ClientContext> context = {}) - { - ::bond::ext::grpc::detail::client::dispatch(_m#{methodName}, std::move(context), {}, request); - }|] - - privateProxyMethodDecl f = [lt|const ::bond::ext::grpc::detail::client::Method _m#{methodName f}{ ::bond::ext::grpc::detail::client::make_method("/#{getDeclTypeName idl s}/#{methodName f}") };|] - - serviceMethodName f = [lt|"/#{getDeclTypeName idl s}/#{methodName f}"|] - - serviceDataMember (index,f) = [lt|::bond::ext::grpc::detail::service::Method _m#{index}{ _s, #{index}, ::bond::ext::grpc::detail::service::make_callback(&#{serviceName}::#{methodName f}, _s) };|] - - serviceVirtualMethod f = [lt|virtual void #{methodName f}(::bond::ext::grpc::unary_call<#{payload $ methodTypeToMaybe $ methodInput f}, #{resultType f}>) = 0;|] - - resultType Function{..} = payload (methodTypeToMaybe methodResult) - resultType Event{} = "::bond::reflection::nothing" - - grpc _ = mempty
src/Language/Bond/Codegen/Cpp/Types_h.hs view
@@ -39,7 +39,7 @@ #{newlineBeginSep 0 includeHeader userHeaders} #include <bond/core/bond_version.h> -#if BOND_VERSION < 0x0900 +#if BOND_VERSION < 0x0b00 #error This file was generated by a newer version of the Bond compiler and is incompatible with your version of the Bond library. #endif
− src/Language/Bond/Codegen/Cs/Grpc_cs.hs
@@ -1,241 +0,0 @@--- Copyright (c) Microsoft. All rights reserved. --- Licensed under the MIT license. See LICENSE file in the project root for full license information. - -{-# LANGUAGE OverloadedStrings, QuasiQuotes, RecordWildCards #-} - -module Language.Bond.Codegen.Cs.Grpc_cs ( - grpc_cs) -where - -import Data.Monoid -import qualified Data.Text.Lazy as L -import qualified Language.Bond.Codegen.Cs.Util as CS -import Language.Bond.Codegen.TypeMapping -import Language.Bond.Codegen.Util -import Language.Bond.Syntax.Types hiding (methodTypeToMaybe) -import Language.Bond.Util -import Prelude -import Text.Shakespeare.Text - --- | Represents a parameter in an abstract server method. --- --- This data definition would be in the where clause of grpc_cs if data --- definitions were permitted in where clauses. -data CsServerMethodParam = CsServerMethodParam { name :: L.Text, csType :: L.Text } - --- | Generates a C# parameter declaration for a server method parameter. -csServerParamDecl :: CsServerMethodParam -> L.Text -csServerParamDecl (CsServerMethodParam {..}) = [lt|#{csType} #{name}|] - --- | Contains splicable text for a client method's first parameter. Create --- one of these with the function csClientRequestParam. Some kinds of --- methods don't need a first param, so some of the record's fields may be --- empty. If non-empty, the correct comma and space are included so this --- text can just be spliced in. --- --- This data definition would be in the where clause of grpc_cs if data --- definitions were permitted in where clauses. -data CsClientRequestParam = CsClientRequestParam - { bareParam :: L.Text -- bare param declaration: what the caller passes in, if applicable - , messageParam :: L.Text -- param declaration wrapped in an IMessage - , toMessage :: L.Text -- code to create an IMessage for the request - , forwardMessageParam :: L.Text -- code to forward the IMessage param on to the CallInvoker - } - --- | Codegen template for generating code containing declarations of --- of services including proxies and services files for gRPC integration. -grpc_cs :: MappingContext -> String -> [Import] -> [Declaration] -> (String, L.Text) -grpc_cs cs _ _ declarations = ("_grpc.cs", [lt| -#{CS.disableCscWarnings} -#{CS.disableReSharperWarnings} - -namespace #{csNamespace} -{ - using System.Collections.Generic; - - #{doubleLineSep 1 grpc declarations} -} // #{csNamespace} -|]) - where - csNamespace = sepBy "." toText $ getNamespace cs - idl = MappingContext idlTypeMapping [] [] [] - - grpc s@Service{..} = [lt|#{CS.typeAttributes cs s}public static class #{declName}#{generics} #{genericsWhere} - { - static readonly string ServiceName = "#{getDeclTypeName idl s}"; - - #{doubleLineSep 2 methodDeclaration serviceMethods} - - public abstract class #{declName}Base - { - #{doubleLineSep 3 serverBaseMethods serviceMethods} - } - - public class #{declName}Client : global::Grpc.Core.ClientBase<#{declName}Client> - { - public #{declName}Client(global::Grpc.Core.Channel channel) : base(channel) - { - } - - public #{declName}Client(global::Grpc.Core.CallInvoker callInvoker) : base(callInvoker) - { - } - - protected #{declName}Client() : base() - { - } - - protected #{declName}Client(global::Grpc.Core.ClientBase.ClientBaseConfiguration configuration) : base(configuration) - { - } - - #{doubleLineSep 3 clientMethods serviceMethods} - - protected override #{declName}Client NewInstance(global::Grpc.Core.ClientBase.ClientBaseConfiguration configuration) - { - return new #{declName}Client(configuration); - } - } - - public static global::Grpc.Core.ServerServiceDefinition BindService(#{declName}Base serviceImpl) - { - return global::Grpc.Core.ServerServiceDefinition.CreateBuilder() - #{newlineSep 5 serviceMethodBuilder serviceMethods} - .Build(); - } - } -|] - where - methodNames = map methodName serviceMethods - - uniqImplName name = uniqueName (name ++ "_impl") methodNames - - csTypeOf Void = "global::Bond.Void" - csTypeOf (Unary t) = getTypeName cs t - csTypeOf (Streaming t) = getTypeName cs t - - csRequestTypeName (Function {..}) = csTypeOf methodInput - csRequestTypeName (Event {..}) = csTypeOf methodInput - - csResponseTypeName (Function {..}) = csTypeOf methodResult - csResponseTypeName Event{} = csTypeOf Void - - messageVoid = [lt|global::Bond.Grpc.IMessage<global::Bond.Void>|] - - messageOf :: Type -> L.Text - messageOf t = [lt|global::Bond.Grpc.IMessage<#{getTypeName cs t}>|] - - methodTypeEnum :: Method -> L.Text - methodTypeEnum (Function {..}) = case (methodResult, methodInput) of - (Streaming _, Streaming _) -> [lt|global::Grpc.Core.MethodType.DuplexStreaming|] - (Streaming _, _) -> [lt|global::Grpc.Core.MethodType.ServerStreaming|] - (_, Streaming _) -> [lt|global::Grpc.Core.MethodType.ClientStreaming|] - _ -> [lt|global::Grpc.Core.MethodType.Unary|] - methodTypeEnum (Event {..}) = case methodInput of - Streaming _ -> error ("Unexpected event '" ++ methodName ++ "' with Streaming parameter") -- the parser should have rejected this - _ -> [lt|global::Grpc.Core.MethodType.Unary|] - - generics = angles $ sepBy ", " paramName declParams - - genericsWhere = sepBy " " addWhere declParams - where - addWhere a = [lt|where #{paramName a} : class|] - - methodDeclaration m = [lt|static readonly global::Grpc.Core.Method<global::Bond.Grpc.IMessage<#{csRequestTypeName m}>, global::Bond.Grpc.IMessage<#{csResponseTypeName m}>> Method_#{methodName m} = new global::Grpc.Core.Method<global::Bond.Grpc.IMessage<#{csRequestTypeName m}>, global::Bond.Grpc.IMessage<#{csResponseTypeName m}>>( - #{methodTypeEnum m}, - ServiceName, - "#{methodName m}", - global::Bond.Grpc.Marshaller<#{csRequestTypeName m}>.Instance, - global::Bond.Grpc.Marshaller<#{csResponseTypeName m}>.Instance);|] - - serverMethodParams :: MethodType -> MethodType -> [CsServerMethodParam] - serverMethodParams reqType respType = (forRequest reqType) ++ (forResponse respType) ++ context - where - forRequest Void = [(CsServerMethodParam [lt|request|] messageVoid)] - forRequest (Unary t) = [(CsServerMethodParam [lt|request|] [lt|#{messageOf t}|])] - forRequest (Streaming t) = [(CsServerMethodParam [lt|requests|] [lt|Grpc.Core.IAsyncStreamReader<#{messageOf t}>|])] - forResponse Void = [] - forResponse (Unary _) = [] - forResponse (Streaming t) = [(CsServerMethodParam [lt|responses|] [lt|Grpc.Core.IAsyncStreamWriter<#{messageOf t}>|])] - context = [(CsServerMethodParam [lt|context|] [lt|global::Grpc.Core.ServerCallContext|])] - - -- | For functions (not events), given the result type, compute the - -- C# abstract method return type. - csServerFunctionReturn :: MethodType -> L.Text - csServerFunctionReturn Void = [lt|global::System.Threading.Tasks.Task<#{messageVoid}>|] - csServerFunctionReturn (Unary t) = [lt|global::System.Threading.Tasks.Task<#{messageOf t}>|] - csServerFunctionReturn (Streaming _) = [lt|global::System.Threading.Tasks.Task|] - - serverBaseMethods Function{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public abstract #{csServerFunctionReturn methodResult} #{methodName}(#{csParams});|] - where params = serverMethodParams methodInput methodResult - csParams = commaSep csServerParamDecl params - - serverBaseMethods Event{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public abstract global::System.Threading.Tasks.Task #{methodName}(#{csParams}); - - internal global::System.Threading.Tasks.Task<#{messageVoid}> #{uniqImplName methodName}(#{csParams}) { - return global::Bond.Grpc.Internal.NothingCallHandler.Handle(#{handlerArgs}); - }|] - where params = serverMethodParams methodInput Void - csParams = commaSep csServerParamDecl params - handlerArgs = commaSep id ((L.pack methodName):(map name params)) - - -- | For functions (not events), given the input and result types, - -- compute the C# client method return type. - csClientFunctionReturn :: MethodType -> MethodType -> L.Text - csClientFunctionReturn (Streaming input) (Streaming result) = [lt|global::Grpc.Core.AsyncDuplexStreamingCall<#{messageOf input}, #{messageOf result}>|] - csClientFunctionReturn (Streaming input) (Unary result) = [lt|global::Grpc.Core.AsyncClientStreamingCall<#{messageOf input}, #{messageOf result}>|] - csClientFunctionReturn _ (Streaming result) = [lt|global::Grpc.Core.AsyncServerStreamingCall<#{messageOf result}>|] - csClientFunctionReturn _ (Unary result) = [lt|global::Grpc.Core.AsyncUnaryCall<#{messageOf result}>|] - csClientFunctionReturn _ Void = [lt|global::Grpc.Core.AsyncUnaryCall<#{messageVoid}>|] - - -- | Given the input type, compute the client method parameter. - csClientRequestParam :: MethodType -> CsClientRequestParam - csClientRequestParam Void = CsClientRequestParam - { bareParam = mempty - , messageParam = [lt|#{messageVoid} request, |] - , toMessage = [lt|global::Bond.Grpc.Message.Void, |] - , forwardMessageParam = [lt|, request|] } - csClientRequestParam (Unary t) = CsClientRequestParam - { bareParam = [lt|#{getTypeName cs t} request, |] - , messageParam = [lt|#{messageOf t} request, |] - , toMessage = [lt|global::Bond.Grpc.Message.From(request), |] - , forwardMessageParam = [lt|, request|] } - csClientRequestParam (Streaming _) = CsClientRequestParam - { bareParam = mempty - , messageParam = mempty - , toMessage = mempty - , forwardMessageParam = mempty } - - -- | Given the input and result types, compute the call invoker needed. - clientCallInvoker :: MethodType -> MethodType -> L.Text - clientCallInvoker (Streaming _) (Streaming _) = [lt|AsyncDuplexStreamingCall|] - clientCallInvoker (Streaming _) (Unary _) = [lt|AsyncClientStreamingCall|] - clientCallInvoker (Unary _) (Streaming _) = [lt|AsyncServerStreamingCall|] - clientCallInvoker _ _ = [lt|AsyncUnaryCall|] - - clientMethods Function{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public virtual #{csClientFunctionReturn methodInput methodResult} #{methodName}Async(#{bareParam requestParam}global::Grpc.Core.Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return #{methodName}Async(#{toMessage requestParam}new global::Grpc.Core.CallOptions(headers, deadline, cancellationToken)); - } - - #{CS.schemaAttributes 3 methodAttributes}public virtual #{csClientFunctionReturn methodInput methodResult} #{methodName}Async(#{messageParam requestParam}global::Grpc.Core.CallOptions options) - { - return CallInvoker.#{clientCallInvoker methodInput methodResult}(Method_#{methodName}, null, options#{forwardMessageParam requestParam}); - }|] - where requestParam = csClientRequestParam methodInput - - clientMethods Event{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public virtual void #{methodName}Async(#{bareParam requestParam}global::Grpc.Core.Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - #{methodName}Async(#{toMessage requestParam}new global::Grpc.Core.CallOptions(headers, deadline, cancellationToken)); - } - - #{CS.schemaAttributes 3 methodAttributes}public virtual void #{methodName}Async(#{messageParam requestParam}global::Grpc.Core.CallOptions options) - { - global::Bond.Grpc.Internal.NothingCallInvoker.NothingCall(CallInvoker, Method_#{methodName}, null, options#{forwardMessageParam requestParam}); - }|] - where requestParam = csClientRequestParam methodInput - - serviceMethodBuilder Function{..} = [lt|.AddMethod(Method_#{methodName}, serviceImpl.#{methodName})|] - serviceMethodBuilder Event{..} = [lt|.AddMethod(Method_#{methodName}, serviceImpl.#{uniqImplName methodName})|] - - grpc _ = mempty
src/Language/Bond/Codegen/Cs/Util.hs view
@@ -16,7 +16,8 @@ import Data.Int (Int64) import Data.Monoid import Prelude -import Data.Text.Lazy (Text) +import Data.Text.Lazy (Text, isPrefixOf) +import Data.Text.Lazy.Builder (toLazyText) import Text.Shakespeare.Text import Paths_bond (version) import Data.Version (showVersion) @@ -112,15 +113,20 @@ constraint (TypeParam _ Nothing) = mempty constraint (TypeParam name (Just Value)) = [lt|where #{name} : struct|] +isImmutableCollection :: MappingContext -> Type -> Bool +isImmutableCollection cs t = [lt|System.Collections.Immutable.Immutable|] `isPrefixOf` toLazyText (getInstanceTypeName cs t) + -- Initial value for C# field/property or Nothing if C# implicit default is OK defaultValue :: MappingContext -> Field -> Maybe Text defaultValue cs Field {fieldDefault = Nothing, ..} = implicitDefault fieldType where newInstance t = Just [lt|new #{getInstanceTypeName cs t}()|] + staticEmptyField t = Just [lt|#{getInstanceTypeName cs t}.Empty|] implicitDefault (BT_Bonded t) = Just [lt|global::Bond.Bonded<#{getTypeName cs t}>.Empty|] implicitDefault t@(BT_TypeParam _) = Just [lt|global::Bond.GenericFactory.Create<#{getInstanceTypeName cs t}>()|] implicitDefault t@BT_Blob = newInstance t implicitDefault t@(BT_UserDefined a@Alias {..} args) + | isImmutableCollection cs t = staticEmptyField t | customAliasMapping cs a = newInstance t | otherwise = implicitDefault $ resolveAlias a args implicitDefault t
src/Language/Bond/Codegen/Templates.hs view
@@ -41,14 +41,11 @@ , apply_h , apply_cpp , Protocol(..) - , grpc_h - , grpc_cpp -- ** C# , FieldMapping(..) , StructMapping(..) , ConstructorOptions(..) , types_cs - , grpc_cs -- ** Java , JavaFieldMapping(..) , class_java @@ -63,10 +60,7 @@ import Language.Bond.Codegen.Cpp.Reflection_h import Language.Bond.Codegen.Cpp.Types_cpp import Language.Bond.Codegen.Cpp.Types_h -import Language.Bond.Codegen.Cpp.Grpc_cpp -import Language.Bond.Codegen.Cpp.Grpc_h import Language.Bond.Codegen.Cs.Types_cs -import Language.Bond.Codegen.Cs.Grpc_cs import Language.Bond.Codegen.Java.Class_java import Language.Bond.Codegen.Java.Enum_java -- redundant imports for haddock
tests/TestMain.hs view
@@ -124,11 +124,6 @@ [ "c++" , "--export-attribute=DllExport" ] - "service" - , verifyExportsCodegen - [ "c++" - , "--export-attribute=DllExport" - ] "with_enum_header" ] , verifyCodegen @@ -136,20 +131,6 @@ , "--namespace=tests=nsmapped" ] "basic_types_nsmapped" - , testGroup "Grpc" - [ verifyCppGrpcCodegen - [ "c++" - ] - "service" - , verifyCppGrpcCodegen - [ "c++" - ] - "generic_service" - , verifyCppGrpcCodegen - [ "c++" - ] - "service_attributes" - ] ] , testGroup "C#" [ verifyCsCodegen "attributes" @@ -163,6 +144,16 @@ , verifyCsCodegen "inheritance" , verifyCsCodegen "aliases" , verifyCsCodegen "complex_inheritance" + , verifyCodegen + [ "c#" + , "--using=ImmutableArray=System.Collections.Immutable.ImmutableArray<{0}>" + , "--using=ImmutableList=System.Collections.Immutable.ImmutableList<{0}>" + , "--using=ImmutableHashSet=System.Collections.Immutable.ImmutableHashSet<{0}>" + , "--using=ImmutableSortedSet=System.Collections.Immutable.ImmutableSortedSet<{0}>" + , "--using=ImmutableDictionary=System.Collections.Immutable.ImmutableDictionary<{0},{1}>" + , "--using=ImmutableSortedDictionary=System.Collections.Immutable.ImmutableSortedDictionary<{0},{1}>" + ] + "immutable_collections" , verifyCodegenVariation [ "c#" , "--preview-constructor-parameters" @@ -199,24 +190,6 @@ ] "empty_struct" "constructor-parameters" - , testGroup "Grpc" - [ verifyCsGrpcCodegen - [ "c#" - ] - "service" - , verifyCsGrpcCodegen - [ "c#" - ] - "generic_service" - , verifyCsGrpcCodegen - [ "c#" - ] - "service_attributes" - , verifyCsGrpcCodegen - [ "c#" - ] - "streaming" - ] ] , testGroup "Java" [ verifyJavaCodegen "attributes"
tests/Tests/Codegen.hs view
@@ -8,11 +8,9 @@ ( verifyCodegen , verifyCodegenVariation , verifyCppCodegen - , verifyCppGrpcCodegen , verifyApplyCodegen , verifyExportsCodegen , verifyCsCodegen - , verifyCsGrpcCodegen , verifyJavaCodegen ) where @@ -85,35 +83,6 @@ [ reflection_h export_attribute , types_h export_attribute header enum_header allocator alloc_ctors_enabled type_aliases_enabled scoped_alloc_enabled ] - -verifyCppGrpcCodegen :: [String] -> FilePath -> TestTree -verifyCppGrpcCodegen args baseName = - testGroup baseName $ - map (verifyFile options baseName (cppExpandAliases (type_aliases_enabled options) cppTypeMapping) "") templates - where - options = processOptions args - templates = - [ grpc_h (export_attribute options) - , grpc_cpp - , types_cpp - ] - -verifyCsGrpcCodegen :: [String] -> FilePath -> TestTree -verifyCsGrpcCodegen args baseName = - testGroup baseName $ - map (verifyFile (processOptions args) baseName csTypeMapping "") - [ grpc_cs - , types_cs Class (fieldMapping (processOptions args)) (constructorOptions (processOptions args)) - ] - where - fieldMapping Cs {..} = if readonly_properties - then ReadOnlyProperties - else if fields - then PublicFields - else Properties - constructorOptions Cs {..} = if constructor_parameters - then ConstructorParameters - else DefaultWithProtectedBase verifyFiles :: Options -> FilePath -> FilePath -> [TestTree] verifyFiles options baseName variation =