Upgrading dependency to Thrift 0.12.0

This commit is contained in:
Renan DelValle 2018-11-27 18:03:50 -08:00
parent 3e4590dcc0
commit 356978cb42
No known key found for this signature in database
GPG key ID: C240AD6D6F443EC9
1302 changed files with 101701 additions and 26784 deletions

View file

@ -16,30 +16,37 @@
# specific language governing permissions and limitations
# under the License.
#
cmake_minimum_required(VERSION 2.8.12)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/thrift/version.h)
if(MSVC)
# The winflexbison generator outputs some macros that conflict with the Visual Studio 2010 copy of stdint.h
# This might be fixed in later versions of Visual Studio, but an easy solution is to include stdint.h first
if(HAVE_STDINT_H)
add_definitions(-D__STDC_FORMAT_MACROS)
add_definitions(-D__STDC_LIMIT_MACROS)
add_definitions(/FI"stdint.h")
endif(HAVE_STDINT_H)
endif()
find_package(FLEX REQUIRED)
find_package(BISON REQUIRED)
# create directory for thrifty and thriftl
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/thrift/)
# Create flex and bison files and build the lib parse static library
BISON_TARGET(thrifty ${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/thrifty.yy ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc)
FLEX_TARGET(thriftl ${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/thriftl.ll ${CMAKE_CURRENT_BINARY_DIR}/thrift/thriftl.cc)
ADD_FLEX_BISON_DEPENDENCY(thriftl thrifty)
# HACK: Work around the fact that bison crates a .hh file but we need a .h file
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.h
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.hh ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.h
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.hh
)
set(libparse_SOURCES
set(parse_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc
${CMAKE_CURRENT_BINARY_DIR}/thrift/thriftl.cc
${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.h
${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.hh
)
add_library(libparse STATIC ${libparse_SOURCES})
add_library(parse STATIC ${parse_SOURCES})
# Create the thrift compiler
set(compiler_core
@ -55,6 +62,9 @@ set(thrift-compiler_SOURCES
src/thrift/audit/t_audit.cpp
)
set(thrift_compiler_LANGS
)
# This macro adds an option THRIFT_COMPILER_${NAME}
# that allows enabling or disabling certain languages
macro(THRIFT_ADD_COMPILER name description initial)
@ -63,6 +73,7 @@ macro(THRIFT_ADD_COMPILER name description initial)
option(${enabler} ${description} ${initial})
if(${enabler})
list(APPEND thrift-compiler_SOURCES ${src})
list(APPEND thrift_compiler_LANGS ${name})
endif()
endmacro()
@ -74,6 +85,7 @@ THRIFT_ADD_COMPILER(as3 "Enable compiler for ActionScript 3" ON)
THRIFT_ADD_COMPILER(dart "Enable compiler for Dart" ON)
THRIFT_ADD_COMPILER(haxe "Enable compiler for Haxe" ON)
THRIFT_ADD_COMPILER(csharp "Enable compiler for C#" ON)
THRIFT_ADD_COMPILER(netcore "Enable compiler for .NET Core" ON)
THRIFT_ADD_COMPILER(py "Enable compiler for Python 2.0" ON)
THRIFT_ADD_COMPILER(rb "Enable compiler for Ruby" ON)
THRIFT_ADD_COMPILER(perl "Enable compiler for Perl" ON)
@ -94,6 +106,7 @@ THRIFT_ADD_COMPILER(go "Enable compiler for Go" ON)
THRIFT_ADD_COMPILER(d "Enable compiler for D" ON)
THRIFT_ADD_COMPILER(lua "Enable compiler for Lua" ON)
THRIFT_ADD_COMPILER(gv "Enable compiler for GraphViz" ON)
THRIFT_ADD_COMPILER(rs "Enable compiler for Rust" ON)
THRIFT_ADD_COMPILER(xml "Enable compiler for XML" ON)
# Thrift is looking for include files in the src directory
@ -103,6 +116,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} src)
if(NOT ${WITH_PLUGIN})
list(APPEND thrift-compiler_SOURCES ${compiler_core})
endif()
add_executable(thrift-compiler ${thrift-compiler_SOURCES})
if(${WITH_PLUGIN})
@ -111,7 +125,7 @@ if(${WITH_PLUGIN})
src/thrift/audit/t_audit.cpp
src/thrift/generate/t_cpp_generator.cc
)
target_link_libraries(thrift-bootstrap libparse)
target_link_libraries(thrift-bootstrap parse)
set(PLUGIN_GEN_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/thrift/plugin/plugin_types.h
@ -144,11 +158,12 @@ if(${WITH_PLUGIN})
LINK_AGAINST_THRIFT_LIBRARY(thrift-compiler thriftc)
endif()
set_target_properties(thrift-compiler PROPERTIES RUNTIME_OUTPUT_DIRECTORY bin/)
set_target_properties(thrift-compiler PROPERTIES OUTPUT_NAME thrift)
target_link_libraries(thrift-compiler libparse)
target_link_libraries(thrift-compiler parse)
install(TARGETS thrift-compiler DESTINATION "${BIN_INSTALL_DIR}")
install(TARGETS thrift-compiler DESTINATION bin)
if(${WITH_PLUGIN})
# Install the headers

View file

@ -71,7 +71,7 @@ compiler_core = src/thrift/common.h \
src/thrift/parse/parse.cc \
src/thrift/generate/t_generator.h \
src/thrift/generate/t_oop_generator.h \
src/thrift/generate/t_html_generator.h
src/thrift/generate/t_html_generator.h
thrift_SOURCES = src/thrift/main.h \
src/thrift/main.cc \
@ -87,6 +87,8 @@ thrift_SOURCES += src/thrift/generate/t_c_glib_generator.cc \
src/thrift/generate/t_dart_generator.cc \
src/thrift/generate/t_haxe_generator.cc \
src/thrift/generate/t_csharp_generator.cc \
src/thrift/generate/t_netcore_generator.cc \
src/thrift/generate/t_netcore_generator.h \
src/thrift/generate/t_py_generator.cc \
src/thrift/generate/t_rb_generator.cc \
src/thrift/generate/t_perl_generator.cc \
@ -106,10 +108,12 @@ thrift_SOURCES += src/thrift/generate/t_c_glib_generator.cc \
src/thrift/generate/t_go_generator.cc \
src/thrift/generate/t_gv_generator.cc \
src/thrift/generate/t_d_generator.cc \
src/thrift/generate/t_lua_generator.cc
src/thrift/generate/t_lua_generator.cc \
src/thrift/generate/t_rs_generator.cc \
src/thrift/generate/t_cl_generator.cc
thrift_CPPFLAGS = -I$(srcdir)/src
thrift_CXXFLAGS = -Wall -Wextra -pedantic
thrift_CXXFLAGS = -Wall -Wextra -pedantic -Werror
thrift_LDADD = @LEXLIB@ src/thrift/libparse.a
if !WITH_PLUGIN
@ -151,7 +155,7 @@ include_generatedir = $(include_thriftdir)/generate
include_generate_HEADERS = src/thrift/generate/t_generator.h \
src/thrift/generate/t_generator_registry.h \
src/thrift/generate/t_oop_generator.h \
src/thrift/generate/t_html_generator.h
src/thrift/generate/t_html_generator.h
include_parsedir = $(include_thriftdir)/parse
include_parse_HEADERS = src/thrift/parse/t_service.h \

View file

@ -1,83 +1,175 @@
# Build compiler using CMake
# Build Thrift IDL compiler using CMake
Use the following steps to build using cmake:
<!-- TOC -->
mkdir cmake-build
cd cmake-build
cmake ..
make
- [Build Thrift IDL compiler using CMake](#build-thrift-idl-compiler-using-cmake)
- [Build on Unix-like System](#build-on-unix-like-system)
- [Prerequisites](#prerequisites)
- [Build using CMake](#build-using-cmake)
- [Build with Eclipse IDE](#build-with-eclipse-ide)
- [Build with XCode IDE in MacOS](#build-with-xcode-ide-in-macos)
- [Usage of other IDEs](#usage-of-other-ides)
- [Build on Windows](#build-on-windows)
- [Prerequisites](#prerequisites-1)
- [Build using Git Bash](#build-using-git-bash)
- [Using Visual Studio and Win flex-bison](#using-visual-studio-and-win-flex-bison)
- [Cross compile using mingw32 and generate a Windows Installer with CPack](#cross-compile-using-mingw32-and-generate-a-windows-installer-with-cpack)
- [Other cases](#other-cases)
- [Building the Thrift IDL compiler in Windows without CMake](#building-the-thrift-idl-compiler-in-windows-without-cmake)
- [Unit tests for compiler](#unit-tests-for-compiler)
- [Using boost test](#using-boost-test)
- [Using Catch C++ test library](#using-catch-c-test-library)
- [Have a Happy free time and holidays](#have-a-happy-free-time-and-holidays)
<!-- /TOC -->
### Create an eclipse project
## Build on Unix-like System
mkdir cmake-ec && cd cmake-ec
cmake -G "Eclipse CDT4 - Unix Makefiles" ..
make
### Prerequisites
- Install CMake
- Install flex and bison
### Build using CMake
- Go to **thrift\compiler\cpp**
- Use the following steps to build using cmake:
```
mkdir cmake-build && cd cmake-build
cmake ..
make
```
#### Build with Eclipse IDE
- Go to **thrift\compiler\cpp**
- Use the following steps to build using cmake:
```
mkdir cmake-ec && cd cmake-ec
cmake -G "Eclipse CDT4 - Unix Makefiles" ..
make
```
Now open the folder cmake-ec using eclipse.
#### Build with XCode IDE in MacOS
- Install/update flex, bison and cmake with brew
```
brew install cmake
brew install bison
```
- Go to **thrift\compiler\cpp**
- Run commands in command line:
```
mkdir cmake-build && cd cmake-build
cmake -G "Xcode" -DWITH_PLUGIN=OFF ..
cmake --build .
```
#### Usage of other IDEs
Please check list of supported IDE
```
cmake --help
```
## Build on Windows
### Prerequisites
- Install CMake - https://cmake.org/download/
- In case if you want to build without Git Bash - install winflexbison - https://sourceforge.net/projects/winflexbison/
- In case if you want to build with Visual Studio - install Visual Studio
- Better to use the latest stable Visual Studio Community Edition - https://www.visualstudio.com/vs/whatsnew/ (ensure that you installed workload "Desktop Development with C++" for VS2017) - Microsoft added some support for CMake and improving it in Visual Studio
### Build using Git Bash
Git Bash provides flex and bison
- Go to **thrift\compiler\cpp**
- Use the following steps to build using cmake:
```
mkdir cmake-vs && cd cmake-vs
cmake -DWITH_SHARED_LIB=off ..
cmake --build .
```
### Using Visual Studio and Win flex-bison
- Generate a Visual Studio project for version of Visual Studio which you have (**cmake --help** can show list of supportable VS versions):
- Run commands in command line:
```
mkdir cmake-vs
cd cmake-vs
cmake -G "Visual Studio 15 2017" -DWITH_PLUGIN=OFF ..
```
- Now open the folder cmake-vs using Visual Studio.
### Cross compile using mingw32 and generate a Windows Installer with CPack
mkdir cmake-mingw32 && cd cmake-mingw32
cmake -DCMAKE_TOOLCHAIN_FILE=../build/cmake/mingw32-toolchain.cmake -DBUILD_COMPILER=ON -DBUILD_LIBRARIES=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF ..
cpack
## Build on windows
### using Git Bash
Git Bash provides flex and bison, so you just need to do this:
mkdir cmake-vs && cd cmake-vs
cmake -DWITH_SHARED_LIB=off ..
### using Win flex-bison
In order to build on windows with winflexbison a few additional steps are necessary:
1. Download winflexbison from http://sourceforge.net/projects/winflexbison/
2. Extract the winflex bison files to for e.g. C:\winflexbison
3. Make the CMake variables point to the correct binaries.
* FLEX_EXECUTABLE = C:/winbuild/win_flex.exe
* BISON_EXECUTABLE = C:/winbuild/win_bison.exe
4. Generate a Visual Studio project:
```
mkdir cmake-vs && cd cmake-vs
cmake -G "Visual Studio 12" -DWITH_SHARED_LIB=off ..
mkdir cmake-mingw32 && cd cmake-mingw32
cmake -DCMAKE_TOOLCHAIN_FILE=../build/cmake/mingw32-toolchain.cmake -DBUILD_COMPILER=ON -DBUILD_LIBRARIES=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF ..
cpack
```
5. Now open the folder build_vs using Visual Studio 2013.
# Building the Thrift IDL compiler in Windows
# Other cases
If you don't want to use CMake you can use the already available Visual Studio
2010 solution.
The Visual Studio project contains pre-build commands to generate the
thriftl.cc, thrifty.cc and thrifty.hh files which are necessary to build
the compiler. These depend on bison, flex and their dependencies to
work properly.
Download flex & bison as described above.
Place these binaries somewhere in the path and
rename win_flex.exe and win_bison.exe to flex.exe and bison.exe respectively.
## Building the Thrift IDL compiler in Windows without CMake
If you don't want to use CMake you can use the already available Visual Studio 2010 solution.
The Visual Studio project contains pre-build commands to generate the thriftl.cc, thrifty.cc and thrifty.hh files which are necessary to build the compiler.
These depend on bison, flex and their dependencies to work properly.
Download flex & bison as described above.
Place these binaries somewhere in the path and rename win_flex.exe and win_bison.exe to flex.exe and bison.exe respectively.
If this doesn't work on a system, try these manual pre-build steps.
Open compiler.sln and remove the Pre-build commands under the project's
Properties -> Build Events -> Pre-Build Events.
Open compiler.sln and remove the Pre-build commands under the project's: Properties -> Build Events -> Pre-Build Events.
From a command prompt:
> cd thrift/compiler/cpp
> flex -osrc\thrift\thriftl.cc src\thrift\thriftl.ll
```
cd thrift/compiler/cpp
flex -o src\thrift\thriftl.cc src\thrift\thriftl.ll
```
In the generated thriftl.cc, comment out #include <unistd.h>
Place a copy of bison.simple in thrift/compiler/cpp
> bison -y -o "src/thrift/thrifty.cc" --defines src/thrift/thrifty.yy
> move src\thrift\thrifty.cc.hh src\thrift\thrifty.hh
```
bison -y -o "src/thrift/thrifty.cc" --defines src/thrift/thrifty.yy
move src\thrift\thrifty.cc.hh src\thrift\thrifty.hh
```
Bison might generate the yacc header file "thrifty.cc.h" with just one h ".h" extension; in this case you'll have to rename to "thrifty.h".
> move src\thrift\version.h.in src\thrift\version.h
```
move src\thrift\version.h.in src\thrift\version.h
```
Download inttypes.h from the interwebs and place it in an include path
location (e.g. thrift/compiler/cpp/src).
Build the compiler in Visual Studio.
# Unit tests for compiler
## Using boost test
- pls check **test** folder
## Using Catch C++ test library
Added generic way to cover code by tests for many languages (you just need to make a correct header file for generator for your language - example in **netcore** implementation)
- pls check **tests** folder
# Have a Happy free time and holidays

View file

@ -51,12 +51,13 @@
<ClInclude Include="src\thrift\version.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\thrift\audit\t_audit.cpp"/>
<ClCompile Include="src\thrift\audit\t_audit.cpp" />
<ClCompile Include="src\thrift\common.cc" />
<ClCompile Include="src\thrift\generate\t_as3_generator.cc" />
<ClCompile Include="src\thrift\generate\t_cocoa_generator.cc" />
<ClCompile Include="src\thrift\generate\t_cpp_generator.cc" />
<ClCompile Include="src\thrift\generate\t_csharp_generator.cc" />
<ClCompile Include="src\thrift\generate\t_netcore_generator.cc" />
<ClCompile Include="src\thrift\generate\t_c_glib_generator.cc" />
<ClCompile Include="src\thrift\generate\t_d_generator.cc" />
<ClCompile Include="src\thrift\generate\t_dart_generator.cc" />
@ -78,6 +79,7 @@
<ClCompile Include="src\thrift\generate\t_php_generator.cc" />
<ClCompile Include="src\thrift\generate\t_py_generator.cc" />
<ClCompile Include="src\thrift\generate\t_rb_generator.cc" />
<ClCompile Include="src\thrift\generate\t_rs_generator.cc" />
<ClCompile Include="src\thrift\generate\t_st_generator.cc" />
<ClCompile Include="src\thrift\generate\t_swift_generator.cc" />
<ClCompile Include="src\thrift\generate\t_xml_generator.cc" />
@ -194,7 +196,6 @@
</Link>
<PreBuildEvent>
<Command>flex -o "src\\thrift\\thriftl.cc" src/thrift/thriftl.ll &amp;&amp; bison -y -o "src\\thrift\\thrifty.cc" --defines="src\\thrift\\thrifty.hh" src/thrift/thrifty.yy</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -208,6 +209,7 @@
<PreprocessorDefinitions>WIN32;MINGW;YY_NO_UNISTD_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>thrift\windows\config.h</ForcedIncludeFiles>
<CompileAs>CompileAsCpp</CompileAs>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -217,7 +219,6 @@
</Link>
<PreBuildEvent>
<Command>flex -o "src\\thrift\\thriftl.cc" src/thrift/thriftl.ll &amp;&amp; bison -y -o "src\\thrift\\thrifty.cc" --defines="src\\thrift\\thrifty.hh" src/thrift/thrifty.yy</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -231,6 +232,7 @@
<PreprocessorDefinitions>WIN32;MINGW;YY_NO_UNISTD_H;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>thrift\windows\config.h</ForcedIncludeFiles>
<CompileAs>CompileAsCpp</CompileAs>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -240,10 +242,9 @@
</Link>
<PreBuildEvent>
<Command>flex -o "src\\thrift\\thriftl.cc" src/thrift/thriftl.ll &amp;&amp; bison -y -o "src\\thrift\\thrifty.cc" --defines="src\\thrift\\thrifty.hh" src/thrift/thrifty.yy</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -161,6 +161,9 @@
<ClCompile Include="src\generate\t_rb_generator.cc">
<Filter>generate</Filter>
</ClCompile>
<ClCompile Include="src\generate\t_rs_generator.cc">
<Filter>generate</Filter>
</ClCompile>
<ClCompile Include="src\generate\t_st_generator.cc">
<Filter>generate</Filter>
</ClCompile>
@ -193,4 +196,4 @@
<None Include="src\thriftl.ll" />
<None Include="src\thrifty.yy" />
</ItemGroup>
</Project>
</Project>

View file

@ -202,8 +202,8 @@ bool compare_defaults(t_const_value* newStructDefault, t_const_value* oldStructD
}
case t_const_value::CV_MAP:
{
const std::map<t_const_value*, t_const_value*> newMap = newStructDefault->get_map();
const std::map<t_const_value*, t_const_value*> oldMap = oldStructDefault->get_map();
const std::map<t_const_value*, t_const_value*, t_const_value::value_compare> newMap = newStructDefault->get_map();
const std::map<t_const_value*, t_const_value*, t_const_value::value_compare> oldMap = oldStructDefault->get_map();
bool defaultValuesCompare = (oldMap.size() == newMap.size());

View file

@ -31,7 +31,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -83,13 +83,13 @@ public:
void generate_xception(t_struct* txception);
void generate_service(t_service* tservice);
void print_const_value(std::ofstream& out,
void print_const_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value,
bool in_static,
bool defval = false);
std::string render_const_value(ofstream& out,
std::string render_const_value(ostream& out,
std::string name,
t_type* type,
t_const_value* value);
@ -100,19 +100,19 @@ public:
void generate_as3_struct(t_struct* tstruct, bool is_exception);
void generate_as3_struct_definition(std::ofstream& out,
void generate_as3_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false,
bool in_class = false,
bool is_result = false);
// removed -- equality,compare_to
void generate_as3_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_as3_validator(std::ofstream& out, t_struct* tstruct);
void generate_as3_struct_result_writer(std::ofstream& out, t_struct* tstruct);
void generate_as3_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_as3_struct_tostring(std::ofstream& out, t_struct* tstruct, bool bindable);
void generate_as3_meta_data_map(std::ofstream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ofstream& out, t_type* type);
void generate_as3_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_as3_validator(std::ostream& out, t_struct* tstruct);
void generate_as3_struct_result_writer(std::ostream& out, t_struct* tstruct);
void generate_as3_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_as3_struct_tostring(std::ostream& out, t_struct* tstruct, bool bindable);
void generate_as3_meta_data_map(std::ostream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ostream& out, t_type* type);
std::string get_as3_type_string(t_type* type);
void generate_reflection_setters(std::ostringstream& out,
t_type* type,
@ -122,15 +122,15 @@ public:
t_type* type,
std::string field_name,
std::string cap_name);
void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
void generate_as3_bean_boilerplate(std::ofstream& out, t_struct* tstruct, bool bindable);
void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
void generate_as3_bean_boilerplate(std::ostream& out, t_struct* tstruct, bool bindable);
void generate_function_helpers(t_function* tfunction);
std::string get_cap_name(std::string name);
std::string generate_isset_check(t_field* field);
std::string generate_isset_check(std::string field);
void generate_isset_set(ofstream& out, t_field* field);
void generate_isset_set(ostream& out, t_field* field);
// removed std::string isset_field_id(t_field* field);
void generate_service_interface(t_service* tservice);
@ -143,38 +143,38 @@ public:
* Serialization constructs
*/
void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string iter,
std::string map);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
void generate_as3_doc(std::ofstream& out, t_doc* tdoc);
void generate_as3_doc(std::ostream& out, t_doc* tdoc);
void generate_as3_doc(std::ofstream& out, t_function* tdoc);
void generate_as3_doc(std::ostream& out, t_function* tdoc);
/**
* Helper rendering functions
@ -208,7 +208,7 @@ private:
*/
std::string package_name_;
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_service_;
std::string package_dir_;
bool bindable_;
@ -353,8 +353,8 @@ void t_as3_generator::generate_typedef(t_typedef* ttypedef) {
void t_as3_generator::generate_enum(t_enum* tenum) {
// Make output file
string f_enum_name = package_dir_ + "/" + (tenum->get_name()) + ".as";
ofstream f_enum;
f_enum.open(f_enum_name.c_str());
ofstream_with_content_based_conditional_update f_enum;
f_enum.open(f_enum_name);
// Comment and package it
f_enum << autogen_comment() << as3_package() << endl;
@ -416,8 +416,8 @@ void t_as3_generator::generate_consts(std::vector<t_const*> consts) {
}
string f_consts_name = package_dir_ + "/" + program_name_ + "Constants.as";
ofstream f_consts;
f_consts.open(f_consts_name.c_str());
ofstream_with_content_based_conditional_update f_consts;
f_consts.open(f_consts_name);
// Print header
f_consts << autogen_comment() << as3_package();
@ -443,7 +443,7 @@ void t_as3_generator::generate_consts(std::vector<t_const*> consts) {
f_consts.close();
}
void t_as3_generator::print_const_value(std::ofstream& out,
void t_as3_generator::print_const_value(std::ostream& out,
string name,
t_type* type,
t_const_value* value,
@ -471,8 +471,8 @@ void t_as3_generator::print_const_value(std::ofstream& out,
} else if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
out << name << ":" << type_name(type) << " = new " << type_name(type, false, true) << "();"
<< endl;
if (!in_static) {
@ -516,8 +516,8 @@ void t_as3_generator::print_const_value(std::ofstream& out,
}
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(out, name, ktype, v_iter->first);
string val = render_const_value(out, name, vtype, v_iter->second);
@ -567,7 +567,7 @@ void t_as3_generator::print_const_value(std::ofstream& out,
}
}
string t_as3_generator::render_const_value(ofstream& out,
string t_as3_generator::render_const_value(ostream& out,
string name,
t_type* type,
t_const_value* value) {
@ -644,7 +644,7 @@ void t_as3_generator::generate_xception(t_struct* txception) {
void t_as3_generator::generate_as3_struct(t_struct* tstruct, bool is_exception) {
// Make output file
string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".as";
ofstream f_struct;
ofstream_with_content_based_conditional_update f_struct;
f_struct.open(f_struct_name.c_str());
f_struct << autogen_comment() << as3_package();
@ -678,7 +678,7 @@ void t_as3_generator::generate_as3_struct(t_struct* tstruct, bool is_exception)
* @param in_class If inside a class, needs to be static class
* @param is_result If this is a result it needs a different writer
*/
void t_as3_generator::generate_as3_struct_definition(ofstream& out,
void t_as3_generator::generate_as3_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception,
bool in_class,
@ -782,7 +782,7 @@ void t_as3_generator::generate_as3_struct_definition(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_as3_generator::generate_as3_struct_reader(ofstream& out, t_struct* tstruct) {
void t_as3_generator::generate_as3_struct_reader(ostream& out, t_struct* tstruct) {
out << indent() << "public function read(iprot:TProtocol):void {" << endl;
indent_up();
@ -862,7 +862,7 @@ void t_as3_generator::generate_as3_struct_reader(ofstream& out, t_struct* tstruc
// generates as3 method to perform various checks
// (e.g. check that all required fields are set)
void t_as3_generator::generate_as3_validator(ofstream& out, t_struct* tstruct) {
void t_as3_generator::generate_as3_validator(ostream& out, t_struct* tstruct) {
indent(out) << "public function validate():void {" << endl;
indent_up();
@ -912,7 +912,7 @@ void t_as3_generator::generate_as3_validator(ofstream& out, t_struct* tstruct) {
*
* @param tstruct The struct definition
*/
void t_as3_generator::generate_as3_struct_writer(ofstream& out, t_struct* tstruct) {
void t_as3_generator::generate_as3_struct_writer(ostream& out, t_struct* tstruct) {
out << indent() << "public function write(oprot:TProtocol):void {" << endl;
indent_up();
@ -971,7 +971,7 @@ void t_as3_generator::generate_as3_struct_writer(ofstream& out, t_struct* tstruc
*
* @param tstruct The struct definition
*/
void t_as3_generator::generate_as3_struct_result_writer(ofstream& out, t_struct* tstruct) {
void t_as3_generator::generate_as3_struct_result_writer(ostream& out, t_struct* tstruct) {
out << indent() << "public function write(oprot:TProtocol):void {" << endl;
indent_up();
@ -1044,7 +1044,7 @@ void t_as3_generator::generate_reflection_setters(ostringstream& out,
indent_down();
}
void t_as3_generator::generate_generic_field_getters_setters(std::ofstream& out,
void t_as3_generator::generate_generic_field_getters_setters(std::ostream& out,
t_struct* tstruct) {
std::ostringstream getter_stream;
@ -1100,7 +1100,7 @@ void t_as3_generator::generate_generic_field_getters_setters(std::ofstream& out,
}
// Creates a generic isSet method that takes the field number as argument
void t_as3_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
void t_as3_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -1134,7 +1134,7 @@ void t_as3_generator::generate_generic_isset_method(std::ofstream& out, t_struct
*
* @param tstruct The struct definition
*/
void t_as3_generator::generate_as3_bean_boilerplate(ofstream& out,
void t_as3_generator::generate_as3_bean_boilerplate(ostream& out,
t_struct* tstruct,
bool bindable) {
const vector<t_field*>& fields = tstruct->get_members();
@ -1216,7 +1216,7 @@ void t_as3_generator::generate_as3_bean_boilerplate(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_as3_generator::generate_as3_struct_tostring(ofstream& out,
void t_as3_generator::generate_as3_struct_tostring(ostream& out,
t_struct* tstruct,
bool bindable) {
// If it's bindable, it extends EventDispatcher so toString is an override.
@ -1251,7 +1251,7 @@ void t_as3_generator::generate_as3_struct_tostring(ofstream& out,
indent_up();
}
if (field->get_type()->is_base_type() && ((t_base_type*)(field->get_type()))->is_binary()) {
if (field->get_type()->is_binary()) {
indent(out) << " ret += \"BINARY\";" << endl;
} else if (field->get_type()->is_enum()) {
indent(out) << "var " << field->get_name()
@ -1293,7 +1293,7 @@ void t_as3_generator::generate_as3_struct_tostring(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_as3_generator::generate_as3_meta_data_map(ofstream& out, t_struct* tstruct) {
void t_as3_generator::generate_as3_meta_data_map(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -1381,7 +1381,7 @@ std::string t_as3_generator::get_as3_type_string(t_type* type) {
}
}
void t_as3_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
void t_as3_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
out << endl;
indent_up();
indent_up();
@ -1960,7 +1960,7 @@ void t_as3_generator::generate_process_function(t_service* tservice, t_function*
* @param tfield The field
* @param prefix The variable name or container for this field
*/
void t_as3_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_as3_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
if (type->is_void()) {
@ -1984,7 +1984,7 @@ void t_as3_generator::generate_deserialize_field(ofstream& out, t_field* tfield,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "readBinary();";
} else {
out << "readString();";
@ -2025,7 +2025,7 @@ void t_as3_generator::generate_deserialize_field(ofstream& out, t_field* tfield,
/**
* Generates an unserializer for a struct, invokes read()
*/
void t_as3_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_as3_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent()
<< prefix << ".read(iprot);" << endl;
}
@ -2033,7 +2033,7 @@ void t_as3_generator::generate_deserialize_struct(ofstream& out, t_struct* tstru
/**
* Deserializes a container by reading its size and then iterating
*/
void t_as3_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_as3_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
string obj;
@ -2093,7 +2093,7 @@ void t_as3_generator::generate_deserialize_container(ofstream& out, t_type* ttyp
/**
* Generates code to deserialize a map
*/
void t_as3_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
void t_as3_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
string key = tmp("_key");
string val = tmp("_val");
t_field fkey(tmap->get_key_type(), key);
@ -2111,7 +2111,7 @@ void t_as3_generator::generate_deserialize_map_element(ofstream& out, t_map* tma
/**
* Deserializes a set element
*/
void t_as3_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
void t_as3_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
string elem = tmp("_elem");
t_field felem(tset->get_elem_type(), elem);
@ -2125,7 +2125,7 @@ void t_as3_generator::generate_deserialize_set_element(ofstream& out, t_set* tse
/**
* Deserializes a list element
*/
void t_as3_generator::generate_deserialize_list_element(ofstream& out,
void t_as3_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix) {
string elem = tmp("_elem");
@ -2144,7 +2144,7 @@ void t_as3_generator::generate_deserialize_list_element(ofstream& out,
* @param tfield The field to serialize
* @param prefix Name to prepend to field name
*/
void t_as3_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_as3_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
// Do nothing for void types
@ -2168,7 +2168,7 @@ void t_as3_generator::generate_serialize_field(ofstream& out, t_field* tfield, s
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "writeBinary(" << name << ");";
} else {
out << "writeString(" << name << ");";
@ -2213,7 +2213,7 @@ void t_as3_generator::generate_serialize_field(ofstream& out, t_field* tfield, s
* @param tstruct The struct to serialize
* @param prefix String prefix to attach to all fields
*/
void t_as3_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_as3_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
(void)tstruct;
out << indent() << prefix << ".write(oprot);" << endl;
}
@ -2224,7 +2224,7 @@ void t_as3_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct
* @param ttype The type of container
* @param prefix String prefix for fields
*/
void t_as3_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_as3_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
if (ttype->is_map()) {
@ -2282,7 +2282,7 @@ void t_as3_generator::generate_serialize_container(ofstream& out, t_type* ttype,
/**
* Serializes the members of a map.
*/
void t_as3_generator::generate_serialize_map_element(ofstream& out,
void t_as3_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string iter,
string map) {
@ -2295,7 +2295,7 @@ void t_as3_generator::generate_serialize_map_element(ofstream& out,
/**
* Serializes the members of a set.
*/
void t_as3_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_as3_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
@ -2303,7 +2303,7 @@ void t_as3_generator::generate_serialize_set_element(ofstream& out, t_set* tset,
/**
* Serializes the members of a list.
*/
void t_as3_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
void t_as3_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
t_field efield(tlist->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
@ -2390,7 +2390,7 @@ string t_as3_generator::declare_field(t_field* tfield, bool init) {
if (init) {
t_type* ttype = get_true_type(tfield->get_type());
if (ttype->is_base_type() && tfield->get_value() != NULL) {
ofstream dummy;
std::ofstream dummy;
result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
} else if (ttype->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@ -2539,7 +2539,7 @@ string t_as3_generator::constant_name(string name) {
/**
* Emits a As3Doc comment if the provided object has a doc in Thrift
*/
void t_as3_generator::generate_as3_doc(ofstream& out, t_doc* tdoc) {
void t_as3_generator::generate_as3_doc(ostream& out, t_doc* tdoc) {
if (tdoc->has_doc()) {
generate_docstring_comment(out, "/**\n", " * ", tdoc->get_doc(), " */\n");
}
@ -2548,7 +2548,7 @@ void t_as3_generator::generate_as3_doc(ofstream& out, t_doc* tdoc) {
/**
* Emits a As3Doc comment if the provided function object has a doc in Thrift
*/
void t_as3_generator::generate_as3_doc(ofstream& out, t_function* tfunction) {
void t_as3_generator::generate_as3_doc(ostream& out, t_function* tfunction) {
if (tfunction->has_doc()) {
stringstream ss;
ss << tfunction->get_doc();
@ -2573,7 +2573,7 @@ std::string t_as3_generator::generate_isset_check(std::string field_name) {
return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
}
void t_as3_generator::generate_isset_set(ofstream& out, t_field* field) {
void t_as3_generator::generate_isset_set(ostream& out, t_field* field) {
if (!type_can_be_null(field->get_type())) {
indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl;
}

View file

@ -33,7 +33,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -116,10 +116,10 @@ public:
private:
/* file streams */
ofstream f_types_;
ofstream f_types_impl_;
ofstream f_header_;
ofstream f_service_;
ofstream_with_content_based_conditional_update f_types_;
ofstream_with_content_based_conditional_update f_types_impl_;
ofstream_with_content_based_conditional_update f_header_;
ofstream_with_content_based_conditional_update f_service_;
/* namespace variables */
string nspace;
@ -145,8 +145,8 @@ private:
bool pointer = false,
bool constant = false,
bool reference = false);
void declare_local_variable(ofstream& out, t_type* ttype, string& base_name, bool for_hash_table);
void declore_local_variable_for_write(ofstream& out, t_type* ttype, string& base_name);
void declare_local_variable(ostream& out, t_type* ttype, string& base_name, bool for_hash_table);
void declore_local_variable_for_write(ostream& out, t_type* ttype, string& base_name);
/* generation functions */
void generate_const_initializer(string name,
@ -159,51 +159,51 @@ private:
void generate_service_processor(t_service* tservice);
void generate_service_server(t_service* tservice);
void generate_object(t_struct* tstruct);
void generate_struct_writer(ofstream& out,
void generate_struct_writer(ostream& out,
t_struct* tstruct,
string this_name,
string this_get = "",
bool is_function = true);
void generate_struct_reader(ofstream& out,
void generate_struct_reader(ostream& out,
t_struct* tstruct,
string this_name,
string this_get = "",
bool is_function = true);
void generate_serialize_field(ofstream& out,
void generate_serialize_field(ostream& out,
t_field* tfield,
string prefix,
string suffix,
int error_ret);
void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix, int error_ret);
void generate_serialize_container(ofstream& out, t_type* ttype, string prefix, int error_ret);
void generate_serialize_map_element(ofstream& out,
void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix, int error_ret);
void generate_serialize_container(ostream& out, t_type* ttype, string prefix, int error_ret);
void generate_serialize_map_element(ostream& out,
t_map* tmap,
string key,
string value,
int error_ret);
void generate_serialize_set_element(ofstream& out, t_set* tset, string element, int error_ret);
void generate_serialize_list_element(ofstream& out,
void generate_serialize_set_element(ostream& out, t_set* tset, string element, int error_ret);
void generate_serialize_list_element(ostream& out,
t_list* tlist,
string list,
string index,
int error_ret);
void generate_deserialize_field(ofstream& out,
void generate_deserialize_field(ostream& out,
t_field* tfield,
string prefix,
string suffix,
int error_ret,
bool allocate = true);
void generate_deserialize_struct(ofstream& out,
void generate_deserialize_struct(ostream& out,
t_struct* tstruct,
string prefix,
int error_ret,
bool allocate = true);
void generate_deserialize_container(ofstream& out, t_type* ttype, string prefix, int error_ret);
void generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix, int error_ret);
void generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix, int error_ret);
void generate_deserialize_list_element(ofstream& out,
void generate_deserialize_container(ostream& out, t_type* ttype, string prefix, int error_ret);
void generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix, int error_ret);
void generate_deserialize_set_element(ostream& out, t_set* tset, string prefix, int error_ret);
void generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix,
string index,
@ -250,11 +250,21 @@ void t_c_glib_generator::init_generator() {
/* include other thrift includes */
const vector<t_program*>& includes = program_->get_includes();
for (size_t i = 0; i < includes.size(); ++i) {
f_types_ << "/* other thrift includes */" << endl << "#include \"" << this->nspace_lc
<< initial_caps_to_underscores(includes[i]->get_name()) << "_types.h\"" << endl;
if (!includes.empty()) {
f_types_ << "/* other thrift includes */" << endl;
for (vector<t_program*>::const_iterator iter = includes.begin();
iter != includes.end();
++iter) {
const std::string& include_nspace = (*iter)->get_namespace("c_glib");
std::string include_nspace_prefix =
include_nspace.empty() ? "" : initial_caps_to_underscores(include_nspace) + "_";
f_types_ << "#include \"" << include_nspace_prefix
<< initial_caps_to_underscores((*iter)->get_name()) << "_types.h\"" << endl;
}
f_types_ << endl;
}
f_types_ << endl;
/* include custom headers */
const vector<string>& c_includes = program_->get_c_includes();
@ -579,7 +589,7 @@ string t_c_glib_generator::type_name(t_type* ttype, bool in_typedef, bool is_con
// TODO: discuss whether or not to implement TSet, THashSet or GHashSet
cname = "GHashTable";
} else if (ttype->is_list()) {
t_type* etype = ((t_list*)ttype)->get_elem_type();
t_type* etype = get_true_type(((t_list*)ttype)->get_elem_type());
if (etype->is_void()) {
throw std::runtime_error("compiler error: list element type cannot be void");
}
@ -602,7 +612,8 @@ string t_c_glib_generator::type_name(t_type* ttype, bool in_typedef, bool is_con
}
// check for a namespace
string pname = this->nspace + ttype->get_name();
t_program* tprogram = ttype->get_program();
string pname = (tprogram ? tprogram->get_namespace("c_glib") : "") + ttype->get_name();
if (is_complex_type(ttype)) {
pname += " *";
@ -997,8 +1008,8 @@ void t_c_glib_generator::generate_const_initializer(string name,
if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
ostringstream initializers;
// initialize any constants that may be referenced by this initializer
@ -1171,8 +1182,8 @@ void t_c_glib_generator::generate_const_initializer(string name,
} else if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
ostringstream initializers;
ostringstream appenders;
@ -1831,8 +1842,10 @@ void t_c_glib_generator::generate_service_handler(t_service* tservice) {
string service_name_lc = to_lower_case(initial_caps_to_underscores(service_name_));
string service_name_uc = to_upper_case(service_name_lc);
string class_name = this->nspace + service_name_ + "Handler";
string class_name_lc = to_lower_case(initial_caps_to_underscores(class_name));
string service_handler_name = service_name_ + "Handler";
string class_name = this->nspace + service_handler_name;
string class_name_lc = this->nspace_lc + initial_caps_to_underscores(service_handler_name);
string class_name_uc = to_upper_case(class_name_lc);
string parent_class_name;
@ -2051,8 +2064,10 @@ void t_c_glib_generator::generate_service_processor(t_service* tservice) {
string service_name_lc = to_lower_case(initial_caps_to_underscores(service_name_));
string service_name_uc = to_upper_case(service_name_lc);
string class_name = this->nspace + service_name_ + "Processor";
string class_name_lc = to_lower_case(initial_caps_to_underscores(class_name));
string service_processor_name = service_name_ + "Processor";
string class_name = this->nspace + service_processor_name;
string class_name_lc = this->nspace_lc + initial_caps_to_underscores(service_processor_name);
string class_name_uc = to_upper_case(class_name_lc);
string parent_class_name;
@ -2784,7 +2799,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) {
string name_uc = to_upper_case(name_u);
string class_name = this->nspace + name;
string class_name_lc = to_lower_case(initial_caps_to_underscores(class_name));
string class_name_lc = this->nspace_lc + initial_caps_to_underscores(name);
string class_name_uc = to_upper_case(class_name_lc);
string function_name;
@ -3124,7 +3139,8 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) {
<< "THRIFT_UNUSED_VAR (object);" << endl;
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
t_type* t = get_true_type((*m_iter)->get_type());
t_type* member_type = (*m_iter)->get_type();
t_type* t = get_true_type(member_type);
if (t->is_base_type()) {
string dval = " = ";
if (t->is_enum()) {
@ -3139,10 +3155,14 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) {
indent(f_types_impl_) << "object->" << (*m_iter)->get_name() << dval << ";" << endl;
} else if (t->is_struct()) {
string name = (*m_iter)->get_name();
string type_name_uc
= to_upper_case(initial_caps_to_underscores((*m_iter)->get_type()->get_name()));
indent(f_types_impl_) << "object->" << name << " = g_object_new (" << this->nspace_uc
<< "TYPE_" << type_name_uc << ", NULL);" << endl;
t_program* type_program = member_type->get_program();
string type_nspace = type_program ? type_program->get_namespace("c_glib") : "";
string type_nspace_prefix =
type_nspace.empty() ? "" : initial_caps_to_underscores(type_nspace) + "_";
string type_name_uc = to_upper_case(initial_caps_to_underscores(member_type->get_name()));
indent(f_types_impl_) << "object->" << name << " = g_object_new ("
<< to_upper_case(type_nspace_prefix) << "TYPE_" << type_name_uc
<< ", NULL);" << endl;
} else if (t->is_xception()) {
string name = (*m_iter)->get_name();
indent(f_types_impl_) << "object->" << name << " = NULL;" << endl;
@ -3424,7 +3444,12 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) {
<< "G_PARAM_READWRITE));" << endl;
indent_down();
} else if (member_type->is_struct() || member_type->is_xception()) {
string param_type = this->nspace_uc + "TYPE_"
t_program* type_program = member_type->get_program();
string type_nspace = type_program ? type_program->get_namespace("c_glib") : "";
string type_nspace_prefix =
type_nspace.empty() ? "" : initial_caps_to_underscores(type_nspace) + "_";
string param_type = to_upper_case(type_nspace_prefix) + "TYPE_"
+ to_upper_case(initial_caps_to_underscores(member_type->get_name()));
args_indent += string(20, ' ');
@ -3480,7 +3505,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) {
/**
* Generates functions to write Thrift structures to a stream.
*/
void t_c_glib_generator::generate_struct_writer(ofstream& out,
void t_c_glib_generator::generate_struct_writer(ostream& out,
t_struct* tstruct,
string this_name,
string this_get,
@ -3553,7 +3578,7 @@ void t_c_glib_generator::generate_struct_writer(ofstream& out,
/**
* Generates code to read Thrift structures from a stream.
*/
void t_c_glib_generator::generate_struct_reader(ofstream& out,
void t_c_glib_generator::generate_struct_reader(ostream& out,
t_struct* tstruct,
string this_name,
string this_get,
@ -3690,7 +3715,7 @@ void t_c_glib_generator::generate_struct_reader(ofstream& out,
indent(out) << "}" << endl << endl;
}
void t_c_glib_generator::generate_serialize_field(ofstream& out,
void t_c_glib_generator::generate_serialize_field(ostream& out,
t_field* tfield,
string prefix,
string suffix,
@ -3734,7 +3759,7 @@ void t_c_glib_generator::generate_serialize_field(ofstream& out,
out << "double (protocol, " << name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "binary (protocol, " << name << " ? ((GByteArray *) " << name << ")->data : NULL, "
<< name << " ? ((GByteArray *) " << name << ")->len : 0";
} else {
@ -3756,7 +3781,7 @@ void t_c_glib_generator::generate_serialize_field(ofstream& out,
}
}
void t_c_glib_generator::generate_serialize_struct(ofstream& out,
void t_c_glib_generator::generate_serialize_struct(ostream& out,
t_struct* tstruct,
string prefix,
int error_ret) {
@ -3766,7 +3791,7 @@ void t_c_glib_generator::generate_serialize_struct(ofstream& out,
<< indent() << "xfer += ret;" << endl << endl;
}
void t_c_glib_generator::generate_serialize_container(ofstream& out,
void t_c_glib_generator::generate_serialize_container(ostream& out,
t_type* ttype,
string prefix,
int error_ret) {
@ -3923,7 +3948,7 @@ void t_c_glib_generator::generate_serialize_container(ofstream& out,
scope_down(out);
}
void t_c_glib_generator::generate_serialize_map_element(ofstream& out,
void t_c_glib_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string key,
string value,
@ -3935,7 +3960,7 @@ void t_c_glib_generator::generate_serialize_map_element(ofstream& out,
generate_serialize_field(out, &vfield, "", "", error_ret);
}
void t_c_glib_generator::generate_serialize_set_element(ofstream& out,
void t_c_glib_generator::generate_serialize_set_element(ostream& out,
t_set* tset,
string element,
int error_ret) {
@ -3943,7 +3968,7 @@ void t_c_glib_generator::generate_serialize_set_element(ofstream& out,
generate_serialize_field(out, &efield, "", "", error_ret);
}
void t_c_glib_generator::generate_serialize_list_element(ofstream& out,
void t_c_glib_generator::generate_serialize_list_element(ostream& out,
t_list* tlist,
string list,
string index,
@ -3975,7 +4000,7 @@ void t_c_glib_generator::generate_serialize_list_element(ofstream& out,
}
/* deserializes a field of any type. */
void t_c_glib_generator::generate_deserialize_field(ofstream& out,
void t_c_glib_generator::generate_deserialize_field(ostream& out,
t_field* tfield,
string prefix,
string suffix,
@ -4010,7 +4035,7 @@ void t_c_glib_generator::generate_deserialize_field(ofstream& out,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "binary (protocol, &data, &len";
} else {
out << "string (protocol, &" << name;
@ -4042,7 +4067,7 @@ void t_c_glib_generator::generate_deserialize_field(ofstream& out,
<< endl;
// load the byte array with the data
if (tbase == t_base_type::TYPE_STRING && ((t_base_type*)type)->is_binary()) {
if (tbase == t_base_type::TYPE_STRING && type->is_binary()) {
indent(out) << name << " = g_byte_array_new();" << endl;
indent(out) << "g_byte_array_append (" << name << ", (guint8 *) data, (guint) len);" << endl;
indent(out) << "g_free (data);" << endl;
@ -4061,14 +4086,14 @@ void t_c_glib_generator::generate_deserialize_field(ofstream& out,
// if the type is not required and this is a thrift struct (no prefix),
// set the isset variable. if the type is required, then set the
// local variable indicating the value was set, so that we can do // validation later.
if (tfield->get_req() != t_field::T_REQUIRED && prefix != "") {
if (prefix != "" && tfield->get_req() != t_field::T_REQUIRED) {
indent(out) << prefix << "__isset_" << tfield->get_name() << suffix << " = TRUE;" << endl;
} else if (tfield->get_req() == t_field::T_REQUIRED && prefix != "") {
} else if (prefix != "" && tfield->get_req() == t_field::T_REQUIRED) {
indent(out) << "isset_" << tfield->get_name() << " = TRUE;" << endl;
}
}
void t_c_glib_generator::generate_deserialize_struct(ofstream& out,
void t_c_glib_generator::generate_deserialize_struct(ostream& out,
t_struct* tstruct,
string prefix,
int error_ret,
@ -4101,7 +4126,7 @@ void t_c_glib_generator::generate_deserialize_struct(ofstream& out,
out << indent() << "}" << endl << indent() << "xfer += ret;" << endl;
}
void t_c_glib_generator::generate_deserialize_container(ofstream& out,
void t_c_glib_generator::generate_deserialize_container(ostream& out,
t_type* ttype,
string prefix,
int error_ret) {
@ -4202,7 +4227,7 @@ void t_c_glib_generator::generate_deserialize_container(ofstream& out,
scope_down(out);
}
void t_c_glib_generator::declare_local_variable(ofstream& out, t_type* ttype, string& name, bool for_hash_table) {
void t_c_glib_generator::declare_local_variable(ostream& out, t_type* ttype, string& name, bool for_hash_table) {
string tname = type_name(ttype);
/* If the given type is a typedef, find its underlying type so we
@ -4226,7 +4251,7 @@ void t_c_glib_generator::declare_local_variable(ofstream& out, t_type* ttype, st
}
}
void t_c_glib_generator::declore_local_variable_for_write(ofstream& out,
void t_c_glib_generator::declore_local_variable_for_write(ostream& out,
t_type* ttype,
string& name) {
string tname = type_name(ttype);
@ -4236,7 +4261,7 @@ void t_c_glib_generator::declore_local_variable_for_write(ofstream& out,
out << indent() << tname << ptr << name << init_val << ";" << endl;
}
void t_c_glib_generator::generate_deserialize_map_element(ofstream& out,
void t_c_glib_generator::generate_deserialize_map_element(ostream& out,
t_map* tmap,
string prefix,
int error_ret) {
@ -4270,7 +4295,7 @@ void t_c_glib_generator::generate_deserialize_map_element(ofstream& out,
indent_down();
}
void t_c_glib_generator::generate_deserialize_set_element(ofstream& out,
void t_c_glib_generator::generate_deserialize_set_element(ostream& out,
t_set* tset,
string prefix,
int error_ret) {
@ -4290,7 +4315,7 @@ void t_c_glib_generator::generate_deserialize_set_element(ofstream& out,
indent_down();
}
void t_c_glib_generator::generate_deserialize_list_element(ofstream& out,
void t_c_glib_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix,
string index,

View file

@ -0,0 +1,558 @@
/*
* Copyright (c) 2008- Patrick Collison <patrick@collison.ie>
* Copyright (c) 2006- Facebook
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <boost/tokenizer.hpp>
#include <sys/stat.h>
#include <sys/types.h>
#include <sstream>
#include <string>
#include <algorithm>
#include "thrift/platform.h"
#include "t_oop_generator.h"
using namespace std;
/**
* Common Lisp code generator.
*
* @author Patrick Collison <patrick@collison.ie>
*/
class t_cl_generator : public t_oop_generator {
public:
t_cl_generator(
t_program* program,
const std::map<std::string, std::string>& parsed_options,
const std::string& option_string)
: t_oop_generator(program)
{
no_asd = false;
system_prefix = "thrift-gen-";
std::map<std::string, std::string>::const_iterator iter;
for(iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
if(iter->first.compare("no_asd") == 0) {
no_asd = true;
} else if (iter->first.compare("sys_pref") == 0) {
system_prefix = iter->second;
} else {
throw "unknown option cl:" + iter->first;
}
}
out_dir_base_ = "gen-cl";
copy_options_ = option_string;
}
void init_generator();
void close_generator();
void generate_typedef (t_typedef* ttypedef);
void generate_enum (t_enum* tenum);
void generate_const (t_const* tconst);
void generate_struct (t_struct* tstruct);
void generate_xception (t_struct* txception);
void generate_service (t_service* tservice);
void generate_cl_struct (std::ostream& out, t_struct* tstruct, bool is_exception);
void generate_cl_struct_internal (std::ostream& out, t_struct* tstruct, bool is_exception);
void generate_exception_sig(std::ostream& out, t_function* f);
std::string render_const_value(t_type* type, t_const_value* value);
std::string cl_autogen_comment();
void asdf_def(std::ostream &out);
void package_def(std::ostream &out);
void package_in(std::ostream &out);
std::string generated_package();
std::string prefix(std::string name);
std::string package_of(t_program* program);
std::string package();
std::string render_includes();
std::string type_name(t_type* ttype);
std::string typespec (t_type *t);
std::string function_signature(t_function* tfunction);
std::string argument_list(t_struct* tstruct);
std::string cl_docstring(std::string raw);
private:
int temporary_var;
/**
* Isolate the variable definitions, as they can require structure definitions
*/
ofstream_with_content_based_conditional_update f_asd_;
ofstream_with_content_based_conditional_update f_types_;
ofstream_with_content_based_conditional_update f_vars_;
std::string copy_options_;
bool no_asd;
std::string system_prefix;
};
void t_cl_generator::init_generator() {
MKDIR(get_out_dir().c_str());
string program_dir = get_out_dir() + "/" + program_name_;
MKDIR(program_dir.c_str());
temporary_var = 0;
string f_types_name = program_dir + "/" + program_name_ + "-types.lisp";
string f_vars_name = program_dir + "/" + program_name_ + "-vars.lisp";
f_types_.open(f_types_name.c_str());
f_types_ << cl_autogen_comment() << endl;
f_vars_.open(f_vars_name.c_str());
f_vars_ << cl_autogen_comment() << endl;
package_def(f_types_);
package_in(f_types_);
package_in(f_vars_);
if (!no_asd) {
string f_asd_name = program_dir + "/" + system_prefix + program_name_ + ".asd";
f_asd_.open(f_asd_name.c_str());
f_asd_ << cl_autogen_comment() << endl;
asdf_def(f_asd_);
}
}
/**
* Renders all the imports necessary for including another Thrift program
*/
string t_cl_generator::render_includes() {
const vector<t_program*>& includes = program_->get_includes();
string result = "";
result += ":depends-on (:thrift";
for (size_t i = 0; i < includes.size(); ++i) {
result += " :" + system_prefix + underscore(includes[i]->get_name());
}
result += ")\n";
return result;
}
string t_cl_generator::package_of(t_program* program) {
string prefix = program->get_namespace("cl");
return prefix.empty() ? "thrift-generated" : prefix;
}
string t_cl_generator::package() {
return package_of(program_);
}
string t_cl_generator::prefix(string symbol) {
return "\"" + symbol + "\"";
}
string t_cl_generator::cl_autogen_comment() {
return
std::string(";;; ") + "Autogenerated by Thrift\n" +
";;; DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n" +
";;; options string: " + copy_options_ + "\n";
}
string t_cl_generator::cl_docstring(string raw) {
replace(raw.begin(), raw.end(), '"', '\'');
return raw;
}
void t_cl_generator::close_generator() {
f_asd_.close();
f_types_.close();
f_vars_.close();
}
string t_cl_generator::generated_package() {
return program_->get_namespace("cpp");
}
void t_cl_generator::asdf_def(std::ostream &out) {
out << "(asdf:defsystem #:" << system_prefix << program_name_ << endl;
indent_up();
out << indent() << render_includes()
<< indent() << ":serial t" << endl
<< indent() << ":components ("
<< "(:file \"" << program_name_ << "-types\") "
<< "(:file \"" << program_name_ << "-vars\")))" << endl;
indent_down();
}
/***
* Generate a package definition. Add use references equivalent to the idl file's include statements.
*/
void t_cl_generator::package_def(std::ostream &out) {
const vector<t_program*>& includes = program_->get_includes();
out << "(thrift:def-package :" << package();
if ( includes.size() > 0 ) {
out << " :use (";
for (size_t i = 0; i < includes.size(); ++i) {
out << " :" << includes[i]->get_name();
}
out << ")";
}
out << ")" << endl << endl;
}
void t_cl_generator::package_in(std::ostream &out) {
out << "(cl:in-package :" << package() << ")" << endl << endl;
}
/**
* Generates a typedef. This is not done in Common Lisp, types are all implicit.
*
* @param ttypedef The type definition
*/
void t_cl_generator::generate_typedef(t_typedef* ttypedef) {
(void)ttypedef;
}
void t_cl_generator::generate_enum(t_enum* tenum) {
f_types_ << "(thrift:def-enum " << prefix(tenum->get_name()) << endl;
vector<t_enum_value*> constants = tenum->get_constants();
vector<t_enum_value*>::iterator c_iter;
int value = -1;
indent_up();
f_types_ << indent() << "(";
for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
value = (*c_iter)->get_value();
if(c_iter != constants.begin()) f_types_ << endl << indent() << " ";
f_types_ << "(\"" << (*c_iter)->get_name() << "\" . " << value << ")";
}
indent_down();
f_types_ << "))" << endl << endl;
}
/**
* Generate a constant value
*/
void t_cl_generator::generate_const(t_const* tconst) {
t_type* type = tconst->get_type();
string name = tconst->get_name();
t_const_value* value = tconst->get_value();
f_vars_ << "(thrift:def-constant " << prefix(name) << " " << render_const_value(type, value) << ")"
<< endl << endl;
}
/**
* Prints the value of a constant with the given type. Note that type checking
* is NOT performed in this function as it is always run beforehand using the
* validate_types method in main.cc
*/
string t_cl_generator::render_const_value(t_type* type, t_const_value* value) {
type = get_true_type(type);
std::ostringstream out;
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
switch (tbase) {
case t_base_type::TYPE_STRING:
out << "\"" << value->get_string() << "\"";
break;
case t_base_type::TYPE_BOOL:
out << (value->get_integer() > 0 ? "t" : "nil");
break;
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
case t_base_type::TYPE_I64:
out << value->get_integer();
break;
case t_base_type::TYPE_DOUBLE:
if (value->get_type() == t_const_value::CV_INTEGER) {
out << value->get_integer();
} else {
out << value->get_double();
}
break;
default:
throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
}
} else if (type->is_enum()) {
indent(out) << value->get_integer();
} else if (type->is_struct() || type->is_xception()) {
out << (type->is_struct() ? "(make-instance '" : "(make-exception '") <<
lowercase(type->get_name()) << " " << endl;
indent_up();
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if ((*f_iter)->get_name() == v_iter->first->get_string()) {
field_type = (*f_iter)->get_type();
}
}
if (field_type == NULL) {
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
}
out << indent() << ":" << v_iter->first->get_string() << " " <<
render_const_value(field_type, v_iter->second) << endl;
}
out << indent() << ")";
indent_down();
} else if (type->is_map()) {
// emit an hash form with both keys and values to be evaluated
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
out << "(thrift:map ";
indent_up();
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
out << endl << indent()
<< "(cl:cons " << render_const_value(ktype, v_iter->first) << " "
<< render_const_value(vtype, v_iter->second) << ")";
}
indent_down();
out << indent() << ")";
} else if (type->is_list() || type->is_set()) {
t_type* etype;
if (type->is_list()) {
etype = ((t_list*)type)->get_elem_type();
} else {
etype = ((t_set*)type)->get_elem_type();
}
if (type->is_set()) {
out << "(thrift:set" << endl;
} else {
out << "(thrift:list" << endl;
}
indent_up();
indent_up();
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
out << indent() << render_const_value(etype, *v_iter) << endl;
}
out << indent() << ")";
indent_down();
indent_down();
} else {
throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
}
return out.str();
}
void t_cl_generator::generate_struct(t_struct* tstruct) {
generate_cl_struct(f_types_, tstruct, false);
}
void t_cl_generator::generate_xception(t_struct* txception) {
generate_cl_struct(f_types_, txception, true);
}
void t_cl_generator::generate_cl_struct_internal(std::ostream& out, t_struct* tstruct, bool is_exception) {
(void)is_exception;
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
out << "(";
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
t_const_value* value = (*m_iter)->get_value();
t_type* type = (*m_iter)->get_type();
if (m_iter != members.begin()) {
out << endl << indent() << " ";
}
out << "(" << prefix((*m_iter)->get_name()) << " " <<
( (NULL != value) ? render_const_value(type, value) : "nil" ) <<
" :id " << (*m_iter)->get_key();
if ( type->is_base_type() && "string" == typespec(type) )
if ( ((t_base_type*)type)->is_binary() )
out << " :type binary";
else
out << " :type string";
else
out << " :type " << typespec(type);
if ( (*m_iter)->get_req() == t_field::T_OPTIONAL ) {
out << " :optional t";
}
if ( (*m_iter)->has_doc()) {
out << " :documentation \"" << cl_docstring((*m_iter)->get_doc()) << "\"";
}
out <<")";
}
out << ")";
}
void t_cl_generator::generate_cl_struct(std::ostream& out, t_struct* tstruct, bool is_exception = false) {
std::string name = type_name(tstruct);
out << (is_exception ? "(thrift:def-exception " : "(thrift:def-struct ") <<
prefix(name) << endl;
indent_up();
if ( tstruct->has_doc() ) {
out << indent() ;
out << "\"" << cl_docstring(tstruct->get_doc()) << "\"" << endl;
}
out << indent() ;
generate_cl_struct_internal(out, tstruct, is_exception);
indent_down();
out << ")" << endl << endl;
}
void t_cl_generator::generate_exception_sig(std::ostream& out, t_function* f) {
generate_cl_struct_internal(out, f->get_xceptions(), true);
}
void t_cl_generator::generate_service(t_service* tservice) {
string extends_client;
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::iterator f_iter;
if (tservice->get_extends() != NULL) {
extends_client = type_name(tservice->get_extends());
}
extends_client = extends_client.empty() ? "nil" : prefix(extends_client);
f_types_ << "(thrift:def-service " << prefix(service_name_) << " "
<< extends_client;
indent_up();
if ( tservice->has_doc()) {
f_types_ << endl << indent()
<< "(:documentation \"" << cl_docstring(tservice->get_doc()) << "\")";
}
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
t_function* function = *f_iter;
string fname = function->get_name();
string signature = function_signature(function);
t_struct* exceptions = function->get_xceptions();
const vector<t_field*>& xmembers = exceptions->get_members();
f_types_ << endl << indent() << "(:method " << prefix(fname);
f_types_ << " (" << signature << " " << typespec((*f_iter)->get_returntype()) << ")";
if (xmembers.size() > 0) {
f_types_ << endl << indent() << " :exceptions " ;
generate_exception_sig(f_types_, function);
}
if ( (*f_iter)->is_oneway() ) {
f_types_ << endl << indent() << " :oneway t";
}
if ( (*f_iter)->has_doc() ) {
f_types_ << endl << indent() << " :documentation \""
<< cl_docstring((*f_iter)->get_doc()) << "\"";
}
f_types_ << ")";
}
f_types_ << ")" << endl << endl;
indent_down();
}
string t_cl_generator::typespec(t_type *t) {
t = get_true_type(t);
if (t -> is_binary()){
return "binary";
} else if (t->is_base_type()) {
return type_name(t);
} else if (t->is_map()) {
t_map *m = (t_map*) t;
return "(thrift:map " + typespec(m->get_key_type()) + " " +
typespec(m->get_val_type()) + ")";
} else if (t->is_struct() || t->is_xception()) {
return "(struct " + prefix(type_name(t)) + ")";
} else if (t->is_list()) {
return "(thrift:list " + typespec(((t_list*) t)->get_elem_type()) + ")";
} else if (t->is_set()) {
return "(thrift:set " + typespec(((t_set*) t)->get_elem_type()) + ")";
} else if (t->is_enum()) {
return "(enum \"" + ((t_enum*) t)->get_name() + "\")";
} else {
throw "Sorry, I don't know how to generate this: " + type_name(t);
}
}
string t_cl_generator::function_signature(t_function* tfunction) {
return argument_list(tfunction->get_arglist());
}
string t_cl_generator::argument_list(t_struct* tstruct) {
stringstream res;
res << "(";
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
res << " ";
}
res << "(" + prefix((*f_iter)->get_name()) << " " <<
typespec((*f_iter)->get_type()) << " " <<
(*f_iter)->get_key() << ")";
}
res << ")";
return res.str();
}
string t_cl_generator::type_name(t_type* ttype) {
string prefix = "";
t_program* program = ttype->get_program();
if (program != NULL && program != program_)
prefix = package_of(program) == package() ? "" : package_of(program) + ":";
string name = ttype->get_name();
if (ttype->is_struct() || ttype->is_xception())
name = lowercase(ttype->get_name());
return prefix + name;
}
THRIFT_REGISTER_GENERATOR(
cl,
"Common Lisp",
" no_asd: Do not define ASDF systems for each generated Thrift program.\n"
" sys_pref= The prefix to give ASDF system names. Default: thrift-gen-\n")

View file

@ -109,35 +109,35 @@ public:
bool box_it = false);
void generate_cocoa_struct(t_struct* tstruct, bool is_exception);
void generate_cocoa_struct_interface(std::ofstream& out,
void generate_cocoa_struct_interface(std::ostream& out,
t_struct* tstruct,
bool is_xception = false);
void generate_cocoa_struct_implementation(std::ofstream& out,
void generate_cocoa_struct_implementation(std::ostream& out,
t_struct* tstruct,
bool is_xception = false,
bool is_result = false);
void generate_cocoa_struct_initializer_signature(std::ofstream& out, t_struct* tstruct);
void generate_cocoa_struct_init_with_coder_method(ofstream& out,
void generate_cocoa_struct_initializer_signature(std::ostream& out, t_struct* tstruct);
void generate_cocoa_struct_init_with_coder_method(ostream& out,
t_struct* tstruct,
bool is_exception);
void generate_cocoa_struct_encode_with_coder_method(ofstream& out,
void generate_cocoa_struct_encode_with_coder_method(ostream& out,
t_struct* tstruct,
bool is_exception);
void generate_cocoa_struct_copy_method(ofstream& out,
void generate_cocoa_struct_copy_method(ostream& out,
t_struct* tstruct,
bool is_exception);
void generate_cocoa_struct_hash_method(ofstream& out, t_struct* tstruct);
void generate_cocoa_struct_is_equal_method(ofstream& out,
void generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct);
void generate_cocoa_struct_is_equal_method(ostream& out,
t_struct* tstruct,
bool is_exception);
void generate_cocoa_struct_field_accessor_implementations(std::ofstream& out,
void generate_cocoa_struct_field_accessor_implementations(std::ostream& out,
t_struct* tstruct,
bool is_exception);
void generate_cocoa_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_cocoa_struct_result_writer(std::ofstream& out, t_struct* tstruct);
void generate_cocoa_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_cocoa_struct_validator(std::ofstream& out, t_struct* tstruct);
void generate_cocoa_struct_description(std::ofstream& out, t_struct* tstruct);
void generate_cocoa_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_cocoa_struct_result_writer(std::ostream& out, t_struct* tstruct);
void generate_cocoa_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_cocoa_struct_validator(std::ostream& out, t_struct* tstruct);
void generate_cocoa_struct_description(std::ostream& out, t_struct* tstruct);
std::string function_result_helper_struct_type(t_service *tservice, t_function* tfunction);
std::string function_args_helper_struct_type(t_service* tservice, t_function* tfunction);
@ -147,29 +147,29 @@ public:
* Service-level generation functions
*/
void generate_cocoa_service_protocol(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_async_protocol(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_protocol(std::ostream& out, t_service* tservice);
void generate_cocoa_service_async_protocol(std::ostream& out, t_service* tservice);
void generate_cocoa_service_client_interface(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_client_async_interface(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_client_interface(std::ostream& out, t_service* tservice);
void generate_cocoa_service_client_async_interface(std::ostream& out, t_service* tservice);
void generate_cocoa_service_client_send_function_implementation(ofstream& out,
void generate_cocoa_service_client_send_function_implementation(ostream& out,
t_service* tservice,
t_function* tfunction,
bool needs_protocol);
void generate_cocoa_service_client_send_function_invocation(ofstream& out, t_function* tfunction);
void generate_cocoa_service_client_send_async_function_invocation(ofstream& out,
void generate_cocoa_service_client_send_function_invocation(ostream& out, t_function* tfunction);
void generate_cocoa_service_client_send_async_function_invocation(ostream& out,
t_function* tfunction,
string failureBlockName);
void generate_cocoa_service_client_recv_function_implementation(ofstream& out,
void generate_cocoa_service_client_recv_function_implementation(ostream& out,
t_service* tservice,
t_function* tfunction,
bool needs_protocol);
void generate_cocoa_service_client_implementation(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_client_async_implementation(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_client_implementation(std::ostream& out, t_service* tservice);
void generate_cocoa_service_client_async_implementation(std::ostream& out, t_service* tservice);
void generate_cocoa_service_server_interface(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_server_implementation(std::ofstream& out, t_service* tservice);
void generate_cocoa_service_server_interface(std::ostream& out, t_service* tservice);
void generate_cocoa_service_server_implementation(std::ostream& out, t_service* tservice);
void generate_cocoa_service_helpers(t_service* tservice);
void generate_service_client(t_service* tservice);
void generate_service_server(t_service* tservice);
@ -179,34 +179,34 @@ public:
* Serialization constructs
*/
void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string fieldName);
void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string fieldName);
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string fieldName = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string fieldName = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string iter,
std::string map);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out,
void generate_serialize_list_element(std::ostream& out,
t_list* tlist,
std::string index,
std::string listName);
@ -238,6 +238,12 @@ public:
std::string getter_name(string field_name);
std::string setter_name(string field_name);
bool type_can_be_copy(t_type* ttype) {
ttype = get_true_type(ttype);
return ttype->is_string();
}
bool type_can_be_null(t_type* ttype) {
ttype = get_true_type(ttype);
@ -254,8 +260,8 @@ private:
* File streams
*/
std::ofstream f_header_;
std::ofstream f_impl_;
ofstream_with_content_based_conditional_update f_header_;
ofstream_with_content_based_conditional_update f_impl_;
bool log_unexpected_;
bool validate_required_;
@ -568,7 +574,7 @@ void t_cocoa_generator::generate_xception(t_struct* txception) {
*
* @param tstruct The struct definition
*/
void t_cocoa_generator::generate_cocoa_struct_interface(ofstream& out,
void t_cocoa_generator::generate_cocoa_struct_interface(ostream& out,
t_struct* tstruct,
bool is_exception) {
@ -618,7 +624,7 @@ void t_cocoa_generator::generate_cocoa_struct_interface(ofstream& out,
* Generate signature for initializer of struct with a parameter for
* each field.
*/
void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ofstream& out,
void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ostream& out,
t_struct* tstruct) {
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
@ -641,7 +647,7 @@ void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ofstream& ou
* Generate the initWithCoder method for this struct so it's compatible with
* the NSCoding protocol
*/
void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ofstream& out,
void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ostream& out,
t_struct* tstruct,
bool is_exception) {
@ -713,7 +719,7 @@ void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ofstream& o
* Generate the encodeWithCoder method for this struct so it's compatible with
* the NSCoding protocol
*/
void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ofstream& out,
void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ostream& out,
t_struct* tstruct,
bool is_exception) {
@ -780,7 +786,7 @@ void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ofstream&
/**
* Generate the copy method for this struct
*/
void t_cocoa_generator::generate_cocoa_struct_copy_method(ofstream& out, t_struct* tstruct, bool is_exception) {
void t_cocoa_generator::generate_cocoa_struct_copy_method(ostream& out, t_struct* tstruct, bool is_exception) {
out << indent() << "- (instancetype) copyWithZone:(NSZone *)zone" << endl;
scope_up(out);
@ -815,7 +821,7 @@ void t_cocoa_generator::generate_cocoa_struct_copy_method(ofstream& out, t_struc
/**
* Generate the hash method for this struct
*/
void t_cocoa_generator::generate_cocoa_struct_hash_method(ofstream& out, t_struct* tstruct) {
void t_cocoa_generator::generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct) {
indent(out) << "- (NSUInteger) hash" << endl;
scope_up(out);
out << indent() << "NSUInteger hash = 17;" << endl;
@ -846,7 +852,7 @@ void t_cocoa_generator::generate_cocoa_struct_hash_method(ofstream& out, t_struc
/**
* Generate the isEqual method for this struct
*/
void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ofstream& out, t_struct* tstruct, bool is_exception) {
void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ostream& out, t_struct* tstruct, bool is_exception) {
indent(out) << "- (BOOL) isEqual: (id) anObject" << endl;
scope_up(out);
@ -913,7 +919,7 @@ void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ofstream& out, t_s
* @param is_exception Is this an exception?
* @param is_result If this is a result it needs a different writer
*/
void t_cocoa_generator::generate_cocoa_struct_implementation(ofstream& out,
void t_cocoa_generator::generate_cocoa_struct_implementation(ostream& out,
t_struct* tstruct,
bool is_exception,
bool is_result) {
@ -1017,7 +1023,7 @@ void t_cocoa_generator::generate_cocoa_struct_implementation(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_cocoa_generator::generate_cocoa_struct_reader(ofstream& out, t_struct* tstruct) {
void t_cocoa_generator::generate_cocoa_struct_reader(ostream& out, t_struct* tstruct) {
out << "- (BOOL) read: (id <TProtocol>) inProtocol error: (NSError *__autoreleasing *)__thriftError" << endl;
scope_up(out);
@ -1111,7 +1117,7 @@ void t_cocoa_generator::generate_cocoa_struct_reader(ofstream& out, t_struct* ts
*
* @param tstruct The struct definition
*/
void t_cocoa_generator::generate_cocoa_struct_writer(ofstream& out, t_struct* tstruct) {
void t_cocoa_generator::generate_cocoa_struct_writer(ostream& out, t_struct* tstruct) {
out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
indent_up();
@ -1162,7 +1168,7 @@ void t_cocoa_generator::generate_cocoa_struct_writer(ofstream& out, t_struct* ts
*
* @param tstruct The struct definition
*/
void t_cocoa_generator::generate_cocoa_struct_result_writer(ofstream& out, t_struct* tstruct) {
void t_cocoa_generator::generate_cocoa_struct_result_writer(ostream& out, t_struct* tstruct) {
out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
indent_up();
@ -1225,7 +1231,7 @@ void t_cocoa_generator::generate_cocoa_struct_result_writer(ofstream& out, t_str
*
* @param tstruct The struct definition
*/
void t_cocoa_generator::generate_cocoa_struct_validator(ofstream& out, t_struct* tstruct) {
void t_cocoa_generator::generate_cocoa_struct_validator(ostream& out, t_struct* tstruct) {
out << indent() << "- (BOOL) validate: (NSError *__autoreleasing *)__thriftError {" << endl;
indent_up();
@ -1259,7 +1265,7 @@ void t_cocoa_generator::generate_cocoa_struct_validator(ofstream& out, t_struct*
*
* @param tstruct The struct definition
*/
void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ofstream& out,
void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ostream& out,
t_struct* tstruct,
bool is_exception) {
(void)is_exception;
@ -1298,7 +1304,7 @@ void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ofs
*
* @param tstruct The struct definition
*/
void t_cocoa_generator::generate_cocoa_struct_description(ofstream& out, t_struct* tstruct) {
void t_cocoa_generator::generate_cocoa_struct_description(ostream& out, t_struct* tstruct) {
// Allow use of debugDescription so the app can add description via a cateogory/extension
if (debug_descriptions_) {
@ -1428,7 +1434,7 @@ void t_cocoa_generator::generate_function_helpers(t_service *tservice, t_functio
*
* @param tservice The service to generate a protocol definition for
*/
void t_cocoa_generator::generate_cocoa_service_protocol(ofstream& out, t_service* tservice) {
void t_cocoa_generator::generate_cocoa_service_protocol(ostream& out, t_service* tservice) {
out << "@protocol " << cocoa_prefix_ << tservice->get_name() << " <NSObject>" << endl;
vector<t_function*> functions = tservice->get_functions();
@ -1452,7 +1458,7 @@ void t_cocoa_generator::generate_cocoa_service_protocol(ofstream& out, t_service
*
* @param tservice The service to generate a protocol definition for
*/
void t_cocoa_generator::generate_cocoa_service_async_protocol(ofstream& out, t_service* tservice) {
void t_cocoa_generator::generate_cocoa_service_async_protocol(ostream& out, t_service* tservice) {
out << "@protocol " << cocoa_prefix_ << tservice->get_name() << "Async"
<< " <NSObject>" << endl;
@ -1472,7 +1478,7 @@ void t_cocoa_generator::generate_cocoa_service_async_protocol(ofstream& out, t_s
*
* @param tservice The service to generate a client interface definition for
*/
void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out,
void t_cocoa_generator::generate_cocoa_service_client_interface(ostream& out,
t_service* tservice) {
out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Client : TBaseClient <"
<< cocoa_prefix_ << tservice->get_name() << "> " << endl;
@ -1488,7 +1494,7 @@ void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out,
*
* @param tservice The service to generate a client interface definition for
*/
void t_cocoa_generator::generate_cocoa_service_client_async_interface(ofstream& out,
void t_cocoa_generator::generate_cocoa_service_client_async_interface(ostream& out,
t_service* tservice) {
out << "@interface " << cocoa_prefix_ << tservice->get_name() << "ClientAsync : TBaseClient <"
<< cocoa_prefix_ << tservice->get_name() << "Async> " << endl
@ -1506,7 +1512,7 @@ void t_cocoa_generator::generate_cocoa_service_client_async_interface(ofstream&
*
* @param tservice The service to generate a client interface definition for
*/
void t_cocoa_generator::generate_cocoa_service_server_interface(ofstream& out,
void t_cocoa_generator::generate_cocoa_service_server_interface(ostream& out,
t_service* tservice) {
out << "@interface " << cocoa_prefix_ << tservice->get_name()
<< "Processor : NSObject <TProcessor> " << endl;
@ -1519,7 +1525,7 @@ void t_cocoa_generator::generate_cocoa_service_server_interface(ofstream& out,
}
void t_cocoa_generator::generate_cocoa_service_client_send_function_implementation(
ofstream& out,
ostream& out,
t_service *tservice,
t_function* tfunction,
bool needs_protocol) {
@ -1577,7 +1583,7 @@ void t_cocoa_generator::generate_cocoa_service_client_send_function_implementati
}
void t_cocoa_generator::generate_cocoa_service_client_recv_function_implementation(
ofstream& out,
ostream& out,
t_service* tservice,
t_function* tfunction,
bool needs_protocol) {
@ -1666,7 +1672,7 @@ void t_cocoa_generator::generate_cocoa_service_client_recv_function_implementati
* @param tfunction The service to generate an implementation for
*/
void t_cocoa_generator::generate_cocoa_service_client_send_function_invocation(
ofstream& out,
ostream& out,
t_function* tfunction) {
t_struct* arg_struct = tfunction->get_arglist();
@ -1696,7 +1702,7 @@ void t_cocoa_generator::generate_cocoa_service_client_send_function_invocation(
* @param tfunction The service to generate an implementation for
*/
void t_cocoa_generator::generate_cocoa_service_client_send_async_function_invocation(
ofstream& out,
ostream& out,
t_function* tfunction,
string failureBlockName) {
@ -1730,7 +1736,7 @@ void t_cocoa_generator::generate_cocoa_service_client_send_async_function_invoca
*
* @param tservice The service to generate an implementation for
*/
void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& out,
void t_cocoa_generator::generate_cocoa_service_client_implementation(ostream& out,
t_service* tservice) {
string name = cocoa_prefix_ + tservice->get_name() + "Client";
@ -1814,7 +1820,7 @@ void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& o
*
* @param tservice The service to generate an implementation for
*/
void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ofstream& out,
void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ostream& out,
t_service* tservice) {
string name = cocoa_prefix_ + tservice->get_name() + "ClientAsync";
@ -1974,7 +1980,7 @@ void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ofstr
*
* @param tservice The service to generate an implementation for
*/
void t_cocoa_generator::generate_cocoa_service_server_implementation(ofstream& out,
void t_cocoa_generator::generate_cocoa_service_server_implementation(ostream& out,
t_service* tservice) {
string name = cocoa_prefix_ + tservice->get_name() + "Processor";
@ -2150,7 +2156,7 @@ void t_cocoa_generator::generate_cocoa_service_server_implementation(ofstream& o
* @param tfield The field
* @param fieldName The variable name for this field
*/
void t_cocoa_generator::generate_deserialize_field(ofstream& out,
void t_cocoa_generator::generate_deserialize_field(ostream& out,
t_field* tfield,
string fieldName) {
t_type* type = get_true_type(tfield->get_type());
@ -2174,7 +2180,7 @@ void t_cocoa_generator::generate_deserialize_field(ofstream& out,
throw "compiler error: cannot serialize void field in a struct: " + tfield->get_name();
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "readBinary:&" << fieldName << " error: __thriftError]";
} else {
out << "readString:&" << fieldName << " error: __thriftError]";
@ -2216,7 +2222,7 @@ void t_cocoa_generator::generate_deserialize_field(ofstream& out,
/**
* Generates an unserializer for a struct, allocates the struct and invokes read:
*/
void t_cocoa_generator::generate_deserialize_struct(ofstream& out,
void t_cocoa_generator::generate_deserialize_struct(ostream& out,
t_struct* tstruct,
string fieldName) {
indent(out) << type_name(tstruct) << fieldName << " = [[" << type_name(tstruct, true)
@ -2227,7 +2233,7 @@ void t_cocoa_generator::generate_deserialize_struct(ofstream& out,
/**
* Deserializes a container by reading its size and then iterating
*/
void t_cocoa_generator::generate_deserialize_container(ofstream& out,
void t_cocoa_generator::generate_deserialize_container(ostream& out,
t_type* ttype,
string fieldName) {
string size = tmp("_size");
@ -2348,7 +2354,7 @@ string t_cocoa_generator::unbox(t_type* ttype, string field_name) {
/**
* Generates code to deserialize a map element
*/
void t_cocoa_generator::generate_deserialize_map_element(ofstream& out,
void t_cocoa_generator::generate_deserialize_map_element(ostream& out,
t_map* tmap,
string fieldName) {
string key = tmp("_key");
@ -2368,7 +2374,7 @@ void t_cocoa_generator::generate_deserialize_map_element(ofstream& out,
/**
* Deserializes a set element
*/
void t_cocoa_generator::generate_deserialize_set_element(ofstream& out,
void t_cocoa_generator::generate_deserialize_set_element(ostream& out,
t_set* tset,
string fieldName) {
string elem = tmp("_elem");
@ -2383,7 +2389,7 @@ void t_cocoa_generator::generate_deserialize_set_element(ofstream& out,
/**
* Deserializes a list element
*/
void t_cocoa_generator::generate_deserialize_list_element(ofstream& out,
void t_cocoa_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string fieldName) {
string elem = tmp("_elem");
@ -2401,7 +2407,7 @@ void t_cocoa_generator::generate_deserialize_list_element(ofstream& out,
* @param tfield The field to serialize
* @param fieldName Name to of the variable holding the field
*/
void t_cocoa_generator::generate_serialize_field(ofstream& out, t_field* tfield, string fieldName) {
void t_cocoa_generator::generate_serialize_field(ostream& out, t_field* tfield, string fieldName) {
t_type* type = get_true_type(tfield->get_type());
// Do nothing for void types
@ -2423,7 +2429,7 @@ void t_cocoa_generator::generate_serialize_field(ofstream& out, t_field* tfield,
throw "compiler error: cannot serialize void field in a struct: " + fieldName;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "writeBinary: " << fieldName << " error: __thriftError]";
} else {
out << "writeString: " << fieldName << " error: __thriftError]";
@ -2468,7 +2474,7 @@ void t_cocoa_generator::generate_serialize_field(ofstream& out, t_field* tfield,
* @param tstruct The struct to serialize
* @param fieldName Name of variable holding struct
*/
void t_cocoa_generator::generate_serialize_struct(ofstream& out,
void t_cocoa_generator::generate_serialize_struct(ostream& out,
t_struct* tstruct,
string fieldName) {
(void)tstruct;
@ -2481,7 +2487,7 @@ void t_cocoa_generator::generate_serialize_struct(ofstream& out,
* @param ttype The type of container
* @param fieldName Name of variable holding container
*/
void t_cocoa_generator::generate_serialize_container(ofstream& out,
void t_cocoa_generator::generate_serialize_container(ostream& out,
t_type* ttype,
string fieldName) {
scope_up(out);
@ -2547,7 +2553,7 @@ void t_cocoa_generator::generate_serialize_container(ofstream& out,
/**
* Serializes the members of a map.
*/
void t_cocoa_generator::generate_serialize_map_element(ofstream& out,
void t_cocoa_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string key,
string mapName) {
@ -2560,7 +2566,7 @@ void t_cocoa_generator::generate_serialize_map_element(ofstream& out,
/**
* Serializes the members of a set.
*/
void t_cocoa_generator::generate_serialize_set_element(ofstream& out,
void t_cocoa_generator::generate_serialize_set_element(ostream& out,
t_set* tset,
string elementName) {
t_field efield(tset->get_elem_type(), elementName);
@ -2570,7 +2576,7 @@ void t_cocoa_generator::generate_serialize_set_element(ofstream& out,
/**
* Serializes the members of a list.
*/
void t_cocoa_generator::generate_serialize_list_element(ofstream& out,
void t_cocoa_generator::generate_serialize_list_element(ostream& out,
t_list* tlist,
string index,
string listName) {
@ -2733,8 +2739,8 @@ void t_cocoa_generator::print_const_value(ostream& out,
indent(out);
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
if (defval)
out << type_name(type) << " ";
out << name << " = [" << type_name(type, true) << " new];"
@ -2758,8 +2764,8 @@ void t_cocoa_generator::print_const_value(ostream& out,
indent(mapout);
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
if (defval)
mapout << type_name(type) << " ";
mapout << name << " = @{";
@ -2824,7 +2830,7 @@ string t_cocoa_generator::render_const_value(ostream& out,
case t_base_type::TYPE_STRING:
// We must handle binary constant but the syntax of IDL defines
// nothing about binary constant.
// if ((t_base_type*)type)->is_binary())
// if type->is_binary())
// // binary code
render << "@\"" << get_escaped_string(value) << '"';
break;
@ -2904,8 +2910,8 @@ string t_cocoa_generator::render_const_value(string name,
} else if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
if (val.size() > 0)
render << "[[" << type_name(type, true) << " alloc] initWith";
else
@ -2937,8 +2943,8 @@ string t_cocoa_generator::render_const_value(string name,
render << "[[NSDictionary alloc] initWithObjectsAndKeys: ";
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
bool first = true;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(name, ktype, v_iter->first, true);
@ -3011,7 +3017,9 @@ string t_cocoa_generator::declare_property(t_field* tfield) {
std::ostringstream render;
render << "@property (";
if (type_can_be_null(tfield->get_type())) {
if (type_can_be_copy(tfield->get_type())) {
render << "copy, ";
} else if (type_can_be_null(tfield->get_type())) {
render << "strong, ";
} else {
render << "assign, ";

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -100,46 +100,46 @@ public:
void generate_union(t_struct* tunion);
void generate_xception(t_struct* txception);
void generate_service(t_service* tservice);
void generate_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset);
void generate_csharp_property(ofstream& out,
void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
void generate_csharp_property(ostream& out,
t_field* tfield,
bool isPublic,
bool includeIsset = true,
std::string fieldPrefix = "");
bool print_const_value(std::ofstream& out,
bool print_const_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value,
bool in_static,
bool defval = false,
bool needtype = false);
std::string render_const_value(std::ofstream& out,
std::string render_const_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value);
void print_const_constructor(std::ofstream& out, std::vector<t_const*> consts);
void print_const_def_value(std::ofstream& out,
void print_const_constructor(std::ostream& out, std::vector<t_const*> consts);
void print_const_def_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value);
void generate_csharp_struct(t_struct* tstruct, bool is_exception);
void generate_csharp_union(t_struct* tunion);
void generate_csharp_struct_definition(std::ofstream& out,
void generate_csharp_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false,
bool in_class = false,
bool is_result = false);
void generate_csharp_union_definition(std::ofstream& out, t_struct* tunion);
void generate_csharp_union_class(std::ofstream& out, t_struct* tunion, t_field* tfield);
void generate_csharp_wcffault(std::ofstream& out, t_struct* tstruct);
void generate_csharp_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_csharp_struct_result_writer(std::ofstream& out, t_struct* tstruct);
void generate_csharp_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_csharp_struct_tostring(std::ofstream& out, t_struct* tstruct);
void generate_csharp_struct_equals(std::ofstream& out, t_struct* tstruct);
void generate_csharp_struct_hashcode(std::ofstream& out, t_struct* tstruct);
void generate_csharp_union_reader(std::ofstream& out, t_struct* tunion);
void generate_csharp_union_definition(std::ostream& out, t_struct* tunion);
void generate_csharp_union_class(std::ostream& out, t_struct* tunion, t_field* tfield);
void generate_csharp_wcffault(std::ostream& out, t_struct* tstruct);
void generate_csharp_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_csharp_struct_result_writer(std::ostream& out, t_struct* tstruct);
void generate_csharp_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_csharp_struct_tostring(std::ostream& out, t_struct* tstruct);
void generate_csharp_struct_equals(std::ostream& out, t_struct* tstruct);
void generate_csharp_struct_hashcode(std::ostream& out, t_struct* tstruct);
void generate_csharp_union_reader(std::ostream& out, t_struct* tunion);
void generate_function_helpers(t_function* tfunction);
void generate_service_interface(t_service* tservice);
@ -156,36 +156,36 @@ public:
void generate_process_function(t_service* tservice, t_function* function);
void generate_process_function_async(t_service* tservice, t_function* function);
void generate_deserialize_field(std::ofstream& out,
void generate_deserialize_field(std::ostream& out,
t_field* tfield,
std::string prefix = "",
bool is_propertyless = false);
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out, t_list* list, std::string prefix = "");
void generate_serialize_field(std::ofstream& out,
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ostream& out, t_list* list, std::string prefix = "");
void generate_serialize_field(std::ostream& out,
t_field* tfield,
std::string prefix = "",
bool is_element = false,
bool is_propertyless = false);
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string iter,
std::string map);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
void generate_csharp_doc(std::ofstream& out, t_field* field);
void generate_csharp_doc(std::ofstream& out, t_doc* tdoc);
void generate_csharp_doc(std::ofstream& out, t_function* tdoc);
void generate_csharp_docstring_comment(std::ofstream& out, string contents);
void generate_csharp_doc(std::ostream& out, t_field* field);
void generate_csharp_doc(std::ostream& out, t_doc* tdoc);
void generate_csharp_doc(std::ostream& out, t_function* tdoc);
void generate_csharp_docstring_comment(std::ostream& out, string contents);
void start_csharp_namespace(std::ofstream& out);
void end_csharp_namespace(std::ofstream& out);
void start_csharp_namespace(std::ostream& out);
void end_csharp_namespace(std::ostream& out);
std::string csharp_type_usings();
std::string csharp_thrift_usings();
@ -224,7 +224,7 @@ public:
private:
std::string namespace_name_;
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_service_;
std::string namespace_dir_;
bool async_;
bool nullable_;
@ -403,14 +403,14 @@ void t_csharp_generator::init_keywords() {
csharp_keywords["yield"] = 1;
}
void t_csharp_generator::start_csharp_namespace(ofstream& out) {
void t_csharp_generator::start_csharp_namespace(ostream& out) {
if (!namespace_name_.empty()) {
out << "namespace " << namespace_name_ << "\n";
scope_up(out);
}
}
void t_csharp_generator::end_csharp_namespace(ofstream& out) {
void t_csharp_generator::end_csharp_namespace(ostream& out) {
if (!namespace_name_.empty()) {
scope_down(out);
}
@ -438,7 +438,7 @@ void t_csharp_generator::generate_typedef(t_typedef* ttypedef) {
void t_csharp_generator::generate_enum(t_enum* tenum) {
string f_enum_name = namespace_dir_ + "/" + (tenum->get_name()) + ".cs";
ofstream f_enum;
ofstream_with_content_based_conditional_update f_enum;
f_enum.open(f_enum_name.c_str());
f_enum << autogen_comment() << endl;
@ -471,7 +471,7 @@ void t_csharp_generator::generate_consts(std::vector<t_const*> consts) {
return;
}
string f_consts_name = namespace_dir_ + '/' + program_name_ + ".Constants.cs";
ofstream f_consts;
ofstream_with_content_based_conditional_update f_consts;
f_consts.open(f_consts_name.c_str());
f_consts << autogen_comment() << csharp_type_usings() << endl;
@ -504,15 +504,15 @@ void t_csharp_generator::generate_consts(std::vector<t_const*> consts) {
f_consts.close();
}
void t_csharp_generator::print_const_def_value(std::ofstream& out,
void t_csharp_generator::print_const_def_value(std::ostream& out,
string name,
t_type* type,
t_const_value* value) {
if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
prepare_member_name_mapping((t_struct*)type);
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_field* field = NULL;
@ -532,8 +532,8 @@ void t_csharp_generator::print_const_def_value(std::ofstream& out,
} else if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(out, name, ktype, v_iter->first);
string val = render_const_value(out, name, vtype, v_iter->second);
@ -557,7 +557,7 @@ void t_csharp_generator::print_const_def_value(std::ofstream& out,
}
}
void t_csharp_generator::print_const_constructor(std::ofstream& out, std::vector<t_const*> consts) {
void t_csharp_generator::print_const_constructor(std::ostream& out, std::vector<t_const*> consts) {
indent(out) << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()"
<< endl;
scope_up(out);
@ -574,7 +574,7 @@ void t_csharp_generator::print_const_constructor(std::ofstream& out, std::vector
// it seems like all that methods that call this are using in_static to be the opposite of what it
// would imply
bool t_csharp_generator::print_const_value(std::ofstream& out,
bool t_csharp_generator::print_const_value(std::ostream& out,
string name,
t_type* type,
t_const_value* value,
@ -614,7 +614,7 @@ bool t_csharp_generator::print_const_value(std::ofstream& out,
return need_static_construction;
}
std::string t_csharp_generator::render_const_value(ofstream& out,
std::string t_csharp_generator::render_const_value(ostream& out,
string name,
t_type* type,
t_const_value* value) {
@ -671,7 +671,7 @@ void t_csharp_generator::generate_xception(t_struct* txception) {
void t_csharp_generator::generate_csharp_struct(t_struct* tstruct, bool is_exception) {
string f_struct_name = namespace_dir_ + "/" + (tstruct->get_name()) + ".cs";
ofstream f_struct;
ofstream_with_content_based_conditional_update f_struct;
f_struct.open(f_struct_name.c_str());
@ -682,7 +682,7 @@ void t_csharp_generator::generate_csharp_struct(t_struct* tstruct, bool is_excep
f_struct.close();
}
void t_csharp_generator::generate_csharp_struct_definition(ofstream& out,
void t_csharp_generator::generate_csharp_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception,
bool in_class,
@ -843,7 +843,7 @@ void t_csharp_generator::generate_csharp_struct_definition(ofstream& out,
} else {
out << ", ";
}
out << type_name((*m_iter)->get_type()) << " " << (*m_iter)->get_name();
out << type_name((*m_iter)->get_type()) << " " << normalize_name((*m_iter)->get_name());
}
}
out << ") : this() {" << endl;
@ -851,7 +851,7 @@ void t_csharp_generator::generate_csharp_struct_definition(ofstream& out,
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if (field_is_required((*m_iter))) {
indent(out) << "this." << prop_name((*m_iter)) << " = " << (*m_iter)->get_name() << ";"
indent(out) << "this." << prop_name((*m_iter)) << " = " << normalize_name((*m_iter)->get_name()) << ";"
<< endl;
}
}
@ -885,7 +885,7 @@ void t_csharp_generator::generate_csharp_struct_definition(ofstream& out,
}
}
void t_csharp_generator::generate_csharp_wcffault(ofstream& out, t_struct* tstruct) {
void t_csharp_generator::generate_csharp_wcffault(ostream& out, t_struct* tstruct) {
out << endl;
indent(out) << "#if !SILVERLIGHT" << endl;
indent(out) << "[Serializable]" << endl;
@ -915,7 +915,7 @@ void t_csharp_generator::generate_csharp_wcffault(ofstream& out, t_struct* tstru
out << endl;
}
void t_csharp_generator::generate_csharp_struct_reader(ofstream& out, t_struct* tstruct) {
void t_csharp_generator::generate_csharp_struct_reader(ostream& out, t_struct* tstruct) {
indent(out) << "public void Read (TProtocol iprot)" << endl;
scope_up(out);
@ -986,7 +986,10 @@ void t_csharp_generator::generate_csharp_struct_reader(ofstream& out, t_struct*
if (field_is_required((*f_iter))) {
indent(out) << "if (!isset_" << (*f_iter)->get_name() << ")" << endl;
indent_up();
indent(out) << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << endl;
out << indent()
<< "throw new TProtocolException(TProtocolException.INVALID_DATA, "
<< "\"required field " << prop_name((*f_iter)) << " not set\");"
<< endl;
indent_down();
}
}
@ -1002,7 +1005,7 @@ void t_csharp_generator::generate_csharp_struct_reader(ofstream& out, t_struct*
indent(out) << "}" << endl << endl;
}
void t_csharp_generator::generate_csharp_struct_writer(ofstream& out, t_struct* tstruct) {
void t_csharp_generator::generate_csharp_struct_writer(ostream& out, t_struct* tstruct) {
out << indent() << "public void Write(TProtocol oprot) {" << endl;
indent_up();
@ -1022,20 +1025,36 @@ void t_csharp_generator::generate_csharp_struct_writer(ofstream& out, t_struct*
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
bool is_required = field_is_required((*f_iter));
bool has_default = field_has_default((*f_iter));
if (nullable_ && !has_default && !is_required) {
indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
indent_up();
} else if (!is_required) {
bool null_allowed = type_can_be_null((*f_iter)->get_type());
bool null_allowed = type_can_be_null((*f_iter)->get_type());
if (is_required)
{
if (null_allowed) {
indent(out) << "if (" << prop_name((*f_iter)) << " != null && __isset."
<< normalize_name((*f_iter)->get_name()) << ") {" << endl;
indent_up();
} else {
indent(out) << "if (__isset." << normalize_name((*f_iter)->get_name()) << ") {" << endl;
indent(out) << "if (" << prop_name((*f_iter)) << " == null)" << endl;
indent_up();
out << indent()
<< "throw new TProtocolException(TProtocolException.INVALID_DATA, "
<< "\"required field " << prop_name((*f_iter)) << " not set\");"
<< endl;
indent_down();
}
}
else
{
if (nullable_ && !has_default) {
indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
}
else if (null_allowed) {
out << indent()
<< "if (" << prop_name((*f_iter)) << " != null && __isset."
<< normalize_name((*f_iter)->get_name()) << ") {"
<< endl;
}
else {
indent(out) << "if (__isset." << normalize_name((*f_iter)->get_name()) << ") {" << endl;
}
indent_up();
}
indent(out) << "field.Name = \"" << (*f_iter)->get_name() << "\";" << endl;
indent(out) << "field.Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl;
indent(out) << "field.ID = " << (*f_iter)->get_key() << ";" << endl;
@ -1065,7 +1084,7 @@ void t_csharp_generator::generate_csharp_struct_writer(ofstream& out, t_struct*
indent(out) << "}" << endl << endl;
}
void t_csharp_generator::generate_csharp_struct_result_writer(ofstream& out, t_struct* tstruct) {
void t_csharp_generator::generate_csharp_struct_result_writer(ostream& out, t_struct* tstruct) {
indent(out) << "public void Write(TProtocol oprot) {" << endl;
indent_up();
@ -1137,7 +1156,7 @@ void t_csharp_generator::generate_csharp_struct_result_writer(ofstream& out, t_s
indent(out) << "}" << endl << endl;
}
void t_csharp_generator::generate_csharp_struct_tostring(ofstream& out, t_struct* tstruct) {
void t_csharp_generator::generate_csharp_struct_tostring(ostream& out, t_struct* tstruct) {
indent(out) << "public override string ToString() {" << endl;
indent_up();
@ -1211,7 +1230,7 @@ void t_csharp_generator::generate_csharp_struct_tostring(ofstream& out, t_struct
void t_csharp_generator::generate_csharp_union(t_struct* tunion) {
string f_union_name = namespace_dir_ + "/" + (tunion->get_name()) + ".cs";
ofstream f_union;
ofstream_with_content_based_conditional_update f_union;
f_union.open(f_union_name.c_str());
@ -1222,7 +1241,7 @@ void t_csharp_generator::generate_csharp_union(t_struct* tunion) {
f_union.close();
}
void t_csharp_generator::generate_csharp_union_definition(std::ofstream& out, t_struct* tunion) {
void t_csharp_generator::generate_csharp_union_definition(std::ostream& out, t_struct* tunion) {
// Let's define the class first
start_csharp_namespace(out);
@ -1273,7 +1292,7 @@ void t_csharp_generator::generate_csharp_union_definition(std::ofstream& out, t_
end_csharp_namespace(out);
}
void t_csharp_generator::generate_csharp_union_class(std::ofstream& out,
void t_csharp_generator::generate_csharp_union_class(std::ostream& out,
t_struct* tunion,
t_field* tfield) {
indent(out) << "public class " << tfield->get_name() << " : " << tunion->get_name() << " {"
@ -1322,7 +1341,7 @@ void t_csharp_generator::generate_csharp_union_class(std::ofstream& out,
indent(out) << "}" << endl << endl;
}
void t_csharp_generator::generate_csharp_struct_equals(ofstream& out, t_struct* tstruct) {
void t_csharp_generator::generate_csharp_struct_equals(ostream& out, t_struct* tstruct) {
indent(out) << "public override bool Equals(object that) {" << endl;
indent_up();
@ -1350,7 +1369,7 @@ void t_csharp_generator::generate_csharp_struct_equals(ofstream& out, t_struct*
<< normalize_name((*f_iter)->get_name()) << ") || (";
}
t_type* ttype = (*f_iter)->get_type();
if (ttype->is_container() || (ttype->is_base_type() && (((t_base_type*)ttype)->is_binary()))) {
if (ttype->is_container() || ttype->is_binary()) {
out << "TCollections.Equals(";
} else {
out << "System.Object.Equals(";
@ -1371,7 +1390,7 @@ void t_csharp_generator::generate_csharp_struct_equals(ofstream& out, t_struct*
indent(out) << "}" << endl << endl;
}
void t_csharp_generator::generate_csharp_struct_hashcode(ofstream& out, t_struct* tstruct) {
void t_csharp_generator::generate_csharp_struct_hashcode(ostream& out, t_struct* tstruct) {
indent(out) << "public override int GetHashCode() {" << endl;
indent_up();
@ -2030,7 +2049,7 @@ void t_csharp_generator::generate_service_server_async(t_service* tservice) {
string extends_processor = "";
if (tservice->get_extends() != NULL) {
extends = type_name(tservice->get_extends());
extends_processor = extends + ".Processor, ";
extends_processor = extends + ".AsyncProcessor, ";
}
indent(f_service_) << "public class AsyncProcessor : " << extends_processor << "TAsyncProcessor {" << endl;
@ -2359,7 +2378,7 @@ void t_csharp_generator::generate_process_function_async(t_service* tservice, t_
f_service_ << endl;
}
void t_csharp_generator::generate_csharp_union_reader(std::ofstream& out, t_struct* tunion) {
void t_csharp_generator::generate_csharp_union_reader(std::ostream& out, t_struct* tunion) {
// Thanks to THRIFT-1768, we don't need to check for required fields in the union
const vector<t_field*>& fields = tunion->get_members();
vector<t_field*>::const_iterator f_iter;
@ -2433,7 +2452,7 @@ void t_csharp_generator::generate_csharp_union_reader(std::ofstream& out, t_stru
indent(out) << "}" << endl << endl;
}
void t_csharp_generator::generate_deserialize_field(ofstream& out,
void t_csharp_generator::generate_deserialize_field(ostream& out,
t_field* tfield,
string prefix,
bool is_propertyless) {
@ -2468,7 +2487,7 @@ void t_csharp_generator::generate_deserialize_field(ofstream& out,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "ReadBinary();";
} else {
out << "ReadString();";
@ -2506,7 +2525,7 @@ void t_csharp_generator::generate_deserialize_field(ofstream& out,
}
}
void t_csharp_generator::generate_deserialize_struct(ofstream& out,
void t_csharp_generator::generate_deserialize_struct(ostream& out,
t_struct* tstruct,
string prefix) {
if (union_ && tstruct->is_union()) {
@ -2517,7 +2536,7 @@ void t_csharp_generator::generate_deserialize_struct(ofstream& out,
}
}
void t_csharp_generator::generate_deserialize_container(ofstream& out,
void t_csharp_generator::generate_deserialize_container(ostream& out,
t_type* ttype,
string prefix) {
scope_up(out);
@ -2568,7 +2587,7 @@ void t_csharp_generator::generate_deserialize_container(ofstream& out,
scope_down(out);
}
void t_csharp_generator::generate_deserialize_map_element(ofstream& out,
void t_csharp_generator::generate_deserialize_map_element(ostream& out,
t_map* tmap,
string prefix) {
string key = tmp("_key");
@ -2586,7 +2605,7 @@ void t_csharp_generator::generate_deserialize_map_element(ofstream& out,
indent(out) << prefix << "[" << key << "] = " << val << ";" << endl;
}
void t_csharp_generator::generate_deserialize_set_element(ofstream& out,
void t_csharp_generator::generate_deserialize_set_element(ostream& out,
t_set* tset,
string prefix) {
string elem = tmp("_elem");
@ -2599,7 +2618,7 @@ void t_csharp_generator::generate_deserialize_set_element(ofstream& out,
indent(out) << prefix << ".Add(" << elem << ");" << endl;
}
void t_csharp_generator::generate_deserialize_list_element(ofstream& out,
void t_csharp_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix) {
string elem = tmp("_elem");
@ -2612,7 +2631,7 @@ void t_csharp_generator::generate_deserialize_list_element(ofstream& out,
indent(out) << prefix << ".Add(" << elem << ");" << endl;
}
void t_csharp_generator::generate_serialize_field(ofstream& out,
void t_csharp_generator::generate_serialize_field(ostream& out,
t_field* tfield,
string prefix,
bool is_element,
@ -2645,7 +2664,7 @@ void t_csharp_generator::generate_serialize_field(ofstream& out,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "WriteBinary(";
} else {
out << "WriteString(";
@ -2685,14 +2704,14 @@ void t_csharp_generator::generate_serialize_field(ofstream& out,
}
}
void t_csharp_generator::generate_serialize_struct(ofstream& out,
void t_csharp_generator::generate_serialize_struct(ostream& out,
t_struct* tstruct,
string prefix) {
(void)tstruct;
out << indent() << prefix << ".Write(oprot);" << endl;
}
void t_csharp_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_csharp_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
if (ttype->is_map()) {
@ -2744,7 +2763,7 @@ void t_csharp_generator::generate_serialize_container(ofstream& out, t_type* tty
scope_down(out);
}
void t_csharp_generator::generate_serialize_map_element(ofstream& out,
void t_csharp_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string iter,
string map) {
@ -2754,25 +2773,25 @@ void t_csharp_generator::generate_serialize_map_element(ofstream& out,
generate_serialize_field(out, &vfield, "", true);
}
void t_csharp_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_csharp_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield, "", true);
}
void t_csharp_generator::generate_serialize_list_element(ofstream& out,
void t_csharp_generator::generate_serialize_list_element(ostream& out,
t_list* tlist,
string iter) {
t_field efield(tlist->get_elem_type(), iter);
generate_serialize_field(out, &efield, "", true);
}
void t_csharp_generator::generate_property(ofstream& out,
void t_csharp_generator::generate_property(ostream& out,
t_field* tfield,
bool isPublic,
bool generateIsset) {
generate_csharp_property(out, tfield, isPublic, generateIsset, "_");
}
void t_csharp_generator::generate_csharp_property(ofstream& out,
void t_csharp_generator::generate_csharp_property(ostream& out,
t_field* tfield,
bool isPublic,
bool generateIsset,
@ -2801,6 +2820,8 @@ void t_csharp_generator::generate_csharp_property(ofstream& out,
}
if (ttype->is_base_type()) {
use_nullable = ((t_base_type*)ttype)->get_base() != t_base_type::TYPE_STRING;
} else if (ttype->is_enum()) {
use_nullable = true;
}
}
indent(out) << "return " << fieldPrefix + tfield->get_name() << ";" << endl;
@ -2888,6 +2909,7 @@ void t_csharp_generator::prepare_member_name_mapping(void* scope,
const string& structname) {
// begin new scope
member_mapping_scope dummy;
dummy.scope_member = 0;
member_mapping_scopes.push_back(dummy);
member_mapping_scope& active = member_mapping_scopes.back();
active.scope_member = scope;
@ -3018,7 +3040,7 @@ string t_csharp_generator::declare_field(t_field* tfield, bool init, std::string
ttype = ((t_typedef*)ttype)->get_type();
}
if (ttype->is_base_type() && field_has_default(tfield)) {
ofstream dummy;
std::ofstream dummy;
result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
} else if (ttype->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@ -3136,11 +3158,11 @@ string t_csharp_generator::type_to_enum(t_type* type) {
throw "INVALID TYPE IN type_to_enum: " + type->get_name();
}
void t_csharp_generator::generate_csharp_docstring_comment(ofstream& out, string contents) {
void t_csharp_generator::generate_csharp_docstring_comment(ostream& out, string contents) {
generate_docstring_comment(out, "/// <summary>\n", "/// ", contents, "/// </summary>\n");
}
void t_csharp_generator::generate_csharp_doc(ofstream& out, t_field* field) {
void t_csharp_generator::generate_csharp_doc(ostream& out, t_field* field) {
if (field->get_type()->is_enum()) {
string combined_message = field->get_doc() + "\n<seealso cref=\""
+ get_enum_class_name(field->get_type()) + "\"/>";
@ -3150,13 +3172,13 @@ void t_csharp_generator::generate_csharp_doc(ofstream& out, t_field* field) {
}
}
void t_csharp_generator::generate_csharp_doc(ofstream& out, t_doc* tdoc) {
void t_csharp_generator::generate_csharp_doc(ostream& out, t_doc* tdoc) {
if (tdoc->has_doc()) {
generate_csharp_docstring_comment(out, tdoc->get_doc());
}
}
void t_csharp_generator::generate_csharp_doc(ofstream& out, t_function* tfunction) {
void t_csharp_generator::generate_csharp_doc(ostream& out, t_function* tfunction) {
if (tfunction->has_doc()) {
stringstream ps;
const vector<t_field*>& fields = tfunction->get_arglist()->get_members();

View file

@ -103,7 +103,7 @@ protected:
// Include type modules from other imported programs.
const vector<t_program*>& includes = program_->get_includes();
for (size_t i = 0; i < includes.size(); ++i) {
f_types_ << "import " << render_package(*(includes[i])) << includes[i]->get_name()
f_types_ << "public import " << render_package(*(includes[i])) << includes[i]->get_name()
<< "_types;" << endl;
}
if (!includes.empty())
@ -118,7 +118,7 @@ protected:
virtual void generate_consts(std::vector<t_const*> consts) {
if (!consts.empty()) {
string f_consts_name = package_dir_ + program_name_ + "_constants.d";
ofstream f_consts;
ofstream_with_content_based_conditional_update f_consts;
f_consts.open(f_consts_name.c_str());
f_consts << autogen_comment() << "module " << render_package(*program_) << program_name_
@ -131,6 +131,7 @@ protected:
vector<t_const*>::iterator c_iter;
for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
this->emit_doc(*c_iter, f_consts);
string name = (*c_iter)->get_name();
t_type* type = (*c_iter)->get_type();
indent(f_consts) << "immutable(" << render_type_name(type) << ") " << name << ";" << endl;
@ -159,6 +160,7 @@ protected:
}
virtual void generate_typedef(t_typedef* ttypedef) {
this->emit_doc(ttypedef, f_types_);
f_types_ << indent() << "alias " << render_type_name(ttypedef->get_type()) << " "
<< ttypedef->get_symbolic() << ";" << endl << endl;
}
@ -166,21 +168,17 @@ protected:
virtual void generate_enum(t_enum* tenum) {
vector<t_enum_value*> constants = tenum->get_constants();
this->emit_doc(tenum, f_types_);
string enum_name = tenum->get_name();
f_types_ << indent() << "enum " << enum_name << " {" << endl;
indent_up();
vector<t_enum_value*>::const_iterator c_iter;
bool first = true;
for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
if (first) {
first = false;
} else {
f_types_ << "," << endl;
}
this->emit_doc(*c_iter, f_types_);
indent(f_types_) << (*c_iter)->get_name();
f_types_ << " = " << (*c_iter)->get_value();
f_types_ << " = " << (*c_iter)->get_value() << ",";
}
f_types_ << endl;
@ -203,7 +201,7 @@ protected:
// Service implementation file includes
string f_servicename = package_dir_ + svc_name + ".d";
std::ofstream f_service;
ofstream_with_content_based_conditional_update f_service;
f_service.open(f_servicename.c_str());
f_service << autogen_comment() << "module " << render_package(*program_) << svc_name << ";"
<< endl << endl;
@ -225,6 +223,7 @@ protected:
extends = " : " + render_type_name(tservice->get_extends());
}
this->emit_doc(tservice, f_service);
f_service << indent() << "interface " << svc_name << extends << " {" << endl;
indent_up();
@ -236,6 +235,7 @@ protected:
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::iterator fn_iter;
for (fn_iter = functions.begin(); fn_iter != functions.end(); ++fn_iter) {
this->emit_doc(*fn_iter, f_service);
f_service << indent();
print_function_signature(f_service, *fn_iter);
f_service << ";" << endl;
@ -339,12 +339,26 @@ protected:
// Server skeleton generation.
string f_skeletonname = package_dir_ + svc_name + "_server.skeleton.d";
std::ofstream f_skeleton;
ofstream_with_content_based_conditional_update f_skeleton;
f_skeleton.open(f_skeletonname.c_str());
print_server_skeleton(f_skeleton, tservice);
f_skeleton.close();
}
void emit_doc(t_doc *doc, std::ostream& out) {
if (!doc->has_doc()) {
return;
}
indent(out) << "/**" << std::endl;
indent_up();
// No endl -- comments reliably have a newline at the end.
// This is true even for stuff like:
// /** method infos */ void foo(/** huh?*/ 1: i64 stuff)
indent(out) << doc->get_doc();
indent_down();
indent(out) << "*/" << std::endl;
}
private:
/**
* Writes a server skeleton for the passed service to out.
@ -381,8 +395,8 @@ private:
out << indent() << "// Your implementation goes here." << endl << indent() << "writeln(\""
<< (*f_iter)->get_name() << " called\");" << endl;
t_base_type* rt = (t_base_type*)(*f_iter)->get_returntype();
if (rt->get_base() != t_base_type::TYPE_VOID) {
t_type* rt = (*f_iter)->get_returntype();
if (!rt->is_void()) {
indent(out) << "return typeof(return).init;" << endl;
}
@ -543,8 +557,8 @@ private:
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -562,8 +576,8 @@ private:
} else if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(ktype, v_iter->first);
string val = render_const_value(vtype, v_iter->second);
@ -719,8 +733,8 @@ private:
* File streams, stored here to avoid passing them as parameters to every
* function.
*/
ofstream f_types_;
ofstream f_header_;
ofstream_with_content_based_conditional_update f_types_;
ofstream_with_content_based_conditional_update f_header_;
string package_dir_;
};

View file

@ -31,7 +31,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -141,13 +141,13 @@ public:
void generate_xception(t_struct* txception);
void generate_service(t_service* tservice);
void print_const_value(std::ofstream& out,
void print_const_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value,
bool in_static,
bool defval = false);
std::string render_const_value(ofstream& out,
std::string render_const_value(ostream& out,
std::string name,
t_type* type,
t_const_value* value);
@ -158,21 +158,21 @@ public:
void generate_dart_struct(t_struct* tstruct, bool is_exception);
void generate_dart_struct_definition(std::ofstream& out,
void generate_dart_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false,
bool is_result = false,
string export_file_name = "");
void generate_dart_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_dart_validator(std::ofstream& out, t_struct* tstruct);
void generate_dart_struct_result_writer(std::ofstream& out, t_struct* tstruct);
void generate_dart_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_dart_struct_tostring(std::ofstream& out, t_struct* tstruct);
void generate_dart_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_dart_validator(std::ostream& out, t_struct* tstruct);
void generate_dart_struct_result_writer(std::ostream& out, t_struct* tstruct);
void generate_dart_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_dart_struct_tostring(std::ostream& out, t_struct* tstruct);
std::string get_dart_type_string(t_type* type);
void generate_generic_field_getters(std::ofstream& out, t_struct* tstruct);
void generate_generic_field_setters(std::ofstream& out, t_struct* tstruct);
void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
void generate_dart_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
void generate_generic_field_getters(std::ostream& out, t_struct* tstruct);
void generate_generic_field_setters(std::ostream& out, t_struct* tstruct);
void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
void generate_dart_bean_boilerplate(std::ostream& out, t_struct* tstruct);
void generate_function_helpers(t_function* tfunction);
std::string init_value(t_field* tfield);
@ -184,7 +184,7 @@ public:
std::string get_constants_class_name(std::string name);
std::string generate_isset_check(t_field* field);
std::string generate_isset_check(std::string field);
void generate_isset_set(ofstream& out, t_field* field);
void generate_isset_set(ostream& out, t_field* field);
void generate_service_interface(t_service* tservice);
void generate_service_helpers(t_service* tservice);
@ -196,38 +196,38 @@ public:
* Serialization constructs
*/
void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string iter,
std::string map);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
void generate_dart_doc(std::ofstream& out, t_doc* tdoc);
void generate_dart_doc(std::ostream& out, t_doc* tdoc);
void generate_dart_doc(std::ofstream& out, t_function* tdoc);
void generate_dart_doc(std::ostream& out, t_function* tdoc);
/**
* Helper rendering functions
@ -265,7 +265,7 @@ public:
std::string constant_name(std::string name);
private:
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_service_;
std::string library_name_;
std::string library_prefix_;
@ -391,7 +391,7 @@ void t_dart_generator::generate_dart_library() {
f_library_name = get_out_dir() + "/" + library_name_ + ".dart";
}
ofstream f_library;
ofstream_with_content_based_conditional_update f_library;
f_library.open(f_library_name.c_str());
f_library << autogen_comment() << endl;
@ -413,7 +413,7 @@ void t_dart_generator::export_class_to_library(string file_name, string class_na
void t_dart_generator::generate_dart_pubspec() {
string f_pubspec_name = base_dir_ + "/pubspec.yaml";
ofstream f_pubspec;
ofstream_with_content_based_conditional_update f_pubspec;
f_pubspec.open(f_pubspec_name.c_str());
indent(f_pubspec) << "name: " << library_name_ << endl;
@ -478,7 +478,7 @@ void t_dart_generator::generate_enum(t_enum* tenum) {
string file_name = get_file_name(tenum->get_name());
string f_enum_name = src_dir_ + "/" + file_name + ".dart";
ofstream f_enum;
ofstream_with_content_based_conditional_update f_enum;
f_enum.open(f_enum_name.c_str());
// Comment and add library
@ -540,7 +540,7 @@ void t_dart_generator::generate_consts(std::vector<t_const*> consts) {
string file_name = get_file_name(class_name);
string f_consts_name = src_dir_ + "/" + file_name + ".dart";
ofstream f_consts;
ofstream_with_content_based_conditional_update f_consts;
f_consts.open(f_consts_name.c_str());
// Print header
@ -566,7 +566,7 @@ void t_dart_generator::generate_consts(std::vector<t_const*> consts) {
f_consts.close();
}
void t_dart_generator::print_const_value(std::ofstream& out,
void t_dart_generator::print_const_value(std::ostream& out,
string name,
t_type* type,
t_const_value* value,
@ -594,8 +594,8 @@ void t_dart_generator::print_const_value(std::ofstream& out,
} else if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
out << type_name(type) << " " << name << " = new " << type_name(type) << "()";
indent_up();
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
@ -623,8 +623,8 @@ void t_dart_generator::print_const_value(std::ofstream& out,
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(out, name, ktype, v_iter->first);
@ -668,7 +668,7 @@ void t_dart_generator::print_const_value(std::ofstream& out,
}
}
string t_dart_generator::render_const_value(ofstream& out,
string t_dart_generator::render_const_value(ostream& out,
string name,
t_type* type,
t_const_value* value) {
@ -740,7 +740,7 @@ void t_dart_generator::generate_xception(t_struct* txception) {
void t_dart_generator::generate_dart_struct(t_struct* tstruct, bool is_exception) {
string file_name = get_file_name(tstruct->get_name());
string f_struct_name = src_dir_ + "/" + file_name + ".dart";
ofstream f_struct;
ofstream_with_content_based_conditional_update f_struct;
f_struct.open(f_struct_name.c_str());
f_struct << autogen_comment() << dart_library(file_name) << endl;
@ -764,7 +764,7 @@ void t_dart_generator::generate_dart_struct(t_struct* tstruct, bool is_exception
* @param in_class If inside a class, needs to be static class
* @param is_result If this is a result it needs a different writer
*/
void t_dart_generator::generate_dart_struct_definition(ofstream& out,
void t_dart_generator::generate_dart_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception,
bool is_result,
@ -777,10 +777,10 @@ void t_dart_generator::generate_dart_struct_definition(ofstream& out,
}
indent(out) << "class " << class_name << " ";
if (is_exception) {
out << "extends Error ";
}
out << "implements TBase";
if (is_exception) {
out << ", Exception ";
}
scope_up(out);
indent(out) << "static final TStruct _STRUCT_DESC = new TStruct(\"" << class_name
@ -861,7 +861,7 @@ void t_dart_generator::generate_dart_struct_definition(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_dart_generator::generate_dart_struct_reader(ofstream& out, t_struct* tstruct) {
void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstruct) {
indent(out) << "read(TProtocol iprot)";
scope_up(out);
@ -949,7 +949,7 @@ void t_dart_generator::generate_dart_struct_reader(ofstream& out, t_struct* tstr
// generates dart method to perform various checks
// (e.g. check that all required fields are set)
void t_dart_generator::generate_dart_validator(ofstream& out, t_struct* tstruct) {
void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) {
indent(out) << "validate()";
scope_up(out);
@ -1000,7 +1000,7 @@ void t_dart_generator::generate_dart_validator(ofstream& out, t_struct* tstruct)
*
* @param tstruct The struct definition
*/
void t_dart_generator::generate_dart_struct_writer(ofstream& out, t_struct* tstruct) {
void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstruct) {
out << indent() << "write(TProtocol oprot)";
scope_up(out);
@ -1056,7 +1056,7 @@ void t_dart_generator::generate_dart_struct_writer(ofstream& out, t_struct* tstr
*
* @param tstruct The struct definition
*/
void t_dart_generator::generate_dart_struct_result_writer(ofstream& out, t_struct* tstruct) {
void t_dart_generator::generate_dart_struct_result_writer(ostream& out, t_struct* tstruct) {
indent(out) << "write(TProtocol oprot)";
scope_up(out);
@ -1097,7 +1097,7 @@ void t_dart_generator::generate_dart_struct_result_writer(ofstream& out, t_struc
scope_down(out, endl2);
}
void t_dart_generator::generate_generic_field_getters(std::ofstream& out,
void t_dart_generator::generate_generic_field_getters(std::ostream& out,
t_struct* tstruct) {
// create the getter
indent(out) << "getFieldValue(int fieldID)";
@ -1127,7 +1127,7 @@ void t_dart_generator::generate_generic_field_getters(std::ofstream& out,
scope_down(out, endl2); // method
}
void t_dart_generator::generate_generic_field_setters(std::ofstream& out,
void t_dart_generator::generate_generic_field_setters(std::ostream& out,
t_struct* tstruct) {
// create the setter
@ -1172,7 +1172,7 @@ void t_dart_generator::generate_generic_field_setters(std::ofstream& out,
}
// Creates a generic isSet method that takes the field number as argument
void t_dart_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
void t_dart_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -1208,7 +1208,7 @@ void t_dart_generator::generate_generic_isset_method(std::ofstream& out, t_struc
*
* @param tstruct The struct definition
*/
void t_dart_generator::generate_dart_bean_boilerplate(ofstream& out,
void t_dart_generator::generate_dart_bean_boilerplate(ostream& out,
t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -1257,7 +1257,7 @@ void t_dart_generator::generate_dart_bean_boilerplate(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_dart_generator::generate_dart_struct_tostring(ofstream& out,
void t_dart_generator::generate_dart_struct_tostring(ostream& out,
t_struct* tstruct) {
indent(out) << "String toString()";
scope_up(out);
@ -1292,7 +1292,7 @@ void t_dart_generator::generate_dart_struct_tostring(ofstream& out,
scope_up(out);
}
if (field->get_type()->is_base_type() && ((t_base_type*)(field->get_type()))->is_binary()) {
if (field->get_type()->is_binary()) {
indent(out) << "ret.write(\"BINARY\");" << endl;
} else if (field->get_type()->is_enum()) {
indent(out) << "String " << field_name << "_name = "
@ -1784,7 +1784,7 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function
* @param tfield The field
* @param prefix The variable name or container for this field
*/
void t_dart_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_dart_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
string field_name = get_member_name(tfield->get_name());
@ -1809,7 +1809,7 @@ void t_dart_generator::generate_deserialize_field(ofstream& out, t_field* tfield
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "readBinary();";
} else {
out << "readString();";
@ -1850,7 +1850,7 @@ void t_dart_generator::generate_deserialize_field(ofstream& out, t_field* tfield
/**
* Generates an unserializer for a struct, invokes read()
*/
void t_dart_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_dart_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
indent(out) << prefix << " = new " << type_name(tstruct) << "();" << endl;
indent(out) << prefix << ".read(iprot);" << endl;
}
@ -1858,7 +1858,7 @@ void t_dart_generator::generate_deserialize_struct(ofstream& out, t_struct* tstr
/**
* Deserializes a container by reading its size and then iterating
*/
void t_dart_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_dart_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
indent(out);
scope_up(out, "");
@ -1915,7 +1915,7 @@ void t_dart_generator::generate_deserialize_container(ofstream& out, t_type* tty
/**
* Generates code to deserialize a map
*/
void t_dart_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
void t_dart_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
string key = tmp("_key");
string val = tmp("_val");
t_field fkey(tmap->get_key_type(), key);
@ -1933,7 +1933,7 @@ void t_dart_generator::generate_deserialize_map_element(ofstream& out, t_map* tm
/**
* Deserializes a set element
*/
void t_dart_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
void t_dart_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
string elem = tmp("_elem");
t_field felem(tset->get_elem_type(), elem);
@ -1947,7 +1947,7 @@ void t_dart_generator::generate_deserialize_set_element(ofstream& out, t_set* ts
/**
* Deserializes a list element
*/
void t_dart_generator::generate_deserialize_list_element(ofstream& out,
void t_dart_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix) {
string elem = tmp("_elem");
@ -1966,7 +1966,7 @@ void t_dart_generator::generate_deserialize_list_element(ofstream& out,
* @param tfield The field to serialize
* @param prefix Name to prepend to field name
*/
void t_dart_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
string field_name = get_member_name(tfield->get_name());
@ -1991,7 +1991,7 @@ void t_dart_generator::generate_serialize_field(ofstream& out, t_field* tfield,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "writeBinary(" << name << ");";
} else {
out << "writeString(" << name << ");";
@ -2036,7 +2036,7 @@ void t_dart_generator::generate_serialize_field(ofstream& out, t_field* tfield,
* @param tstruct The struct to serialize
* @param prefix String prefix to attach to all fields
*/
void t_dart_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_dart_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
(void)tstruct;
indent(out) << prefix << ".write(oprot);" << endl;
}
@ -2047,7 +2047,7 @@ void t_dart_generator::generate_serialize_struct(ofstream& out, t_struct* tstruc
* @param ttype The type of container
* @param prefix String prefix for fields
*/
void t_dart_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_dart_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
indent(out);
scope_up(out, "");
@ -2098,7 +2098,7 @@ void t_dart_generator::generate_serialize_container(ofstream& out, t_type* ttype
/**
* Serializes the members of a map.
*/
void t_dart_generator::generate_serialize_map_element(ofstream& out,
void t_dart_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string iter,
string map) {
@ -2111,7 +2111,7 @@ void t_dart_generator::generate_serialize_map_element(ofstream& out,
/**
* Serializes the members of a set.
*/
void t_dart_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_dart_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
@ -2119,7 +2119,7 @@ void t_dart_generator::generate_serialize_set_element(ofstream& out, t_set* tset
/**
* Serializes the members of a list.
*/
void t_dart_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
void t_dart_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
t_field efield(tlist->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
@ -2194,7 +2194,7 @@ string t_dart_generator::declare_field(t_field* tfield, bool init) {
if (init) {
t_type* ttype = get_true_type(tfield->get_type());
if (ttype->is_base_type() && tfield->get_value() != NULL) {
ofstream dummy;
std:: ofstream dummy;
result += " = " + render_const_value(dummy, field_name, ttype, tfield->get_value());
} else if (ttype->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@ -2452,7 +2452,7 @@ string t_dart_generator::constant_name(string name) {
/**
* Emits a doc comment if the provided object has a doc in Thrift
*/
void t_dart_generator::generate_dart_doc(ofstream& out, t_doc* tdoc) {
void t_dart_generator::generate_dart_doc(ostream& out, t_doc* tdoc) {
if (tdoc->has_doc()) {
generate_docstring_comment(out, "", "/// ", tdoc->get_doc(), "");
}
@ -2461,7 +2461,7 @@ void t_dart_generator::generate_dart_doc(ofstream& out, t_doc* tdoc) {
/**
* Emits a doc comment if the provided function object has a doc in Thrift
*/
void t_dart_generator::generate_dart_doc(ofstream& out, t_function* tfunction) {
void t_dart_generator::generate_dart_doc(ostream& out, t_function* tfunction) {
if (tfunction->has_doc()) {
stringstream ss;
ss << tfunction->get_doc();
@ -2488,7 +2488,7 @@ std::string t_dart_generator::generate_isset_check(std::string field_name) {
return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
}
void t_dart_generator::generate_isset_set(ofstream& out, t_field* field) {
void t_dart_generator::generate_isset_set(ostream& out, t_field* field) {
if (!type_can_be_null(field->get_type())) {
string field_name = get_member_name(field->get_name());
indent(out) << "this.__isset_" << field_name << " = true;" << endl;

View file

@ -65,6 +65,7 @@ public:
constprefix_ = false;
events_ = false;
xmldoc_ = false;
async_ = false;
for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
if( iter->first.compare("ansistr_binary") == 0) {
ansistr_binary_ = true;
@ -76,6 +77,8 @@ public:
events_ = true;
} else if( iter->first.compare("xmldoc") == 0) {
xmldoc_ = true;
} else if( iter->first.compare("async") == 0) {
async_ = true;
} else {
throw "unknown option delphi:" + iter->first;
}
@ -128,7 +131,7 @@ public:
bool is_xception_class,
bool is_union,
bool is_xception_factory,
std::string xception_factroy_name);
std::string xception_factory_name);
void generate_delphi_clear_union_value(ostream& out,
std::string cls_prefix,
std::string name,
@ -138,7 +141,7 @@ public:
bool is_xception_class,
bool is_union,
bool is_xception_factory,
std::string xception_factroy_name);
std::string xception_factory_name);
void generate_delphi_isset_reader_impl(ostream& out,
std::string cls_prefix,
std::string name,
@ -236,6 +239,7 @@ public:
void generate_function_helpers(t_function* tfunction);
void generate_service_interface(t_service* tservice);
void generate_service_interface(t_service* tservice, bool for_async);
void generate_service_helpers(t_service* tservice);
void generate_service_client(t_service* tservice);
void generate_service_server(t_service* tservice);
@ -323,6 +327,7 @@ public:
std::string prefix = "",
bool is_xception_class = false);
std::string function_signature(t_function* tfunction,
bool for_async,
std::string full_cls = "",
bool is_xception = false);
std::string argument_list(t_struct* tstruct);
@ -399,6 +404,7 @@ private:
bool constprefix_;
bool events_;
bool xmldoc_;
bool async_;
void indent_up_impl() { ++indent_impl_; };
void indent_down_impl() { --indent_impl_; };
std::string indent_impl() {
@ -636,10 +642,21 @@ void t_delphi_generator::create_keywords() {
// reserved/predefined variables and types (lowercase!)
delphi_keywords["result"] = 1;
delphi_keywords["system"] = 1;
delphi_keywords["sysutils"] = 1;
delphi_keywords["thrift"] = 1;
delphi_keywords["tbytes"] = 1;
delphi_keywords["tobject"] = 1;
delphi_keywords["tclass"] = 1;
delphi_keywords["tinterfacedobject"] = 1;
delphi_keywords["ansistring"] = 1;
delphi_keywords["string"] = 1;
delphi_keywords["boolean"] = 1;
delphi_keywords["shortint"] = 1;
delphi_keywords["smallint"] = 1;
delphi_keywords["integer"] = 1;
delphi_keywords["int64"] = 1;
delphi_keywords["double"] = 1;
delphi_reserved_method["create"] = 1;
delphi_reserved_method["free"] = 1;
@ -721,15 +738,19 @@ void t_delphi_generator::init_generator() {
has_enum = false;
has_const = false;
create_keywords();
add_delphi_uses_list("Classes");
add_delphi_uses_list("SysUtils");
add_delphi_uses_list("Generics.Collections");
if(async_) {
add_delphi_uses_list("System.Threading");
}
add_delphi_uses_list("Thrift");
add_delphi_uses_list("Thrift.Utils");
add_delphi_uses_list("Thrift.Collections");
add_delphi_uses_list("Thrift.Protocol");
add_delphi_uses_list("Thrift.Transport");
if (register_types_) {
add_delphi_uses_list("Thrift.TypeRegistry");
}
@ -742,7 +763,7 @@ void t_delphi_generator::init_generator() {
unitname = includes[i]->get_name();
nsname = includes[i]->get_namespace("delphi");
if ("" != nsname) {
unitname = nsname;
unitname = normalize_name(nsname);
}
add_delphi_uses_list(unitname);
}
@ -762,8 +783,10 @@ void t_delphi_generator::close_generator() {
}
}
unitname = normalize_name(unitname);
std::string f_name = get_out_dir() + "/" + unitname + ".pas";
std::ofstream f_all;
ofstream_with_content_based_conditional_update f_all;
f_all.open(f_name.c_str());
@ -1195,8 +1218,8 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars,
if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -1215,8 +1238,8 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars,
} else if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(vars, out, name, ktype, v_iter->first);
string val = render_const_value(vars, out, name, vtype, v_iter->second);
@ -1460,8 +1483,6 @@ void t_delphi_generator::generate_delphi_struct_impl(ostream& out,
indent_up_impl();
if (is_exception && (!is_x_factory)) {
indent_impl(out) << "inherited Create('');" << endl;
indent_impl(out) << "F" << exception_factory_name << " := T" << exception_factory_name
<< "Impl.Create;" << endl;
} else {
indent_impl(out) << "inherited;" << endl;
}
@ -1507,6 +1528,19 @@ void t_delphi_generator::generate_delphi_struct_impl(ostream& out,
indent_down_impl();
indent_impl(out) << "end;" << endl << endl;
if (is_exception && (!is_x_factory)) {
indent_impl(out) << "function " << cls_prefix << cls_nm << "." << exception_factory_name
<< ": I" << exception_factory_name << ";" << endl;
indent_impl(out) << "begin" << endl;
indent_up_impl();
indent_impl(out) << "if F" << exception_factory_name << " = nil" << endl;
indent_impl(out) << "then F" << exception_factory_name << " := T" << exception_factory_name << "Impl.Create;" << endl;
indent_impl(out) << endl;
indent_impl(out) << "result := F" << exception_factory_name << ";" << endl;
indent_down_impl();
indent_impl(out) << "end;" << endl << endl;
}
if (tstruct->is_union()) {
indent_impl(out) << "procedure " << cls_prefix << cls_nm << "."
<< "ClearUnionValues;" << endl;
@ -1692,7 +1726,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out,
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if ((*m_iter)->get_req() != t_field::T_REQUIRED) {
isset_name = "__isset_" + prop_name(*m_iter, is_exception);
indent(out) << "property " << isset_name << ": Boolean read Get" << isset_name << ";"
indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << ";"
<< endl;
}
}
@ -1741,7 +1775,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out,
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if ((*m_iter)->get_req() != t_field::T_REQUIRED) {
isset_name = "F__isset_" + prop_name(*m_iter, is_exception);
indent(out) << isset_name << ": Boolean;" << endl;
indent(out) << isset_name << ": System.Boolean;" << endl;
}
}
}
@ -1764,7 +1798,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out,
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if ((*m_iter)->get_req() != t_field::T_REQUIRED) {
isset_name = "__isset_" + prop_name(*m_iter, is_exception);
indent(out) << "function Get" << isset_name << ": Boolean;" << endl;
indent(out) << "function Get" << isset_name << ": System.Boolean;" << endl;
}
}
}
@ -1790,8 +1824,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out,
if (is_exception && (!is_x_factory)) {
out << endl;
indent(out) << "// Exception Factory" << endl;
indent(out) << "property " << exception_factory_name << ": " << struct_intf_name << " read F"
<< exception_factory_name << " write F" << exception_factory_name << ";" << endl;
indent(out) << "function " << exception_factory_name << ": " << struct_intf_name << ";" << endl;
}
if ((!is_exception) || is_x_factory) {
@ -1821,7 +1854,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream& out,
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if ((*m_iter)->get_req() != t_field::T_REQUIRED) {
isset_name = "__isset_" + prop_name(*m_iter, is_exception);
indent(out) << "property " << isset_name << ": Boolean read Get" << isset_name << ";"
indent(out) << "property " << isset_name << ": System.Boolean read Get" << isset_name << ";"
<< endl;
}
}
@ -1850,19 +1883,28 @@ void t_delphi_generator::generate_service(t_service* tservice) {
}
void t_delphi_generator::generate_service_interface(t_service* tservice) {
generate_service_interface(tservice,false);
if(async_) {
generate_service_interface(tservice,true);
}
}
void t_delphi_generator::generate_service_interface(t_service* tservice, bool for_async) {
string extends = "";
string extends_iface = "";
string iface_name = for_async ? "IAsync" : "Iface";
indent_up();
generate_delphi_doc(s_service, tservice);
if (tservice->get_extends() != NULL) {
extends = type_name(tservice->get_extends(), true, true);
extends_iface = extends + ".Iface";
extends_iface = extends + "." + iface_name;
generate_delphi_doc(s_service, tservice);
indent(s_service) << "Iface = interface(" << extends_iface << ")" << endl;
indent(s_service) << iface_name << " = interface(" << extends_iface << ")" << endl;
} else {
indent(s_service) << "Iface = interface" << endl;
indent(s_service) << iface_name << " = interface" << endl;
}
indent_up();
@ -1870,7 +1912,7 @@ void t_delphi_generator::generate_service_interface(t_service* tservice) {
vector<t_function*>::iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
generate_delphi_doc(s_service, *f_iter);
indent(s_service) << function_signature(*f_iter) << endl;
indent(s_service) << function_signature(*f_iter, for_async) << endl;
}
indent_down();
indent(s_service) << "end;" << endl << endl;
@ -1896,20 +1938,15 @@ void t_delphi_generator::generate_service_helpers(t_service* tservice) {
void t_delphi_generator::generate_service_client(t_service* tservice) {
indent_up();
string extends = "";
string extends_client = "";
if (tservice->get_extends() != NULL) {
extends = type_name(tservice->get_extends());
extends_client = extends + ".Client, ";
}
string extends_client = "TInterfacedObject";
string implements = async_ ? "Iface, IAsync" : "Iface";
generate_delphi_doc(s_service, tservice);
if (tservice->get_extends() != NULL) {
extends = type_name(tservice->get_extends(), true, true);
extends_client = extends + ".TClient";
indent(s_service) << "TClient = class(" << extends_client << ", Iface)" << endl;
} else {
indent(s_service) << "TClient = class( TInterfacedObject, Iface)" << endl;
}
indent(s_service) << "TClient = class( " << extends_client << ", " << implements << ")" << endl;
indent(s_service) << "public" << endl;
indent_up();
@ -1945,7 +1982,7 @@ void t_delphi_generator::generate_service_client(t_service* tservice) {
indent_up();
indent(s_service) << "iprot_: IProtocol;" << endl;
indent(s_service) << "oprot_: IProtocol;" << endl;
indent(s_service) << "seqid_: Integer;" << endl;
indent(s_service) << "seqid_: System.Integer;" << endl;
indent_down();
indent(s_service) << "public" << endl;
@ -1960,12 +1997,24 @@ void t_delphi_generator::generate_service_client(t_service* tservice) {
indent(s_service) << "protected" << endl;
indent_up();
indent(s_service) << "// Iface" << endl;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
string funname = (*f_iter)->get_name();
generate_delphi_doc(s_service, *f_iter);
indent(s_service) << function_signature(*f_iter) << endl;
indent(s_service) << function_signature(*f_iter, false) << endl;
}
if( async_) {
indent(s_service) << endl;
indent(s_service) << "// IAsync" << endl;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
string funname = (*f_iter)->get_name();
generate_delphi_doc(s_service, *f_iter);
indent(s_service) << function_signature(*f_iter, true) << endl;
}
}
indent_down();
indent(s_service) << "public" << endl;
@ -1976,36 +2025,65 @@ void t_delphi_generator::generate_service_client(t_service* tservice) {
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
string funname = (*f_iter)->get_name();
indent_impl(s_service_impl) << function_signature(*f_iter, full_cls) << endl;
indent_impl(s_service_impl) << "begin" << endl;
indent_up_impl();
indent_impl(s_service_impl) << "send_" << funname << "(";
t_struct* arg_struct = (*f_iter)->get_arglist();
const vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator fld_iter;
bool first = true;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
if (first) {
first = false;
} else {
s_service_impl << ", ";
}
s_service_impl << normalize_name((*fld_iter)->get_name());
}
s_service_impl << ");" << endl;
t_struct* arg_struct = (*f_iter)->get_arglist();
const vector<t_field*>& fields = arg_struct->get_members();
if (!(*f_iter)->is_oneway()) {
s_service_impl << indent_impl();
if (!(*f_iter)->get_returntype()->is_void()) {
s_service_impl << "Result := ";
}
s_service_impl << "recv_" << funname << "();" << endl;
}
// one for sync only, two for async+sync
int mode = async_ ? 1 : 0;
while( mode >= 0) {
bool for_async = (mode != 0);
mode--;
indent_down_impl();
indent_impl(s_service_impl) << "end;" << endl << endl;
indent_impl(s_service_impl) << function_signature(*f_iter, for_async, full_cls) << endl;
indent_impl(s_service_impl) << "begin" << endl;
indent_up_impl();
t_type* ttype = (*f_iter)->get_returntype();
if( for_async) {
if (is_void(ttype)) {
// Delphi forces us to specify a type with IFuture<T>, so we use Integer=0 for void methods
indent_impl(s_service_impl) << "result := TTask.Future<System.Integer>(function: System.Integer" << endl;
} else {
string rettype = type_name(ttype, false, true, false, true);
indent_impl(s_service_impl) << "result := TTask.Future<" << rettype << ">(function: " << rettype << endl;
}
indent_impl(s_service_impl) << "begin" << endl;
indent_up_impl();
}
indent_impl(s_service_impl) << "send_" << funname << "(";
bool first = true;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
if (first) {
first = false;
} else {
s_service_impl << ", ";
}
s_service_impl << normalize_name((*fld_iter)->get_name());
}
s_service_impl << ");" << endl;
if (!(*f_iter)->is_oneway()) {
s_service_impl << indent_impl();
if (!(*f_iter)->get_returntype()->is_void()) {
s_service_impl << "Result := ";
}
s_service_impl << "recv_" << funname << "();" << endl;
}
if( for_async) {
if (is_void(ttype)) {
indent_impl(s_service_impl) << "Result := 0;" << endl; // no IFuture<void> in Delphi
}
indent_down_impl();
indent_impl(s_service_impl) << "end);" << endl;
}
indent_down_impl();
indent_impl(s_service_impl) << "end;" << endl << endl;
}
t_function send_function(g_type_void,
string("send_") + (*f_iter)->get_name(),
@ -2018,18 +2096,18 @@ void t_delphi_generator::generate_service_client(t_service* tservice) {
string argsvar = tmp("_args");
string msgvar = tmp("_msg");
indent(s_service) << function_signature(&send_function) << endl;
indent_impl(s_service_impl) << function_signature(&send_function, full_cls) << endl;
indent(s_service) << function_signature(&send_function, false) << endl;
indent_impl(s_service_impl) << function_signature(&send_function, false, full_cls) << endl;
indent_impl(s_service_impl) << "var" << endl;
indent_up_impl();
indent_impl(s_service_impl) << argsvar << " : " << args_intfnm << ";" << endl;
indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.IMessage;" << endl;
indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << endl;
indent_down_impl();
indent_impl(s_service_impl) << "begin" << endl;
indent_up_impl();
indent_impl(s_service_impl) << "seqid_ := seqid_ + 1;" << endl;
indent_impl(s_service_impl) << msgvar << " := Thrift.Protocol.TMessageImpl.Create('" << funname
indent_impl(s_service_impl) << "Thrift.Protocol.Init( " << msgvar << ", '" << funname
<< "', " << ((*f_iter)->is_oneway() ? "TMessageType.Oneway"
: "TMessageType.Call")
<< ", seqid_);" << endl;
@ -2072,11 +2150,11 @@ void t_delphi_generator::generate_service_client(t_service* tservice) {
string appexvar = tmp("_ax");
string retvar = tmp("_ret");
indent(s_service) << function_signature(&recv_function) << endl;
indent_impl(s_service_impl) << function_signature(&recv_function, full_cls) << endl;
indent(s_service) << function_signature(&recv_function, false) << endl;
indent_impl(s_service_impl) << function_signature(&recv_function, false, full_cls) << endl;
indent_impl(s_service_impl) << "var" << endl;
indent_up_impl();
indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.IMessage;" << endl;
indent_impl(s_service_impl) << msgvar << " : Thrift.Protocol.TThriftMessage;" << endl;
if (xceptions.size() > 0) {
indent_impl(s_service_impl) << exceptvar << " : Exception;" << endl;
}
@ -2131,7 +2209,7 @@ void t_delphi_generator::generate_service_client(t_service* tservice) {
if (!(*f_iter)->get_returntype()->is_void()) {
indent_impl(s_service_impl)
<< "raise TApplicationExceptionMissingResult.Create('"
<< "raise TApplicationExceptionMissingResult.Create('"
<< (*f_iter)->get_name() << " failed: unknown result');" << endl;
}
@ -2207,7 +2285,7 @@ void t_delphi_generator::generate_service_server(t_service* tservice) {
indent_up();
indent(s_service) << "type" << endl;
indent_up();
indent(s_service) << "TProcessFunction = reference to procedure( seqid: Integer; const iprot: "
indent(s_service) << "TProcessFunction = reference to procedure( seqid: System.Integer; const iprot: "
"IProtocol; const oprot: IProtocol"
<< (events_ ? "; const events : IRequestEvents" : "") << ");" << endl;
indent_down();
@ -2222,19 +2300,19 @@ void t_delphi_generator::generate_service_server(t_service* tservice) {
indent_up();
if (extends.empty()) {
indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const "
"events : IProcessorEvents): Boolean;" << endl;
"events : IProcessorEvents): System.Boolean;" << endl;
} else {
indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const "
"events : IProcessorEvents): Boolean; reintroduce;" << endl;
"events : IProcessorEvents): System.Boolean; reintroduce;" << endl;
}
indent_impl(s_service_impl) << "function " << full_cls << ".Process( const iprot: IProtocol; "
"const oprot: IProtocol; const events "
": IProcessorEvents): Boolean;" << endl;
": IProcessorEvents): System.Boolean;" << endl;
;
indent_impl(s_service_impl) << "var" << endl;
indent_up_impl();
indent_impl(s_service_impl) << "msg : Thrift.Protocol.IMessage;" << endl;
indent_impl(s_service_impl) << "msg : Thrift.Protocol.TThriftMessage;" << endl;
indent_impl(s_service_impl) << "fn : TProcessFunction;" << endl;
indent_impl(s_service_impl) << "x : TApplicationException;" << endl;
if (events_) {
@ -2254,10 +2332,10 @@ void t_delphi_generator::generate_service_server(t_service* tservice) {
indent_impl(s_service_impl) << "TProtocolUtil.Skip(iprot, TType.Struct);" << endl;
indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << endl;
indent_impl(s_service_impl) << "x := "
"TApplicationExceptionUnknownMethod.Create("
"'Invalid method name: ''' + msg.Name + '''');" << endl;
"TApplicationExceptionUnknownMethod.Create("
"'Invalid method name: ''' + msg.Name + '''');" << endl;
indent_impl(s_service_impl)
<< "msg := Thrift.Protocol.TMessageImpl.Create(msg.Name, TMessageType.Exception, msg.SeqID);"
<< "Thrift.Protocol.Init( msg, msg.Name, TMessageType.Exception, msg.SeqID);"
<< endl;
indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << endl;
indent_impl(s_service_impl) << "x.Write(oprot);" << endl;
@ -2356,7 +2434,7 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi
string result_intfnm = normalize_clsnm(org_resultname, "I");
indent(s_service) << "procedure " << funcname
<< "_Process( seqid: Integer; const iprot: IProtocol; const oprot: IProtocol"
<< "_Process( seqid: System.Integer; const iprot: IProtocol; const oprot: IProtocol"
<< (events_ ? "; const events : IRequestEvents" : "") << ");" << endl;
if (tfunction->is_oneway()) {
@ -2367,13 +2445,13 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi
indent_impl(s_service_impl)
<< "procedure " << full_cls << "." << funcname
<< "_Process( seqid: Integer; const iprot: IProtocol; const oprot: IProtocol"
<< "_Process( seqid: System.Integer; const iprot: IProtocol; const oprot: IProtocol"
<< (events_ ? "; const events : IRequestEvents" : "") << ");" << endl;
indent_impl(s_service_impl) << "var" << endl;
indent_up_impl();
indent_impl(s_service_impl) << "args: " << args_intfnm << ";" << endl;
if (!tfunction->is_oneway()) {
indent_impl(s_service_impl) << "msg: Thrift.Protocol.IMessage;" << endl;
indent_impl(s_service_impl) << "msg: Thrift.Protocol.TThriftMessage;" << endl;
indent_impl(s_service_impl) << "ret: " << result_intfnm << ";" << endl;
indent_impl(s_service_impl) << "appx : TApplicationException;" << endl;
}
@ -2452,14 +2530,14 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi
indent_impl(s_service_impl) << "if events <> nil then events.UnhandledError(E);" << endl;
}
if (!tfunction->is_oneway()) {
indent_impl(s_service_impl) << "appx := TApplicationExceptionInternalError.Create(E.Message);"
indent_impl(s_service_impl) << "appx := TApplicationExceptionInternalError.Create(E.Message);"
<< endl;
indent_impl(s_service_impl) << "try" << endl;
indent_up_impl();
if(events_) {
indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << endl;
}
indent_impl(s_service_impl) << "msg := Thrift.Protocol.TMessageImpl.Create('"
indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, '"
<< tfunction->get_name() << "', TMessageType.Exception, seqid);"
<< endl;
indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << endl;
@ -2487,7 +2565,7 @@ void t_delphi_generator::generate_process_function(t_service* tservice, t_functi
if (events_) {
indent_impl(s_service_impl) << "if events <> nil then events.PreWrite;" << endl;
}
indent_impl(s_service_impl) << "msg := Thrift.Protocol.TMessageImpl.Create('"
indent_impl(s_service_impl) << "Thrift.Protocol.Init( msg, '"
<< tfunction->get_name() << "', TMessageType.Reply, seqid); "
<< endl;
indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg); " << endl;
@ -2541,7 +2619,7 @@ void t_delphi_generator::generate_deserialize_field(ostream& out,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
if (ansistr_binary_) {
out << "ReadAnsiString();";
} else {
@ -2619,15 +2697,15 @@ void t_delphi_generator::generate_deserialize_container(ostream& out,
}
if (ttype->is_map()) {
local_var = obj + ": IMap;";
local_var = obj + ": TThriftMap;";
} else if (ttype->is_set()) {
local_var = obj + ": ISet;";
local_var = obj + ": TThriftSet;";
} else if (ttype->is_list()) {
local_var = obj + ": IList;";
local_var = obj + ": TThriftList;";
}
local_vars << " " << local_var << endl;
counter = tmp("_i");
local_var = counter + ": Integer;";
local_var = counter + ": System.Integer;";
local_vars << " " << local_var << endl;
indent_impl(out) << name << " := " << type_name(ttype, true) << ".Create;" << endl;
@ -2742,7 +2820,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
if (ansistr_binary_) {
out << "WriteAnsiString(";
} else {
@ -2775,7 +2853,7 @@ void t_delphi_generator::generate_serialize_field(ostream& out,
throw "compiler error: no Delphi name for base type " + t_base_type::t_base_name(tbase);
}
} else if (type->is_enum()) {
out << "WriteI32(Integer(" << name << "));";
out << "WriteI32(System.Integer(" << name << "));";
}
out << endl;
} else {
@ -2803,23 +2881,23 @@ void t_delphi_generator::generate_serialize_container(ostream& out,
string obj;
if (ttype->is_map()) {
obj = tmp("map");
local_vars << " " << obj << " : IMap;" << endl;
indent_impl(out) << obj << " := TMapImpl.Create( "
local_vars << " " << obj << " : TThriftMap;" << endl;
indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", "
<< type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
<< type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << prefix
<< ".Count);" << endl;
indent_impl(out) << "oprot.WriteMapBegin( " << obj << ");" << endl;
} else if (ttype->is_set()) {
obj = tmp("set_");
local_vars << " " << obj << " : ISet;" << endl;
indent_impl(out) << obj << " := TSetImpl.Create("
local_vars << " " << obj << " : TThriftSet;" << endl;
indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", "
<< type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << prefix
<< ".Count);" << endl;
indent_impl(out) << "oprot.WriteSetBegin( " << obj << ");" << endl;
} else if (ttype->is_list()) {
obj = tmp("list_");
local_vars << " " << obj << " : IList;" << endl;
indent_impl(out) << obj << " := TListImpl.Create("
local_vars << " " << obj << " : TThriftList;" << endl;
indent_impl(out) << "Thrift.Protocol.Init( " << obj << ", "
<< type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix
<< ".Count);" << endl;
indent_impl(out) << "oprot.WriteListBegin( " << obj << ");" << endl;
@ -3086,25 +3164,25 @@ string t_delphi_generator::base_type_name(t_base_type* tbase) {
case t_base_type::TYPE_STRING:
if (tbase->is_binary()) {
if (ansistr_binary_) {
return "AnsiString";
return "System.AnsiString";
} else {
return "TBytes";
return "SysUtils.TBytes";
}
} else {
return "string";
return "System.string";
}
case t_base_type::TYPE_BOOL:
return "Boolean";
return "System.Boolean";
case t_base_type::TYPE_I8:
return "ShortInt";
return "System.ShortInt";
case t_base_type::TYPE_I16:
return "SmallInt";
return "System.SmallInt";
case t_base_type::TYPE_I32:
return "Integer";
return "System.Integer";
case t_base_type::TYPE_I64:
return "Int64";
return "System.Int64";
case t_base_type::TYPE_DOUBLE:
return "Double";
return "System.Double";
default:
throw "compiler error: no Delphi name for base type "
+ t_base_type::t_base_name(tbase->get_base());
@ -3126,6 +3204,7 @@ string t_delphi_generator::declare_field(t_field* tfield,
}
string t_delphi_generator::function_signature(t_function* tfunction,
bool for_async,
std::string full_cls,
bool is_xception) {
t_type* ttype = tfunction->get_returntype();
@ -3135,13 +3214,25 @@ string t_delphi_generator::function_signature(t_function* tfunction,
} else {
prefix = full_cls + ".";
}
if (is_void(ttype)) {
return "procedure " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
+ argument_list(tfunction->get_arglist()) + ");";
if( for_async) {
if (is_void(ttype)) {
return "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async("
+ argument_list(tfunction->get_arglist()) + "): IFuture<Integer>;"; // no IFuture<void> in Delphi
} else {
return "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async("
+ argument_list(tfunction->get_arglist()) + "): IFuture<"
+ type_name(ttype, false, true, is_xception, true) + ">;";
}
} else {
return "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
+ argument_list(tfunction->get_arglist()) + "): "
+ type_name(ttype, false, true, is_xception, true) + ";";
if (is_void(ttype)) {
return "procedure " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
+ argument_list(tfunction->get_arglist()) + ");";
} else {
return "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
+ argument_list(tfunction->get_arglist()) + "): "
+ type_name(ttype, false, true, is_xception, true) + ";";
}
}
}
@ -3268,7 +3359,7 @@ string t_delphi_generator::empty_value(t_type* type) {
case t_base_type::TYPE_VOID:
return "0";
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
if (ansistr_binary_) {
return "''";
} else {
@ -3326,7 +3417,7 @@ void t_delphi_generator::generate_delphi_property_reader_definition(ostream& out
void t_delphi_generator::generate_delphi_isset_reader_definition(ostream& out,
t_field* tfield,
bool is_xception) {
indent(out) << "function Get__isset_" << prop_name(tfield, is_xception) << ": Boolean;" << endl;
indent(out) << "function Get__isset_" << prop_name(tfield, is_xception) << ": System.Boolean;" << endl;
}
void t_delphi_generator::generate_delphi_clear_union_value(ostream& out,
@ -3369,7 +3460,7 @@ void t_delphi_generator::generate_delphi_property_writer_impl(ostream& out,
bool is_xception_class,
bool is_union,
bool is_xception_factory,
std::string xception_factroy_name) {
std::string xception_factory_name) {
(void)type;
t_type* ftype = tfield->get_type();
@ -3390,7 +3481,7 @@ void t_delphi_generator::generate_delphi_property_writer_impl(ostream& out,
indent_impl(out) << fieldPrefix << prop_name(tfield, is_xception_class) << " := Value;" << endl;
if (is_xception_class && (!is_xception_factory)) {
indent_impl(out) << "F" << xception_factroy_name << "." << prop_name(tfield, is_xception_class)
indent_impl(out) << xception_factory_name << "." << prop_name(tfield, is_xception_class)
<< " := Value;" << endl;
}
@ -3432,7 +3523,7 @@ void t_delphi_generator::generate_delphi_isset_reader_impl(ostream& out,
string isset_name = "__isset_" + prop_name(tfield, is_xception);
indent_impl(out) << "function " << cls_prefix << name << "."
<< "Get" << isset_name << ": Boolean;" << endl;
<< "Get" << isset_name << ": System.Boolean;" << endl;
indent_impl(out) << "begin" << endl;
indent_up_impl();
indent_impl(out) << "Result := " << fieldPrefix << isset_name << ";" << endl;
@ -3457,7 +3548,7 @@ void t_delphi_generator::generate_delphi_create_exception_impl(ostream& out,
indent_impl(out) << "Result := " << exception_cls_nm << ".Create;" << endl;
string factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory";
indent_impl(out) << "Result." << factory_name << " := Self;" << endl;
indent_impl(out) << "Result.F" << factory_name << " := Self;" << endl;
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -3467,8 +3558,7 @@ void t_delphi_generator::generate_delphi_create_exception_impl(ostream& out,
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
propname = prop_name(*f_iter, is_exception);
if ((*f_iter)->get_req() != t_field::T_REQUIRED) {
indent_impl(out) << "if __isset_" << propname << " then" << endl;
indent_impl(out) << "begin" << endl;
indent_impl(out) << "if __isset_" << propname << " then begin" << endl;
indent_up_impl();
}
indent_impl(out) << "Result." << propname << " := " << propname << ";" << endl;
@ -3504,7 +3594,7 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out,
// local bools for required fields
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
indent_impl(local_vars) << "_req_isset_" << prop_name(*f_iter, is_exception) << " : Boolean;"
indent_impl(local_vars) << "_req_isset_" << prop_name(*f_iter, is_exception) << " : System.Boolean;"
<< endl;
indent_impl(code_block) << "_req_isset_" << prop_name(*f_iter, is_exception) << " := FALSE;"
<< endl;
@ -3548,7 +3638,7 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out,
<< ") then begin" << endl;
indent_up_impl();
generate_deserialize_field(code_block, is_exception, *f_iter, "", local_vars);
generate_deserialize_field(code_block, is_exception, *f_iter, "Self.", local_vars);
// required field?
if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
@ -3617,8 +3707,8 @@ void t_delphi_generator::generate_delphi_struct_reader_impl(ostream& out,
<< endl;
indent_impl(out) << "var" << endl;
indent_up_impl();
indent_impl(out) << "field_ : IField;" << endl;
indent_impl(out) << "struc : IStruct;" << endl;
indent_impl(out) << "field_ : TThriftField;" << endl;
indent_impl(out) << "struc : TThriftStruct;" << endl;
indent_down_impl();
out << local_vars.str() << endl;
out << code_block.str();
@ -3642,11 +3732,11 @@ void t_delphi_generator::generate_delphi_struct_result_writer_impl(ostream& out,
indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl;
indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << endl;
indent_impl(code_block) << "struc := TStructImpl.Create('" << name << "');" << endl;
indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << endl;
indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << endl;
if (fields.size() > 0) {
indent_impl(code_block) << "field_ := TFieldImpl.Create;" << endl;
indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << endl;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
indent_impl(code_block) << "if (__isset_" << prop_name(*f_iter, is_exception) << ") then"
<< endl;
@ -3657,7 +3747,7 @@ void t_delphi_generator::generate_delphi_struct_result_writer_impl(ostream& out,
<< endl;
indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << endl;
indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << endl;
generate_serialize_field(code_block, is_exception, *f_iter, "", local_vars);
generate_serialize_field(code_block, is_exception, *f_iter, "Self.", local_vars);
indent_impl(code_block) << "oprot.WriteFieldEnd();" << endl;
indent_down_impl();
}
@ -3677,10 +3767,10 @@ void t_delphi_generator::generate_delphi_struct_result_writer_impl(ostream& out,
<< endl;
indent_impl(out) << "var" << endl;
indent_up_impl();
indent_impl(out) << "struc : IStruct;" << endl;
indent_impl(out) << "struc : TThriftStruct;" << endl;
if (fields.size() > 0) {
indent_impl(out) << "field_ : IField;" << endl;
indent_impl(out) << "field_ : TThriftField;" << endl;
}
out << local_vars.str();
@ -3706,11 +3796,11 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out,
indent_impl(local_vars) << "tracker : IProtocolRecursionTracker;" << endl;
indent_impl(code_block) << "tracker := oprot.NextRecursionLevel;" << endl;
indent_impl(code_block) << "struc := TStructImpl.Create('" << name << "');" << endl;
indent_impl(code_block) << "Thrift.Protocol.Init( struc, '" << name << "');" << endl;
indent_impl(code_block) << "oprot.WriteStructBegin(struc);" << endl;
if (fields.size() > 0) {
indent_impl(code_block) << "field_ := TFieldImpl.Create;" << endl;
indent_impl(code_block) << "Thrift.Protocol.Init( field_);" << endl;
}
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -3720,13 +3810,13 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out,
bool has_isset = (!is_required);
if (is_required && null_allowed) {
null_allowed = false;
indent_impl(code_block) << "if (" << fieldname << " = nil)" << endl;
indent_impl(code_block) << "then raise TProtocolExceptionInvalidData.Create("
indent_impl(code_block) << "if (Self." << fieldname << " = nil)" << endl;
indent_impl(code_block) << "then raise TProtocolExceptionInvalidData.Create("
<< "'required field " << fieldname << " not set');"
<< endl;
}
if (null_allowed) {
indent_impl(code_block) << "if (" << fieldname << " <> nil)";
indent_impl(code_block) << "if (Self." << fieldname << " <> nil)";
if (has_isset) {
code_block << " and __isset_" << fieldname;
}
@ -3743,7 +3833,7 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out,
<< endl;
indent_impl(code_block) << "field_.ID := " << (*f_iter)->get_key() << ";" << endl;
indent_impl(code_block) << "oprot.WriteFieldBegin(field_);" << endl;
generate_serialize_field(code_block, is_exception, *f_iter, "", local_vars);
generate_serialize_field(code_block, is_exception, *f_iter, "Self.", local_vars);
indent_impl(code_block) << "oprot.WriteFieldEnd();" << endl;
if (null_allowed || has_isset) {
indent_down_impl();
@ -3765,9 +3855,9 @@ void t_delphi_generator::generate_delphi_struct_writer_impl(ostream& out,
<< endl;
indent_impl(out) << "var" << endl;
indent_up_impl();
indent_impl(out) << "struc : IStruct;" << endl;
indent_impl(out) << "struc : TThriftStruct;" << endl;
if (fields.size() > 0) {
indent_impl(out) << "field_ : IField;" << endl;
indent_impl(out) << "field_ : TThriftField;" << endl;
}
out << local_vars.str();
indent_down_impl();
@ -3802,7 +3892,7 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out,
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
bool is_optional = ((*f_iter)->get_req() != t_field::T_REQUIRED);
if (is_optional) {
indent_impl(out) << tmp_first << " : Boolean;" << endl;
indent_impl(out) << tmp_first << " : System.Boolean;" << endl;
useFirstFlag = true;
}
break;
@ -3825,7 +3915,7 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out,
bool null_allowed = type_can_be_null((*f_iter)->get_type());
bool is_optional = ((*f_iter)->get_req() != t_field::T_REQUIRED);
if (null_allowed) {
indent_impl(out) << "if (" << prop_name((*f_iter), is_exception) << " <> nil)";
indent_impl(out) << "if (Self." << prop_name((*f_iter), is_exception) << " <> nil)";
if (is_optional) {
out << " and __isset_" << prop_name(*f_iter, is_exception);
}
@ -3857,14 +3947,14 @@ void t_delphi_generator::generate_delphi_struct_tostring_impl(ostream& out,
}
if (ttype->is_xception() || ttype->is_struct()) {
indent_impl(out) << "if (" << prop_name((*f_iter), is_exception) << " = nil) then " << tmp_sb
<< ".Append('<null>') else " << tmp_sb << ".Append("
indent_impl(out) << "if (Self." << prop_name((*f_iter), is_exception) << " = nil) then " << tmp_sb
<< ".Append('<null>') else " << tmp_sb << ".Append( Self."
<< prop_name((*f_iter), is_exception) << ".ToString());" << endl;
} else if (ttype->is_enum()) {
indent_impl(out) << tmp_sb << ".Append(Integer(" << prop_name((*f_iter), is_exception)
indent_impl(out) << tmp_sb << ".Append(System.Integer( Self." << prop_name((*f_iter), is_exception)
<< "));" << endl;
} else {
indent_impl(out) << tmp_sb << ".Append(" << prop_name((*f_iter), is_exception) << ");"
indent_impl(out) << tmp_sb << ".Append( Self." << prop_name((*f_iter), is_exception) << ");"
<< endl;
}
@ -3917,4 +4007,5 @@ THRIFT_REGISTER_GENERATOR(
" and container instances by interface or TypeInfo()\n"
" constprefix: Name TConstants classes after IDL to reduce ambiguities\n"
" events: Enable and use processing events in the generated code.\n"
" xmldoc: Enable XMLDoc comments for Help Insight etc.\n")
" xmldoc: Enable XMLDoc comments for Help Insight etc.\n"
" async: Generate IAsync interface to use Parallel Programming Library (XE7+ only).\n")

View file

@ -20,6 +20,7 @@
#include <string>
#include <fstream>
#include <iostream>
#include <limits>
#include <vector>
#include <stdlib.h>
@ -56,6 +57,9 @@ public:
legacy_names_ = false;
maps_ = false;
otp16_ = false;
export_lines_first_ = true;
export_types_lines_first_ = true;
for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
if( iter->first.compare("legacynames") == 0) {
legacy_names_ = true;
@ -117,6 +121,8 @@ public:
void generate_type_metadata(std::string function_name, vector<string> names);
void generate_enum_info(t_enum* tenum);
void generate_enum_metadata();
void generate_const_function(t_const* tconst, ostringstream& exports, ostringstream& functions);
void generate_const_functions();
/**
* Service-level generation functions
@ -135,6 +141,7 @@ public:
std::string erl_imports();
std::string render_includes();
std::string type_name(t_type* ttype);
std::string render_const_list_values(t_type* type, t_const_value* value);
std::string function_signature(t_function* tfunction, std::string prefix = "");
@ -187,7 +194,6 @@ private:
void export_function(t_function* tfunction, std::string prefix = "");
void export_string(std::string name, int num);
void export_types_function(t_function* tfunction, std::string prefix = "");
void export_types_string(std::string name, int num);
/**
@ -214,13 +220,15 @@ private:
std::ostringstream f_info_;
std::ostringstream f_info_ext_;
std::ofstream f_types_file_;
std::ofstream f_types_hrl_file_;
ofstream_with_content_based_conditional_update f_types_file_;
ofstream_with_content_based_conditional_update f_types_hrl_file_;
ofstream_with_content_based_conditional_update f_consts_file_;
ofstream_with_content_based_conditional_update f_consts_hrl_file_;
std::ofstream f_consts_;
std::ostringstream f_service_;
std::ofstream f_service_file_;
std::ofstream f_service_hrl_;
ofstream_with_content_based_conditional_update f_service_file_;
ofstream_with_content_based_conditional_update f_service_hrl_;
/**
* Metadata containers
@ -229,6 +237,7 @@ private:
std::vector<std::string> v_enum_names_;
std::vector<std::string> v_exception_names_;
std::vector<t_enum*> v_enums_;
std::vector<t_const*> v_consts_;
};
/**
@ -245,31 +254,41 @@ void t_erl_generator::init_generator() {
export_lines_first_ = true;
export_types_lines_first_ = true;
string program_module_name = make_safe_for_module_name(program_name_);
// types files
string f_types_name = get_out_dir() + make_safe_for_module_name(program_name_) + "_types.erl";
string f_types_hrl_name = get_out_dir() + make_safe_for_module_name(program_name_) + "_types.hrl";
string f_types_name = get_out_dir() + program_module_name + "_types.erl";
string f_types_hrl_name = get_out_dir() + program_module_name + "_types.hrl";
f_types_file_.open(f_types_name.c_str());
f_types_hrl_file_.open(f_types_hrl_name.c_str());
hrl_header(f_types_hrl_file_, make_safe_for_module_name(program_name_) + "_types");
hrl_header(f_types_hrl_file_, program_module_name + "_types");
f_types_file_ << erl_autogen_comment() << endl << "-module("
<< make_safe_for_module_name(program_name_) << "_types)." << endl << erl_imports()
<< endl;
f_types_file_ << erl_autogen_comment() << endl
<< "-module(" << program_module_name << "_types)." << endl
<< erl_imports() << endl;
f_types_file_ << "-include(\"" << make_safe_for_module_name(program_name_) << "_types.hrl\")."
<< endl << endl;
f_types_file_ << "-include(\"" << program_module_name << "_types.hrl\")." << endl
<< endl;
f_types_hrl_file_ << render_includes() << endl;
// consts file
string f_consts_name = get_out_dir() + make_safe_for_module_name(program_name_)
+ "_constants.hrl";
f_consts_.open(f_consts_name.c_str());
// consts files
string f_consts_name = get_out_dir() + program_module_name + "_constants.erl";
string f_consts_hrl_name = get_out_dir() + program_module_name + "_constants.hrl";
f_consts_ << erl_autogen_comment() << endl << erl_imports() << endl << "-include(\""
<< make_safe_for_module_name(program_name_) << "_types.hrl\")." << endl << endl;
f_consts_file_.open(f_consts_name.c_str());
f_consts_hrl_file_.open(f_consts_hrl_name.c_str());
f_consts_file_ << erl_autogen_comment() << endl
<< "-module(" << program_module_name << "_constants)." << endl
<< erl_imports() << endl
<< "-include(\"" << program_module_name << "_types.hrl\")." << endl
<< endl;
f_consts_hrl_file_ << erl_autogen_comment() << endl << erl_imports() << endl
<< "-include(\"" << program_module_name << "_types.hrl\")." << endl << endl;
}
/**
@ -350,6 +369,8 @@ void t_erl_generator::close_generator() {
f_types_file_ << f_info_ext_.str();
f_types_file_ << "struct_info_ext(_) -> erlang:error(function_clause)." << endl << endl;
generate_const_functions();
generate_type_metadata("struct_names", v_struct_names_);
generate_enum_metadata();
generate_type_metadata("enum_names", v_enum_names_);
@ -359,7 +380,38 @@ void t_erl_generator::close_generator() {
f_types_file_.close();
f_types_hrl_file_.close();
f_consts_.close();
f_consts_file_.close();
f_consts_hrl_file_.close();
}
const std::string emit_double_as_string(const double value) {
std::stringstream double_output_stream;
// sets the maximum precision: http://en.cppreference.com/w/cpp/io/manip/setprecision
// sets the output format to fixed: http://en.cppreference.com/w/cpp/io/manip/fixed (not in scientific notation)
double_output_stream << std::setprecision(std::numeric_limits<double>::digits10 + 1);
#ifdef _MSC_VER
// strtod is broken in MSVC compilers older than 2015, so std::fixed fails to format a double literal.
// more details: https://blogs.msdn.microsoft.com/vcblog/2014/06/18/
// c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
// and
// http://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
#if _MSC_VER >= MSC_2015_VER
double_output_stream << std::fixed;
#else
// note that if this function is called from the erlang generator and the MSVC compiler is older than 2015,
// the double literal must be output in the scientific format. There can be some cases where the
// mantissa of the output does not have fractionals, which is illegal in Erlang.
// example => 10000000000000000.0 being output as 1e+16
double_output_stream << std::scientific;
#endif
#else
double_output_stream << std::fixed;
#endif
double_output_stream << value;
return double_output_stream.str();
}
void t_erl_generator::generate_type_metadata(std::string function_name, vector<string> names) {
@ -392,6 +444,68 @@ void t_erl_generator::generate_typedef(t_typedef* ttypedef) {
(void)ttypedef;
}
void t_erl_generator::generate_const_function(t_const* tconst, ostringstream& exports, ostringstream& functions) {
t_type* type = get_true_type(tconst->get_type());
string name = tconst->get_name();
t_const_value* value = tconst->get_value();
if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
string const_fun_name = lowercase(name);
// Emit const function export.
if (exports.tellp() > 0) { exports << ", "; }
exports << const_fun_name << "/1, " << const_fun_name << "/2";
// Emit const function definition.
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator i, end = value->get_map().end();
// The one-argument form throws an error if the key does not exist in the map.
for (i = value->get_map().begin(); i != end;) {
functions << const_fun_name << "(" << render_const_value(ktype, i->first) << ") -> "
<< render_const_value(vtype, i->second);
++i;
functions << (i != end ? ";\n" : ".\n\n");
}
// The two-argument form returns a default value if the key does not exist in the map.
for (i = value->get_map().begin(); i != end; ++i) {
functions << const_fun_name << "(" << render_const_value(ktype, i->first) << ", _) -> "
<< render_const_value(vtype, i->second) << ";\n";
}
functions << const_fun_name << "(_, Default) -> Default.\n\n";
} else if (type->is_list()) {
string const_fun_name = lowercase(name);
if (exports.tellp() > 0) { exports << ", "; }
exports << const_fun_name << "/1, " << const_fun_name << "/2";
size_t list_size = value->get_list().size();
string rendered_list = render_const_list_values(type, value);
functions << const_fun_name << "(N) when N >= 1, N =< " << list_size << " ->\n"
<< indent_str() << "element(N, {" << rendered_list << "}).\n";
functions << const_fun_name << "(N, _) when N >= 1, N =< " << list_size << " ->\n"
<< indent_str() << "element(N, {" << rendered_list << "});\n"
<< const_fun_name << "(_, Default) -> Default.\n\n";
indent_down();
}
}
void t_erl_generator::generate_const_functions() {
ostringstream exports;
ostringstream functions;
vector<t_const*>::iterator c_iter;
for (c_iter = v_consts_.begin(); c_iter != v_consts_.end(); ++c_iter) {
generate_const_function(*c_iter, exports, functions);
}
if (exports.tellp() > 0) {
f_consts_file_ << "-export([" << exports.str() << "]).\n\n"
<< functions.str();
}
}
/**
* Generates code for an enumerated type. Done using a class to scope
* the values.
@ -458,8 +572,11 @@ void t_erl_generator::generate_const(t_const* tconst) {
string name = tconst->get_name();
t_const_value* value = tconst->get_value();
f_consts_ << "-define(" << constify(make_safe_for_module_name(program_name_)) << "_"
<< constify(name) << ", " << render_const_value(type, value) << ")." << endl << endl;
// Save the tconst so that function can be emitted in generate_const_functions().
v_consts_.push_back(tconst);
f_consts_hrl_file_ << "-define(" << constify(make_safe_for_module_name(program_name_)) << "_"
<< constify(name) << ", " << render_const_value(type, value) << ")." << endl << endl;
}
/**
@ -488,9 +605,9 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) {
break;
case t_base_type::TYPE_DOUBLE:
if (value->get_type() == t_const_value::CV_INTEGER) {
out << value->get_integer();
out << "float(" << value->get_integer() << ")";
} else {
out << value->get_double();
out << emit_double_as_string(value->get_double());
}
break;
default:
@ -503,8 +620,8 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) {
out << "#" << type_name(type) << "{";
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
bool first = true;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
@ -539,7 +656,7 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) {
} else {
out << "dict:from_list([";
}
map<t_const_value*, t_const_value*>::const_iterator i, end = value->get_map().end();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator i, end = value->get_map().end();
for (i = value->get_map().begin(); i != end;) {
out << "{" << render_const_value(ktype, i->first) << ","
<< render_const_value(vtype, i->second) << "}";
@ -560,28 +677,32 @@ string t_erl_generator::render_const_value(t_type* type, t_const_value* value) {
}
out << "])";
} else if (type->is_list()) {
t_type* etype;
etype = ((t_list*)type)->get_elem_type();
out << "[";
bool first = true;
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
if (first) {
first = false;
} else {
out << ",";
}
out << render_const_value(etype, *v_iter);
}
out << "]";
out << "[" << render_const_list_values(type, value) << "]";
} else {
throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
}
return out.str();
}
string t_erl_generator::render_const_list_values(t_type* type, t_const_value* value) {
std::ostringstream out;
t_type* etype = ((t_list*)type)->get_elem_type();
bool first = true;
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
if (first) {
first = false;
} else {
out << ",";
}
out << render_const_value(etype, *v_iter);
}
return out.str();
}
string t_erl_generator::render_default_value(t_field* field) {
t_type* type = field->get_type();
if (type->is_struct() || type->is_xception()) {
@ -626,7 +747,7 @@ string t_erl_generator::render_member_type(t_field* field) {
return type_name(type) + "()";
} else if (type->is_map()) {
if (maps_) {
return "#{}";
return "map()";
} else if (otp16_) {
return "dict()";
} else {
@ -719,6 +840,8 @@ void t_erl_generator::generate_erl_struct_member(ostream& out, t_field* tmember)
if (has_default_value(tmember))
out << " = " << render_member_value(tmember);
out << " :: " << render_member_type(tmember);
if (tmember->get_req() != t_field::T_REQUIRED)
out << " | 'undefined'";
}
bool t_erl_generator::has_default_value(t_field* field) {
@ -967,13 +1090,6 @@ void t_erl_generator::export_string(string name, int num) {
export_lines_ << name << "/" << num;
}
void t_erl_generator::export_types_function(t_function* tfunction, string prefix) {
export_types_string(prefix + tfunction->get_name(),
1 // This
+ ((tfunction->get_arglist())->get_members()).size());
}
void t_erl_generator::export_types_string(string name, int num) {
if (export_types_lines_first_) {
export_types_lines_first_ = false;
@ -984,10 +1100,13 @@ void t_erl_generator::export_types_string(string name, int num) {
}
void t_erl_generator::export_function(t_function* tfunction, string prefix) {
t_struct::members_type::size_type num = tfunction->get_arglist()->get_members().size();
if (num > static_cast<t_struct::members_type::size_type>(std::numeric_limits<int>().max())) {
throw "integer overflow in t_erl_generator::export_function, name " + tfunction->get_name();
}
export_string(prefix + tfunction->get_name(),
1 // This
+ ((tfunction->get_arglist())->get_members()).size());
+ static_cast<int>(num));
}
/**
@ -1012,19 +1131,14 @@ string t_erl_generator::argument_list(t_struct* tstruct) {
}
string t_erl_generator::type_name(t_type* ttype) {
string prefix = "";
string erl_namespace = ttype->get_program()->get_namespace("erl");
if (erl_namespace.length() > 0) {
prefix = erl_namespace + ".";
string prefix = ttype->get_program()->get_namespace("erl");
size_t prefix_length = prefix.length();
if (prefix_length > 0 && prefix[prefix_length - 1] != '_') {
prefix += '.';
}
string name = ttype->get_name();
if (ttype->is_struct() || ttype->is_xception() || ttype->is_service()) {
name = ttype->get_name();
}
return atomify(prefix + name);
}

View file

@ -76,6 +76,77 @@ void t_generator::generate_program() {
close_generator();
}
std::set<std::string> t_generator::lang_keywords() const {
std::string keywords[] = { "BEGIN", "END", "__CLASS__", "__DIR__", "__FILE__", "__FUNCTION__",
"__LINE__", "__METHOD__", "__NAMESPACE__", "abstract", "alias", "and", "args", "as",
"assert", "begin", "break", "case", "catch", "class", "clone", "continue", "declare",
"def", "default", "del", "delete", "do", "dynamic", "elif", "else", "elseif", "elsif",
"end", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "ensure",
"except", "exec", "finally", "float", "for", "foreach", "from", "function", "global",
"goto", "if", "implements", "import", "in", "inline", "instanceof", "interface", "is",
"lambda", "module", "native", "new", "next", "nil", "not", "or", "package", "pass",
"public", "print", "private", "protected", "raise", "redo", "rescue", "retry", "register",
"return", "self", "sizeof", "static", "super", "switch", "synchronized", "then", "this",
"throw", "transient", "try", "undef", "unless", "unsigned", "until", "use", "var",
"virtual", "volatile", "when", "while", "with", "xor", "yield" };
return std::set<std::string>(keywords, keywords + sizeof(keywords)/sizeof(keywords[0]) );
}
void t_generator::validate_input() const {
validate(program_->get_enums());
validate(program_->get_typedefs());
validate(program_->get_objects());
validate(program_->get_consts());
validate(program_->get_services());
}
template <typename T>
void t_generator::validate(const vector<T>& list) const{
typename vector<T>::const_iterator it;
for(it=list.begin(); it != list.end(); ++it) {
validate(*it);
}
}
void t_generator::validate(t_function const* f) const {
validate_id(f->get_name());
validate(f->get_arglist());
validate(f->get_xceptions());
}
void t_generator::validate(t_service const* s) const {
validate_id(s->get_name());
validate(s->get_functions());
}
void t_generator::validate(t_enum const* en) const {
validate_id(en->get_name());
validate(en->get_constants());
}
void t_generator::validate(t_struct const* s) const {
validate_id(s->get_name());
validate(s->get_members());
}
void t_generator::validate(t_enum_value const* en_val) const {
validate_id(en_val->get_name());
}
void t_generator::validate(t_typedef const* td) const {
validate_id(td->get_name());
}
void t_generator::validate(t_const const* c) const {
validate_id(c->get_name());
}
void t_generator::validate(t_field const* f) const {
validate_id(f->get_name());
}
void t_generator::validate_id(const string& id) const {
if (keywords_.find(id) != keywords_.end()) {
failure("Cannot use reserved language keyword: \"%s\"", id.c_str());
}
}
string t_generator::escape_string(const string& in) const {
string result = "";
for (string::const_iterator it = in.begin(); it < in.end(); it++) {
@ -101,21 +172,22 @@ void t_generator::generate_docstring_comment(ostream& out,
const string& line_prefix,
const string& contents,
const string& comment_end) {
if (comment_start != "")
if (!comment_start.empty())
indent(out) << comment_start;
stringstream docs(contents, ios_base::in);
while (!(docs.eof() || docs.fail())) {
char line[1024];
docs.getline(line, 1024);
// Just prnt a newline when the line & prefix are empty.
if (strlen(line) == 0 && line_prefix == "" && !docs.eof()) {
out << std::endl;
} else if (strlen(line) > 0 || !docs.eof()) { // skip the empty last line
if (strlen(line) > 0) {
indent(out) << line_prefix << line << std::endl;
} else if (line_prefix.empty()){
out << std::endl;
} else if(!docs.eof()) {
indent(out) << line_prefix << std::endl;
}
}
if (comment_end != "")
if (!comment_end.empty())
indent(out) << comment_end;
}

View file

@ -19,12 +19,17 @@
#ifndef T_GENERATOR_H
#define T_GENERATOR_H
#define MSC_2015_VER 1900
#include <cstring>
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <limits>
#include <sstream>
#include "thrift/common.h"
#include "thrift/logging.h"
#include "thrift/version.h"
#include "thrift/generate/t_generator_registry.h"
#include "thrift/parse/t_program.h"
@ -37,7 +42,8 @@
*/
class t_generator {
public:
t_generator(t_program* program) {
t_generator(t_program* program)
: keywords_(lang_keywords()){
tmp_ = 0;
indent_ = 0;
program_ = program;
@ -91,9 +97,35 @@ public:
return escape_string(constval->get_string());
}
protected:
/**
* Optional methods that may be imlemented by subclasses to take necessary
* Check if all identifiers are valid for the target language
*/
virtual void validate_input() const;
protected:
virtual std::set<std::string> lang_keywords() const;
/**
* A list of reserved words that cannot be used as identifiers.
*/
const std::set<std::string> keywords_;
virtual void validate_id(const std::string& id) const;
virtual void validate(t_enum const* en) const;
virtual void validate(t_enum_value const* en_val) const;
virtual void validate(t_typedef const* td) const;
virtual void validate(t_const const* c) const;
virtual void validate(t_service const* s) const;
virtual void validate(t_struct const* c) const;
virtual void validate(t_field const* f) const;
virtual void validate(t_function const* f) const;
template <typename T>
void validate(const std::vector<T>& list) const;
/**
* Optional methods that may be implemented by subclasses to take necessary
* steps at the beginning or end of code generation.
*/
@ -172,6 +204,17 @@ protected:
void indent_down() { --indent_; }
/**
* Indentation validation helper
*/
int indent_count() { return indent_; }
void indent_validate( int expected, const char * func_name) {
if (indent_ != expected) {
pverbose("Wrong indent count in %s: difference = %i \n", func_name, (expected - indent_));
}
}
/**
* Indentation print function
*/
@ -212,6 +255,7 @@ protected:
}
return in;
}
/**
* Transforms a camel case string to an equivalent one separated by underscores
* e.g. aMultiWord -> a_multi_word
@ -230,6 +274,7 @@ protected:
}
return in;
}
/**
* Transforms a string with words separated by underscores to a camel case equivalent
* e.g. a_multi_word -> aMultiWord
@ -256,6 +301,30 @@ protected:
return out.str();
}
const std::string emit_double_as_string(const double value) {
std::stringstream double_output_stream;
// sets the maximum precision: http://en.cppreference.com/w/cpp/io/manip/setprecision
// sets the output format to fixed: http://en.cppreference.com/w/cpp/io/manip/fixed (not in scientific notation)
double_output_stream << std::setprecision(std::numeric_limits<double>::digits10 + 1);
#ifdef _MSC_VER
// strtod is broken in MSVC compilers older than 2015, so std::fixed fails to format a double literal.
// more details: https://blogs.msdn.microsoft.com/vcblog/2014/06/18/
// c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
// and
// http://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
#if _MSC_VER >= MSC_2015_VER
double_output_stream << std::fixed;
#endif
#else
double_output_stream << std::fixed;
#endif
double_output_stream << value;
return double_output_stream.str();
}
public:
/**
* Get the true type behind a series of typedefs.
@ -307,4 +376,77 @@ private:
int tmp_;
};
template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
class template_ofstream_with_content_based_conditional_update : public std::ostringstream {
public:
template_ofstream_with_content_based_conditional_update(): contents_written(false) {}
template_ofstream_with_content_based_conditional_update(std::string const& output_file_path_)
: output_file_path(output_file_path_), contents_written(false) {}
~template_ofstream_with_content_based_conditional_update() {
if (!contents_written) {
close();
}
}
void open(std::string const& output_file_path_) {
output_file_path = output_file_path_;
clear_buf();
contents_written = false;
}
void close() {
if (contents_written || output_file_path == "")
return;
if (!is_readable(output_file_path)) {
dump();
return;
}
std::ifstream old_file;
old_file.exceptions(old_file.exceptions() | std::ifstream::badbit | std::ifstream::failbit);
old_file.open(output_file_path.c_str(), std::ios::in);
if (old_file) {
std::string const old_file_contents(static_cast<std::ostringstream const&>(std::ostringstream() << old_file.rdbuf()).str());
old_file.close();
if (old_file_contents != str()) {
dump();
}
}
}
protected:
void dump() {
std::ofstream out_file;
out_file.exceptions(out_file.exceptions() | std::ofstream::badbit | std::ofstream::failbit);
try {
out_file.open(output_file_path.c_str(), std::ios::out);
}
catch (const std::ios_base::failure& e) {
::failure("failed to write the output to the file '%s', details: '%s'", output_file_path.c_str(), e.what());
}
out_file << str();
out_file.close();
clear_buf();
contents_written = true;
}
void clear_buf() {
str(std::string());
}
static bool is_readable(std::string const& file_name) {
return static_cast<bool>(std::ifstream(file_name.c_str()));
}
private:
std::string output_file_path;
bool contents_written;
};
typedef template_ofstream_with_content_based_conditional_update<char> ofstream_with_content_based_conditional_update;
#endif

File diff suppressed because it is too large Load diff

View file

@ -87,7 +87,7 @@ protected:
void print_const_value(t_type* type, t_const_value* tvalue);
private:
std::ofstream f_out_;
ofstream_with_content_based_conditional_update f_out_;
std::list<string> edges;
bool exception_arrows;
};
@ -225,7 +225,7 @@ void t_gv_generator::print_type(t_type* ttype, string struct_field_ref) {
f_out_ << "\\>";
}
} else if (ttype->is_base_type()) {
f_out_ << (((t_base_type*)ttype)->is_binary() ? "binary" : ttype->get_name());
f_out_ << (ttype->is_binary() ? "binary" : ttype->get_name());
} else {
f_out_ << ttype->get_name();
edges.push_back(struct_field_ref + " -> " + ttype->get_name());
@ -249,8 +249,8 @@ void t_gv_generator::print_const_value(t_type* type, t_const_value* tvalue) {
break;
case t_const_value::CV_MAP: {
f_out_ << "\\{ ";
map<t_const_value*, t_const_value*> map_elems = tvalue->get_map();
map<t_const_value*, t_const_value*>::iterator map_iter;
map<t_const_value*, t_const_value*, t_const_value::value_compare> map_elems = tvalue->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::iterator map_iter;
for (map_iter = map_elems.begin(); map_iter != map_elems.end(); map_iter++) {
if (!first) {
f_out_ << ", ";

View file

@ -31,7 +31,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -89,13 +89,13 @@ public:
void generate_xception(t_struct* txception);
void generate_service(t_service* tservice);
void print_const_value(std::ofstream& out,
void print_const_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value,
bool in_static,
bool defval = false);
std::string render_const_value(ofstream& out,
std::string render_const_value(ostream& out,
std::string name,
t_type* type,
t_const_value* value);
@ -106,18 +106,18 @@ public:
void generate_haxe_struct(t_struct* tstruct, bool is_exception, bool is_result = false);
void generate_haxe_struct_definition(std::ofstream& out,
void generate_haxe_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false,
bool is_result = false);
// removed -- equality,compare_to
void generate_haxe_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_haxe_validator(std::ofstream& out, t_struct* tstruct);
void generate_haxe_struct_result_writer(std::ofstream& out, t_struct* tstruct);
void generate_haxe_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_haxe_struct_tostring(std::ofstream& out, t_struct* tstruct);
void generate_haxe_meta_data_map(std::ofstream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ofstream& out, t_type* type);
void generate_haxe_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_haxe_validator(std::ostream& out, t_struct* tstruct);
void generate_haxe_struct_result_writer(std::ostream& out, t_struct* tstruct);
void generate_haxe_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_haxe_struct_tostring(std::ostream& out, t_struct* tstruct);
void generate_haxe_meta_data_map(std::ostream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ostream& out, t_type* type);
std::string get_haxe_type_string(t_type* type);
void generate_reflection_setters(std::ostringstream& out,
t_type* type,
@ -127,15 +127,15 @@ public:
t_type* type,
std::string field_name,
std::string cap_name);
void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
void generate_property_getters_setters(std::ofstream& out, t_struct* tstruct);
void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
void generate_property_getters_setters(std::ostream& out, t_struct* tstruct);
void generate_function_helpers(t_function* tfunction);
std::string get_cap_name(std::string name);
std::string generate_isset_check(t_field* field);
std::string generate_isset_check(std::string field);
void generate_isset_set(ofstream& out, t_field* field);
void generate_isset_set(ostream& out, t_field* field);
// removed std::string isset_field_id(t_field* field);
void generate_service_interface(t_service* tservice);
@ -149,30 +149,30 @@ public:
* Serialization constructs
*/
void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string iter,
std::string map);
void generate_haxe_doc(std::ofstream& out, t_doc* tdoc);
void generate_haxe_doc(std::ofstream& out, t_function* tdoc);
void generate_haxe_doc(std::ostream& out, t_doc* tdoc);
void generate_haxe_doc(std::ostream& out, t_function* tdoc);
void generate_rtti_decoration(std::ofstream& out);
void generate_macro_decoration(std::ofstream& out);
void generate_rtti_decoration(std::ostream& out);
void generate_macro_decoration(std::ostream& out);
/**
* Helper rendering functions
@ -229,7 +229,7 @@ private:
*/
std::string package_name_;
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_service_;
std::string package_dir_;
};
@ -386,7 +386,7 @@ void t_haxe_generator::generate_typedef(t_typedef* ttypedef) {
void t_haxe_generator::generate_enum(t_enum* tenum) {
// Make output file
string f_enum_name = package_dir_ + "/" + get_cap_name(tenum->get_name()) + ".hx";
ofstream f_enum;
ofstream_with_content_based_conditional_update f_enum;
f_enum.open(f_enum_name.c_str());
// Comment and package it
@ -448,7 +448,7 @@ void t_haxe_generator::generate_consts(std::vector<t_const*> consts) {
}
string f_consts_name = package_dir_ + "/" + get_cap_name(program_name_) + "Constants.hx";
ofstream f_consts;
ofstream_with_content_based_conditional_update f_consts;
f_consts.open(f_consts_name.c_str());
// Print header
@ -475,7 +475,7 @@ void t_haxe_generator::generate_consts(std::vector<t_const*> consts) {
f_consts.close();
}
void t_haxe_generator::print_const_value(std::ofstream& out,
void t_haxe_generator::print_const_value(std::ostream& out,
string name,
t_type* type,
t_const_value* value,
@ -503,8 +503,8 @@ void t_haxe_generator::print_const_value(std::ofstream& out,
} else if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
out << name << ":" << type_name(type) << " = new " << type_name(type, false, true) << "();"
<< endl;
if (!in_static) {
@ -548,8 +548,8 @@ void t_haxe_generator::print_const_value(std::ofstream& out,
}
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(out, name, ktype, v_iter->first);
string val = render_const_value(out, name, vtype, v_iter->second);
@ -599,7 +599,7 @@ void t_haxe_generator::print_const_value(std::ofstream& out,
}
}
string t_haxe_generator::render_const_value(ofstream& out,
string t_haxe_generator::render_const_value(ostream& out,
string name,
t_type* type,
t_const_value* value) {
@ -676,7 +676,7 @@ void t_haxe_generator::generate_xception(t_struct* txception) {
void t_haxe_generator::generate_haxe_struct(t_struct* tstruct, bool is_exception, bool is_result) {
// Make output file
string f_struct_name = package_dir_ + "/" + get_cap_name(tstruct->get_name()) + ".hx";
ofstream f_struct;
ofstream_with_content_based_conditional_update f_struct;
f_struct.open(f_struct_name.c_str());
f_struct << autogen_comment() << haxe_package() << ";" << endl;
@ -703,7 +703,7 @@ void t_haxe_generator::generate_haxe_struct(t_struct* tstruct, bool is_exception
* @param in_class If inside a class, needs to be static class
* @param is_result If this is a result it needs a different writer
*/
void t_haxe_generator::generate_haxe_struct_definition(ofstream& out,
void t_haxe_generator::generate_haxe_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception,
bool is_result) {
@ -817,7 +817,7 @@ void t_haxe_generator::generate_haxe_struct_definition(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_haxe_generator::generate_haxe_struct_reader(ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_haxe_struct_reader(ostream& out, t_struct* tstruct) {
out << indent() << "public function read( iprot : TProtocol) : Void {" << endl;
indent_up();
@ -910,7 +910,7 @@ void t_haxe_generator::generate_haxe_struct_reader(ofstream& out, t_struct* tstr
// generates haxe method to perform various checks
// (e.g. check that all required fields are set)
void t_haxe_generator::generate_haxe_validator(ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) {
indent(out) << "public function validate() : Void {" << endl;
indent_up();
@ -961,7 +961,7 @@ void t_haxe_generator::generate_haxe_validator(ofstream& out, t_struct* tstruct)
*
* @param tstruct The struct definition
*/
void t_haxe_generator::generate_haxe_struct_writer(ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstruct) {
out << indent() << "public function write(oprot:TProtocol) : Void {" << endl;
indent_up();
@ -1031,7 +1031,7 @@ void t_haxe_generator::generate_haxe_struct_writer(ofstream& out, t_struct* tstr
*
* @param tstruct The struct definition
*/
void t_haxe_generator::generate_haxe_struct_result_writer(ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_haxe_struct_result_writer(ostream& out, t_struct* tstruct) {
out << indent() << "public function write(oprot:TProtocol) : Void {" << endl;
indent_up();
@ -1116,7 +1116,7 @@ void t_haxe_generator::generate_reflection_setters(ostringstream& out,
indent_down();
}
void t_haxe_generator::generate_generic_field_getters_setters(std::ofstream& out,
void t_haxe_generator::generate_generic_field_getters_setters(std::ostream& out,
t_struct* tstruct) {
std::ostringstream getter_stream;
@ -1174,7 +1174,7 @@ void t_haxe_generator::generate_generic_field_getters_setters(std::ofstream& out
}
// Creates a generic isSet method that takes the field number as argument
void t_haxe_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -1210,7 +1210,7 @@ void t_haxe_generator::generate_generic_isset_method(std::ofstream& out, t_struc
*
* @param tstruct The struct definition
*/
void t_haxe_generator::generate_property_getters_setters(ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_property_getters_setters(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -1272,7 +1272,7 @@ void t_haxe_generator::generate_property_getters_setters(ofstream& out, t_struct
*
* @param tstruct The struct definition
*/
void t_haxe_generator::generate_haxe_struct_tostring(ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tstruct) {
out << indent() << "public "
<< "function toString() : String {" << endl;
indent_up();
@ -1304,7 +1304,7 @@ void t_haxe_generator::generate_haxe_struct_tostring(ofstream& out, t_struct* ts
indent_up();
}
if (field->get_type()->is_base_type() && ((t_base_type*)(field->get_type()))->is_binary()) {
if (field->get_type()->is_binary()) {
indent(out) << " ret += \"BINARY\";" << endl;
} else if (field->get_type()->is_enum()) {
indent(out) << "var " << field->get_name()
@ -1346,7 +1346,7 @@ void t_haxe_generator::generate_haxe_struct_tostring(ofstream& out, t_struct* ts
*
* @param tstruct The struct definition
*/
void t_haxe_generator::generate_haxe_meta_data_map(ofstream& out, t_struct* tstruct) {
void t_haxe_generator::generate_haxe_meta_data_map(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -1434,7 +1434,7 @@ std::string t_haxe_generator::get_haxe_type_string(t_type* type) {
}
}
void t_haxe_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
void t_haxe_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
out << endl;
indent_up();
indent_up();
@ -2176,7 +2176,7 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function
* @param tfield The field
* @param prefix The variable name or container for this field
*/
void t_haxe_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_haxe_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
if (type->is_void()) {
@ -2200,7 +2200,7 @@ void t_haxe_generator::generate_deserialize_field(ofstream& out, t_field* tfield
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "readBinary();";
} else {
out << "readString();";
@ -2241,7 +2241,7 @@ void t_haxe_generator::generate_deserialize_field(ofstream& out, t_field* tfield
/**
* Generates an unserializer for a struct, invokes read()
*/
void t_haxe_generator::generate_deserialize_struct(ofstream& out,
void t_haxe_generator::generate_deserialize_struct(ostream& out,
t_struct* tstruct,
string prefix) {
out << indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << endl
@ -2251,7 +2251,7 @@ void t_haxe_generator::generate_deserialize_struct(ofstream& out,
/**
* Deserializes a container by reading its size and then iterating
*/
void t_haxe_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_haxe_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
string obj;
@ -2309,7 +2309,7 @@ void t_haxe_generator::generate_deserialize_container(ofstream& out, t_type* tty
/**
* Generates code to deserialize a map
*/
void t_haxe_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
void t_haxe_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
string key = tmp("_key");
string val = tmp("_val");
t_field fkey(tmap->get_key_type(), key);
@ -2327,7 +2327,7 @@ void t_haxe_generator::generate_deserialize_map_element(ofstream& out, t_map* tm
/**
* Deserializes a set element
*/
void t_haxe_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
void t_haxe_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
string elem = tmp("_elem");
t_field felem(tset->get_elem_type(), elem);
@ -2341,7 +2341,7 @@ void t_haxe_generator::generate_deserialize_set_element(ofstream& out, t_set* ts
/**
* Deserializes a list element
*/
void t_haxe_generator::generate_deserialize_list_element(ofstream& out,
void t_haxe_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix) {
string elem = tmp("_elem");
@ -2360,7 +2360,7 @@ void t_haxe_generator::generate_deserialize_list_element(ofstream& out,
* @param tfield The field to serialize
* @param prefix Name to prepend to field name
*/
void t_haxe_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_haxe_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
// Do nothing for void types
@ -2384,7 +2384,7 @@ void t_haxe_generator::generate_serialize_field(ofstream& out, t_field* tfield,
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "writeBinary(" << name << ");";
} else {
out << "writeString(" << name << ");";
@ -2429,7 +2429,7 @@ void t_haxe_generator::generate_serialize_field(ofstream& out, t_field* tfield,
* @param tstruct The struct to serialize
* @param prefix String prefix to attach to all fields
*/
void t_haxe_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_haxe_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
(void)tstruct;
out << indent() << prefix << ".write(oprot);" << endl;
}
@ -2440,7 +2440,7 @@ void t_haxe_generator::generate_serialize_struct(ofstream& out, t_struct* tstruc
* @param ttype The type of container
* @param prefix String prefix for fields
*/
void t_haxe_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_haxe_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
if (ttype->is_map()) {
@ -2498,7 +2498,7 @@ void t_haxe_generator::generate_serialize_container(ofstream& out, t_type* ttype
/**
* Serializes the members of a map.
*/
void t_haxe_generator::generate_serialize_map_element(ofstream& out,
void t_haxe_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string iter,
string map) {
@ -2511,7 +2511,7 @@ void t_haxe_generator::generate_serialize_map_element(ofstream& out,
/**
* Serializes the members of a set.
*/
void t_haxe_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_haxe_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
@ -2519,7 +2519,7 @@ void t_haxe_generator::generate_serialize_set_element(ofstream& out, t_set* tset
/**
* Serializes the members of a list.
*/
void t_haxe_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
void t_haxe_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
t_field efield(tlist->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
@ -2553,9 +2553,10 @@ string t_haxe_generator::type_name(t_type* ttype, bool in_container, bool in_ini
t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base();
switch (tbase) {
case t_base_type::TYPE_STRING:
if (!(((t_base_type*)tkey)->is_binary())) {
if (!(tkey->is_binary())) {
return "StringMap< " + type_name(tval) + ">";
}
break; // default to ObjectMap<>
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
@ -2573,14 +2574,15 @@ string t_haxe_generator::type_name(t_type* ttype, bool in_container, bool in_ini
}
if (ttype->is_set()) {
t_type* tkey = get_true_type(((t_list*)ttype)->get_elem_type());
t_type* tkey = get_true_type(((t_set*)ttype)->get_elem_type());
if (tkey->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base();
switch (tbase) {
case t_base_type::TYPE_STRING:
if (!(((t_base_type*)tkey)->is_binary())) {
if (!(tkey->is_binary())) {
return "StringSet";
}
break; // default to ObjectSet
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
@ -2659,7 +2661,7 @@ string t_haxe_generator::declare_field(t_field* tfield, bool init) {
if (init) {
t_type* ttype = get_true_type(tfield->get_type());
if (ttype->is_base_type() && tfield->get_value() != NULL) {
ofstream dummy;
std::ofstream dummy;
result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
} else if (ttype->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@ -2902,7 +2904,7 @@ string t_haxe_generator::constant_name(string name) {
/**
* Enables RTTI for a class or interface
*/
void t_haxe_generator::generate_rtti_decoration(ofstream& out) {
void t_haxe_generator::generate_rtti_decoration(ostream& out) {
if (rtti_) {
out << "@:rtti" << endl;
}
@ -2911,7 +2913,7 @@ void t_haxe_generator::generate_rtti_decoration(ofstream& out) {
/**
* Adds build macros to a class or interface
*/
void t_haxe_generator::generate_macro_decoration(ofstream& out) {
void t_haxe_generator::generate_macro_decoration(ostream& out) {
if (!buildmacro_.empty()) {
out << "#if ! macro" << endl;
out << "@:build( " << buildmacro_ << ")" << endl; // current class/interface
@ -2923,7 +2925,7 @@ void t_haxe_generator::generate_macro_decoration(ofstream& out) {
/**
* Emits a haxeDoc comment if the provided object has a doc in Thrift
*/
void t_haxe_generator::generate_haxe_doc(ofstream& out, t_doc* tdoc) {
void t_haxe_generator::generate_haxe_doc(ostream& out, t_doc* tdoc) {
if (tdoc->has_doc()) {
generate_docstring_comment(out, "/**\n", " * ", tdoc->get_doc(), " */\n");
}
@ -2932,7 +2934,7 @@ void t_haxe_generator::generate_haxe_doc(ofstream& out, t_doc* tdoc) {
/**
* Emits a haxeDoc comment if the provided function object has a doc in Thrift
*/
void t_haxe_generator::generate_haxe_doc(ofstream& out, t_function* tfunction) {
void t_haxe_generator::generate_haxe_doc(ostream& out, t_function* tfunction) {
if (tfunction->has_doc()) {
stringstream ss;
ss << tfunction->get_doc();
@ -2957,7 +2959,7 @@ std::string t_haxe_generator::generate_isset_check(std::string field_name) {
return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
}
void t_haxe_generator::generate_isset_set(ofstream& out, t_field* field) {
void t_haxe_generator::generate_isset_set(ostream& out, t_field* field) {
if (!type_can_be_null(field->get_type())) {
indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl;
}

View file

@ -33,7 +33,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -87,22 +87,22 @@ public:
void generate_hs_struct(t_struct* tstruct, bool is_exception);
void generate_hs_struct_definition(ofstream& out,
void generate_hs_struct_definition(ostream& out,
t_struct* tstruct,
bool is_xception = false,
bool helper = false);
void generate_hs_struct_reader(ofstream& out, t_struct* tstruct);
void generate_hs_struct_reader(ostream& out, t_struct* tstruct);
void generate_hs_struct_writer(ofstream& out, t_struct* tstruct);
void generate_hs_struct_writer(ostream& out, t_struct* tstruct);
void generate_hs_struct_arbitrary(ofstream& out, t_struct* tstruct);
void generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct);
void generate_hs_function_helpers(t_function* tfunction);
void generate_hs_typemap(ofstream& out, t_struct* tstruct);
void generate_hs_typemap(ostream& out, t_struct* tstruct);
void generate_hs_default(ofstream& out, t_struct* tstruct);
void generate_hs_default(ostream& out, t_struct* tstruct);
/**
* Service-level generation functions
@ -118,29 +118,29 @@ public:
* Serialization constructs
*/
void generate_deserialize_field(ofstream& out, t_field* tfield, string prefix);
void generate_deserialize_field(ostream& out, t_field* tfield, string prefix);
void generate_deserialize_struct(ofstream& out, t_struct* tstruct, string name = "");
void generate_deserialize_struct(ostream& out, t_struct* tstruct, string name = "");
void generate_deserialize_container(ofstream& out, t_type* ttype, string arg = "");
void generate_deserialize_container(ostream& out, t_type* ttype, string arg = "");
void generate_deserialize_set_element(ofstream& out, t_set* tset);
void generate_deserialize_set_element(ostream& out, t_set* tset);
void generate_deserialize_list_element(ofstream& out, t_list* tlist, string prefix = "");
void generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix = "");
void generate_deserialize_type(ofstream& out, t_type* type, string arg = "");
void generate_deserialize_type(ostream& out, t_type* type, string arg = "");
void generate_serialize_type(ofstream& out, t_type* type, string name = "");
void generate_serialize_type(ostream& out, t_type* type, string name = "");
void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix = "");
void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
void generate_serialize_container(ofstream& out, t_type* ttype, string prefix = "");
void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
void generate_serialize_map_element(ofstream& out, t_map* tmap, string kiter, string viter);
void generate_serialize_map_element(ostream& out, t_map* tmap, string kiter, string viter);
void generate_serialize_set_element(ofstream& out, t_set* tmap, string iter);
void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
void generate_serialize_list_element(ofstream& out, t_list* tlist, string iter);
void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
/**
* Helper rendering functions
@ -170,11 +170,11 @@ public:
string render_hs_type_for_function_name(t_type* type);
private:
ofstream f_types_;
ofstream f_consts_;
ofstream f_service_;
ofstream f_iface_;
ofstream f_client_;
ofstream_with_content_based_conditional_update f_types_;
ofstream_with_content_based_conditional_update f_consts_;
ofstream_with_content_based_conditional_update f_service_;
ofstream_with_content_based_conditional_update f_iface_;
ofstream_with_content_based_conditional_update f_client_;
};
/**
@ -424,10 +424,10 @@ string t_hs_generator::render_const_value(t_type* type, t_const_value* value) {
out << "default_" << cname << "{";
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
const map<t_const_value*, t_const_value*>& val = value->get_map();
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
bool first = true;
for (map<t_const_value*, t_const_value*>::const_iterator v_iter = val.begin();
for (map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter = val.begin();
v_iter != val.end();
++v_iter) {
t_field* field = NULL;
@ -458,8 +458,8 @@ string t_hs_generator::render_const_value(t_type* type, t_const_value* value) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
out << "(Map.fromList [";
@ -530,7 +530,7 @@ void t_hs_generator::generate_hs_struct(t_struct* tstruct, bool is_exception) {
*
* @param tstruct The struct definition
*/
void t_hs_generator::generate_hs_struct_definition(ofstream& out,
void t_hs_generator::generate_hs_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception,
bool helper) {
@ -586,7 +586,7 @@ void t_hs_generator::generate_hs_struct_definition(ofstream& out,
generate_hs_default(out, tstruct);
}
void t_hs_generator::generate_hs_struct_arbitrary(ofstream& out, t_struct* tstruct) {
void t_hs_generator::generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct) {
string tname = type_name(tstruct);
string name = tstruct->get_name();
const vector<t_field*>& members = tstruct->get_members();
@ -652,7 +652,7 @@ void t_hs_generator::generate_hs_struct_arbitrary(ofstream& out, t_struct* tstru
/**
* Generates the read method for a struct
*/
void t_hs_generator::generate_hs_struct_reader(ofstream& out, t_struct* tstruct) {
void t_hs_generator::generate_hs_struct_reader(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -711,18 +711,18 @@ void t_hs_generator::generate_hs_struct_reader(ofstream& out, t_struct* tstruct)
string tmap = type_name(tstruct, "typemap_");
indent(out) << "to_" << sname << " _ = P.error \"not a struct\"" << endl;
indent(out) << "read_" << sname << " :: (T.Transport t, T.Protocol p) => p t -> P.IO " << sname
indent(out) << "read_" << sname << " :: T.Protocol p => p -> P.IO " << sname
<< endl;
indent(out) << "read_" << sname << " iprot = to_" << sname;
out << " <$> T.readVal iprot (T.T_STRUCT " << tmap << ")" << endl;
indent(out) << "decode_" << sname
<< " :: (T.Protocol p, T.Transport t) => p t -> LBS.ByteString -> " << sname << endl;
<< " :: T.StatelessProtocol p => p -> LBS.ByteString -> " << sname << endl;
indent(out) << "decode_" << sname << " iprot bs = to_" << sname << " $ ";
out << "T.deserializeVal iprot (T.T_STRUCT " << tmap << ") bs" << endl;
}
void t_hs_generator::generate_hs_struct_writer(ofstream& out, t_struct* tstruct) {
void t_hs_generator::generate_hs_struct_writer(ostream& out, t_struct* tstruct) {
string name = type_name(tstruct);
const vector<t_field*>& fields = tstruct->get_sorted_members();
vector<t_field*>::const_iterator f_iter;
@ -818,13 +818,13 @@ void t_hs_generator::generate_hs_struct_writer(ofstream& out, t_struct* tstruct)
indent_down();
// write
indent(out) << "write_" << name << " :: (T.Protocol p, T.Transport t) => p t -> " << name
indent(out) << "write_" << name << " :: T.Protocol p => p -> " << name
<< " -> P.IO ()" << endl;
indent(out) << "write_" << name << " oprot record = T.writeVal oprot $ from_";
out << name << " record" << endl;
// encode
indent(out) << "encode_" << name << " :: (T.Protocol p, T.Transport t) => p t -> " << name
indent(out) << "encode_" << name << " :: T.StatelessProtocol p => p -> " << name
<< " -> LBS.ByteString" << endl;
indent(out) << "encode_" << name << " oprot record = T.serializeVal oprot $ ";
out << "from_" << name << " record" << endl;
@ -906,7 +906,7 @@ void t_hs_generator::generate_hs_function_helpers(t_function* tfunction) {
* Generate the map from field names to (type, id)
* @param tstruct the Struct
*/
void t_hs_generator::generate_hs_typemap(ofstream& out, t_struct* tstruct) {
void t_hs_generator::generate_hs_typemap(ostream& out, t_struct* tstruct) {
string name = type_name(tstruct);
const vector<t_field*>& fields = tstruct->get_sorted_members();
vector<t_field*>::const_iterator f_iter;
@ -932,7 +932,7 @@ void t_hs_generator::generate_hs_typemap(ofstream& out, t_struct* tstruct) {
* generate the struct with default values filled in
* @param tstruct the Struct
*/
void t_hs_generator::generate_hs_default(ofstream& out, t_struct* tstruct) {
void t_hs_generator::generate_hs_default(ostream& out, t_struct* tstruct) {
string name = type_name(tstruct);
string fname = type_name(tstruct, "default_");
const vector<t_field*>& fields = tstruct->get_sorted_members();
@ -1085,8 +1085,9 @@ void t_hs_generator::generate_service_client(t_service* tservice) {
// Serialize the request header
string fname = (*f_iter)->get_name();
string msgType = (*f_iter)->is_oneway() ? "T.M_ONEWAY" : "T.M_CALL";
indent(f_client_) << "T.writeMessageBegin op (\"" << fname << "\", " << msgType << ", seqn)"
indent(f_client_) << "T.writeMessage op (\"" << fname << "\", " << msgType << ", seqn) $"
<< endl;
indent_up();
indent(f_client_) << "write_" << argsname << " op (" << argsname << "{";
bool first = true;
@ -1102,10 +1103,7 @@ void t_hs_generator::generate_service_client(t_service* tservice) {
first = false;
}
f_client_ << "})" << endl;
indent(f_client_) << "T.writeMessageEnd op" << endl;
// Write to the stream
indent(f_client_) << "T.tFlush (T.getTransport op)" << endl;
indent_down();
indent_down();
if (!(*f_iter)->is_oneway()) {
@ -1119,12 +1117,12 @@ void t_hs_generator::generate_service_client(t_service* tservice) {
indent(f_client_) << funname << " ip = do" << endl;
indent_up();
indent(f_client_) << "(fname, mtype, rseqid) <- T.readMessageBegin ip" << endl;
indent(f_client_) << "T.readMessage ip $ \\(fname, mtype, rseqid) -> do" << endl;
indent_up();
indent(f_client_) << "M.when (mtype == T.M_EXCEPTION) $ do { exn <- T.readAppExn ip ; "
"T.readMessageEnd ip ; X.throw exn }" << endl;
"X.throw exn }" << endl;
indent(f_client_) << "res <- read_" << resultname << " ip" << endl;
indent(f_client_) << "T.readMessageEnd ip" << endl;
t_struct* xs = (*f_iter)->get_xceptions();
const vector<t_field*>& xceptions = xs->get_members();
@ -1142,6 +1140,7 @@ void t_hs_generator::generate_service_client(t_service* tservice) {
// Close function
indent_down();
indent_down();
}
}
@ -1180,11 +1179,11 @@ void t_hs_generator::generate_service_server(t_service* tservice) {
f_service_ << "do" << endl;
indent_up();
indent(f_service_) << "_ <- T.readVal iprot (T.T_STRUCT Map.empty)" << endl;
indent(f_service_) << "T.writeMessageBegin oprot (name,T.M_EXCEPTION,seqid)" << endl;
indent(f_service_) << "T.writeMessage oprot (name,T.M_EXCEPTION,seqid) $" << endl;
indent_up();
indent(f_service_) << "T.writeAppExn oprot (T.AppExn T.AE_UNKNOWN_METHOD (\"Unknown function "
"\" ++ LT.unpack name))" << endl;
indent(f_service_) << "T.writeMessageEnd oprot" << endl;
indent(f_service_) << "T.tFlush (T.getTransport oprot)" << endl;
indent_down();
indent_down();
}
@ -1194,9 +1193,8 @@ void t_hs_generator::generate_service_server(t_service* tservice) {
indent(f_service_) << "process handler (iprot, oprot) = do" << endl;
indent_up();
indent(f_service_) << "(name, typ, seqid) <- T.readMessageBegin iprot" << endl;
indent(f_service_) << "proc_ handler (iprot,oprot) (name,typ,seqid)" << endl;
indent(f_service_) << "T.readMessageEnd iprot" << endl;
indent(f_service_) << "T.readMessage iprot (" << endl;
indent(f_service_) << " proc_ handler (iprot,oprot))" << endl;
indent(f_service_) << "P.return P.True" << endl;
indent_down();
}
@ -1286,11 +1284,11 @@ void t_hs_generator::generate_process_function(t_service* tservice, t_function*
if (tfunction->is_oneway()) {
indent(f_service_) << "P.return ()";
} else {
indent(f_service_) << "T.writeMessageBegin oprot (\"" << tfunction->get_name()
<< "\", T.M_REPLY, seqid)" << endl;
indent(f_service_) << "write_" << resultname << " oprot res" << endl;
indent(f_service_) << "T.writeMessageEnd oprot" << endl;
indent(f_service_) << "T.tFlush (T.getTransport oprot)";
indent(f_service_) << "T.writeMessage oprot (\"" << tfunction->get_name()
<< "\", T.M_REPLY, seqid) $" << endl;
indent_up();
indent(f_service_) << "write_" << resultname << " oprot res";
indent_down();
}
if (n > 0) {
f_service_ << ")";
@ -1307,11 +1305,11 @@ void t_hs_generator::generate_process_function(t_service* tservice, t_function*
indent(f_service_) << "let res = default_" << resultname << "{"
<< field_name(resultname, (*x_iter)->get_name()) << " = P.Just e}"
<< endl;
indent(f_service_) << "T.writeMessageBegin oprot (\"" << tfunction->get_name()
<< "\", T.M_REPLY, seqid)" << endl;
indent(f_service_) << "write_" << resultname << " oprot res" << endl;
indent(f_service_) << "T.writeMessageEnd oprot" << endl;
indent(f_service_) << "T.tFlush (T.getTransport oprot)";
indent(f_service_) << "T.writeMessage oprot (\"" << tfunction->get_name()
<< "\", T.M_REPLY, seqid) $" << endl;
indent_up();
indent(f_service_) << "write_" << resultname << " oprot res";
indent_down();
} else {
indent(f_service_) << "P.return ()";
}
@ -1324,11 +1322,11 @@ void t_hs_generator::generate_process_function(t_service* tservice, t_function*
indent_up();
if (!tfunction->is_oneway()) {
indent(f_service_) << "T.writeMessageBegin oprot (\"" << tfunction->get_name()
<< "\", T.M_EXCEPTION, seqid)" << endl;
indent(f_service_) << "T.writeAppExn oprot (T.AppExn T.AE_UNKNOWN \"\")" << endl;
indent(f_service_) << "T.writeMessageEnd oprot" << endl;
indent(f_service_) << "T.tFlush (T.getTransport oprot)";
indent(f_service_) << "T.writeMessage oprot (\"" << tfunction->get_name()
<< "\", T.M_EXCEPTION, seqid) $" << endl;
indent_up();
indent(f_service_) << "T.writeAppExn oprot (T.AppExn T.AE_UNKNOWN \"\")";
indent_down();
} else {
indent(f_service_) << "P.return ()";
}
@ -1344,7 +1342,7 @@ void t_hs_generator::generate_process_function(t_service* tservice, t_function*
/**
* Deserializes a field of any type.
*/
void t_hs_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_hs_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
(void)prefix;
t_type* type = tfield->get_type();
generate_deserialize_type(out, type, prefix);
@ -1353,7 +1351,7 @@ void t_hs_generator::generate_deserialize_field(ofstream& out, t_field* tfield,
/**
* Deserializes a field of any type.
*/
void t_hs_generator::generate_deserialize_type(ofstream& out, t_type* type, string arg) {
void t_hs_generator::generate_deserialize_type(ostream& out, t_type* type, string arg) {
type = get_true_type(type);
string val = tmp("_val");
out << "(case " << arg << " of {" << type_to_constructor(type) << " " << val << " -> ";
@ -1369,11 +1367,11 @@ void t_hs_generator::generate_deserialize_type(ofstream& out, t_type* type, stri
} else if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
if (tbase == t_base_type::TYPE_STRING && !((t_base_type*)type)->is_binary()) {
if (tbase == t_base_type::TYPE_STRING && !type->is_binary()) {
out << "E.decodeUtf8 ";
}
out << val;
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
// Since wire type of binary is the same as string, we actually receive T.TString not
// T.TBinary
out << "; T.TString " << val << " -> " << val;
@ -1390,7 +1388,7 @@ void t_hs_generator::generate_deserialize_type(ofstream& out, t_type* type, stri
/**
* Generates an unserializer for a struct, calling read()
*/
void t_hs_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string name) {
void t_hs_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string name) {
out << "(" << type_name(tstruct, "to_") << " (T.TStruct " << name << "))";
}
@ -1399,7 +1397,7 @@ void t_hs_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruc
* Serialize a container by writing out the header followed by
* data and then a footer.
*/
void t_hs_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string arg) {
void t_hs_generator::generate_deserialize_container(ostream& out, t_type* ttype, string arg) {
string val = tmp("_v");
// Declare variables, read header
@ -1415,12 +1413,12 @@ void t_hs_generator::generate_deserialize_container(ofstream& out, t_type* ttype
} else if (ttype->is_set()) {
out << "(Set.fromList $ P.map (\\" << val << " -> ";
generate_deserialize_type(out, ((t_map*)ttype)->get_key_type(), val);
generate_deserialize_type(out, ((t_set*)ttype)->get_elem_type(), val);
out << ") " << arg << ")";
} else if (ttype->is_list()) {
out << "(Vector.fromList $ P.map (\\" << val << " -> ";
generate_deserialize_type(out, ((t_map*)ttype)->get_key_type(), val);
generate_deserialize_type(out, ((t_list*)ttype)->get_elem_type(), val);
out << ") " << arg << ")";
}
}
@ -1431,7 +1429,7 @@ void t_hs_generator::generate_deserialize_container(ofstream& out, t_type* ttype
* @param tfield The field to serialize
* @param prefix Name to prepend to field name
*/
void t_hs_generator::generate_serialize_type(ofstream& out, t_type* type, string name) {
void t_hs_generator::generate_serialize_type(ostream& out, t_type* type, string name) {
type = get_true_type(type);
// Do nothing for void types
@ -1448,7 +1446,7 @@ void t_hs_generator::generate_serialize_type(ofstream& out, t_type* type, string
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
out << type_to_constructor(type) << " ";
if (tbase == t_base_type::TYPE_STRING && !((t_base_type*)type)->is_binary()) {
if (tbase == t_base_type::TYPE_STRING && !type->is_binary()) {
out << "$ E.encodeUtf8 ";
}
out << name;
@ -1469,11 +1467,11 @@ void t_hs_generator::generate_serialize_type(ofstream& out, t_type* type, string
* @param tstruct The struct to serialize
* @param prefix String prefix to attach to all fields
*/
void t_hs_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_hs_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
out << type_name(tstruct, "from_") << " " << prefix;
}
void t_hs_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_hs_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
string k = tmp("_k");
string v = tmp("_v");
@ -1488,9 +1486,9 @@ void t_hs_generator::generate_serialize_container(ofstream& out, t_type* ttype,
out << ")) $ Map.toList " << prefix;
} else if (ttype->is_set()) {
out << "T.TSet " << type_to_enum(((t_list*)ttype)->get_elem_type());
out << "T.TSet " << type_to_enum(((t_set*)ttype)->get_elem_type());
out << " $ P.map (\\" << v << " -> ";
generate_serialize_type(out, ((t_list*)ttype)->get_elem_type(), v);
generate_serialize_type(out, ((t_set*)ttype)->get_elem_type(), v);
out << ") $ Set.toList " << prefix;
} else if (ttype->is_list()) {
@ -1550,7 +1548,7 @@ string t_hs_generator::type_to_enum(t_type* type) {
case t_base_type::TYPE_VOID:
return "T.T_VOID";
case t_base_type::TYPE_STRING:
return ((t_base_type*)type)->is_binary() ? "T.T_BINARY" : "T.T_STRING";
return type->is_binary() ? "T.T_BINARY" : "T.T_STRING";
case t_base_type::TYPE_BOOL:
return "T.T_BOOL";
case t_base_type::TYPE_I8:
@ -1577,7 +1575,7 @@ string t_hs_generator::type_to_enum(t_type* type) {
return "(T.T_MAP " + ktype + " " + vtype + ")";
} else if (type->is_set()) {
return "(T.T_SET " + type_to_enum(((t_list*)type)->get_elem_type()) + ")";
return "(T.T_SET " + type_to_enum(((t_set*)type)->get_elem_type()) + ")";
} else if (type->is_list()) {
return "(T.T_LIST " + type_to_enum(((t_list*)type)->get_elem_type()) + ")";
@ -1645,7 +1643,7 @@ string t_hs_generator::render_hs_type(t_type* type, bool needs_parens) {
case t_base_type::TYPE_VOID:
return "()";
case t_base_type::TYPE_STRING:
return (((t_base_type*)type)->is_binary() ? "LBS.ByteString" : "LT.Text");
return (type->is_binary() ? "LBS.ByteString" : "LT.Text");
case t_base_type::TYPE_BOOL:
return "P.Bool";
case t_base_type::TYPE_I8:
@ -1698,7 +1696,7 @@ string t_hs_generator::type_to_constructor(t_type* type) {
case t_base_type::TYPE_VOID:
throw "invalid type: T_VOID";
case t_base_type::TYPE_STRING:
return ((t_base_type*)type)->is_binary() ? "T.TBinary" : "T.TString";
return type->is_binary() ? "T.TBinary" : "T.TString";
case t_base_type::TYPE_BOOL:
return "T.TBool";
case t_base_type::TYPE_I8:

View file

@ -90,7 +90,7 @@ public:
std::string escape_html(std::string const& str);
std::string escape_html_tags(std::string const& str);
void generate_css();
void generate_css_content(std::ofstream& f_target);
void generate_css_content(std::ostream& f_target);
void generate_style_tag();
std::string make_file_link(std::string name);
bool is_utf8_sequence(std::string const& str, size_t firstpos);
@ -114,7 +114,7 @@ public:
void print_fn_args_doc(t_function* tfunction);
private:
std::ofstream f_out_;
ofstream_with_content_based_conditional_update f_out_;
std::string current_file_;
input_type input_type_;
std::map<std::string, int> allowed_markup;
@ -359,7 +359,7 @@ void t_html_generator::generate_css() {
}
}
void t_html_generator::generate_css_content(std::ofstream& f_target) {
void t_html_generator::generate_css_content(std::ostream& f_target) {
f_target << BOOTSTRAP_CSS() << endl;
f_target << "/* Auto-generated CSS for generated Thrift docs */" << endl;
f_target << "h3, h4 { margin-bottom: 6px; }" << endl;
@ -405,7 +405,7 @@ void t_html_generator::print_doc(t_doc* tdoc) {
if (unsafe_) {
f_out_ << tdoc->get_doc() << "<br/>";
} else {
f_out_ << escape_html(tdoc->get_doc()) << "<br/>";
f_out_ << "<pre>" << escape_html(tdoc->get_doc()) << "</pre><br/>";
}
}
}
@ -691,14 +691,14 @@ int t_html_generator::print_type(t_type* ttype) {
f_out_ << "&gt;";
}
} else if (ttype->is_base_type()) {
f_out_ << (((t_base_type*)ttype)->is_binary() ? "binary" : ttype->get_name());
f_out_ << (ttype->is_binary() ? "binary" : ttype->get_name());
len = ttype->get_name().size();
} else {
string prog_name = ttype->get_program()->get_name();
string type_name = ttype->get_name();
f_out_ << "<a href=\"" << make_file_link(prog_name + ".html") << "#";
if (ttype->is_typedef()) {
f_out_ << "Typedef_";
f_out_ << "Struct_";
} else if (ttype->is_struct() || ttype->is_xception()) {
f_out_ << "Struct_";
} else if (ttype->is_enum()) {
@ -777,8 +777,8 @@ void t_html_generator::print_const_value(t_type* type, t_const_value* tvalue) {
f_out_ << "{ ";
const vector<t_field*>& fields = ((t_struct*)truetype)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = tvalue->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = tvalue->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -800,8 +800,8 @@ void t_html_generator::print_const_value(t_type* type, t_const_value* tvalue) {
f_out_ << " }";
} else if (truetype->is_map()) {
f_out_ << "{ ";
map<t_const_value*, t_const_value*> map_elems = tvalue->get_map();
map<t_const_value*, t_const_value*>::iterator map_iter;
map<t_const_value*, t_const_value*, t_const_value::value_compare> map_elems = tvalue->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::iterator map_iter;
for (map_iter = map_elems.begin(); map_iter != map_elems.end(); map_iter++) {
if (!first) {
f_out_ << ", ";

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -81,13 +81,13 @@ public:
void generate_xception(t_struct* txception);
void generate_service(t_service* tservice);
void print_const_value(std::ofstream& out,
void print_const_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value,
bool in_static,
bool defval = false);
std::string render_const_value(std::ofstream& out,
std::string render_const_value(std::ostream& out,
std::string name,
t_type* type,
t_const_value* value);
@ -98,20 +98,20 @@ public:
void generate_java_struct(t_struct* tstruct, bool is_exception);
void generate_java_struct_definition(std::ofstream& out,
void generate_java_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false,
bool in_class = false,
bool is_result = false);
void generate_java_struct_equality(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_compare_to(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_java_validator(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_result_writer(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_tostring(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_clear(std::ofstream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ofstream& out, t_type* type);
void generate_java_struct_equality(std::ostream& out, t_struct* tstruct);
void generate_java_struct_compare_to(std::ostream& out, t_struct* tstruct);
void generate_java_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_java_validator(std::ostream& out, t_struct* tstruct);
void generate_java_struct_result_writer(std::ostream& out, t_struct* tstruct);
void generate_java_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_java_struct_tostring(std::ostream& out, t_struct* tstruct);
void generate_java_struct_clear(std::ostream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ostream& out, t_type* type);
std::string get_java_type_string(t_type* type);
void generate_reflection_setters(std::ostringstream& out,
t_type* type,
@ -121,14 +121,14 @@ public:
t_type* type,
std::string field_name,
std::string cap_name);
void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
void generate_java_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
void generate_java_bean_boilerplate(std::ostream& out, t_struct* tstruct);
void generate_function_helpers(t_function* tfunction);
std::string get_cap_name(std::string name);
std::string generate_isset_check(t_field* field);
std::string generate_isset_check(std::string field);
void generate_isset_set(ofstream& out, t_field* field);
void generate_isset_set(ostream& out, t_field* field);
std::string isset_field_id(t_field* field);
void generate_primitive_service_interface(t_service* tservice);
@ -139,66 +139,66 @@ public:
void generate_process_function(t_service* tservice, t_function* tfunction);
void generate_java_union(t_struct* tstruct);
void generate_union_constructor(ofstream& out, t_struct* tstruct);
void generate_union_getters_and_setters(ofstream& out, t_struct* tstruct);
void generate_union_abstract_methods(ofstream& out, t_struct* tstruct);
void generate_check_type(ofstream& out, t_struct* tstruct);
void generate_read_value(ofstream& out, t_struct* tstruct);
void generate_write_value(ofstream& out, t_struct* tstruct);
void generate_get_field_desc(ofstream& out, t_struct* tstruct);
void generate_get_struct_desc(ofstream& out, t_struct* tstruct);
void generate_get_field_name(ofstream& out, t_struct* tstruct);
void generate_union_constructor(ostream& out, t_struct* tstruct);
void generate_union_getters_and_setters(ostream& out, t_struct* tstruct);
void generate_union_abstract_methods(ostream& out, t_struct* tstruct);
void generate_check_type(ostream& out, t_struct* tstruct);
void generate_read_value(ostream& out, t_struct* tstruct);
void generate_write_value(ostream& out, t_struct* tstruct);
void generate_get_field_desc(ostream& out, t_struct* tstruct);
void generate_get_struct_desc(ostream& out, t_struct* tstruct);
void generate_get_field_name(ostream& out, t_struct* tstruct);
void generate_union_comparisons(ofstream& out, t_struct* tstruct);
void generate_union_hashcode(ofstream& out, t_struct* tstruct);
void generate_union_comparisons(ostream& out, t_struct* tstruct);
void generate_union_hashcode(ostream& out, t_struct* tstruct);
/**
* Serialization constructs
*/
void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string iter,
std::string map);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
void generate_java_doc(std::ofstream& out, t_field* field);
void generate_java_doc(std::ostream& out, t_field* field);
void generate_java_doc(std::ofstream& out, t_doc* tdoc);
void generate_java_doc(std::ostream& out, t_doc* tdoc);
void generate_java_doc(std::ofstream& out, t_function* tdoc);
void generate_java_doc(std::ostream& out, t_function* tdoc);
void generate_java_docstring_comment(std::ofstream& out, string contents);
void generate_java_docstring_comment(std::ostream& out, string contents);
void generate_deep_copy_container(std::ofstream& out,
void generate_deep_copy_container(std::ostream& out,
std::string source_name_p1,
std::string source_name_p2,
std::string result_name,
t_type* type);
void generate_deep_copy_non_container(std::ofstream& out,
void generate_deep_copy_non_container(std::ostream& out,
std::string source_name,
std::string dest_name,
t_type* type);
@ -222,8 +222,8 @@ public:
std::string argument_list(t_struct* tstruct, bool include_types = true);
std::string type_to_enum(t_type* ttype);
std::string get_enum_class_name(t_type* type);
void generate_struct_desc(ofstream& out, t_struct* tstruct);
void generate_field_descs(ofstream& out, t_struct* tstruct);
void generate_struct_desc(ostream& out, t_struct* tstruct);
void generate_field_descs(ostream& out, t_struct* tstruct);
std::string box_type(t_type* type, string value);
bool type_can_be_null(t_type* ttype) {
@ -241,7 +241,7 @@ private:
*/
std::string package_name_;
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_service_;
std::string package_dir_;
};
@ -329,7 +329,7 @@ void t_javame_generator::generate_typedef(t_typedef* ttypedef) {
void t_javame_generator::generate_enum(t_enum* tenum) {
// Make output file
string f_enum_name = package_dir_ + "/" + (tenum->get_name()) + ".java";
ofstream f_enum;
ofstream_with_content_based_conditional_update f_enum;
f_enum.open(f_enum_name.c_str());
// Comment and package it
@ -408,7 +408,7 @@ void t_javame_generator::generate_consts(std::vector<t_const*> consts) {
}
string f_consts_name = package_dir_ + "/" + program_name_ + "Constants.java";
ofstream f_consts;
ofstream_with_content_based_conditional_update f_consts;
f_consts.open(f_consts_name.c_str());
// Print header
@ -434,7 +434,7 @@ void t_javame_generator::generate_consts(std::vector<t_const*> consts) {
* is NOT performed in this function as it is always run beforehand using the
* validate_types method in main.cc
*/
void t_javame_generator::print_const_value(std::ofstream& out,
void t_javame_generator::print_const_value(std::ostream& out,
string name,
t_type* type,
t_const_value* value,
@ -454,8 +454,8 @@ void t_javame_generator::print_const_value(std::ofstream& out,
} else if (type->is_struct() || type->is_xception()) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
out << name << " = new " << type_name(type, false, true) << "();" << endl;
if (!in_static) {
indent(out) << "static {" << endl;
@ -489,8 +489,8 @@ void t_javame_generator::print_const_value(std::ofstream& out,
}
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
string key = render_const_value(out, name, ktype, v_iter->first);
string val = render_const_value(out, name, vtype, v_iter->second);
@ -535,7 +535,7 @@ void t_javame_generator::print_const_value(std::ofstream& out,
}
}
string t_javame_generator::render_const_value(ofstream& out,
string t_javame_generator::render_const_value(ostream& out,
string name,
t_type* type,
t_const_value* value) {
@ -638,7 +638,7 @@ void t_javame_generator::generate_xception(t_struct* txception) {
void t_javame_generator::generate_java_struct(t_struct* tstruct, bool is_exception) {
// Make output file
string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".java";
ofstream f_struct;
ofstream_with_content_based_conditional_update f_struct;
f_struct.open(f_struct_name.c_str());
f_struct << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports();
@ -655,7 +655,7 @@ void t_javame_generator::generate_java_struct(t_struct* tstruct, bool is_excepti
void t_javame_generator::generate_java_union(t_struct* tstruct) {
// Make output file
string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".java";
ofstream f_struct;
ofstream_with_content_based_conditional_update f_struct;
f_struct.open(f_struct_name.c_str());
f_struct << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports();
@ -699,7 +699,7 @@ void t_javame_generator::generate_java_union(t_struct* tstruct) {
f_struct.close();
}
void t_javame_generator::generate_union_constructor(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_union_constructor(ostream& out, t_struct* tstruct) {
indent(out) << "public " << type_name(tstruct) << "() {" << endl;
indent(out) << " super();" << endl;
indent(out) << "}" << endl << endl;
@ -730,7 +730,7 @@ void t_javame_generator::generate_union_constructor(ofstream& out, t_struct* tst
}
}
void t_javame_generator::generate_union_getters_and_setters(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_union_getters_and_setters(ostream& out, t_struct* tstruct) {
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
@ -772,7 +772,7 @@ void t_javame_generator::generate_union_getters_and_setters(ofstream& out, t_str
}
}
void t_javame_generator::generate_union_abstract_methods(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) {
generate_check_type(out, tstruct);
out << endl;
generate_read_value(out, tstruct);
@ -785,7 +785,7 @@ void t_javame_generator::generate_union_abstract_methods(ofstream& out, t_struct
out << endl;
}
void t_javame_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_check_type(ostream& out, t_struct* tstruct) {
indent(out)
<< "protected void checkType(_Fields setField, Object value) throws ClassCastException {"
<< endl;
@ -821,7 +821,7 @@ void t_javame_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
indent(out) << "}" << endl;
}
void t_javame_generator::generate_read_value(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_read_value(ostream& out, t_struct* tstruct) {
indent(out) << "protected Object readValue(TProtocol iprot, TField field) throws TException {"
<< endl;
@ -875,7 +875,7 @@ void t_javame_generator::generate_read_value(ofstream& out, t_struct* tstruct) {
indent(out) << "}" << endl;
}
void t_javame_generator::generate_write_value(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_write_value(ostream& out, t_struct* tstruct) {
indent(out) << "protected void writeValue(TProtocol oprot) throws TException {" << endl;
indent_up();
@ -910,7 +910,7 @@ void t_javame_generator::generate_write_value(ofstream& out, t_struct* tstruct)
indent(out) << "}" << endl;
}
void t_javame_generator::generate_get_field_desc(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) {
indent(out) << "protected TField getFieldDesc(_Fields setField) {" << endl;
indent_up();
@ -936,14 +936,14 @@ void t_javame_generator::generate_get_field_desc(ofstream& out, t_struct* tstruc
indent(out) << "}" << endl;
}
void t_javame_generator::generate_get_struct_desc(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) {
(void)tstruct;
indent(out) << "protected TStruct getStructDesc() {" << endl;
indent(out) << " return STRUCT_DESC;" << endl;
indent(out) << "}" << endl;
}
void t_javame_generator::generate_union_comparisons(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) {
// equality
indent(out) << "public boolean equals(Object other) {" << endl;
indent(out) << " if (other instanceof " << tstruct->get_name() << ") {" << endl;
@ -973,7 +973,7 @@ void t_javame_generator::generate_union_comparisons(ofstream& out, t_struct* tst
out << endl;
}
void t_javame_generator::generate_union_hashcode(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) {
(void)tstruct;
indent(out) << "/**" << endl;
indent(out)
@ -995,7 +995,7 @@ void t_javame_generator::generate_union_hashcode(ofstream& out, t_struct* tstruc
* @param in_class If inside a class, needs to be static class
* @param is_result If this is a result it needs a different writer
*/
void t_javame_generator::generate_java_struct_definition(ofstream& out,
void t_javame_generator::generate_java_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception,
bool in_class,
@ -1177,7 +1177,7 @@ void t_javame_generator::generate_java_struct_definition(ofstream& out,
*
* @param tstruct The struct definition
*/
void t_javame_generator::generate_java_struct_equality(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) {
out << indent() << "public boolean equals(Object that) {" << endl;
indent_up();
out << indent() << "if (that == null)" << endl << indent() << " return false;" << endl
@ -1222,7 +1222,7 @@ void t_javame_generator::generate_java_struct_equality(ofstream& out, t_struct*
<< "this_present_" << name << " && that_present_" << name << "))" << endl << indent()
<< " return false;" << endl;
if (t->is_base_type() && ((t_base_type*)t)->is_binary()) {
if (t->is_binary()) {
unequal = "TBaseHelper.compareTo(this." + name + ", that." + name + ") != 0";
} else if (can_be_null) {
unequal = "!this." + name + ".equals(that." + name + ")";
@ -1246,7 +1246,7 @@ void t_javame_generator::generate_java_struct_equality(ofstream& out, t_struct*
indent(out) << "}" << endl << endl;
}
void t_javame_generator::generate_java_struct_compare_to(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) {
indent(out) << "public int compareTo(Object otherObject) {" << endl;
// indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl;
indent_up();
@ -1297,7 +1297,7 @@ void t_javame_generator::generate_java_struct_compare_to(ofstream& out, t_struct
*
* @param tstruct The struct definition
*/
void t_javame_generator::generate_java_struct_reader(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_struct_reader(ostream& out, t_struct* tstruct) {
out << indent() << "public void read(TProtocol iprot) throws TException {" << endl;
indent_up();
@ -1365,7 +1365,7 @@ void t_javame_generator::generate_java_struct_reader(ofstream& out, t_struct* ts
// generates java method to perform various checks
// (e.g. check that all required fields are set)
void t_javame_generator::generate_java_validator(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_validator(ostream& out, t_struct* tstruct) {
indent(out) << "public void validate() throws TException {" << endl;
indent_up();
@ -1390,7 +1390,7 @@ void t_javame_generator::generate_java_validator(ofstream& out, t_struct* tstruc
*
* @param tstruct The struct definition
*/
void t_javame_generator::generate_java_struct_writer(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tstruct) {
out << indent() << "public void write(TProtocol oprot) throws TException {" << endl;
indent_up();
@ -1449,7 +1449,7 @@ void t_javame_generator::generate_java_struct_writer(ofstream& out, t_struct* ts
*
* @param tstruct The struct definition
*/
void t_javame_generator::generate_java_struct_result_writer(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_struct_result_writer(ostream& out, t_struct* tstruct) {
out << indent() << "public void write(TProtocol oprot) throws TException {" << endl;
indent_up();
@ -1527,7 +1527,7 @@ void t_javame_generator::generate_reflection_setters(ostringstream& out,
indent_down();
}
void t_javame_generator::generate_generic_field_getters_setters(std::ofstream& out,
void t_javame_generator::generate_generic_field_getters_setters(std::ostream& out,
t_struct* tstruct) {
(void)out;
std::ostringstream getter_stream;
@ -1555,7 +1555,7 @@ void t_javame_generator::generate_generic_field_getters_setters(std::ofstream& o
*
* @param tstruct The struct definition
*/
void t_javame_generator::generate_java_bean_boilerplate(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -1708,7 +1708,7 @@ void t_javame_generator::generate_java_bean_boilerplate(ofstream& out, t_struct*
*
* @param tstruct The struct definition
*/
void t_javame_generator::generate_java_struct_tostring(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) {
out << indent() << "public String toString() {" << endl;
indent_up();
@ -1740,7 +1740,7 @@ void t_javame_generator::generate_java_struct_tostring(ofstream& out, t_struct*
indent_up();
}
if (field->get_type()->is_base_type() && ((t_base_type*)(field->get_type()))->is_binary()) {
if (field->get_type()->is_binary()) {
indent(out) << "TBaseHelper.toString(this." << field->get_name() << ", sb);" << endl;
} else {
indent(out) << "sb.append(this." << (*f_iter)->get_name() << ");" << endl;
@ -1819,7 +1819,7 @@ std::string t_javame_generator::get_java_type_string(t_type* type) {
}
}
void t_javame_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
void t_javame_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
out << endl;
indent_up();
indent_up();
@ -1894,7 +1894,7 @@ void t_javame_generator::generate_primitive_service_interface(t_service* tservic
<< endl << endl;
string f_interface_name = package_dir_ + "/" + service_name_ + "Iface.java";
std::ofstream f_iface;
ofstream_with_content_based_conditional_update f_iface;
f_iface.open(f_interface_name.c_str());
string extends_iface = "";
@ -2391,7 +2391,7 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi
* @param tfield The field
* @param prefix The variable name or container for this field
*/
void t_javame_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_javame_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
if (type->is_void()) {
@ -2413,7 +2413,7 @@ void t_javame_generator::generate_deserialize_field(ofstream& out, t_field* tfie
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (!((t_base_type*)type)->is_binary()) {
if (!type->is_binary()) {
out << "readString();";
} else {
out << "readBinary();";
@ -2455,7 +2455,7 @@ void t_javame_generator::generate_deserialize_field(ofstream& out, t_field* tfie
/**
* Generates an unserializer for a struct, invokes read()
*/
void t_javame_generator::generate_deserialize_struct(ofstream& out,
void t_javame_generator::generate_deserialize_struct(ostream& out,
t_struct* tstruct,
string prefix) {
out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent()
@ -2465,7 +2465,7 @@ void t_javame_generator::generate_deserialize_struct(ofstream& out,
/**
* Deserializes a container by reading its size and then iterating
*/
void t_javame_generator::generate_deserialize_container(ofstream& out,
void t_javame_generator::generate_deserialize_container(ostream& out,
t_type* ttype,
string prefix) {
scope_up(out);
@ -2527,7 +2527,7 @@ void t_javame_generator::generate_deserialize_container(ofstream& out,
/**
* Generates code to deserialize a map
*/
void t_javame_generator::generate_deserialize_map_element(ofstream& out,
void t_javame_generator::generate_deserialize_map_element(ostream& out,
t_map* tmap,
string prefix) {
string key = tmp("_key");
@ -2548,7 +2548,7 @@ void t_javame_generator::generate_deserialize_map_element(ofstream& out,
/**
* Deserializes a set element
*/
void t_javame_generator::generate_deserialize_set_element(ofstream& out,
void t_javame_generator::generate_deserialize_set_element(ostream& out,
t_set* tset,
string prefix) {
string elem = tmp("_elem");
@ -2565,7 +2565,7 @@ void t_javame_generator::generate_deserialize_set_element(ofstream& out,
/**
* Deserializes a list element
*/
void t_javame_generator::generate_deserialize_list_element(ofstream& out,
void t_javame_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix) {
string elem = tmp("_elem");
@ -2584,7 +2584,7 @@ void t_javame_generator::generate_deserialize_list_element(ofstream& out,
* @param tfield The field to serialize
* @param prefix Name to prepend to field name
*/
void t_javame_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_javame_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
// Do nothing for void types
@ -2609,7 +2609,7 @@ void t_javame_generator::generate_serialize_field(ofstream& out, t_field* tfield
throw "compiler error: cannot serialize void field in a struct: " + name;
break;
case t_base_type::TYPE_STRING:
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "writeBinary(" << name << ");";
} else {
out << "writeString(" << name << ");";
@ -2654,7 +2654,7 @@ void t_javame_generator::generate_serialize_field(ofstream& out, t_field* tfield
* @param tstruct The struct to serialize
* @param prefix String prefix to attach to all fields
*/
void t_javame_generator::generate_serialize_struct(ofstream& out,
void t_javame_generator::generate_serialize_struct(ostream& out,
t_struct* tstruct,
string prefix) {
(void)tstruct;
@ -2667,7 +2667,7 @@ void t_javame_generator::generate_serialize_struct(ofstream& out,
* @param ttype The type of container
* @param prefix String prefix for fields
*/
void t_javame_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
if (ttype->is_map()) {
@ -2733,7 +2733,7 @@ void t_javame_generator::generate_serialize_container(ofstream& out, t_type* tty
/**
* Serializes the members of a map.
*/
void t_javame_generator::generate_serialize_map_element(ofstream& out,
void t_javame_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string iter,
string map) {
@ -2747,7 +2747,7 @@ void t_javame_generator::generate_serialize_map_element(ofstream& out,
/**
* Serializes the members of a set.
*/
void t_javame_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_javame_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
@ -2755,7 +2755,7 @@ void t_javame_generator::generate_serialize_set_element(ofstream& out, t_set* ts
/**
* Serializes the members of a list.
*/
void t_javame_generator::generate_serialize_list_element(ofstream& out,
void t_javame_generator::generate_serialize_list_element(ostream& out,
t_list* tlist,
string iter) {
t_field efield(tlist->get_elem_type(), iter);
@ -2847,7 +2847,7 @@ string t_javame_generator::declare_field(t_field* tfield, bool init) {
if (init) {
t_type* ttype = get_true_type(tfield->get_type());
if (ttype->is_base_type() && tfield->get_value() != NULL) {
ofstream dummy;
std::ofstream dummy;
result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
} else if (ttype->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@ -2997,11 +2997,11 @@ string t_javame_generator::constant_name(string name) {
return constant_name;
}
void t_javame_generator::generate_java_docstring_comment(ofstream& out, string contents) {
void t_javame_generator::generate_java_docstring_comment(ostream& out, string contents) {
generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
}
void t_javame_generator::generate_java_doc(ofstream& out, t_field* field) {
void t_javame_generator::generate_java_doc(ostream& out, t_field* field) {
if (field->get_type()->is_enum()) {
string combined_message = field->get_doc() + "\n@see " + get_enum_class_name(field->get_type());
generate_java_docstring_comment(out, combined_message);
@ -3013,7 +3013,7 @@ void t_javame_generator::generate_java_doc(ofstream& out, t_field* field) {
/**
* Emits a JavaDoc comment if the provided object has a doc in Thrift
*/
void t_javame_generator::generate_java_doc(ofstream& out, t_doc* tdoc) {
void t_javame_generator::generate_java_doc(ostream& out, t_doc* tdoc) {
if (tdoc->has_doc()) {
generate_java_docstring_comment(out, tdoc->get_doc());
}
@ -3022,7 +3022,7 @@ void t_javame_generator::generate_java_doc(ofstream& out, t_doc* tdoc) {
/**
* Emits a JavaDoc comment if the provided function object has a doc in Thrift
*/
void t_javame_generator::generate_java_doc(ofstream& out, t_function* tfunction) {
void t_javame_generator::generate_java_doc(ostream& out, t_function* tfunction) {
if (tfunction->has_doc()) {
stringstream ss;
ss << tfunction->get_doc();
@ -3039,7 +3039,7 @@ void t_javame_generator::generate_java_doc(ofstream& out, t_function* tfunction)
}
}
void t_javame_generator::generate_deep_copy_container(ofstream& out,
void t_javame_generator::generate_deep_copy_container(ostream& out,
std::string source_name_p1,
std::string source_name_p2,
std::string result_name,
@ -3144,7 +3144,7 @@ void t_javame_generator::generate_deep_copy_container(ofstream& out,
}
} else {
// iterative copy
if (((t_base_type*)elem_type)->is_binary()) {
if (elem_type->is_binary()) {
indent(out) << type_name(elem_type, true, false) << " temp_binary_element = ";
generate_deep_copy_non_container(out,
iterator_element_name,
@ -3169,13 +3169,13 @@ void t_javame_generator::generate_deep_copy_container(ofstream& out,
}
}
void t_javame_generator::generate_deep_copy_non_container(ofstream& out,
void t_javame_generator::generate_deep_copy_non_container(ostream& out,
std::string source_name,
std::string dest_name,
t_type* type) {
if (type->is_base_type() || type->is_enum() || type->is_typedef()) {
// binary fields need to be copied with System.arraycopy
if (((t_base_type*)type)->is_binary()) {
if (type->is_binary()) {
out << "new byte[" << source_name << ".length];" << endl;
indent(out) << "System.arraycopy(" << source_name << ", 0, " << dest_name << ", 0, "
<< source_name << ".length)";
@ -3200,7 +3200,7 @@ std::string t_javame_generator::generate_isset_check(std::string field_name) {
return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
}
void t_javame_generator::generate_isset_set(ofstream& out, t_field* field) {
void t_javame_generator::generate_isset_set(ostream& out, t_field* field) {
if (!type_can_be_null(field->get_type())) {
indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(true);"
<< endl;
@ -3216,12 +3216,12 @@ std::string t_javame_generator::get_enum_class_name(t_type* type) {
return package + type->get_name();
}
void t_javame_generator::generate_struct_desc(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_struct_desc(ostream& out, t_struct* tstruct) {
indent(out) << "private static final TStruct STRUCT_DESC = new TStruct(\"" << tstruct->get_name()
<< "\");" << endl;
}
void t_javame_generator::generate_field_descs(ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_field_descs(ostream& out, t_struct* tstruct) {
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
@ -3245,7 +3245,7 @@ bool t_javame_generator::has_bit_vector(t_struct* tstruct) {
return false;
}
void t_javame_generator::generate_java_struct_clear(std::ofstream& out, t_struct* tstruct) {
void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) {
indent(out) << "public void clear() {" << endl;
const vector<t_field*>& members = tstruct->get_members();

File diff suppressed because it is too large Load diff

View file

@ -89,7 +89,7 @@ public:
private:
bool should_merge_includes_;
std::ofstream f_json_;
ofstream_with_content_based_conditional_update f_json_;
std::stack<bool> comma_needed_;
template <typename T>
@ -264,6 +264,15 @@ void t_json_generator::write_type_spec(t_type* ttype) {
write_string(get_type_name(ttype));
if (ttype->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
for (map<string, string>::iterator it = ttype->annotations_.begin(); it != ttype->annotations_.end(); ++it) {
write_key_and_string(it->first, it->second);
}
end_object();
}
if (ttype->is_struct() || ttype->is_xception()) {
write_key_and_string("class", get_qualified_name(ttype));
} else if (ttype->is_map()) {
@ -273,10 +282,14 @@ void t_json_generator::write_type_spec(t_type* ttype) {
write_key_and_string("valueTypeId", get_type_name(vtype));
write_type_spec_object("keyType", ktype);
write_type_spec_object("valueType", vtype);
} else if (ttype->is_list() || ttype->is_set()) {
} else if (ttype->is_list()) {
t_type* etype = ((t_list*)ttype)->get_elem_type();
write_key_and_string("elemTypeId", get_type_name(etype));
write_type_spec_object("elemType", etype);
} else if (ttype->is_set()) {
t_type* etype = ((t_set*)ttype)->get_elem_type();
write_key_and_string("elemTypeId", get_type_name(etype));
write_type_spec_object("elemType", etype);
}
}
@ -441,6 +454,14 @@ void t_json_generator::generate_typedef(t_typedef* ttypedef) {
if (ttypedef->has_doc()) {
write_key_and_string("doc", ttypedef->get_doc());
}
if (ttypedef->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
for (map<string, string>::iterator it = ttypedef->annotations_.begin(); it != ttypedef->annotations_.end(); ++it) {
write_key_and_string(it->first, it->second);
}
end_object();
}
end_object();
}
@ -489,8 +510,8 @@ void t_json_generator::write_const_value(t_const_value* value, bool should_force
case t_const_value::CV_MAP: {
start_object(NO_INDENT);
std::map<t_const_value*, t_const_value*> map = value->get_map();
std::map<t_const_value*, t_const_value*>::iterator mit;
std::map<t_const_value*, t_const_value*, t_const_value::value_compare> map = value->get_map();
std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::iterator mit;
for (mit = map.begin(); mit != map.end(); ++mit) {
write_comma_if_needed();
f_json_ << indent();
@ -540,6 +561,15 @@ void t_json_generator::generate_enum(t_enum* tenum) {
write_key_and_string("doc", tenum->get_doc());
}
if (tenum->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
for (map<string, string>::iterator it = tenum->annotations_.begin(); it != tenum->annotations_.end(); ++it) {
write_key_and_string(it->first, it->second);
}
end_object();
}
write_key_and("members");
start_array();
vector<t_enum_value*> values = tenum->get_constants();
@ -570,6 +600,15 @@ void t_json_generator::generate_struct(t_struct* tstruct) {
write_key_and_string("doc", tstruct->get_doc());
}
if (tstruct->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
for (map<string, string>::iterator it = tstruct->annotations_.begin(); it != tstruct->annotations_.end(); ++it) {
write_key_and_string(it->first, it->second);
}
end_object();
}
write_key_and_bool("isException", tstruct->is_xception());
write_key_and_bool("isUnion", tstruct->is_union());
@ -601,6 +640,15 @@ void t_json_generator::generate_service(t_service* tservice) {
write_key_and_string("doc", tservice->get_doc());
}
if (tservice->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
for (map<string, string>::iterator it = tservice->annotations_.begin(); it != tservice->annotations_.end(); ++it) {
write_key_and_string(it->first, it->second);
}
end_object();
}
write_key_and("functions");
start_array();
vector<t_function*> functions = tservice->get_functions();
@ -629,6 +677,15 @@ void t_json_generator::generate_function(t_function* tfunc) {
write_key_and_string("doc", tfunc->get_doc());
}
if (tfunc->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
for (map<string, string>::iterator it = tfunc->annotations_.begin(); it != tfunc->annotations_.end(); ++it) {
write_key_and_string(it->first, it->second);
}
end_object();
}
write_key_and("arguments");
start_array();
vector<t_field*> members = tfunc->get_arglist()->get_members();
@ -666,6 +723,15 @@ void t_json_generator::generate_field(t_field* field) {
write_key_and_string("doc", field->get_doc());
}
if (field->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
for (map<string, string>::iterator it = field->annotations_.begin(); it != field->annotations_.end(); ++it) {
write_key_and_string(it->first, it->second);
}
end_object();
}
write_key_and("required");
switch (field->get_req()) {
case t_field::T_REQUIRED:

View file

@ -21,7 +21,7 @@
#include "thrift/platform.h"
#include "thrift/generate/t_oop_generator.h"
using std::ofstream;
using std::ostream;
using std::string;
using std::vector;
using std::map;
@ -80,65 +80,65 @@ private:
/**
* Struct-level generation functions
*/
void generate_lua_struct_definition(std::ofstream& out,
void generate_lua_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false);
void generate_lua_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_lua_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_lua_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_lua_struct_writer(std::ostream& out, t_struct* tstruct);
/**
* Service-level generation functions
*/
void generate_service_client(std::ofstream& out, t_service* tservice);
void generate_service_interface(std::ofstream& out, t_service* tservice);
void generate_service_processor(std::ofstream& out, t_service* tservice);
void generate_process_function(std::ofstream& out, t_service* tservice, t_function* tfunction);
void generate_service_helpers(ofstream& out, t_service* tservice);
void generate_function_helpers(ofstream& out, t_function* tfunction);
void generate_service_client(std::ostream& out, t_service* tservice);
void generate_service_interface(std::ostream& out, t_service* tservice);
void generate_service_processor(std::ostream& out, t_service* tservice);
void generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction);
void generate_service_helpers(ostream& out, t_service* tservice);
void generate_function_helpers(ostream& out, t_function* tfunction);
/**
* Deserialization (Read)
*/
void generate_deserialize_field(std::ofstream& out,
void generate_deserialize_field(std::ostream& out,
t_field* tfield,
bool local,
std::string prefix = "");
void generate_deserialize_struct(std::ofstream& out,
void generate_deserialize_struct(std::ostream& out,
t_struct* tstruct,
bool local,
std::string prefix = "");
void generate_deserialize_container(std::ofstream& out,
void generate_deserialize_container(std::ostream& out,
t_type* ttype,
bool local,
std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
/**
* Serialization (Write)
*/
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string kiter,
std::string viter);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
/**
* Helper rendering functions
@ -159,9 +159,9 @@ private:
/**
* File streams
*/
std::ofstream f_types_;
std::ofstream f_consts_;
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_types_;
ofstream_with_content_based_conditional_update f_consts_;
ofstream_with_content_based_conditional_update f_service_;
};
/**
@ -276,8 +276,8 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end();) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -308,8 +308,8 @@ string t_lua_generator::render_const_value(t_type* type, t_const_value* value) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end();) {
indent(out) << "[" << render_const_value(ktype, v_iter->first)
<< "] = " << render_const_value(vtype, v_iter->second);
@ -366,7 +366,7 @@ void t_lua_generator::generate_xception(t_struct* txception) {
/**
* Generate a thrift struct or exception (lua table)
*/
void t_lua_generator::generate_lua_struct_definition(ofstream& out,
void t_lua_generator::generate_lua_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception) {
vector<t_field*>::const_iterator m_iter;
@ -402,7 +402,7 @@ void t_lua_generator::generate_lua_struct_definition(ofstream& out,
/**
* Generate a struct/exception reader
*/
void t_lua_generator::generate_lua_struct_reader(ofstream& out, t_struct* tstruct) {
void t_lua_generator::generate_lua_struct_reader(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -459,7 +459,7 @@ void t_lua_generator::generate_lua_struct_reader(ofstream& out, t_struct* tstruc
/**
* Generate a struct/exception writer
*/
void t_lua_generator::generate_lua_struct_writer(ofstream& out, t_struct* tstruct) {
void t_lua_generator::generate_lua_struct_writer(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -527,7 +527,7 @@ void t_lua_generator::generate_service(t_service* tservice) {
f_service_.close();
}
void t_lua_generator::generate_service_interface(ofstream& out, t_service* tservice) {
void t_lua_generator::generate_service_interface(ostream& out, t_service* tservice) {
string classname = tservice->get_name() + "Iface";
t_service* extends_s = tservice->get_extends();
@ -541,7 +541,7 @@ void t_lua_generator::generate_service_interface(ofstream& out, t_service* tserv
out << " __type = '" << classname << "'" << endl << "}" << endl << endl;
}
void t_lua_generator::generate_service_client(ofstream& out, t_service* tservice) {
void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) {
string classname = tservice->get_name() + "Client";
t_service* extends_s = tservice->get_extends();
@ -637,14 +637,14 @@ void t_lua_generator::generate_service_client(ofstream& out, t_service* tservice
}
}
void t_lua_generator::generate_service_processor(ofstream& out, t_service* tservice) {
void t_lua_generator::generate_service_processor(ostream& out, t_service* tservice) {
string classname = tservice->get_name() + "Processor";
t_service* extends_s = tservice->get_extends();
// Define processor table
out << endl << classname << " = __TObject.new(";
if (extends_s != NULL) {
out << extends_s << "Processor" << endl;
out << extends_s->get_name() << "Processor" << endl;
} else {
out << "__TProcessor" << endl;
}
@ -680,7 +680,7 @@ void t_lua_generator::generate_service_processor(ofstream& out, t_service* tserv
}
}
void t_lua_generator::generate_process_function(ofstream& out,
void t_lua_generator::generate_process_function(ostream& out,
t_service* tservice,
t_function* tfunction) {
string classname = tservice->get_name() + "Processor";
@ -731,7 +731,7 @@ void t_lua_generator::generate_process_function(ofstream& out,
}
// Service helpers
void t_lua_generator::generate_service_helpers(ofstream& out, t_service* tservice) {
void t_lua_generator::generate_service_helpers(ostream& out, t_service* tservice) {
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::iterator f_iter;
@ -743,7 +743,7 @@ void t_lua_generator::generate_service_helpers(ofstream& out, t_service* tservic
}
}
void t_lua_generator::generate_function_helpers(ofstream& out, t_function* tfunction) {
void t_lua_generator::generate_function_helpers(ostream& out, t_function* tfunction) {
if (!tfunction->is_oneway()) {
t_struct result(program_, tfunction->get_name() + "_result");
t_field success(tfunction->get_returntype(), "success", 0);
@ -764,7 +764,7 @@ void t_lua_generator::generate_function_helpers(ofstream& out, t_function* tfunc
/**
* Deserialize (Read)
*/
void t_lua_generator::generate_deserialize_field(ofstream& out,
void t_lua_generator::generate_deserialize_field(ostream& out,
t_field* tfield,
bool local,
string prefix) {
@ -825,7 +825,7 @@ void t_lua_generator::generate_deserialize_field(ofstream& out,
}
}
void t_lua_generator::generate_deserialize_struct(ofstream& out,
void t_lua_generator::generate_deserialize_struct(ostream& out,
t_struct* tstruct,
bool local,
string prefix) {
@ -833,7 +833,7 @@ void t_lua_generator::generate_deserialize_struct(ofstream& out,
<< endl << indent() << prefix << ":read(iprot)" << endl;
}
void t_lua_generator::generate_deserialize_container(ofstream& out,
void t_lua_generator::generate_deserialize_container(ostream& out,
t_type* ttype,
bool local,
string prefix) {
@ -883,7 +883,7 @@ void t_lua_generator::generate_deserialize_container(ofstream& out,
}
}
void t_lua_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
void t_lua_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
// A map is represented by a table indexable by any lua type
string key = tmp("_key");
string val = tmp("_val");
@ -896,7 +896,7 @@ void t_lua_generator::generate_deserialize_map_element(ofstream& out, t_map* tma
indent(out) << prefix << "[" << key << "] = " << val << endl;
}
void t_lua_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
void t_lua_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
// A set is represented by a table indexed by the value
string elem = tmp("_elem");
t_field felem(tset->get_elem_type(), elem);
@ -906,7 +906,7 @@ void t_lua_generator::generate_deserialize_set_element(ofstream& out, t_set* tse
indent(out) << prefix << "[" << elem << "] = " << elem << endl;
}
void t_lua_generator::generate_deserialize_list_element(ofstream& out,
void t_lua_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix) {
// A list is represented by a table indexed by integer values
@ -922,7 +922,7 @@ void t_lua_generator::generate_deserialize_list_element(ofstream& out,
/**
* Serialize (Write)
*/
void t_lua_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_lua_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
string name = prefix + tfield->get_name();
@ -979,12 +979,12 @@ void t_lua_generator::generate_serialize_field(ofstream& out, t_field* tfield, s
}
}
void t_lua_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_lua_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
(void)tstruct;
indent(out) << prefix << ":write(oprot)" << endl;
}
void t_lua_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_lua_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
// Begin writing
if (ttype->is_map()) {
indent(out) << "oprot:writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
@ -1034,7 +1034,7 @@ void t_lua_generator::generate_serialize_container(ofstream& out, t_type* ttype,
}
}
void t_lua_generator::generate_serialize_map_element(ofstream& out,
void t_lua_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string kiter,
string viter) {
@ -1045,12 +1045,12 @@ void t_lua_generator::generate_serialize_map_element(ofstream& out,
generate_serialize_field(out, &vfield, "");
}
void t_lua_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_lua_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}
void t_lua_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
void t_lua_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
t_field efield(tlist->get_elem_type(), iter);
generate_serialize_field(out, &efield, "");
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,137 @@
#include <cassert>
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
#include <cctype>
#include <stdlib.h>
#include <sys/stat.h>
#include <sstream>
#include "thrift/platform.h"
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
using std::vector;
static const string endl = "\n"; // avoid ostream << std::endl flushes
class t_netcore_generator : public t_oop_generator
{
struct member_mapping_scope
{
public:
member_mapping_scope() : scope_member(0) { }
void* scope_member;
map<string, string> mapping_table;
};
public:
t_netcore_generator(t_program* program, const map<string, string>& parsed_options, const string& option_string);
bool is_wcf_enabled() const;
bool is_nullable_enabled() const;
bool is_hashcode_enabled() const;
bool is_serialize_enabled() const;
bool is_union_enabled() const;
map<string, int> get_keywords_list() const;
// overrides
void init_generator();
void close_generator();
void generate_consts(vector<t_const*> consts);
void generate_consts(ostream& out, vector<t_const*> consts);
void generate_typedef(t_typedef* ttypedef);
void generate_enum(t_enum* tenum);
void generate_enum(ostream& out, t_enum* tenum);
void generate_struct(t_struct* tstruct);
void generate_xception(t_struct* txception);
void generate_service(t_service* tservice);
void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
void generate_netcore_property(ostream& out, t_field* tfield, bool isPublic, bool includeIsset = true, string fieldPrefix = "");
bool print_const_value(ostream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval = false, bool needtype = false);
string render_const_value(ostream& out, string name, t_type* type, t_const_value* value);
void print_const_constructor(ostream& out, vector<t_const*> consts);
void print_const_def_value(ostream& out, string name, t_type* type, t_const_value* value);
void generate_netcore_struct(t_struct* tstruct, bool is_exception);
void generate_netcore_union(t_struct* tunion);
void generate_netcore_struct_definition(ostream& out, t_struct* tstruct, bool is_xception = false, bool in_class = false, bool is_result = false);
void generate_netcore_union_definition(ostream& out, t_struct* tunion);
void generate_netcore_union_class(ostream& out, t_struct* tunion, t_field* tfield);
void generate_netcore_wcffault(ostream& out, t_struct* tstruct);
void generate_netcore_struct_reader(ostream& out, t_struct* tstruct);
void generate_netcore_struct_result_writer(ostream& out, t_struct* tstruct);
void generate_netcore_struct_writer(ostream& out, t_struct* tstruct);
void generate_netcore_struct_tostring(ostream& out, t_struct* tstruct);
void generate_netcore_struct_equals(ostream& out, t_struct* tstruct);
void generate_netcore_struct_hashcode(ostream& out, t_struct* tstruct);
void generate_netcore_union_reader(ostream& out, t_struct* tunion);
void generate_function_helpers(ostream& out, t_function* tfunction);
void generate_service_interface(ostream& out, t_service* tservice);
void generate_service_helpers(ostream& out, t_service* tservice);
void generate_service_client(ostream& out, t_service* tservice);
void generate_service_server(ostream& out, t_service* tservice);
void generate_process_function_async(ostream& out, t_service* tservice, t_function* function);
void generate_deserialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_propertyless = false);
void generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
void generate_deserialize_container(ostream& out, t_type* ttype, string prefix = "");
void generate_deserialize_set_element(ostream& out, t_set* tset, string prefix = "");
void generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix = "");
void generate_deserialize_list_element(ostream& out, t_list* list, string prefix = "");
void generate_serialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_element = false, bool is_propertyless = false);
void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
void generate_serialize_map_element(ostream& out, t_map* tmap, string iter, string map);
void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
void generate_netcore_doc(ostream& out, t_field* field);
void generate_netcore_doc(ostream& out, t_doc* tdoc);
void generate_netcore_doc(ostream& out, t_function* tdoc);
void generate_netcore_docstring_comment(ostream& out, string contents);
void docstring_comment(ostream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end);
void start_netcore_namespace(ostream& out);
void end_netcore_namespace(ostream& out);
string netcore_type_usings() const;
string netcore_thrift_usings() const;
string type_name(t_type* ttype, bool in_countainer = false, bool in_init = false, bool in_param = false, bool is_required = false);
string base_type_name(t_base_type* tbase, bool in_container = false, bool in_param = false, bool is_required = false);
string declare_field(t_field* tfield, bool init = false, string prefix = "");
string function_signature_async(t_function* tfunction, string prefix = "");
string function_signature(t_function* tfunction, string prefix = "");
string argument_list(t_struct* tstruct);
string type_to_enum(t_type* ttype);
string prop_name(t_field* tfield, bool suppress_mapping = false);
string get_enum_class_name(t_type* type);
private:
string namespace_name_;
string namespace_dir_;
bool nullable_;
bool union_;
bool hashcode_;
bool serialize_;
bool wcf_;
string wcf_namespace_;
map<string, int> netcore_keywords;
vector<member_mapping_scope> member_mapping_scopes;
void init_keywords();
string normalize_name(string name);
string make_valid_csharp_identifier(string const& fromName);
void prepare_member_name_mapping(t_struct* tstruct);
void prepare_member_name_mapping(void* scope, const vector<t_field*>& members, const string& structname);
void cleanup_member_name_mapping(void* scope);
string get_mapped_member_name(string oldname);
};

View file

@ -32,7 +32,7 @@
using std::ios;
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -90,16 +90,16 @@ public:
*/
void generate_ocaml_struct(t_struct* tstruct, bool is_exception);
void generate_ocaml_struct_definition(std::ofstream& out,
void generate_ocaml_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false);
void generate_ocaml_struct_member(std::ofstream& out, string tname, t_field* tmember);
void generate_ocaml_struct_sig(std::ofstream& out, t_struct* tstruct, bool is_exception);
void generate_ocaml_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_ocaml_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_ocaml_struct_member(std::ostream& out, string tname, t_field* tmember);
void generate_ocaml_struct_sig(std::ostream& out, t_struct* tstruct, bool is_exception);
void generate_ocaml_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_ocaml_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_ocaml_function_helpers(t_function* tfunction);
void generate_ocaml_method_copy(std::ofstream& out, const vector<t_field*>& members);
void generate_ocaml_member_copy(std::ofstream& out, t_field* member);
void generate_ocaml_method_copy(std::ostream& out, const vector<t_field*>& members);
void generate_ocaml_member_copy(std::ostream& out, t_field* member);
/**
* Service-level generation functions
@ -115,33 +115,33 @@ public:
* Serialization constructs
*/
void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix);
void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix);
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct);
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct);
void generate_deserialize_container(std::ofstream& out, t_type* ttype);
void generate_deserialize_container(std::ostream& out, t_type* ttype);
void generate_deserialize_set_element(std::ofstream& out, t_set* tset);
void generate_deserialize_set_element(std::ostream& out, t_set* tset);
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
void generate_deserialize_type(std::ofstream& out, t_type* type);
void generate_deserialize_type(std::ostream& out, t_type* type);
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string name = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string name = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string kiter,
std::string viter);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
/**
* Helper rendering functions
@ -161,12 +161,12 @@ private:
* File streams
*/
std::ofstream f_types_;
std::ofstream f_consts_;
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_types_;
ofstream_with_content_based_conditional_update f_consts_;
ofstream_with_content_based_conditional_update f_service_;
std::ofstream f_types_i_;
std::ofstream f_service_i_;
ofstream_with_content_based_conditional_update f_types_i_;
ofstream_with_content_based_conditional_update f_service_i_;
};
/*
@ -401,8 +401,8 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value)
indent_up();
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -425,8 +425,8 @@ string t_ocaml_generator::render_const_value(t_type* type, t_const_value* value)
} else if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
string hm = tmp("_hm");
out << endl;
indent_up();
@ -499,7 +499,7 @@ void t_ocaml_generator::generate_ocaml_struct(t_struct* tstruct, bool is_excepti
generate_ocaml_struct_sig(f_types_i_, tstruct, is_exception);
}
void t_ocaml_generator::generate_ocaml_method_copy(ofstream& out, const vector<t_field*>& members) {
void t_ocaml_generator::generate_ocaml_method_copy(ostream& out, const vector<t_field*>& members) {
vector<t_field*>::const_iterator m_iter;
/* Create a copy of the current object */
@ -555,7 +555,7 @@ string t_ocaml_generator::struct_member_copy_of(t_type* type, string what) {
return what;
}
void t_ocaml_generator::generate_ocaml_member_copy(ofstream& out, t_field* tmember) {
void t_ocaml_generator::generate_ocaml_member_copy(ostream& out, t_field* tmember) {
string mname = decapitalize(tmember->get_name());
t_type* type = get_true_type(tmember->get_type());
@ -576,7 +576,7 @@ void t_ocaml_generator::generate_ocaml_member_copy(ofstream& out, t_field* tmemb
*
* @param tstruct The struct definition
*/
void t_ocaml_generator::generate_ocaml_struct_definition(ofstream& out,
void t_ocaml_generator::generate_ocaml_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception) {
const vector<t_field*>& members = tstruct->get_members();
@ -611,7 +611,7 @@ void t_ocaml_generator::generate_ocaml_struct_definition(ofstream& out,
* @param tname Name of the parent structure for the member
* @param tmember Member definition
*/
void t_ocaml_generator::generate_ocaml_struct_member(ofstream& out,
void t_ocaml_generator::generate_ocaml_struct_member(ostream& out,
string tname,
t_field* tmember) {
string x = tmp("_x");
@ -713,7 +713,7 @@ bool t_ocaml_generator::struct_member_default_cheaply_comparable(t_field* tmembe
*
* @param tstruct The struct definition
*/
void t_ocaml_generator::generate_ocaml_struct_sig(ofstream& out,
void t_ocaml_generator::generate_ocaml_struct_sig(ostream& out,
t_struct* tstruct,
bool is_exception) {
const vector<t_field*>& members = tstruct->get_members();
@ -752,7 +752,7 @@ void t_ocaml_generator::generate_ocaml_struct_sig(ofstream& out,
/**
* Generates the read method for a struct
*/
void t_ocaml_generator::generate_ocaml_struct_reader(ofstream& out, t_struct* tstruct) {
void t_ocaml_generator::generate_ocaml_struct_reader(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
string sname = type_name(tstruct);
@ -812,7 +812,7 @@ void t_ocaml_generator::generate_ocaml_struct_reader(ofstream& out, t_struct* ts
indent_down();
}
void t_ocaml_generator::generate_ocaml_struct_writer(ofstream& out, t_struct* tstruct) {
void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tstruct) {
string name = tstruct->get_name();
const vector<t_field*>& fields = tstruct->get_sorted_members();
vector<t_field*>::const_iterator f_iter;
@ -1309,7 +1309,7 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio
/**
* Deserializes a field of any type.
*/
void t_ocaml_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_ocaml_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = tfield->get_type();
string name = decapitalize(tfield->get_name());
@ -1321,7 +1321,7 @@ void t_ocaml_generator::generate_deserialize_field(ofstream& out, t_field* tfiel
/**
* Deserializes a field of any type.
*/
void t_ocaml_generator::generate_deserialize_type(ofstream& out, t_type* type) {
void t_ocaml_generator::generate_deserialize_type(ostream& out, t_type* type) {
type = get_true_type(type);
if (type->is_void()) {
@ -1374,7 +1374,7 @@ void t_ocaml_generator::generate_deserialize_type(ofstream& out, t_type* type) {
/**
* Generates an unserializer for a struct, calling read()
*/
void t_ocaml_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct) {
void t_ocaml_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct) {
string prefix = "";
t_program* program = tstruct->get_program();
if (program != NULL && program != program_) {
@ -1388,7 +1388,7 @@ void t_ocaml_generator::generate_deserialize_struct(ofstream& out, t_struct* tst
* Serialize a container by writing out the header followed by
* data and then a footer.
*/
void t_ocaml_generator::generate_deserialize_container(ofstream& out, t_type* ttype) {
void t_ocaml_generator::generate_deserialize_container(ostream& out, t_type* ttype) {
string size = tmp("_size");
string ktype = tmp("_ktype");
string vtype = tmp("_vtype");
@ -1454,7 +1454,7 @@ void t_ocaml_generator::generate_deserialize_container(ofstream& out, t_type* tt
* @param tfield The field to serialize
* @param prefix Name to prepend to field name
*/
void t_ocaml_generator::generate_serialize_field(ofstream& out, t_field* tfield, string name) {
void t_ocaml_generator::generate_serialize_field(ostream& out, t_field* tfield, string name) {
t_type* type = get_true_type(tfield->get_type());
// Do nothing for void types
@ -1523,12 +1523,12 @@ void t_ocaml_generator::generate_serialize_field(ofstream& out, t_field* tfield,
* @param tstruct The struct to serialize
* @param prefix String prefix to attach to all fields
*/
void t_ocaml_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_ocaml_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
(void)tstruct;
indent(out) << prefix << "#write(oprot)";
}
void t_ocaml_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_ocaml_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
if (ttype->is_map()) {
indent(out) << "oprot#writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ",";
out << type_to_enum(((t_map*)ttype)->get_val_type()) << ",";
@ -1579,7 +1579,7 @@ void t_ocaml_generator::generate_serialize_container(ofstream& out, t_type* ttyp
* Serializes the members of a map.
*
*/
void t_ocaml_generator::generate_serialize_map_element(ofstream& out,
void t_ocaml_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string kiter,
string viter) {
@ -1593,7 +1593,7 @@ void t_ocaml_generator::generate_serialize_map_element(ofstream& out,
/**
* Serializes the members of a set.
*/
void t_ocaml_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_ocaml_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield);
}
@ -1601,7 +1601,7 @@ void t_ocaml_generator::generate_serialize_set_element(ofstream& out, t_set* tse
/**
* Serializes the members of a list.
*/
void t_ocaml_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
void t_ocaml_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
t_field efield(tlist->get_elem_type(), iter);
generate_serialize_field(out, &efield);
}

View file

@ -65,11 +65,11 @@ public:
return package + type->get_name();
}
virtual void generate_java_docstring_comment(std::ofstream& out, std::string contents) {
virtual void generate_java_docstring_comment(std::ostream& out, std::string contents) {
generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
}
virtual void generate_java_doc(std::ofstream& out, t_field* field) {
virtual void generate_java_doc(std::ostream& out, t_field* field) {
if (field->get_type()->is_enum()) {
std::string combined_message = field->get_doc() + "\n@see "
+ get_enum_class_name(field->get_type());
@ -82,7 +82,7 @@ public:
/**
* Emits a JavaDoc comment if the provided object has a doc in Thrift
*/
virtual void generate_java_doc(std::ofstream& out, t_doc* tdoc) {
virtual void generate_java_doc(std::ostream& out, t_doc* tdoc) {
if (tdoc->has_doc()) {
generate_java_docstring_comment(out, tdoc->get_doc());
}
@ -91,7 +91,7 @@ public:
/**
* Emits a JavaDoc comment if the provided function object has a doc in Thrift
*/
virtual void generate_java_doc(std::ofstream& out, t_function* tfunction) {
virtual void generate_java_doc(std::ostream& out, t_function* tfunction) {
if (tfunction->has_doc()) {
std::stringstream ss;
ss << tfunction->get_doc();

View file

@ -31,7 +31,7 @@
#include "thrift/generate/t_oop_generator.h"
using std::map;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::string;
using std::stringstream;
@ -48,7 +48,7 @@ public:
t_perl_generator(t_program* program,
const std::map<std::string, std::string>& parsed_options,
const std::string& option_string)
: t_oop_generator(program) {
: t_oop_generator(program), f_types_use_includes_emitted_(false) {
(void)option_string;
std::map<std::string, std::string>::const_iterator iter;
@ -87,11 +87,11 @@ public:
*/
void generate_perl_struct(t_struct* tstruct, bool is_exception);
void generate_perl_struct_definition(std::ofstream& out,
void generate_perl_struct_definition(std::ostream& out,
t_struct* tstruct,
bool is_xception = false);
void generate_perl_struct_reader(std::ofstream& out, t_struct* tstruct);
void generate_perl_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_perl_struct_reader(std::ostream& out, t_struct* tstruct);
void generate_perl_struct_writer(std::ostream& out, t_struct* tstruct);
void generate_perl_function_helpers(t_function* tfunction);
/**
@ -104,42 +104,43 @@ public:
void generate_service_client(t_service* tservice);
void generate_service_processor(t_service* tservice);
void generate_process_function(t_service* tservice, t_function* tfunction);
void generate_use_includes(std::ostream& os, bool& done, t_type *type, bool selfish);
/**
* Serialization constructs
*/
void generate_deserialize_field(std::ofstream& out,
void generate_deserialize_field(std::ostream& out,
t_field* tfield,
std::string prefix = "",
bool inclass = false);
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
void generate_deserialize_list_element(std::ofstream& out,
void generate_deserialize_list_element(std::ostream& out,
t_list* tlist,
std::string prefix = "");
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
void generate_serialize_map_element(std::ofstream& out,
void generate_serialize_map_element(std::ostream& out,
t_map* tmap,
std::string kiter,
std::string viter);
void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
/**
* Helper rendering functions
@ -207,10 +208,12 @@ private:
/**
* File streams
*/
std::ofstream f_types_;
std::ofstream f_consts_;
std::ofstream f_helpers_;
std::ofstream f_service_;
ofstream_with_content_based_conditional_update f_types_;
ofstream_with_content_based_conditional_update f_consts_;
ofstream_with_content_based_conditional_update f_helpers_;
ofstream_with_content_based_conditional_update f_service_;
bool f_types_use_includes_emitted_;
};
/**
@ -252,10 +255,12 @@ void t_perl_generator::init_generator() {
string t_perl_generator::perl_includes() {
string inc;
inc = "require 5.6.0;\n";
inc = "use 5.10.0;\n";
inc += "use strict;\n";
inc += "use warnings;\n";
inc += "use Thrift;\n\n";
inc += "use Thrift::Exception;\n";
inc += "use Thrift::MessageType;\n";
inc += "use Thrift::Type;\n\n";
return inc;
}
@ -351,10 +356,11 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value)
} else if (type->is_struct() || type->is_xception()) {
out << "new " << perl_namespace(type->get_program()) << type->get_name() << "({" << endl;
indent_up();
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -365,29 +371,30 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value)
if (field_type == NULL) {
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
}
out << render_const_value(g_type_string, v_iter->first);
indent(out) << render_const_value(g_type_string, v_iter->first);
out << " => ";
out << render_const_value(field_type, v_iter->second);
out << ",";
out << endl;
}
out << "})";
indent_down();
indent(out) << "})";
} else if (type->is_map()) {
t_type* ktype = ((t_map*)type)->get_key_type();
t_type* vtype = ((t_map*)type)->get_val_type();
out << "{" << endl;
indent_up();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
out << render_const_value(ktype, v_iter->first);
indent(out) << render_const_value(ktype, v_iter->first);
out << " => ";
out << render_const_value(vtype, v_iter->second);
out << "," << endl;
}
out << "}";
indent_down();
indent(out) << "}";
} else if (type->is_list() || type->is_set()) {
t_type* etype;
if (type->is_list()) {
@ -396,17 +403,20 @@ string t_perl_generator::render_const_value(t_type* type, t_const_value* value)
etype = ((t_set*)type)->get_elem_type();
}
out << "[" << endl;
indent_up();
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
out << render_const_value(etype, *v_iter);
indent(out) << render_const_value(etype, *v_iter);
if (type->is_set()) {
out << " => 1";
}
out << "," << endl;
}
out << "]";
indent_down();
indent(out) << "]";
}
return out.str();
}
@ -432,6 +442,7 @@ void t_perl_generator::generate_xception(t_struct* txception) {
* Structs can be normal or exceptions.
*/
void t_perl_generator::generate_perl_struct(t_struct* tstruct, bool is_exception) {
generate_use_includes(f_types_, f_types_use_includes_emitted_, tstruct, false);
generate_perl_struct_definition(f_types_, tstruct, is_exception);
}
@ -442,7 +453,7 @@ void t_perl_generator::generate_perl_struct(t_struct* tstruct, bool is_exception
*
* @param tstruct The struct definition
*/
void t_perl_generator::generate_perl_struct_definition(ofstream& out,
void t_perl_generator::generate_perl_struct_definition(ostream& out,
t_struct* tstruct,
bool is_exception) {
const vector<t_field*>& members = tstruct->get_members();
@ -520,7 +531,7 @@ void t_perl_generator::generate_perl_struct_definition(ofstream& out,
/**
* Generates the read() method for a struct
*/
void t_perl_generator::generate_perl_struct_reader(ofstream& out, t_struct* tstruct) {
void t_perl_generator::generate_perl_struct_reader(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@ -542,7 +553,7 @@ void t_perl_generator::generate_perl_struct_reader(ofstream& out, t_struct* tstr
indent(out) << "$xfer += $input->readFieldBegin(\\$fname, \\$ftype, \\$fid);" << endl;
// Check for field STOP marker and break
indent(out) << "if ($ftype == TType::STOP) {" << endl;
indent(out) << "if ($ftype == Thrift::TType::STOP) {" << endl;
indent_up();
indent(out) << "last;" << endl;
indent_down();
@ -590,7 +601,7 @@ void t_perl_generator::generate_perl_struct_reader(ofstream& out, t_struct* tstr
/**
* Generates the write() method for a struct
*/
void t_perl_generator::generate_perl_struct_writer(ofstream& out, t_struct* tstruct) {
void t_perl_generator::generate_perl_struct_writer(ostream& out, t_struct* tstruct) {
string name = tstruct->get_name();
const vector<t_field*>& fields = tstruct->get_sorted_members();
vector<t_field*>::const_iterator f_iter;
@ -629,6 +640,31 @@ void t_perl_generator::generate_perl_struct_writer(ofstream& out, t_struct* tstr
out << indent() << "}" << endl << endl;
}
/**
* Generates use clauses for included entities
*
* @param os The output stream
* @param done A flag reference to debounce the action
* @param type The type being processed
* @param selfish Flag to indicate if the current namespace types should be "use"d as well.
*/
void t_perl_generator::generate_use_includes(std::ostream& os, bool& done, t_type *type, bool selfish) {
t_program *current = type->get_program();
if (current && !done) {
std::vector<t_program*>& currInc = current->get_includes();
std::vector<t_program*>::size_type numInc = currInc.size();
if (selfish) {
os << "use " << perl_namespace(current) << "Types;" << endl;
}
for (std::vector<t_program*>::size_type i = 0; i < numInc; ++i) {
t_program* incProgram = currInc.at(i);
os << "use " << perl_namespace(incProgram) << "Types;" << endl;
}
os << endl;
done = true;
}
}
/**
* Generates a thrift service.
*
@ -638,11 +674,10 @@ void t_perl_generator::generate_service(t_service* tservice) {
string f_service_name = get_namespace_out_dir() + service_name_ + ".pm";
f_service_.open(f_service_name.c_str());
f_service_ <<
/// "package "<<service_name_<<";"<<endl<<
autogen_comment() << perl_includes();
f_service_ << autogen_comment() << perl_includes();
f_service_ << "use " << perl_namespace(tservice->get_program()) << "Types;" << endl;
bool done = false;
generate_use_includes(f_service_, done, tservice, true);
t_service* extends_s = tservice->get_extends();
if (extends_s != NULL) {
@ -721,11 +756,11 @@ void t_perl_generator::generate_service_processor(t_service* tservice) {
<< "if (!$self->can($methodname)) {" << endl;
indent_up();
f_service_ << indent() << "$input->skip(TType::STRUCT);" << endl << indent()
f_service_ << indent() << "$input->skip(Thrift::TType::STRUCT);" << endl << indent()
<< "$input->readMessageEnd();" << endl << indent()
<< "my $x = new TApplicationException('Function '.$fname.' not implemented.', "
"TApplicationException::UNKNOWN_METHOD);" << endl << indent()
<< "$output->writeMessageBegin($fname, TMessageType::EXCEPTION, $rseqid);" << endl
<< "my $x = new Thrift::TApplicationException('Function '.$fname.' not implemented.', "
"Thrift::TApplicationException::UNKNOWN_METHOD);" << endl << indent()
<< "$output->writeMessageBegin($fname, Thrift::TMessageType::EXCEPTION, $rseqid);" << endl
<< indent() << "$x->write($output);" << endl << indent()
<< "$output->writeMessageEnd();" << endl << indent()
<< "$output->getTransport()->flush();" << endl << indent() << "return;" << endl;
@ -823,8 +858,8 @@ void t_perl_generator::generate_process_function(t_service* tservice, t_function
f_service_ << indent() << "if ($@) {" << endl;
indent_up();
f_service_ << indent() << "$@ =~ s/^\\s+|\\s+$//g;" << endl
<< indent() << "my $err = new TApplicationException(\"Unexpected Exception: \" . $@, TApplicationException::INTERNAL_ERROR);" << endl
<< indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', TMessageType::EXCEPTION, $seqid);" << endl
<< indent() << "my $err = new Thrift::TApplicationException(\"Unexpected Exception: \" . $@, Thrift::TApplicationException::INTERNAL_ERROR);" << endl
<< indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::EXCEPTION, $seqid);" << endl
<< indent() << "$err->write($output);" << endl
<< indent() << "$output->writeMessageEnd();" << endl
<< indent() << "$output->getTransport()->flush();" << endl
@ -843,7 +878,7 @@ void t_perl_generator::generate_process_function(t_service* tservice, t_function
}
// Serialize the reply
f_service_ << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', TMessageType::REPLY, $seqid);" << endl
f_service_ << indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', Thrift::TMessageType::REPLY, $seqid);" << endl
<< indent() << "$result->write($output);" << endl
<< indent() << "$output->writeMessageEnd();" << endl
<< indent() << "$output->getTransport()->flush();" << endl;
@ -1068,7 +1103,7 @@ void t_perl_generator::generate_service_client(t_service* tservice) {
// Serialize the request header
f_service_ << indent() << "$self->{output}->writeMessageBegin('" << (*f_iter)->get_name()
<< "', " << ((*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL")
<< "', " << ((*f_iter)->is_oneway() ? "Thrift::TMessageType::ONEWAY" : "Thrift::TMessageType::CALL")
<< ", $self->{seqid});" << endl;
f_service_ << indent() << "my $args = new " << argsname << "();" << endl;
@ -1104,8 +1139,8 @@ void t_perl_generator::generate_service_client(t_service* tservice) {
<< indent() << "my $mtype = 0;" << endl << endl;
f_service_ << indent() << "$self->{input}->readMessageBegin(\\$fname, \\$mtype, \\$rseqid);"
<< endl << indent() << "if ($mtype == TMessageType::EXCEPTION) {" << endl
<< indent() << " my $x = new TApplicationException();" << endl << indent()
<< endl << indent() << "if ($mtype == Thrift::TMessageType::EXCEPTION) {" << endl
<< indent() << " my $x = new Thrift::TApplicationException();" << endl << indent()
<< " $x->read($self->{input});" << endl << indent()
<< " $self->{input}->readMessageEnd();" << endl << indent() << " die $x;" << endl
<< indent() << "}" << endl;
@ -1148,7 +1183,7 @@ void t_perl_generator::generate_service_client(t_service* tservice) {
/**
* Deserializes a field of any type.
*/
void t_perl_generator::generate_deserialize_field(ofstream& out,
void t_perl_generator::generate_deserialize_field(ostream& out,
t_field* tfield,
string prefix,
bool inclass) {
@ -1221,15 +1256,15 @@ void t_perl_generator::generate_deserialize_field(ofstream& out,
* buffer for deserialization, and that there is a variable protocol which
* is a reference to a TProtocol serialization object.
*/
void t_perl_generator::generate_deserialize_struct(ofstream& out,
void t_perl_generator::generate_deserialize_struct(ostream& out,
t_struct* tstruct,
string prefix) {
out << indent() << "$" << prefix << " = new " << perl_namespace(tstruct->get_program())
<< tstruct->get_name() << "();" << endl << indent() << "$xfer += $" << prefix
out << indent() << "$" << prefix << " = " << perl_namespace(tstruct->get_program())
<< tstruct->get_name() << "->new();" << endl << indent() << "$xfer += $" << prefix
<< "->read($input);" << endl;
}
void t_perl_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
string size = tmp("_size");
@ -1297,7 +1332,7 @@ void t_perl_generator::generate_deserialize_container(ofstream& out, t_type* tty
/**
* Generates code to deserialize a map
*/
void t_perl_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
void t_perl_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
string key = tmp("key");
string val = tmp("val");
t_field fkey(tmap->get_key_type(), key);
@ -1312,7 +1347,7 @@ void t_perl_generator::generate_deserialize_map_element(ofstream& out, t_map* tm
indent(out) << "$" << prefix << "->{$" << key << "} = $" << val << ";" << endl;
}
void t_perl_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
void t_perl_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
string elem = tmp("elem");
t_field felem(tset->get_elem_type(), elem);
@ -1323,7 +1358,7 @@ void t_perl_generator::generate_deserialize_set_element(ofstream& out, t_set* ts
indent(out) << "$" << prefix << "->{$" << elem << "} = 1;" << endl;
}
void t_perl_generator::generate_deserialize_list_element(ofstream& out,
void t_perl_generator::generate_deserialize_list_element(ostream& out,
t_list* tlist,
string prefix) {
string elem = tmp("elem");
@ -1342,7 +1377,7 @@ void t_perl_generator::generate_deserialize_list_element(ofstream& out,
* @param tfield The field to serialize
* @param prefix Name to prepend to field name
*/
void t_perl_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
void t_perl_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
t_type* type = get_true_type(tfield->get_type());
// Do nothing for void types
@ -1413,7 +1448,7 @@ void t_perl_generator::generate_serialize_field(ofstream& out, t_field* tfield,
* @param tstruct The struct to serialize
* @param prefix String prefix to attach to all fields
*/
void t_perl_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
void t_perl_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
(void)tstruct;
indent(out) << "$xfer += $" << prefix << "->write($output);" << endl;
}
@ -1421,7 +1456,7 @@ void t_perl_generator::generate_serialize_struct(ofstream& out, t_struct* tstruc
/**
* Writes out a container
*/
void t_perl_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
scope_up(out);
if (ttype->is_map()) {
@ -1485,7 +1520,7 @@ void t_perl_generator::generate_serialize_container(ofstream& out, t_type* ttype
* Serializes the members of a map.
*
*/
void t_perl_generator::generate_serialize_map_element(ofstream& out,
void t_perl_generator::generate_serialize_map_element(ostream& out,
t_map* tmap,
string kiter,
string viter) {
@ -1499,7 +1534,7 @@ void t_perl_generator::generate_serialize_map_element(ofstream& out,
/**
* Serializes the members of a set.
*/
void t_perl_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
void t_perl_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
t_field efield(tset->get_elem_type(), iter);
generate_serialize_field(out, &efield);
}
@ -1507,7 +1542,7 @@ void t_perl_generator::generate_serialize_set_element(ofstream& out, t_set* tset
/**
* Serializes the members of a list.
*/
void t_perl_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
void t_perl_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
t_field efield(tlist->get_elem_type(), iter);
generate_serialize_field(out, &efield);
}
@ -1616,30 +1651,30 @@ string t_perl_generator::type_to_enum(t_type* type) {
case t_base_type::TYPE_VOID:
throw "NO T_VOID CONSTRUCT";
case t_base_type::TYPE_STRING:
return "TType::STRING";
return "Thrift::TType::STRING";
case t_base_type::TYPE_BOOL:
return "TType::BOOL";
return "Thrift::TType::BOOL";
case t_base_type::TYPE_I8:
return "TType::BYTE";
return "Thrift::TType::BYTE";
case t_base_type::TYPE_I16:
return "TType::I16";
return "Thrift::TType::I16";
case t_base_type::TYPE_I32:
return "TType::I32";
return "Thrift::TType::I32";
case t_base_type::TYPE_I64:
return "TType::I64";
return "Thrift::TType::I64";
case t_base_type::TYPE_DOUBLE:
return "TType::DOUBLE";
return "Thrift::TType::DOUBLE";
}
} else if (type->is_enum()) {
return "TType::I32";
return "Thrift::TType::I32";
} else if (type->is_struct() || type->is_xception()) {
return "TType::STRUCT";
return "Thrift::TType::STRUCT";
} else if (type->is_map()) {
return "TType::MAP";
return "Thrift::TType::MAP";
} else if (type->is_set()) {
return "TType::SET";
return "Thrift::TType::SET";
} else if (type->is_list()) {
return "TType::LIST";
return "Thrift::TType::LIST";
}
throw "INVALID TYPE IN type_to_enum: " + type->get_name();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -113,6 +113,7 @@ public:
void generate_enum(t_enum* tenum);
void generate_const(t_const* tconst);
void generate_struct(t_struct* tstruct);
void generate_forward_declaration(t_struct* tstruct);
void generate_union(t_struct* tunion);
void generate_xception(t_struct* txception);
void generate_service(t_service* tservice);
@ -123,6 +124,7 @@ public:
* Struct generation code
*/
void generate_rb_struct_declaration(t_rb_ofstream& out, t_struct* tstruct, bool is_exception);
void generate_rb_struct(t_rb_ofstream& out, t_struct* tstruct, bool is_exception);
void generate_rb_struct_required_validator(t_rb_ofstream& out, t_struct* tstruct);
void generate_rb_union(t_rb_ofstream& out, t_struct* tstruct, bool is_exception);
@ -455,8 +457,8 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out,
out.indent_up();
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@ -478,8 +480,8 @@ t_rb_ofstream& t_rb_generator::render_const_value(t_rb_ofstream& out,
t_type* vtype = ((t_map*)type)->get_val_type();
out << "{" << endl;
out.indent_up();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
out.indent();
render_const_value(out, ktype, v_iter->first) << " => ";
@ -529,6 +531,29 @@ void t_rb_generator::generate_struct(t_struct* tstruct) {
}
}
/**
* Generates the "forward declarations" for ruby structs.
* These are simply a declaration of each class with proper inheritance.
* The rest of the struct is still generated in generate_struct as has
* always been the case. These declarations allow thrift to generate valid
* ruby in cases where thrift structs rely on recursive definitions.
*/
void t_rb_generator::generate_forward_declaration(t_struct* tstruct) {
generate_rb_struct_declaration(f_types_, tstruct, tstruct->is_xception());
}
void t_rb_generator::generate_rb_struct_declaration(t_rb_ofstream& out, t_struct* tstruct, bool is_exception) {
out.indent() << "class " << type_name(tstruct);
if (tstruct->is_union()) {
out << " < ::Thrift::Union";
}
if (is_exception) {
out << " < ::Thrift::Exception";
}
out << "; end" << endl << endl;
}
/**
* Generates a struct definition for a thrift exception. Basically the same
* as a struct but extends the Exception class.

File diff suppressed because it is too large Load diff

View file

@ -56,6 +56,7 @@ public:
const std::string& option_string)
: t_oop_generator(program) {
(void)option_string;
temporary_var = 0;
std::map<std::string, std::string>::const_iterator iter;
/* no options yet */
@ -92,8 +93,8 @@ public:
* Struct generation code
*/
void generate_st_struct(std::ofstream& out, t_struct* tstruct, bool is_exception);
void generate_accessors(std::ofstream& out, t_struct* tstruct);
void generate_st_struct(std::ostream& out, t_struct* tstruct, bool is_exception);
void generate_accessors(std::ostream& out, t_struct* tstruct);
/**
* Service-level generation functions
@ -123,15 +124,15 @@ public:
std::string st_autogen_comment();
void st_class_def(std::ofstream& out, std::string name);
void st_method(std::ofstream& out, std::string cls, std::string name);
void st_method(std::ofstream& out, std::string cls, std::string name, std::string category);
void st_close_method(std::ofstream& out);
void st_class_method(std::ofstream& out, std::string cls, std::string name);
void st_class_method(std::ofstream& out, std::string cls, std::string name, std::string category);
void st_setter(std::ofstream& out, std::string cls, std::string name, std::string type);
void st_getter(std::ofstream& out, std::string cls, std::string name);
void st_accessors(std::ofstream& out, std::string cls, std::string name, std::string type);
void st_class_def(std::ostream& out, std::string name);
void st_method(std::ostream& out, std::string cls, std::string name);
void st_method(std::ostream& out, std::string cls, std::string name, std::string category);
void st_close_method(std::ostream& out);
void st_class_method(std::ostream& out, std::string cls, std::string name);
void st_class_method(std::ostream& out, std::string cls, std::string name, std::string category);
void st_setter(std::ostream& out, std::string cls, std::string name, std::string type);
void st_getter(std::ostream& out, std::string cls, std::string name);
void st_accessors(std::ostream& out, std::string cls, std::string name, std::string type);
std::string class_name();
static bool is_valid_namespace(const std::string& sub_namespace);
@ -155,7 +156,7 @@ private:
* File streams
*/
int temporary_var;
std::ofstream f_;
ofstream_with_content_based_conditional_update f_;
};
/**
@ -249,7 +250,7 @@ void t_st_generator::generate_typedef(t_typedef* ttypedef) {
(void)ttypedef;
}
void t_st_generator::st_class_def(std::ofstream& out, string name) {
void t_st_generator::st_class_def(std::ostream& out, string name) {
out << "Object subclass: #" << prefix(name) << endl;
indent_up();
out << indent() << "instanceVariableNames: ''" << endl << indent() << "classVariableNames: ''"
@ -257,19 +258,19 @@ void t_st_generator::st_class_def(std::ofstream& out, string name) {
<< generated_category() << "'!" << endl << endl;
}
void t_st_generator::st_method(std::ofstream& out, string cls, string name) {
void t_st_generator::st_method(std::ostream& out, string cls, string name) {
st_method(out, cls, name, "as yet uncategorized");
}
void t_st_generator::st_class_method(std::ofstream& out, string cls, string name) {
void t_st_generator::st_class_method(std::ostream& out, string cls, string name) {
st_method(out, cls + " class", name);
}
void t_st_generator::st_class_method(std::ofstream& out, string cls, string name, string category) {
void t_st_generator::st_class_method(std::ostream& out, string cls, string name, string category) {
st_method(out, cls, name, category);
}
void t_st_generator::st_method(std::ofstream& out, string cls, string name, string category) {
void t_st_generator::st_method(std::ostream& out, string cls, string name, string category) {
char timestr[50];
time_t rawtime;
struct tm* tinfo;
@ -285,12 +286,12 @@ void t_st_generator::st_method(std::ofstream& out, string cls, string name, stri
out << indent();
}
void t_st_generator::st_close_method(std::ofstream& out) {
void t_st_generator::st_close_method(std::ostream& out) {
out << "! !" << endl << endl;
indent_down();
}
void t_st_generator::st_setter(std::ofstream& out,
void t_st_generator::st_setter(std::ostream& out,
string cls,
string name,
string type = "anObject") {
@ -299,13 +300,13 @@ void t_st_generator::st_setter(std::ofstream& out,
st_close_method(out);
}
void t_st_generator::st_getter(std::ofstream& out, string cls, string name) {
void t_st_generator::st_getter(std::ostream& out, string cls, string name) {
st_method(out, cls, name + "");
out << "^ " << name;
st_close_method(out);
}
void t_st_generator::st_accessors(std::ofstream& out,
void t_st_generator::st_accessors(std::ostream& out,
string cls,
string name,
string type = "anObject") {
@ -401,8 +402,8 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
t_type* field_type = NULL;
@ -427,8 +428,8 @@ string t_st_generator::render_const_value(t_type* type, t_const_value* value) {
out << "(Dictionary new" << endl;
indent_up();
indent_up();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
out << indent() << indent();
out << "at: " << render_const_value(ktype, v_iter->first);
@ -489,7 +490,7 @@ void t_st_generator::generate_xception(t_struct* txception) {
/**
* Generates a smalltalk class to represent a struct
*/
void t_st_generator::generate_st_struct(std::ofstream& out,
void t_st_generator::generate_st_struct(std::ostream& out,
t_struct* tstruct,
bool is_exception = false) {
const vector<t_field*>& members = tstruct->get_members();
@ -541,7 +542,7 @@ string t_st_generator::a_type(t_type* type) {
return prefix + capitalize(type_name(type));
}
void t_st_generator::generate_accessors(std::ofstream& out, t_struct* tstruct) {
void t_st_generator::generate_accessors(std::ostream& out, t_struct* tstruct) {
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
string type;

File diff suppressed because it is too large Load diff

View file

@ -101,7 +101,7 @@ private:
bool should_use_default_ns_;
bool should_use_namespaces_;
std::ofstream f_xml_;
ofstream_with_content_based_conditional_update f_xml_;
std::set<string> programs_;
std::stack<string> elements_;
@ -391,11 +391,16 @@ void t_xml_generator::write_type(t_type* ttype) {
if (type == "id") {
write_attribute("type-module", ttype->get_program()->get_name());
write_attribute("type-id", ttype->get_name());
} else if (type == "list" || type == "set") {
} else if (type == "list") {
t_type* etype = ((t_list*)ttype)->get_elem_type();
write_element_start("elemType");
write_type(etype);
write_element_end();
} else if (type == "set") {
t_type* etype = ((t_set*)ttype)->get_elem_type();
write_element_start("elemType");
write_type(etype);
write_element_end();
} else if (type == "map") {
t_type* ktype = ((t_map*)ttype)->get_key_type();
write_element_start("keyType");
@ -478,8 +483,8 @@ void t_xml_generator::write_const_value(t_const_value* value) {
case t_const_value::CV_MAP: {
write_element_start("map");
std::map<t_const_value*, t_const_value*> map = value->get_map();
std::map<t_const_value*, t_const_value*>::iterator mit;
std::map<t_const_value*, t_const_value*, t_const_value::value_compare> map = value->get_map();
std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::iterator mit;
for (mit = map.begin(); mit != map.end(); ++mit) {
write_element_start("entry");
write_element_start("key");

View file

@ -103,8 +103,8 @@ private:
/**
* Output xsd/php file
*/
std::ofstream f_xsd_;
std::ofstream f_php_;
ofstream_with_content_based_conditional_update f_xsd_;
ofstream_with_content_based_conditional_update f_php_;
/**
* Output string stream

View file

@ -805,8 +805,8 @@ void validate_const_rec(std::string name, t_type* type, t_const_value* value) {
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
if (v_iter->first->get_type() != t_const_value::CV_STRING) {
throw "type error: " + name + " struct key must be string";
@ -826,8 +826,8 @@ void validate_const_rec(std::string name, t_type* type, t_const_value* value) {
} else if (type->is_map()) {
t_type* k_type = ((t_map*)type)->get_key_type();
t_type* v_type = ((t_map*)type)->get_val_type();
const map<t_const_value*, t_const_value*>& val = value->get_map();
map<t_const_value*, t_const_value*>::const_iterator v_iter;
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
validate_const_rec(name + "<key>", k_type, v_iter->first);
validate_const_rec(name + "<val>", v_type, v_iter->second);
@ -1028,6 +1028,7 @@ void generate(t_program* program, const vector<string>& generator_strings) {
g_generator_failure = true;
#endif
} else if (generator) {
generator->validate_input();
pverbose("Generating \"%s\"\n", iter->c_str());
generator->generate_program();
delete generator;

View file

@ -57,15 +57,15 @@ public:
void set_string_list(bool val) { string_list_ = val; }
bool is_string_list() const { return (base_ == TYPE_STRING) && string_list_; }
bool is_string_list() const { return string_list_ && (base_ == TYPE_STRING); }
void set_binary(bool val) { binary_ = val; }
bool is_binary() const { return (base_ == TYPE_STRING) && binary_; }
bool is_binary() const { return binary_ && (base_ == TYPE_STRING); }
void set_string_enum(bool val) { string_enum_ = val; }
bool is_string_enum() const { return base_ == TYPE_STRING && string_enum_; }
bool is_string_enum() const { return string_enum_ && base_ == TYPE_STRING; }
void add_string_enum_val(std::string val) { string_enum_vals_.push_back(val); }

View file

@ -38,13 +38,24 @@ void convert(From*, To&);
*/
class t_const_value {
public:
enum t_const_value_type { CV_INTEGER, CV_DOUBLE, CV_STRING, CV_MAP, CV_LIST, CV_IDENTIFIER };
/**
* Comparator to sort fields in ascending order by key.
* Make this a functor instead of a function to help GCC inline it.
*/
struct value_compare {
public:
bool operator()(t_const_value const* const& left, t_const_value const* const& right) const {
return *left < *right;
}
};
t_const_value() {}
enum t_const_value_type { CV_INTEGER, CV_DOUBLE, CV_STRING, CV_MAP, CV_LIST, CV_IDENTIFIER, CV_UNKNOWN };
t_const_value(int64_t val) { set_integer(val); }
t_const_value() : intVal_(0), doubleVal_(0.0f), enum_((t_enum*)0), valType_(CV_UNKNOWN) {}
t_const_value(std::string val) { set_string(val); }
t_const_value(int64_t val) : doubleVal_(0.0f), enum_((t_enum*)0), valType_(CV_UNKNOWN) { set_integer(val); }
t_const_value(std::string val) : intVal_(0), doubleVal_(0.0f), enum_((t_enum*)0), valType_(CV_UNKNOWN) { set_string(val); }
void set_string(std::string val) {
valType_ = CV_STRING;
@ -90,7 +101,7 @@ public:
void add_map(t_const_value* key, t_const_value* val) { mapVal_[key] = val; }
const std::map<t_const_value*, t_const_value*>& get_map() const { return mapVal_; }
const std::map<t_const_value*, t_const_value*, t_const_value::value_compare>& get_map() const { return mapVal_; }
void set_list() { valType_ = CV_LIST; }
@ -134,10 +145,57 @@ public:
void set_enum(t_enum* tenum) { enum_ = tenum; }
t_const_value_type get_type() const { return valType_; }
t_const_value_type get_type() const { if (valType_ == CV_UNKNOWN) { throw std::string("unknown t_const_value"); } return valType_; }
/**
* Comparator to sort map fields in ascending order by key and then value.
* This is used for map comparison in lexicographic order.
*/
struct map_entry_compare {
private:
typedef std::pair<t_const_value*, t_const_value*> ConstPair;
public:
bool operator()(ConstPair left, ConstPair right) const {
if (*(left.first) < *(right.first)) {
return true;
} else {
if (*(right.first) < *(left.first)) {
return false;
} else {
return *(left.second) < *(right.second);
}
}
}
};
bool operator < (const t_const_value& that) const {
::t_const_value::t_const_value_type t1 = get_type();
::t_const_value::t_const_value_type t2 = that.get_type();
if (t1 != t2)
return t1 < t2;
switch (t1) {
case ::t_const_value::CV_INTEGER:
return intVal_ < that.intVal_;
case ::t_const_value::CV_DOUBLE:
return doubleVal_ < that.doubleVal_;
case ::t_const_value::CV_STRING:
return stringVal_ < that.stringVal_;
case ::t_const_value::CV_IDENTIFIER:
return identifierVal_ < that.identifierVal_;
case ::t_const_value::CV_MAP:
return std::lexicographical_compare(
mapVal_.begin(), mapVal_.end(), that.mapVal_.begin(), that.mapVal_.end(), map_entry_compare());
case ::t_const_value::CV_LIST:
return std::lexicographical_compare(
listVal_.begin(), listVal_.end(), that.listVal_.begin(), that.listVal_.end(), value_compare());
case ::t_const_value::CV_UNKNOWN:
default:
throw "unknown value type";
}
}
private:
std::map<t_const_value*, t_const_value*> mapVal_;
std::map<t_const_value*, t_const_value*, value_compare> mapVal_;
std::vector<t_const_value*> listVal_;
std::string stringVal_;
int64_t intVal_;

View file

@ -34,8 +34,12 @@
class t_function : public t_doc {
public:
t_function(t_type* returntype, std::string name, t_struct* arglist, bool oneway = false)
: returntype_(returntype), name_(name), arglist_(arglist), oneway_(oneway) {
xceptions_ = new t_struct(NULL);
: returntype_(returntype),
name_(name),
arglist_(arglist),
xceptions_(new t_struct(NULL)),
own_xceptions_(true),
oneway_(oneway) {
if (oneway_ && (!returntype_->is_void())) {
pwarning(1, "Oneway methods should return void.\n");
}
@ -50,6 +54,7 @@ public:
name_(name),
arglist_(arglist),
xceptions_(xceptions),
own_xceptions_(false),
oneway_(oneway) {
if (oneway_ && !xceptions_->get_members().empty()) {
throw std::string("Oneway methods can't throw exceptions.");
@ -59,7 +64,10 @@ public:
}
}
~t_function() {}
~t_function() {
if (own_xceptions_)
delete xceptions_;
}
t_type* get_returntype() const { return returntype_; }
@ -78,6 +86,7 @@ private:
std::string name_;
t_struct* arglist_;
t_struct* xceptions_;
bool own_xceptions_;
bool oneway_;
};

View file

@ -31,6 +31,7 @@
#include "thrift/parse/t_base_type.h"
#include "thrift/parse/t_map.h"
#include "thrift/parse/t_list.h"
#include "thrift/parse/t_set.h"
namespace plugin_output {
template <typename From, typename To>
@ -75,22 +76,28 @@ public:
void resolve_const_value(t_const_value* const_val, t_type* ttype) {
if (ttype->is_map()) {
const std::map<t_const_value*, t_const_value*>& map = const_val->get_map();
std::map<t_const_value*, t_const_value*>::const_iterator v_iter;
const std::map<t_const_value*, t_const_value*, t_const_value::value_compare>& map = const_val->get_map();
std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = map.begin(); v_iter != map.end(); ++v_iter) {
resolve_const_value(v_iter->first, ((t_map*)ttype)->get_key_type());
resolve_const_value(v_iter->second, ((t_map*)ttype)->get_val_type());
}
} else if (ttype->is_list() || ttype->is_set()) {
} else if (ttype->is_list()) {
const std::vector<t_const_value*>& val = const_val->get_list();
std::vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
resolve_const_value((*v_iter), ((t_list*)ttype)->get_elem_type());
}
} else if (ttype->is_set()) {
const std::vector<t_const_value*>& val = const_val->get_list();
std::vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
resolve_const_value((*v_iter), ((t_set*)ttype)->get_elem_type());
}
} else if (ttype->is_struct()) {
t_struct* tstruct = (t_struct*)ttype;
const std::map<t_const_value*, t_const_value*>& map = const_val->get_map();
std::map<t_const_value*, t_const_value*>::const_iterator v_iter;
const std::map<t_const_value*, t_const_value*, t_const_value::value_compare>& map = const_val->get_map();
std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = map.begin(); v_iter != map.end(); ++v_iter) {
t_field* field = tstruct->get_field_by_name(v_iter->first->get_string());
if (field == NULL) {
@ -130,8 +137,8 @@ public:
throw "Constants cannot be of type VOID";
}
} else if (const_type->is_map()) {
const std::map<t_const_value*, t_const_value*>& map = constant->get_value()->get_map();
std::map<t_const_value*, t_const_value*>::const_iterator v_iter;
const std::map<t_const_value*, t_const_value*, t_const_value::value_compare>& map = constant->get_value()->get_map();
std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
const_val->set_map();
for (v_iter = map.begin(); v_iter != map.end(); ++v_iter) {

View file

@ -47,6 +47,7 @@ public:
virtual bool is_void() const { return false; }
virtual bool is_base_type() const { return false; }
virtual bool is_string() const { return false; }
virtual bool is_binary() const { return false; }
virtual bool is_bool() const { return false; }
virtual bool is_typedef() const { return false; }
virtual bool is_enum() const { return false; }

View file

@ -33,7 +33,7 @@
class t_typedef : public t_type {
public:
t_typedef(t_program* program, t_type* type, const std::string& symbolic)
: t_type(program, symbolic), type_(type), symbolic_(symbolic), forward_(false), seen_(false) {}
: t_type(program, symbolic), type_(type), symbolic_(symbolic), forward_(false) {}
/**
* This constructor is used to refer to a type that is lazily
@ -44,8 +44,8 @@ public:
: t_type(program, symbolic),
type_(NULL),
symbolic_(symbolic),
forward_(forward),
seen_(false) {}
forward_(forward)
{}
~t_typedef() {}
@ -61,7 +61,6 @@ private:
t_type* type_;
std::string symbolic_;
bool forward_;
mutable bool seen_;
};
#endif

View file

@ -34,10 +34,13 @@
#include <sys/stat.h>
#endif
#include <cerrno>
// ignore EEXIST, throw on any other error
#ifdef _WIN32
#define MKDIR(x) mkdir(x)
#define MKDIR(x) { int r = _mkdir(x); if (r == -1 && errno != EEXIST) { throw (std::string(x) + ": ") + strerror(errno); } }
#else
#define MKDIR(x) mkdir(x, S_IRWXU | S_IRWXG | S_IRWXO)
#define MKDIR(x) { int r = mkdir(x, S_IRWXU | S_IRWXG | S_IRWXO); if (r == -1 && errno != EEXIST) { throw (std::string(x) + ": ") + strerror(errno); } }
#endif
#ifdef PATH_MAX

View file

@ -27,17 +27,15 @@
#include <cassert>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/smart_ptr.hpp>
#include "thrift/generate/t_generator.h"
#include "thrift/plugin/type_util.h"
#include "thrift/protocol/TBinaryProtocol.h"
#include "thrift/transport/TBufferTransports.h"
#include "thrift/transport/TFDTransport.h"
#include "thrift/stdcxx.h"
#include "thrift/plugin/plugin_types.h"
namespace apache {
@ -121,11 +119,16 @@ struct TypeCache {
void compileAll() {
boost::for_each(*source | boost::adaptors::map_keys,
boost::bind(&TypeCache::compile, this, _1));
stdcxx::bind(&TypeCache::compile, this, stdcxx::placeholders::_1));
}
std::map<int64_t, S> const* source;
void clear() {
source = nullptr ;
cache.clear() ;
}
protected:
std::map<int64_t, C*> cache;
@ -143,6 +146,12 @@ TypeCache< ::t_type, t_type> g_type_cache;
TypeCache< ::t_const, t_const> g_const_cache;
TypeCache< ::t_service, t_service> g_service_cache;
void clear_global_cache() {
g_type_cache.clear();
g_const_cache.clear();
g_service_cache.clear();
}
void set_global_cache(const TypeRegistry& from) {
g_type_cache.source = &from.types;
g_const_cache.source = &from.constants;
@ -218,7 +227,7 @@ THRIFT_CONVERSION(t_enum, g_program_cache[from.metadata.program_id]) {
assert(to);
THRIFT_ASSIGN_METADATA();
boost::for_each(from.constants | boost::adaptors::transformed(convert<t_enum_value>),
boost::bind(&::t_enum::append, to, _1));
stdcxx::bind(&::t_enum::append, to, stdcxx::placeholders::_1));
}
THRIFT_CONVERSION(t_list, resolve_type< ::t_type>(from.elem_type)) {
assert(to);
@ -255,16 +264,16 @@ THRIFT_CONVERSION(t_const_value, ) {
} else if (from.__isset.list_val) {
to->set_list();
boost::for_each(from.list_val | boost::adaptors::transformed(&convert<t_const_value>),
boost::bind(&::t_const_value::add_list, to, _1));
stdcxx::bind(&::t_const_value::add_list, to, stdcxx::placeholders::_1));
} else
T_CONST_VALUE_CASE(string);
else T_CONST_VALUE_CASE(integer);
else T_CONST_VALUE_CASE(double);
else {
T_CONST_VALUE_CASE(identifier);
if (from.__isset.enum_val)
to->set_enum(resolve_type< ::t_enum>(from.enum_val));
else if (from.__isset.const_identifier_val) {
to->set_identifier(from.const_identifier_val.identifier_val) ;
to->set_enum(resolve_type< ::t_enum>(from.const_identifier_val.enum_val)) ;
}
#undef T_CONST_VALUE_CASE
}
THRIFT_CONVERSION(t_field, resolve_type< ::t_type>(from.type), from.name, from.key) {
@ -282,7 +291,7 @@ THRIFT_CONVERSION(t_struct, g_program_cache[from.metadata.program_id]) {
to->set_union(from.is_union);
to->set_xception(from.is_xception);
boost::for_each(from.members | boost::adaptors::transformed(convert<t_field>),
boost::bind(&::t_struct::append, to, _1));
stdcxx::bind(&::t_struct::append, to, stdcxx::placeholders::_1));
}
THRIFT_CONVERSION(t_const,
resolve_type< ::t_type>(from.type),
@ -309,7 +318,7 @@ THRIFT_CONVERSION(t_service, g_program_cache[from.metadata.program_id]) {
THRIFT_ASSIGN_METADATA();
boost::for_each(from.functions | boost::adaptors::transformed(convert<t_function>),
boost::bind(&::t_service::add_function, to, _1));
stdcxx::bind(&::t_service::add_function, to, stdcxx::placeholders::_1));
if (from.__isset.extends_)
to->set_extends(resolve_service(from.extends_));
@ -390,9 +399,9 @@ THRIFT_CONVERT_COMPLETE(t_program) {
to->set_out_path(from.out_path, from.out_path_is_absolute);
boost::for_each(from.typedefs | boost::adaptors::transformed(&resolve_type< ::t_typedef>),
boost::bind(&::t_program::add_typedef, to, _1));
stdcxx::bind(&::t_program::add_typedef, to, stdcxx::placeholders::_1));
boost::for_each(from.enums | boost::adaptors::transformed(&resolve_type< ::t_enum>),
boost::bind(&::t_program::add_enum, to, _1));
stdcxx::bind(&::t_program::add_enum, to, stdcxx::placeholders::_1));
for (std::vector<int64_t>::const_iterator it = from.objects.begin(); it != from.objects.end();
it++) {
::t_struct* t2 = resolve_type< ::t_struct>(*it);
@ -403,18 +412,18 @@ THRIFT_CONVERT_COMPLETE(t_program) {
}
}
boost::for_each(from.consts | boost::adaptors::transformed(&resolve_const),
boost::bind(&::t_program::add_const, to, _1));
stdcxx::bind(&::t_program::add_const, to, stdcxx::placeholders::_1));
boost::for_each(from.services | boost::adaptors::transformed(&resolve_service),
boost::bind(&::t_program::add_service, to, _1));
stdcxx::bind(&::t_program::add_service, to, stdcxx::placeholders::_1));
for (std::vector<t_program>::const_iterator it = from.includes.begin(); it != from.includes.end();
it++) {
convert(*it, g_program_cache[it->program_id]);
}
std::for_each(from.c_includes.begin(), from.c_includes.end(),
boost::bind(&::t_program::add_c_include, to, _1));
stdcxx::bind(&::t_program::add_c_include, to, stdcxx::placeholders::_1));
std::for_each(from.cpp_includes.begin(), from.cpp_includes.end(),
boost::bind(&::t_program::add_cpp_include, to, _1));
stdcxx::bind(&::t_program::add_cpp_include, to, stdcxx::placeholders::_1));
for (std::map<std::string, std::string>::const_iterator it = from.namespaces.begin();
it != from.namespaces.end(); it++) {
to->set_namespace(it->first, it->second);
@ -428,8 +437,8 @@ int GeneratorPlugin::exec(int, char* []) {
#ifdef _WIN32
_setmode(fileno(stdin), _O_BINARY);
#endif
boost::shared_ptr<TFramedTransport> transport(
new TFramedTransport(boost::make_shared<TFDTransport>(fileno(stdin))));
stdcxx::shared_ptr<TFramedTransport> transport(
new TFramedTransport(stdcxx::make_shared<TFDTransport>(fileno(stdin))));
TBinaryProtocol proto(transport);
GeneratorInput input;
try {
@ -460,9 +469,7 @@ int GeneratorPlugin::exec(int, char* []) {
return ::t_const_value::CV_INTEGER;
if (v.__isset.double_val)
return ::t_const_value::CV_DOUBLE;
if (v.__isset.identifier_val)
return ::t_const_value::CV_IDENTIFIER;
if (v.__isset.enum_val)
if (v.__isset.const_identifier_val)
return ::t_const_value::CV_IDENTIFIER;
throw ThriftPluginError("Unknown const value type");
}

View file

@ -105,27 +105,26 @@ enum Requiredness {
T_OPT_IN_REQ_OUT = 2
}
struct t_const_identifier_value {
1: required string identifier_val
2: required t_type_id enum_val
}
union t_const_value {
1: optional map<t_const_value, t_const_value> map_val
2: optional list<t_const_value> list_val
3: optional string string_val
4: optional i64 integer_val
5: optional double double_val
6: optional string identifier_val
7: optional t_type_id enum_val
8: optional t_const_identifier_value const_identifier_val
}
struct t_const {
1: required string name
2: required t_type_id type
3: required t_const_value value
100: optional string doc
}
struct t_struct {
1: required TypeMetadata metadata
2: required list<t_field> members
3: required bool is_union
4: required bool is_xception
}
struct t_field {
1: required string name
2: required t_type_id type
@ -136,6 +135,12 @@ struct t_field {
99: optional map<string, string> annotations
100: optional string doc
}
struct t_struct {
1: required TypeMetadata metadata
2: required list<t_field> members
3: required bool is_union
4: required bool is_xception
}
struct t_function {
1: required string name
2: required t_type_id returntype

View file

@ -34,12 +34,12 @@
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/algorithm/transform.hpp>
#include <boost/smart_ptr.hpp>
#include "thrift/generate/t_generator.h"
#include "thrift/plugin/plugin.h"
#include "thrift/plugin/type_util.h"
#include "thrift/protocol/TBinaryProtocol.h"
#include "thrift/stdcxx.h"
#include "thrift/transport/TBufferTransports.h"
#include "thrift/transport/TFDTransport.h"
@ -55,6 +55,8 @@ typename apache::thrift::plugin::ToType<From>::type convert(From* from) {
}
using apache::thrift::protocol::TBinaryProtocol;
using apache::thrift::stdcxx::make_shared;
using apache::thrift::stdcxx::shared_ptr;
using apache::thrift::transport::TFDTransport;
using apache::thrift::transport::TFramedTransport;
@ -97,29 +99,62 @@ using namespace apache::thrift;
#define THRIFT_ASSIGN_METADATA() convert(reinterpret_cast<t_type*>(from), to.metadata)
// a generator of sequential unique identifiers for addresses -- so
// that the TypeCache below can use those IDs instead of
// addresses. This allows GeneratorInput's various
// t_{program,type,etc}_id types to be dense consecutively-numbered
// integers, instead of large random-seeming integers.
//
// Furthermore, this allows GeneratorInput to be deterministic (no
// addresses, so no pseudo-randomness) and that means reproducibility
// of output.
const int64_t ONE_MILLION = 1000 * 1000;
class id_generator {
public:
id_generator() : addr2id_(), next_id_(ONE_MILLION) {}
void clear() {
addr2id_.clear() ;
next_id_ = ONE_MILLION ;
}
int64_t gensym(const int64_t addr) {
if (!addr) return 0L ;
std::map<int64_t, int64_t>::iterator it = addr2id_.find(addr);
if (it != addr2id_.end()) return it->second ;
int64_t id = next_id_++ ;
addr2id_.insert(std::make_pair(addr, id)) ;
return id ;
}
std::map<int64_t, int64_t> addr2id_ ;
int64_t next_id_ ;
} ;
// To avoid multiple instances of same type, t_type, t_const and t_service are stored in one place
// and referenced by ID.
template <typename T>
struct TypeCache {
typedef typename plugin::ToType<T>::type to_type;
id_generator idgen ;
std::map<int64_t, to_type> cache;
template <typename T2>
int64_t store(T2* t) {
intptr_t id = reinterpret_cast<intptr_t>(t);
if (id) {
typename std::map<int64_t, to_type>::iterator it = cache.find(id);
if (it == cache.end()) {
// HACK: fake resolve for recursive type
cache.insert(std::make_pair(id, to_type()));
// overwrite with true value
cache[id] = convert(t);
}
}
return static_cast<int64_t>(id);
intptr_t addr = reinterpret_cast<intptr_t>(t);
if (!addr) return 0L ;
int64_t id = idgen.gensym(addr) ;
if (cache.end() != cache.find(id)) return id ;
// HACK: fake resolve for recursive type
cache.insert(std::make_pair(id, to_type()));
// overwrite with true value
cache[id] = convert(t);
return id ;
}
void clear() { cache.clear(); }
void clear() { cache.clear() ; idgen.clear(); }
};
template <typename T>
@ -135,6 +170,8 @@ T_STORE(type)
T_STORE(const)
T_STORE(service)
#undef T_STORE
// this id_generator is for gensymm-ing t_program_id
id_generator program_cache ;
#define THRIFT_ASSIGN_ID_N(t, from_name, to_name) \
do { \
@ -155,7 +192,7 @@ T_STORE(service)
} while (0)
THRIFT_CONVERSION_N(::t_type, plugin::TypeMetadata) {
to.program_id = reinterpret_cast<int64_t>(from->get_program());
to.program_id = program_cache.gensym(reinterpret_cast<int64_t>(from->get_program()));
THRIFT_ASSIGN_N(annotations_, annotations, );
if (from->has_doc()) {
to.__set_doc(from->get_doc());
@ -193,8 +230,13 @@ THRIFT_CONVERSION(t_const_value) {
THRIFT_ASSIGN_N(get_string(), string_val, );
break;
case t_const_value::CV_IDENTIFIER:
THRIFT_ASSIGN_ID_N(t_type, enum_, enum_val);
THRIFT_ASSIGN_N(get_identifier(), identifier_val, );
if (from) {
apache::thrift::plugin::t_const_identifier_value cidval ;
if (from->enum_)
cidval.__set_enum_val(store_type<t_type>(from->enum_));
cidval.__set_identifier_val(from->get_identifier());
to.__set_const_identifier_val(cidval) ;
}
break;
case t_const_value::CV_MAP:
to.__isset.map_val = true;
@ -339,6 +381,7 @@ void clear_global_cache() {
type_cache.clear();
const_cache.clear();
service_cache.clear();
program_cache.clear() ;
}
THRIFT_CONVERSION(t_program) {
@ -358,7 +401,7 @@ THRIFT_CONVERSION(t_program) {
THRIFT_ASSIGN_LIST_ID(t_const, const);
THRIFT_ASSIGN_LIST_ID(t_service, service);
THRIFT_ASSIGN_LIST_N(t_program, get_includes(), includes);
to.program_id = reinterpret_cast<plugin::t_program_id>(from);
to.program_id = program_cache.gensym(reinterpret_cast<plugin::t_program_id>(from));
}
PluginDelegateResult delegateToPlugin(t_program* program, const std::string& options) {
@ -377,8 +420,8 @@ PluginDelegateResult delegateToPlugin(t_program* program, const std::string& opt
#ifdef _WIN32
_setmode(fileno(fd), _O_BINARY);
#endif
boost::shared_ptr<TFramedTransport> transport(
new TFramedTransport(boost::make_shared<TFDTransport>(fileno(fd))));
shared_ptr<TFramedTransport> transport(
new TFramedTransport(make_shared<TFDTransport>(fileno(fd))));
TBinaryProtocol proto(transport);
plugin::GeneratorInput input;
@ -408,3 +451,4 @@ PluginDelegateResult delegateToPlugin(t_program* program, const std::string& opt
return PLUGIN_NOT_FOUND;
}
}

View file

@ -38,6 +38,7 @@ typename ToType<From>::type* convert(const From& from);
class TypeRegistry;
void set_global_cache(const TypeRegistry&);
void clear_global_cache();
}
}
}

View file

@ -39,9 +39,15 @@
#endif
#ifdef _MSC_VER
//warning C4102: 'find_rule' : unreferenced label
#pragma warning(disable:4102)
//avoid isatty redefinition
#pragma warning( push )
// warning C4102: 'find_rule' : unreferenced label
#pragma warning( disable : 4102 )
// warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data
#pragma warning( disable : 4267 )
// avoid isatty redefinition
#define YY_NEVER_INTERACTIVE 1
#define YY_NO_UNISTD_H 1
@ -70,11 +76,6 @@
#include "thrift/thrifty.hh"
#endif
void thrift_reserved_keyword(char* keyword) {
yyerror("Cannot use reserved language keyword: \"%s\"\n", keyword);
exit(1);
}
void integer_overflow(char* text) {
yyerror("This integer is too big: \"%s\"\n", text);
exit(1);
@ -263,111 +264,6 @@ literal_begin (['\"])
}
"&" { return tok_reference; }
"BEGIN" { thrift_reserved_keyword(yytext); }
"END" { thrift_reserved_keyword(yytext); }
"__CLASS__" { thrift_reserved_keyword(yytext); }
"__DIR__" { thrift_reserved_keyword(yytext); }
"__FILE__" { thrift_reserved_keyword(yytext); }
"__FUNCTION__" { thrift_reserved_keyword(yytext); }
"__LINE__" { thrift_reserved_keyword(yytext); }
"__METHOD__" { thrift_reserved_keyword(yytext); }
"__NAMESPACE__" { thrift_reserved_keyword(yytext); }
"abstract" { thrift_reserved_keyword(yytext); }
"alias" { thrift_reserved_keyword(yytext); }
"and" { thrift_reserved_keyword(yytext); }
"args" { thrift_reserved_keyword(yytext); }
"as" { thrift_reserved_keyword(yytext); }
"assert" { thrift_reserved_keyword(yytext); }
"begin" { thrift_reserved_keyword(yytext); }
"break" { thrift_reserved_keyword(yytext); }
"case" { thrift_reserved_keyword(yytext); }
"catch" { thrift_reserved_keyword(yytext); }
"class" { thrift_reserved_keyword(yytext); }
"clone" { thrift_reserved_keyword(yytext); }
"continue" { thrift_reserved_keyword(yytext); }
"declare" { thrift_reserved_keyword(yytext); }
"def" { thrift_reserved_keyword(yytext); }
"default" { thrift_reserved_keyword(yytext); }
"del" { thrift_reserved_keyword(yytext); }
"delete" { thrift_reserved_keyword(yytext); }
"do" { thrift_reserved_keyword(yytext); }
"dynamic" { thrift_reserved_keyword(yytext); }
"elif" { thrift_reserved_keyword(yytext); }
"else" { thrift_reserved_keyword(yytext); }
"elseif" { thrift_reserved_keyword(yytext); }
"elsif" { thrift_reserved_keyword(yytext); }
"end" { thrift_reserved_keyword(yytext); }
"enddeclare" { thrift_reserved_keyword(yytext); }
"endfor" { thrift_reserved_keyword(yytext); }
"endforeach" { thrift_reserved_keyword(yytext); }
"endif" { thrift_reserved_keyword(yytext); }
"endswitch" { thrift_reserved_keyword(yytext); }
"endwhile" { thrift_reserved_keyword(yytext); }
"ensure" { thrift_reserved_keyword(yytext); }
"except" { thrift_reserved_keyword(yytext); }
"exec" { thrift_reserved_keyword(yytext); }
"finally" { thrift_reserved_keyword(yytext); }
"float" { thrift_reserved_keyword(yytext); }
"for" { thrift_reserved_keyword(yytext); }
"foreach" { thrift_reserved_keyword(yytext); }
"from" { thrift_reserved_keyword(yytext); }
"function" { thrift_reserved_keyword(yytext); }
"global" { thrift_reserved_keyword(yytext); }
"goto" { thrift_reserved_keyword(yytext); }
"if" { thrift_reserved_keyword(yytext); }
"implements" { thrift_reserved_keyword(yytext); }
"import" { thrift_reserved_keyword(yytext); }
"in" { thrift_reserved_keyword(yytext); }
"inline" { thrift_reserved_keyword(yytext); }
"instanceof" { thrift_reserved_keyword(yytext); }
"interface" { thrift_reserved_keyword(yytext); }
"is" { thrift_reserved_keyword(yytext); }
"lambda" { thrift_reserved_keyword(yytext); }
"module" { thrift_reserved_keyword(yytext); }
"native" { thrift_reserved_keyword(yytext); }
"new" { thrift_reserved_keyword(yytext); }
"next" { thrift_reserved_keyword(yytext); }
"nil" { thrift_reserved_keyword(yytext); }
"not" { thrift_reserved_keyword(yytext); }
"or" { thrift_reserved_keyword(yytext); }
"package" { thrift_reserved_keyword(yytext); }
"pass" { thrift_reserved_keyword(yytext); }
"public" { thrift_reserved_keyword(yytext); }
"print" { thrift_reserved_keyword(yytext); }
"private" { thrift_reserved_keyword(yytext); }
"protected" { thrift_reserved_keyword(yytext); }
"raise" { thrift_reserved_keyword(yytext); }
"redo" { thrift_reserved_keyword(yytext); }
"rescue" { thrift_reserved_keyword(yytext); }
"retry" { thrift_reserved_keyword(yytext); }
"register" { thrift_reserved_keyword(yytext); }
"return" { thrift_reserved_keyword(yytext); }
"self" { thrift_reserved_keyword(yytext); }
"sizeof" { thrift_reserved_keyword(yytext); }
"static" { thrift_reserved_keyword(yytext); }
"super" { thrift_reserved_keyword(yytext); }
"switch" { thrift_reserved_keyword(yytext); }
"synchronized" { thrift_reserved_keyword(yytext); }
"then" { thrift_reserved_keyword(yytext); }
"this" { thrift_reserved_keyword(yytext); }
"throw" { thrift_reserved_keyword(yytext); }
"transient" { thrift_reserved_keyword(yytext); }
"try" { thrift_reserved_keyword(yytext); }
"undef" { thrift_reserved_keyword(yytext); }
"unless" { thrift_reserved_keyword(yytext); }
"unsigned" { thrift_reserved_keyword(yytext); }
"until" { thrift_reserved_keyword(yytext); }
"use" { thrift_reserved_keyword(yytext); }
"var" { thrift_reserved_keyword(yytext); }
"virtual" { thrift_reserved_keyword(yytext); }
"volatile" { thrift_reserved_keyword(yytext); }
"when" { thrift_reserved_keyword(yytext); }
"while" { thrift_reserved_keyword(yytext); }
"with" { thrift_reserved_keyword(yytext); }
"xor" { thrift_reserved_keyword(yytext); }
"yield" { thrift_reserved_keyword(yytext); }
{intconstant} {
errno = 0;
yylval.iconst = strtoll(yytext, NULL, 10);
@ -459,5 +355,9 @@ literal_begin (['\"])
%%
#ifdef _MSC_VER
#pragma warning( pop )
#endif
/* vim: filetype=lex
*/

View file

@ -1,3 +1,6 @@
%code requires {
#include "thrift/parse/t_program.h"
}
%{
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -25,9 +28,14 @@
*
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <stdio.h>
#include <string.h>
#ifndef _MSC_VER
#include <inttypes.h>
#else

View file

@ -34,9 +34,13 @@
#define strtoll(begin_ptr, end_ptr, length) _strtoi64(begin_ptr, end_ptr, length)
#define PRIu64 "I64d"
#define PRIi64 "I64d"
#ifndef PRIu64
#define PRIu64 "I64u"
#endif
#ifndef PRIi64
#define PRIi64 "I64i"
#endif
// squelch deprecation warnings
#pragma warning(disable : 4996)
// squelch bool conversion performance warning

View file

@ -75,3 +75,18 @@ if(${WITH_PLUGIN})
-DSRCDIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cpp_plugin_test.cmake)
endif()
file(GLOB KEYWORD_SAMPLES "${CMAKE_CURRENT_SOURCE_DIR}/keyword-samples/*.thrift")
foreach(LANG ${thrift_compiler_LANGS})
foreach(SAMPLE ${KEYWORD_SAMPLES})
get_filename_component(FILENAME ${SAMPLE} NAME_WE)
add_test(NAME "${LANG}_${FILENAME}"
COMMAND thrift-compiler --gen ${LANG} ${SAMPLE})
set_tests_properties("${LANG}_${FILENAME}" PROPERTIES
PASS_REGULAR_EXPRESSION "Cannot use reserved language keyword")
endforeach()
endforeach()
find_package(PythonInterp REQUIRED)
add_test(NAME StalenessCheckTest COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/compiler/staleness_check.py ${THRIFT_COMPILER})

View file

@ -32,6 +32,8 @@ check_PROGRAMS = plugintest
noinst_PROGRAMS = thrift-gen-mycpp
all-local: thrift-gen-bincat
AM_CPPFLAGS += -I$(top_srcdir)/lib/cpp/src -I$(top_builddir)/lib/cpp/src
plugintest_SOURCES = plugin/conversion_test.cc
@ -43,9 +45,16 @@ thrift_gen_mycpp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/compiler/cpp -I$(top_
thrift_gen_mycpp_LDADD = $(top_builddir)/compiler/cpp/libthriftc.la
cpp_plugin_test.sh: thrift-gen-mycpp
TESTS = $(check_PROGRAMS) cpp_plugin_test.sh
thrift-gen-bincat:
cp bincat.sh $@
chmod 755 $@
plugin_stability_test.sh: thrift-gen-bincat
TESTS = $(check_PROGRAMS) cpp_plugin_test.sh plugin_stability_test.sh
clean-local:
$(RM) -rf gen-cpp gen-mycpp
$(RM) -rf gen-cpp gen-mycpp gen-bincat thrift-gen-bincat
endif

View file

@ -0,0 +1,3 @@
#!/bin/bash
exec /bin/cat

View file

@ -0,0 +1,18 @@
const string foo = "bar"
struct a_struct {
1: bool im_true,
2: bool im_false,
3: i8 a_bite,
4: i16 integer16,
5: i32 integer32,
6: i64 integer64,
7: double double_precision,
8: string some_characters,
9: string zomg_unicode,
10: bool what_who,
}
service AService {
i32 a_procedure(1: i32 arg)
}

View file

@ -0,0 +1,7 @@
include "Included.thrift"
const string s = "string"
struct BStruct {
1: Included.a_struct one_of_each
}

View file

@ -0,0 +1 @@
const string foo = "bar"

View file

@ -0,0 +1,142 @@
#!/usr/bin/env python3
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
from __future__ import print_function
import os
import shutil
import subprocess
import sys
import tempfile
import time
import unittest
class TestStalenessCheck(unittest.TestCase):
CURRENT_DIR_PATH = os.path.dirname(os.path.realpath(__file__))
THRIFT_EXECUTABLE_PATH = None
SINGLE_THRIFT_FILE_PATH = os.path.join(CURRENT_DIR_PATH, "Single.thrift")
INCLUDING_THRIFT_FILE_PATH = os.path.join(CURRENT_DIR_PATH, "Including.thrift")
INCLUDED_THRIFT_FILE_PATH = os.path.join(CURRENT_DIR_PATH, "Included.thrift")
def test_staleness_check_of_single_thrift_file_without_changed_output(self):
temp_dir = tempfile.mkdtemp(dir=TestStalenessCheck.CURRENT_DIR_PATH)
command = [TestStalenessCheck.THRIFT_EXECUTABLE_PATH, "-gen", "cpp", "-o", temp_dir]
command += [TestStalenessCheck.SINGLE_THRIFT_FILE_PATH]
subprocess.call(command)
used_file_path = os.path.join(temp_dir, "gen-cpp", "Single_constants.cpp")
first_modification_time = os.path.getmtime(os.path.join(used_file_path))
time.sleep(0.1)
subprocess.call(command)
second_modification_time = os.path.getmtime(used_file_path)
self.assertEqual(second_modification_time, first_modification_time)
shutil.rmtree(temp_dir, ignore_errors=True)
def test_staleness_check_of_single_thrift_file_with_changed_output(self):
temp_dir = tempfile.mkdtemp(dir=TestStalenessCheck.CURRENT_DIR_PATH)
command = [TestStalenessCheck.THRIFT_EXECUTABLE_PATH, "-gen", "cpp", "-o", temp_dir]
command += [TestStalenessCheck.SINGLE_THRIFT_FILE_PATH]
subprocess.call(command)
used_file_path = os.path.join(temp_dir, "gen-cpp", "Single_constants.cpp")
first_modification_time = os.path.getmtime(os.path.join(used_file_path))
used_file = open(used_file_path, "r")
first_contents = used_file.read()
used_file.close()
used_file = open(used_file_path, "a")
used_file.write("\n/* This is a comment */\n")
used_file.close()
time.sleep(0.1)
subprocess.call(command)
second_modification_time = os.path.getmtime(used_file_path)
used_file = open(used_file_path, "r")
second_contents = used_file.read()
used_file.close()
self.assertGreater(second_modification_time, first_modification_time)
self.assertEqual(first_contents, second_contents)
shutil.rmtree(temp_dir, ignore_errors=True)
def test_staleness_check_of_included_file(self):
temp_dir = tempfile.mkdtemp(dir=TestStalenessCheck.CURRENT_DIR_PATH)
temp_included_file_path = os.path.join(temp_dir, "Included.thrift")
temp_including_file_path = os.path.join(temp_dir, "Including.thrift")
shutil.copy2(TestStalenessCheck.INCLUDED_THRIFT_FILE_PATH, temp_included_file_path)
shutil.copy2(TestStalenessCheck.INCLUDING_THRIFT_FILE_PATH, temp_including_file_path)
command = [TestStalenessCheck.THRIFT_EXECUTABLE_PATH, "-gen", "cpp", "-recurse", "-o", temp_dir]
command += [temp_including_file_path]
subprocess.call(command)
included_constants_cpp_file_path = os.path.join(temp_dir, "gen-cpp", "Included_constants.cpp")
including_constants_cpp_file_path = os.path.join(temp_dir, "gen-cpp", "Including_constants.cpp")
included_constants_cpp_first_modification_time = os.path.getmtime(included_constants_cpp_file_path)
including_constants_cpp_first_modification_time = os.path.getmtime(including_constants_cpp_file_path)
temp_included_file = open(temp_included_file_path, "a")
temp_included_file.write("\nconst i32 an_integer = 42\n")
temp_included_file.close()
time.sleep(0.1)
subprocess.call(command)
included_constants_cpp_second_modification_time = os.path.getmtime(included_constants_cpp_file_path)
including_constants_cpp_second_modification_time = os.path.getmtime(including_constants_cpp_file_path)
self.assertGreater(
included_constants_cpp_second_modification_time, included_constants_cpp_first_modification_time)
self.assertEqual(
including_constants_cpp_first_modification_time, including_constants_cpp_second_modification_time)
shutil.rmtree(temp_dir, ignore_errors=True)
def suite():
suite = unittest.TestSuite()
loader = unittest.TestLoader()
suite.addTest(loader.loadTestsFromTestCase(TestStalenessCheck))
return suite
if __name__ == "__main__":
# The path of Thrift compiler is passed as an argument to the test script.
# Remove it to not confuse the unit testing framework
TestStalenessCheck.THRIFT_EXECUTABLE_PATH = sys.argv[-1]
del sys.argv[-1]
unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))

View file

@ -0,0 +1 @@
const bool return = 0

View file

@ -0,0 +1,2 @@
enum return {
}

View file

@ -0,0 +1,3 @@
enum enum_name {
return
}

View file

@ -0,0 +1 @@
exception return {}

View file

@ -0,0 +1,3 @@
exception exception_name {
1: required i8 return
}

View file

@ -0,0 +1 @@
service return {}

View file

@ -0,0 +1,3 @@
service service_name {
bool function_name(1: i32 return)
}

View file

@ -0,0 +1,3 @@
service service_name {
void return()
}

View file

@ -0,0 +1,5 @@
exception exception_name {}
service service_name {
void function_name() throws ( 1: exception_name return)
}

View file

@ -0,0 +1 @@
struct return {}

View file

@ -0,0 +1,3 @@
struct struct_name {
1: required bool return = 1
}

View file

@ -0,0 +1 @@
typedef bool return

View file

@ -0,0 +1 @@
union return {}

View file

@ -0,0 +1,3 @@
union union_name {
1: optional bool return=1
}

View file

@ -234,6 +234,8 @@ void migrate_global_cache() {
template <typename T>
T* round_trip(T* t) {
typename plugin::ToType<T>::type p;
plugin::clear_global_cache();
plugin_output::clear_global_cache();
plugin_output::convert(t, p);
migrate_global_cache();
return plugin::convert(p);
@ -275,12 +277,12 @@ void test_const_value(t_const_value* sut) {
BOOST_CHECK_EQUAL(sut->get_map().size(), sut2->get_map().size());
{
std::map<t_const_value::t_const_value_type, t_const_value::t_const_value_type> sut_values;
for (std::map<t_const_value*, t_const_value*>::const_iterator it = sut->get_map().begin();
for (std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator it = sut->get_map().begin();
it != sut->get_map().end(); it++) {
sut_values[it->first->get_type()] = it->second->get_type();
}
std::map<t_const_value::t_const_value_type, t_const_value::t_const_value_type> sut2_values;
for (std::map<t_const_value*, t_const_value*>::const_iterator it = sut2->get_map().begin();
for (std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator it = sut2->get_map().begin();
it != sut2->get_map().end(); it++) {
sut2_values[it->first->get_type()] = it->second->get_type();
}

View file

@ -0,0 +1,32 @@
#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# this file is intended to be invoked by make.
#
# This file runs the compiler twice, using a plugin that just invokes
# /bin/cat, and compares the output. If GeneratorInput is
# nondeterminsitic, you'd expect the output to differ from run-to-run.
# So this tests that in fact, the output is stable from run-to-run.
set -e
mkdir -p gen-bincat
PATH=.:"$PATH" ../thrift -r -gen bincat ../../../test/Include.thrift > gen-bincat/1.ser
PATH=.:"$PATH" ../thrift -r -gen bincat ../../../test/Include.thrift > gen-bincat/2.ser
diff --binary gen-bincat/1.ser gen-bincat/2.ser

View file

@ -0,0 +1,153 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
cmake_minimum_required(VERSION 2.8.12)
project(thrift_compiler_tests)
set(THRIFT_COMPILER_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/..
)
# don't generate ZERO_CHECK
set(CMAKE_SUPPRESS_REGENERATION true)
configure_file(${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/thrift/version.h)
if(MSVC)
# The winflexbison generator outputs some macros that conflict with the Visual Studio 2010 copy of stdint.h
# This might be fixed in later versions of Visual Studio, but an easy solution is to include stdint.h first
if(HAVE_STDINT_H)
add_definitions(-D__STDC_LIMIT_MACROS)
add_definitions(/FI"stdint.h")
endif(HAVE_STDINT_H)
endif()
find_package(FLEX REQUIRED)
find_package(BISON REQUIRED)
# create directory for thrifty and thriftl
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/thrift/)
# Create flex and bison files and build the lib parse static library
BISON_TARGET(thrifty ${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/thrifty.yy ${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc)
FLEX_TARGET(thriftl ${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/thriftl.ll ${CMAKE_CURRENT_BINARY_DIR}/thrift/thriftl.cc)
ADD_FLEX_BISON_DEPENDENCY(thriftl thrifty)
set(parse_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.cc
${CMAKE_CURRENT_BINARY_DIR}/thrift/thriftl.cc
${CMAKE_CURRENT_BINARY_DIR}/thrift/thrifty.hh
)
add_library(parse STATIC ${parse_SOURCES})
# Thrift compiler tests
set(thrift_compiler_tests
)
# you can add some files manually there
set(thrift_compiler_tests_manual_SOURCES
# tests file to avoid main in every test file
${CMAKE_CURRENT_SOURCE_DIR}/tests_main.cc
)
# set variable for tests sources - will be filled later
set(thrift_compiler_tests_SOURCES
)
set(thrift_compiler_SOURCES
${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/logging.cc # we use logging instead of main to avoid breaking compillation (2 main v)
${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/audit/t_audit.cpp
${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/common.cc
${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/generate/t_generator.cc
${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/parse/t_typedef.cc
${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/parse/parse.cc
${CMAKE_CURRENT_BINARY_DIR}/thrift/version.h
)
# This macro adds an option THRIFT_COMPILER_${NAME}
# that allows enabling or disabling certain languages
macro(THRIFT_ADD_COMPILER name description initial)
string(TOUPPER "THRIFT_COMPILER_${name}" enabler)
set(src "${THRIFT_COMPILER_SOURCE_DIR}/src/thrift/generate/t_${name}_generator.cc")
option(${enabler} ${description} ${initial})
if(${enabler})
list(APPEND thrift_compiler_SOURCES ${src})
file(GLOB thrift_compiler_tests_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.c*"
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.thrift"
)
endif()
endmacro()
# The following compiler with unit tests can be enabled or disabled
THRIFT_ADD_COMPILER(c_glib "Enable compiler for C with Glib" OFF)
THRIFT_ADD_COMPILER(cpp "Enable compiler for C++" OFF)
THRIFT_ADD_COMPILER(java "Enable compiler for Java" OFF)
THRIFT_ADD_COMPILER(as3 "Enable compiler for ActionScript 3" OFF)
THRIFT_ADD_COMPILER(dart "Enable compiler for Dart" OFF)
THRIFT_ADD_COMPILER(haxe "Enable compiler for Haxe" OFF)
THRIFT_ADD_COMPILER(csharp "Enable compiler for C#" OFF)
THRIFT_ADD_COMPILER(netcore "Enable compiler for .NET Core" ON)
THRIFT_ADD_COMPILER(py "Enable compiler for Python 2.0" OFF)
THRIFT_ADD_COMPILER(rb "Enable compiler for Ruby" OFF)
THRIFT_ADD_COMPILER(perl "Enable compiler for Perl" OFF)
THRIFT_ADD_COMPILER(php "Enable compiler for PHP" OFF)
THRIFT_ADD_COMPILER(erl "Enable compiler for Erlang" OFF)
THRIFT_ADD_COMPILER(cocoa "Enable compiler for Cocoa Objective-C" OFF)
THRIFT_ADD_COMPILER(swift "Enable compiler for Cocoa Swift" OFF)
THRIFT_ADD_COMPILER(st "Enable compiler for Smalltalk" OFF)
THRIFT_ADD_COMPILER(ocaml "Enable compiler for OCaml" OFF)
THRIFT_ADD_COMPILER(hs "Enable compiler for Haskell" OFF)
THRIFT_ADD_COMPILER(xsd "Enable compiler for XSD" OFF)
THRIFT_ADD_COMPILER(html "Enable compiler for HTML Documentation" OFF)
THRIFT_ADD_COMPILER(js "Enable compiler for JavaScript" OFF)
THRIFT_ADD_COMPILER(json "Enable compiler for JSON" OFF)
THRIFT_ADD_COMPILER(javame "Enable compiler for Java ME" OFF)
THRIFT_ADD_COMPILER(delphi "Enable compiler for Delphi" OFF)
THRIFT_ADD_COMPILER(go "Enable compiler for Go" OFF)
THRIFT_ADD_COMPILER(d "Enable compiler for D" OFF)
THRIFT_ADD_COMPILER(lua "Enable compiler for Lua" OFF)
THRIFT_ADD_COMPILER(gv "Enable compiler for GraphViz" OFF)
THRIFT_ADD_COMPILER(rs "Enable compiler for Rust" OFF)
THRIFT_ADD_COMPILER(xml "Enable compiler for XML" OFF)
# Thrift is looking for include files in the src directory
# we also add the current binary directory for generated files
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${THRIFT_COMPILER_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/catch)
add_library(thrift_compiler ${thrift_compiler_SOURCES})
#link parse lib to thrift_compiler lib
target_link_libraries(thrift_compiler parse)
# add tests executable
add_executable(thrift_compiler_tests ${thrift_compiler_tests_manual_SOURCES} ${thrift_compiler_tests_SOURCES})
# if generates for Visual Studio set thrift_compiler_tests as default project
if(MSVC)
set_property(TARGET thrift_compiler_tests PROPERTY VS_STARTUP_PROJECT thrift_compiler_tests)
endif()
set_target_properties(thrift_compiler_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY bin/)
set_target_properties(thrift_compiler_tests PROPERTIES OUTPUT_NAME thrift_compiler_tests)
target_link_libraries(thrift_compiler_tests thrift_compiler)
enable_testing()
add_test(NAME ThriftTests COMMAND thrift_compiler_tests)

View file

@ -0,0 +1,88 @@
# Build and run compiler tests using CMake
<!-- TOC -->
- [Build and run compiler tests using CMake](#build-and-run-compiler-tests-using-cmake)
- [General information](#general-information)
- [How to add your tests](#how-to-add-your-tests)
- [Build and run tests on Unix-like systems](#build-and-run-tests-on-unix-like-systems)
- [Prerequisites:](#prerequisites)
- [Build and run test with CMake](#build-and-run-test-with-cmake)
- [Build and run tests on Windows](#build-and-run-tests-on-windows)
- [Prerequisites:](#prerequisites-1)
- [Generation of VS project with CMake, build and run on Windows](#generation-of-vs-project-with-cmake-build-and-run-on-windows)
<!-- /TOC -->
## General information
Added generic way to cover code by tests for many languages (you just need to make a correct header file for generator for your language - example in **netcore** implementation)
At current moment these tests use free Catch library (https://github.com/catchorg/Catch2/tree/Catch1.x) for easy test creation and usage.
Decision to use it was because of simplicity, easy usage, one header file to use, stable community and growing interest (https://cpp.libhunt.com/project/googletest-google/vs/catch?rel=cmp-cmp)
Also, maybe, later it will be migrated to Catch2 (https://github.com/philsquared/Catch) - depends on need to support legacy compilers (c++98)
## How to add your tests
- Open **CMakeLists.txt**
- Set **On** to call of **THRIFT_ADD_COMPILER** for your language
``` cmake
THRIFT_ADD_COMPILER(netcore "Enable compiler for .NET Core" ON)
```
- Create folder with name specified in list of languages in **CMakeLists.txt**
- Create tests in folder for your language (with extensions like *.c* - cc, cpp, etc)
- Don't forget to add include of catch.hpp in your test file
``` C
#include "../catch/catch.hpp"
```
- If you need - add files manually to **thrift_compiler_tests_manual_SOURCES** in **CMakeLists.txt** similar to
``` cmake
# you can add some files manually there
set(thrift_compiler_tests_manual_SOURCES
# tests file to avoid main in every test file
${CMAKE_CURRENT_SOURCE_DIR}/tests_main.cc
)
```
- Run **cmake** with arguments for your environment and compiler
- Enjoy
## Build and run tests on Unix-like systems
### Prerequisites:
- Install CMake - <https://cmake.org/download/>
- Install winflexbison - <https://sourceforge.net/projects/winflexbison/>
### Build and run test with CMake
- Run commands in command line in current directory:
```
mkdir cmake-vs && cd cmake-vs
cmake ..
cmake --build .
ctest -C Debug -V
```
## Build and run tests on Windows
### Prerequisites:
- Install CMake - <https://cmake.org/download/>
- Install winflexbison - <https://sourceforge.net/projects/winflexbison/>
- Install VS2017 Community Edition - <https://www.visualstudio.com/vs/whatsnew/> (ensure that you installed workload "Desktop Development with C++" for VS2017)
### Generation of VS project with CMake, build and run on Windows
- Run commands in command line in current directory (ensure that VS installed):
```
mkdir cmake-vs
cd cmake-vs
cmake ..
cmake --build .
ctest -C Debug -V
```

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,339 @@
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "../catch/catch.hpp"
#include <thrift/parse/t_program.h>
#include <thrift/generate/t_netcore_generator.h>
#include "t_netcore_generator_functional_tests_helpers.h"
TEST_CASE( "t_netcore_generator should generate valid enum", "[functional]" )
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
std::pair<string, t_enum*> pair = TestDataGenerator::get_test_enum_data(program);
string expected_result = pair.first;
t_enum* test_enum = pair.second;
string file_path = test_enum->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_enum(out, test_enum));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete test_enum;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid void", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
std::pair<string, t_const*> pair = TestDataGenerator::get_test_void_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_THROWS(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
delete const_;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid string with escaping keyword", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
std::pair<string, t_const*> pair = TestDataGenerator::get_test_string_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete const_;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid bool with escaping keyword", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
std::pair<string, t_const*> pair = TestDataGenerator::get_test_bool_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete const_;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid sbyte (i8) with escaping keyword", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
std::pair<string, t_const*> pair = TestDataGenerator::get_test_i8_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete const_;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid short (i16) with escaping keyword", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
std::pair<string, t_const*> pair = TestDataGenerator::get_test_i16_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete const_;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid integer (i32) with escaping keyword", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
std::pair<string, t_const*> pair = TestDataGenerator::get_test_i32_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete const_;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid long (i64) with escaping keyword", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
std::pair<string, t_const*> pair = TestDataGenerator::get_test_i64_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete const_;
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should generate valid double with escaping keyword", "[functional]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
std::pair<string, t_const*> pair = TestDataGenerator::get_test_double_const_data(gen);
string expected_result = pair.first;
t_const* const_ = pair.second;
vector<t_const*> consts_;
consts_.push_back(const_);
string file_path = const_->get_name() + ".cs";
ofstream out;
out.open(file_path.c_str());
REQUIRE_NOTHROW(gen->generate_consts(out, consts_));
out.close();
std::ifstream ifs(file_path);
string actual_result((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
std::remove(file_path.c_str());
REQUIRE(expected_result == actual_result);
delete const_;
delete gen;
delete program;
}

View file

@ -0,0 +1,237 @@
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <thrift/parse/t_program.h>
#include "thrift/common.h"
#include <thrift/generate/t_netcore_generator.h>
#include "t_netcore_generator_functional_tests_helpers.h"
const string TestDataGenerator::DEFAULT_FILE_HEADER = "/**" "\n"
" * Autogenerated by Thrift Compiler ()" "\n"
" *" "\n"
" * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING" "\n"
" * @generated" "\n"
" */";
std::pair<string, t_enum*> TestDataGenerator::get_test_enum_data(t_program* program)
{
string expected_result = DEFAULT_FILE_HEADER +
"\n"
"\n"
"/// <summary>\n"
"/// TestDoc\n"
"/// </summary>\n"
"public enum TestName\n"
"{\n"
" None = 0,\n"
" First = 1,\n"
" Second = 2,\n"
"}\n";
t_enum* enum_ = new t_enum(program);
enum_->set_name("TestName");
enum_->set_doc("TestDoc");
enum_->append(new t_enum_value("None", 0));
enum_->append(new t_enum_value("First", 1));
enum_->append(new t_enum_value("Second", 2));
return std::pair<string, t_enum*>(expected_result, enum_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_void_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER;
t_type* type_ = new t_base_type("void", t_base_type::TYPE_VOID);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_string("VoidValue");
t_const* const_ = new t_const(type_, "void", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_string_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER + "\n" +gen->netcore_type_usings() +
"\n"
"public static class netcoreConstants\n"
"{\n"
" /// <summary>\n"
" /// TestDoc\n"
" /// </summary>\n"
" public const string @string = \"StringValue\";\n"
"}\n";
t_type* type_ = new t_base_type("string", t_base_type::TYPE_STRING);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_string("StringValue");
t_const* const_ = new t_const(type_, "string", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_bool_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER + "\n" +gen->netcore_type_usings() +
"\n"
"public static class netcoreConstants\n"
"{\n"
" /// <summary>\n"
" /// TestDoc\n"
" /// </summary>\n"
" public const bool @bool = true;\n"
"}\n";
t_type* type_ = new t_base_type("bool", t_base_type::TYPE_BOOL);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_integer(1);
t_const* const_ = new t_const(type_, "bool", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_i8_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER + "\n" +gen->netcore_type_usings() +
"\n"
"public static class netcoreConstants\n"
"{\n"
" /// <summary>\n"
" /// TestDoc\n"
" /// </summary>\n"
" public const sbyte @sbyte = 127;\n"
"}\n";
t_type* type_ = new t_base_type("I8", t_base_type::TYPE_I8);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_integer(127);
t_const* const_ = new t_const(type_, "sbyte", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_i16_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER + "\n" +gen->netcore_type_usings() +
"\n"
"public static class netcoreConstants\n"
"{\n"
" /// <summary>\n"
" /// TestDoc\n"
" /// </summary>\n"
" public const short @short = 32767;\n"
"}\n";
t_type* type_ = new t_base_type("i16", t_base_type::TYPE_I16);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_integer(32767);
t_const* const_ = new t_const(type_, "short", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_i32_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER + "\n" +gen->netcore_type_usings() +
"\n"
"public static class netcoreConstants\n"
"{\n"
" /// <summary>\n"
" /// TestDoc\n"
" /// </summary>\n"
" public const int @int = 2147483647;\n"
"}\n";
t_type* type_ = new t_base_type("i32", t_base_type::TYPE_I32);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_integer(2147483647);
t_const* const_ = new t_const(type_, "int", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_i64_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER + "\n" +gen->netcore_type_usings() +
"\n"
"public static class netcoreConstants\n"
"{\n"
" /// <summary>\n"
" /// TestDoc\n"
" /// </summary>\n"
" public const long @long = 9223372036854775807;\n"
"}\n";
t_type* type_ = new t_base_type("i64", t_base_type::TYPE_I64);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_integer(9223372036854775807);
t_const* const_ = new t_const(type_, "long", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}
std::pair<string, t_const*> TestDataGenerator::get_test_double_const_data(t_netcore_generator* gen)
{
string expected_result = DEFAULT_FILE_HEADER + "\n" +gen->netcore_type_usings() +
"\n"
"public static class netcoreConstants\n"
"{\n"
" /// <summary>\n"
" /// TestDoc\n"
" /// </summary>\n"
" public const double @double = 9.22337e+18;\n"
"}\n";
t_type* type_ = new t_base_type("double", t_base_type::TYPE_DOUBLE);
type_->set_doc("TestDoc");
t_const_value* const_value_ = new t_const_value();
const_value_->set_double(9223372036854775807.1);
t_const* const_ = new t_const(type_, "double", const_value_);
const_->set_doc("TestDoc");
return std::pair<string, t_const*>(expected_result, const_);
}

View file

@ -0,0 +1,34 @@
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <thrift/parse/t_program.h>
class TestDataGenerator
{
public:
static const string DEFAULT_FILE_HEADER;
static std::pair<string, t_enum*> get_test_enum_data(t_program* program);
static std::pair<string, t_const*> get_test_void_const_data(t_netcore_generator* gen);
static std::pair<string, t_const*> get_test_string_const_data(t_netcore_generator* gen);
static std::pair<string, t_const*> get_test_bool_const_data(t_netcore_generator* gen);
static std::pair<string, t_const*> get_test_i8_const_data(t_netcore_generator* gen);
static std::pair<string, t_const*> get_test_i16_const_data(t_netcore_generator* gen);
static std::pair<string, t_const*> get_test_i32_const_data(t_netcore_generator* gen);
static std::pair<string, t_const*> get_test_i64_const_data(t_netcore_generator* gen);
static std::pair<string, t_const*> get_test_double_const_data(t_netcore_generator* gen);
};

View file

@ -0,0 +1,209 @@
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "../catch/catch.hpp"
#include <thrift/parse/t_program.h>
#include <thrift/generate/t_netcore_generator.h>
using std::vector;
TEST_CASE("t_netcore_generator::netcore_type_usings() without option wcf should return valid namespaces", "[helpers]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "union", "union" } };
string option_string = "";
string expected_namespaces = "using System;\n"
"using System.Collections;\n"
"using System.Collections.Generic;\n"
"using System.Text;\n"
"using System.IO;\n"
"using System.Threading;\n"
"using System.Threading.Tasks;\n"
"using Thrift;\n"
"using Thrift.Collections;\n" + endl;
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
REQUIRE_FALSE(gen->is_wcf_enabled());
REQUIRE(gen->netcore_type_usings() == expected_namespaces);
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator::netcore_type_usings() with option wcf should return valid namespaces", "[helpers]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
string expected_namespaces_wcf = "using System;\n"
"using System.Collections;\n"
"using System.Collections.Generic;\n"
"using System.Text;\n"
"using System.IO;\n"
"using System.Threading;\n"
"using System.Threading.Tasks;\n"
"using Thrift;\n"
"using Thrift.Collections;\n"
"using System.ServiceModel;\n"
"using System.Runtime.Serialization;\n" + endl;
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
REQUIRE(gen->is_wcf_enabled());
REQUIRE(gen->netcore_type_usings() == expected_namespaces_wcf);
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should contains latest C# keywords to normalize with @", "[helpers]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" } };
string option_string = "";
vector<string> current_keywords = {
{ "abstract" },
{ "as" },
{ "base" },
{ "bool" },
{ "break" },
{ "byte" },
{ "case" },
{ "catch" },
{ "char" },
{ "checked" },
{ "class" },
{ "const" },
{ "continue" },
{ "decimal" },
{ "default" },
{ "delegate" },
{ "do" },
{ "double" },
{ "else" },
{ "enum" },
{ "event" },
{ "explicit" },
{ "extern" },
{ "false" },
{ "finally" },
{ "fixed" },
{ "float" },
{ "for" },
{ "foreach" },
{ "goto" },
{ "if" },
{ "implicit" },
{ "in" },
{ "int" },
{ "interface" },
{ "internal" },
{ "is" },
{ "lock" },
{ "long" },
{ "namespace" },
{ "new" },
{ "null" },
{ "object" },
{ "operator" },
{ "out" },
{ "override" },
{ "params" },
{ "private" },
{ "protected" },
{ "public" },
{ "readonly" },
{ "ref" },
{ "return" },
{ "sbyte" },
{ "sealed" },
{ "short" },
{ "sizeof" },
{ "stackalloc" },
{ "static" },
{ "string" },
{ "struct" },
{ "switch" },
{ "this" },
{ "throw" },
{ "true" },
{ "try" },
{ "typeof" },
{ "uint" },
{ "ulong" },
{ "unchecked" },
{ "unsafe" },
{ "ushort" },
{ "using" },
{ "void" },
{ "volatile" },
{ "while" },
// Contextual Keywords
{ "add" },
{ "alias" },
{ "ascending" },
{ "async" },
{ "await" },
{ "descending" },
{ "dynamic" },
{ "from" },
{ "get" },
{ "global" },
{ "group" },
{ "into" },
{ "join" },
{ "let" },
{ "orderby" },
{ "partial" },
{ "remove" },
{ "select" },
{ "set" },
{ "value" },
{ "var" },
{ "when" },
{ "where" },
{ "yield" }
};
string missed_keywords = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
gen->init_generator();
map<string, int> generators_keywords = gen->get_keywords_list();
for (vector<string>::iterator it = current_keywords.begin(); it != current_keywords.end(); ++it)
{
if (generators_keywords.find(*it) == generators_keywords.end())
{
missed_keywords = missed_keywords + *it + ",";
}
}
REQUIRE(missed_keywords == "");
delete gen;
delete program;
}

View file

@ -0,0 +1,74 @@
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "../catch/catch.hpp"
#include <thrift/parse/t_program.h>
#include <thrift/generate/t_netcore_generator.h>
TEST_CASE( "t_netcore_generator should throw error with unknown options", "[initialization]" )
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "keys", "keys" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = nullptr;
REQUIRE_THROWS(gen = new t_netcore_generator(program, parsed_options, option_string));
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should create valid instance with valid options", "[initialization]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" }, { "nullable", "nullable"} };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = nullptr;
REQUIRE_NOTHROW(gen = new t_netcore_generator(program, parsed_options, option_string));
REQUIRE(gen != nullptr);
REQUIRE(gen->is_wcf_enabled());
REQUIRE(gen->is_nullable_enabled());
REQUIRE_FALSE(gen->is_hashcode_enabled());
REQUIRE_FALSE(gen->is_serialize_enabled());
REQUIRE_FALSE(gen->is_union_enabled());
delete gen;
delete program;
}
TEST_CASE("t_netcore_generator should pass init succesfully", "[initialization]")
{
string path = "CassandraTest.thrift";
string name = "netcore";
map<string, string> parsed_options = { { "wcf", "wcf" },{ "nullable", "nullable" } };
string option_string = "";
t_program* program = new t_program(path, name);
t_netcore_generator* gen = new t_netcore_generator(program, parsed_options, option_string);
REQUIRE_NOTHROW(gen->init_generator());
delete gen;
delete program;
}

View file

@ -0,0 +1,19 @@
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#define CATCH_CONFIG_MAIN
#include "catch/catch.hpp"