mirror of
https://github.com/tars-node/tars2node.git
synced 2024-03-22 13:10:56 +08:00
version: 20190320
This commit is contained in:
parent
59b01b3d3c
commit
3aef9a315f
|
@ -7,7 +7,7 @@ set(CMAKE_VERBOSE_MAKEFILE off)
|
|||
# version
|
||||
set(TARS_VERSION "1.1.0")
|
||||
set(PARSER_VERSION "${TARS_VERSION}")
|
||||
set(GENERATOR_VERSION "20190109")
|
||||
set(GENERATOR_VERSION "20190320")
|
||||
|
||||
# namespace
|
||||
set(IDL_NAMESPACE Tars)
|
||||
|
@ -21,8 +21,8 @@ set(IDL_TYPE "Tars")
|
|||
set(PROTOCOL_NAME "Tup")
|
||||
|
||||
# flag
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O2 -Wall -Wno-sign-compare -Wno-unused-result")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O2 -Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O2 -Wall -Wno-sign-compare -Wno-unused-result -static")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O2 -Wall -static")
|
||||
|
||||
# define
|
||||
add_definitions(-DTARS_VERSION="${TARS_VERSION}")
|
||||
|
|
|
@ -27,6 +27,7 @@ tars2node [OPTIONS] tarsfile
|
|||
| --r-reserved | 精简依赖文件时需保留的成员。|
|
||||
| --client | 生成客户端的调用类代码。|
|
||||
| --server | 生成服务端的框架代码。|
|
||||
| --ts | 打开此选项将后将只生成 TypeScript (.ts) 代码。|
|
||||
| --dts | 生成时附加 TypeScript 描述文件(.d.ts)。|
|
||||
| --use-string-represent | 当需要保持 <long> 类型的精度时,打开此选项使用 \<string\> 存储 \<long\>。|
|
||||
| --string-binary-encoding | 遇到字符编码问题或需对原始数据进行存取时,打开此选项使用 \<buffer\> 存储 \<string\>。|
|
||||
|
|
BIN
build/tars2node
BIN
build/tars2node
Binary file not shown.
|
@ -53,26 +53,47 @@ void CodeGenerator::createFile(const string &file, const bool bEntry)
|
|||
{
|
||||
if (_sIdlFile == contexts[i]->getFileName())
|
||||
{
|
||||
scan(_sIdlFile, true); //分析枚举值、结构体所在的文件
|
||||
scan(_sIdlFile, true); // collect idl symbols
|
||||
|
||||
if (!_bClient && !_bServer)
|
||||
{
|
||||
generateJS(contexts[i]); //生成当前文件的编解码文件
|
||||
if(_bDTS) generateDTS(contexts[i]); //生成 typescript 描述文件
|
||||
if (_bTS)
|
||||
{
|
||||
generateTS(contexts[i]); // generate .ts
|
||||
}
|
||||
else
|
||||
{
|
||||
generateJS(contexts[i]); // generate .js
|
||||
if (_bDTS) generateDTS(contexts[i]); // generate .d.ts
|
||||
}
|
||||
}
|
||||
|
||||
if (_bClient)
|
||||
{
|
||||
if(!generateJSProxy(contexts[i])) return; //生成当前文件的客户端代理类文件
|
||||
if(_bDTS) generateDTSProxy(contexts[i]); //生成客户端 typescript 描述文件
|
||||
if (_bTS)
|
||||
{
|
||||
if (!generateTSProxy(contexts[i])) return; // generate .ts for proxy classes
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!generateJSProxy(contexts[i])) return; // generate .js for proxy classes
|
||||
if (_bDTS) generateDTSProxy(contexts[i]); // generate .d.ts for proxy classes
|
||||
}
|
||||
}
|
||||
|
||||
if (_bServer)
|
||||
{
|
||||
if(!generateJSServer(contexts[i])) return; //生成当前文件的服务端代理类文件
|
||||
if(_bDTS) generateDTSServer(contexts[i]); //生成服务端 typescript 描述文件
|
||||
|
||||
generateJSServerImp(contexts[i]); //生成当前文件的服务端实现类文件
|
||||
if (_bTS)
|
||||
{
|
||||
if (!generateTSServer(contexts[i])) return; // generate .ts for server classes
|
||||
generateTSServerImp(contexts[i]); // generate .ts for server implementations
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!generateJSServer(contexts[i])) return; // generate .js for server classes
|
||||
if (_bDTS) generateDTSServer(contexts[i]); // generate .d.ts for server classes
|
||||
generateJSServerImp(contexts[i]); // generate .js for server implementations
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> files = contexts[i]->getIncludes();
|
||||
|
@ -88,6 +109,7 @@ void CodeGenerator::createFile(const string &file, const bool bEntry)
|
|||
node.setStringBinaryEncoding(_bStringBinaryEncoding);
|
||||
node.setMinimalMembers(_bMinimalMembers);
|
||||
node.setDependent(_depMembers);
|
||||
node.setEnableTS(_bTS);
|
||||
node.setEnableDTS(_bDTS);
|
||||
|
||||
node.createFile(files[ii], false);
|
||||
|
|
322
src/code_generator.h
Normal file
322
src/code_generator.h
Normal file
|
@ -0,0 +1,322 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _CODEGENERATOR_H
|
||||
#define _CODEGENERATOR_H
|
||||
|
||||
#include "parse.h"
|
||||
#include "util/tc_file.h"
|
||||
#include "util/tc_encoder.h"
|
||||
#include <set>
|
||||
|
||||
#ifndef TAB
|
||||
#define TAB g_parse->getTab()
|
||||
#endif
|
||||
|
||||
#ifndef INC_TAB
|
||||
#define INC_TAB g_parse->incTab()
|
||||
#endif
|
||||
|
||||
#ifndef DEL_TAB
|
||||
#define DEL_TAB g_parse->delTab()
|
||||
#endif
|
||||
|
||||
#define TO_LOWER_STRING(str) TC_Common::lower(str)
|
||||
|
||||
#define DEFINE_STRING(str) string(CSTR(str))
|
||||
#define CSTR(str) #str
|
||||
#define IDL_NAMESPACE_STR DEFINE_STRING(IDL_NAMESPACE)
|
||||
|
||||
#define GET_CONST_GRAMMAR_PTR_V(name, ptr) \
|
||||
ptr->getConst##name##Ptr()
|
||||
#define GET_CONST_GRAMMAR_PTR_BASE(name, ptr) \
|
||||
GET_CONST_GRAMMAR_PTR_V(name, ptr)
|
||||
#define GET_CONST_GRAMMAR_PTR(ptr) \
|
||||
GET_CONST_GRAMMAR_PTR_BASE(GRAMMAR_NAME, ptr)
|
||||
|
||||
#define CONST_GRAMMAR_V(name, val) \
|
||||
Const##name::val
|
||||
#define CONST_GRAMMAR_BASE(name, val) \
|
||||
CONST_GRAMMAR_V(name, val)
|
||||
#define CONST_GRAMMAR(val) \
|
||||
CONST_GRAMMAR_BASE(GRAMMAR_NAME, val)
|
||||
|
||||
#define PROTOCOL_V(space, protocol, type) \
|
||||
space + "Stream." + protocol + "." + TC_Common::upper(protocol) + "_" + type
|
||||
#define PROTOCOL_SIMPLE PROTOCOL_V(IDL_NAMESPACE_STR, PROTOCOL_NAME, "SIMPLE")
|
||||
#define PROTOCOL_COMPLEX PROTOCOL_V(IDL_NAMESPACE_STR, PROTOCOL_NAME, "COMPLEX")
|
||||
#define PROTOCOL_VAR TO_LOWER_STRING(PROTOCOL_NAME)
|
||||
|
||||
#define DISABLE_ESLINT "/* eslint-disable */"
|
||||
#define DISABLE_TSLINT "/* tslint:disable */"
|
||||
|
||||
using namespace TC_NAMESPACE;
|
||||
|
||||
class CodeGenerator
|
||||
{
|
||||
public:
|
||||
CodeGenerator()
|
||||
: uiNameIndex(0),
|
||||
_sRpcPath(RPC_MODULE_PATH),
|
||||
_sStreamPath(STREAM_MODULE_PATH),
|
||||
_sToPath("./"),
|
||||
_bClient(false),
|
||||
_bServer(false),
|
||||
_bRecursive(false),
|
||||
_bUseSpecialPath(false),
|
||||
_bUseStringRepresent(false),
|
||||
_bStringBinaryEncoding(false),
|
||||
_bEnumReverseMappings(false),
|
||||
_bMinimalMembers(false),
|
||||
_bTS(false),
|
||||
_bDTS(false),
|
||||
_iOptimizeLevel(O0) {}
|
||||
|
||||
void createFile(const string& file, const bool bEntry = true);
|
||||
|
||||
void setRpcPath(const string& sPath) { _sRpcPath = sPath; }
|
||||
|
||||
void setStreamPath(const string& sPath) { _sStreamPath = sPath; }
|
||||
|
||||
void setEnableClient(bool bEnable) { _bClient = bEnable; }
|
||||
|
||||
void setEnableServer(bool bEnable) { _bServer = bEnable; }
|
||||
|
||||
void setTargetPath(const string& sPath) { _sToPath = sPath + "/"; }
|
||||
|
||||
void setRecursive(bool bEnable) { _bRecursive = bEnable; }
|
||||
|
||||
void setUseSpecialPath(bool bEnable) { _bUseSpecialPath = bEnable; }
|
||||
|
||||
void setUseStringRepresent(bool bEnable) { _bUseStringRepresent = bEnable; }
|
||||
|
||||
void setStringBinaryEncoding(bool bEnable) { _bStringBinaryEncoding = bEnable; }
|
||||
|
||||
void setEnumReverseMappings(bool bEnable) { _bEnumReverseMappings = bEnable; }
|
||||
|
||||
void setMinimalMembers(bool bEnable) { _bMinimalMembers = bEnable; }
|
||||
|
||||
void setDependent(set<string>& deps) { _depMembers = deps; }
|
||||
|
||||
void setEnableTS(bool bEnable) { _bTS = bEnable; }
|
||||
|
||||
void setEnableDTS(bool bEnable) { _bDTS = bEnable; }
|
||||
|
||||
void setOptimize(int iLevel) { _iOptimizeLevel = iLevel; }
|
||||
|
||||
enum OPTIMIZE_LEVEL {O0 = 0, Os};
|
||||
|
||||
private:
|
||||
struct ImportFileType
|
||||
{
|
||||
enum TYPE_T {EN_ENUM = 10000, EN_ENUM_VALUE, EN_STRUCT};
|
||||
int iType;
|
||||
string sNamespace;
|
||||
string sTypeName;
|
||||
string sName;
|
||||
};
|
||||
|
||||
struct ImportFile
|
||||
{
|
||||
string sFile;
|
||||
string sModule;
|
||||
map<string, ImportFileType> mapVars;
|
||||
};
|
||||
|
||||
uint32_t uiNameIndex;
|
||||
|
||||
map<string, ImportFile> _mapFiles;
|
||||
|
||||
set<string> _depMembers;
|
||||
|
||||
void scan(const string & sFile, bool bNotPrefix);
|
||||
|
||||
string makeName();
|
||||
|
||||
string findName(const string & sNamespace, const string & sName, const bool &bBase = false);
|
||||
|
||||
private:
|
||||
string toFunctionName(const TypeIdPtr & pPtr, const string &sAction);
|
||||
|
||||
string getDataType(const TypePtr& pPtr, const bool &bCastEnumAsAny = false);
|
||||
|
||||
string getClassName(const TypePtr& pPtr);
|
||||
|
||||
string getTsType(const TypePtr &pPtr, const bool bStream = true, const bool bBase = false);
|
||||
|
||||
string getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string & sNamespace);
|
||||
|
||||
string getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string & sNamespace, const bool bGlobal);
|
||||
|
||||
private:
|
||||
string generateJS(const StructPtr &pPtr, const string &sNamespace, bool &bNeedAssert, bool &bQuickFunc);
|
||||
|
||||
string generateJS(const ConstPtr &pPtr, const string &sNamespace, bool &bNeedStream);
|
||||
|
||||
string generateJS(const EnumPtr &pPtr, const string &sNamespace);
|
||||
|
||||
string generateJS(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedAssert, bool &bQuickFunc);
|
||||
|
||||
bool generateJS(const ContextPtr &pPtr);
|
||||
|
||||
private:
|
||||
string generateTS(const StructPtr &pPtr, const string &sNamespace, bool &bNeedAssert, bool &bQuickFunc);
|
||||
|
||||
string generateTS(const ConstPtr &pPtr, const string &sNamespace, bool &bNeedStream);
|
||||
|
||||
string generateTS(const EnumPtr &pPtr, const string &sNamespace);
|
||||
|
||||
string generateTS(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedAssert, bool &bQuickFunc);
|
||||
|
||||
string generateTS(const NamespacePtr &pPtr, const string &sContent);
|
||||
|
||||
void generateTS(const ContextPtr &cPtr);
|
||||
|
||||
private:
|
||||
string generateJSProxy(const NamespacePtr &nPtr, bool &bNeedRpc, bool &bNeedStream);
|
||||
|
||||
string generateJSProxy(const NamespacePtr &nPtr, const InterfacePtr &pPtr);
|
||||
|
||||
string generateJSProxy(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
bool generateJSProxy(const ContextPtr &pPtr);
|
||||
|
||||
private:
|
||||
string generateTSProxy(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedRpc);
|
||||
|
||||
string generateTSProxy(const NamespacePtr &nPtr, const InterfacePtr &pPtr);
|
||||
|
||||
string generateTSProxy(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
bool generateTSProxy(const ContextPtr &pPtr);
|
||||
|
||||
private:
|
||||
string generateJSServer(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedRpc, bool &bNeedAssert);
|
||||
|
||||
string generatePing(const NamespacePtr &nPtr, const InterfacePtr &pPtr);
|
||||
|
||||
string generateAsync(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
string generateDispatch(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
string generateJSServer(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
string generateJSServer(const InterfacePtr &pPtr, const NamespacePtr &nPtr);
|
||||
|
||||
bool generateJSServer(const ContextPtr &pPtr);
|
||||
|
||||
private:
|
||||
string generateTSServerAsync(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
string generateTSServerDispatch(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
string generateTSServer(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedRpc, bool &bNeedAssert);
|
||||
|
||||
string generateTSServer(const InterfacePtr &pPtr, const NamespacePtr &nPtr);
|
||||
|
||||
bool generateTSServer(const ContextPtr &pPtr);
|
||||
|
||||
private:
|
||||
string generateJSServerImp(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr);
|
||||
|
||||
string generateJSServerImp(const NamespacePtr &nPtr, const InterfacePtr &pPtr);
|
||||
|
||||
string generateJSServerImp(const ContextPtr &cPtr, const NamespacePtr &nPtr);
|
||||
|
||||
void generateJSServerImp(const ContextPtr &cPtr);
|
||||
|
||||
private:
|
||||
void generateTSServerImp(const ContextPtr &cPtr);
|
||||
|
||||
private:
|
||||
string generateDTS(const StructPtr &pPtr, const string &sNamespace);
|
||||
|
||||
string generateDTS(const ConstPtr &pPtr, const string &sNamespace, bool &bNeedStream);
|
||||
|
||||
string generateDTS(const EnumPtr &pPtr, const string &sNamespace);
|
||||
|
||||
string generateDTS(const NamespacePtr &pPtr, bool &bNeedStream);
|
||||
|
||||
string generateDTS(const NamespacePtr &pPtr, const string &sContent);
|
||||
|
||||
void generateDTS(const ContextPtr &cPtr);
|
||||
|
||||
private:
|
||||
string generateDTSServer(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedRpc);
|
||||
|
||||
string generateDTSServer(const NamespacePtr &nPtr, const InterfacePtr &pPtr);
|
||||
|
||||
void generateDTSServer(const ContextPtr &cPtr);
|
||||
|
||||
private:
|
||||
string generateDTSProxy(const InterfacePtr &pPtr);
|
||||
|
||||
string generateDTSProxy(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedRpc);
|
||||
|
||||
void generateDTSProxy(const ContextPtr &pPtr);
|
||||
|
||||
private:
|
||||
void makeUTF8File(const string & sFileName, const string & sFileContent);
|
||||
|
||||
bool isSimple(const TypePtr & pPtr) const;
|
||||
|
||||
bool isBinBuffer(const TypePtr & pPtr) const;
|
||||
|
||||
bool isRawOrString(const TypePtr & pPtr) const;
|
||||
|
||||
bool isDependent(const string & sNamespace, const string & sName) const;
|
||||
|
||||
string getRealFileInfo(const string & sPath);
|
||||
|
||||
string printHeaderRemark(const string &sTypeName);
|
||||
|
||||
string printHeaderRemark(const string &sTypeName, const string &sSuffix);
|
||||
|
||||
private:
|
||||
string _sRpcPath;
|
||||
|
||||
string _sStreamPath;
|
||||
|
||||
string _sToPath;
|
||||
|
||||
bool _bClient;
|
||||
|
||||
bool _bServer;
|
||||
|
||||
bool _bRecursive;
|
||||
|
||||
bool _bUseSpecialPath;
|
||||
|
||||
bool _bUseStringRepresent;
|
||||
|
||||
bool _bStringBinaryEncoding;
|
||||
|
||||
bool _bEnumReverseMappings;
|
||||
|
||||
bool _bMinimalMembers;
|
||||
|
||||
bool _bEntry;
|
||||
|
||||
string _sIdlFile;
|
||||
|
||||
bool _bTS;
|
||||
|
||||
bool _bDTS;
|
||||
|
||||
int _iOptimizeLevel;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -73,7 +73,6 @@ string CodeGenerator::generateJS(const EnumPtr &pPtr, const string &sNamespace)
|
|||
s << TAB << "};" << endl;
|
||||
}
|
||||
|
||||
//函数
|
||||
s << TAB << sNamespace << "." << pPtr->getId() << "._classname = \"" << sNamespace << "." << pPtr->getId() << "\";" << endl;
|
||||
s << TAB << sNamespace << "." << pPtr->getId() << "._write = function(os, tag, val) { return os.writeInt32(tag, val); };" << endl;
|
||||
s << TAB << sNamespace << "." << pPtr->getId() << "._read = function(is, tag, def) { return is.readInt32(tag, true, def); };" << endl;
|
||||
|
@ -390,7 +389,7 @@ bool CodeGenerator::generateJS(const ContextPtr &pPtr)
|
|||
}
|
||||
}
|
||||
|
||||
//先生成编解码体
|
||||
// generate encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedAssert = false;
|
||||
bool bNeedStream = false;
|
||||
|
@ -404,7 +403,7 @@ bool CodeGenerator::generateJS(const ContextPtr &pPtr)
|
|||
return false;
|
||||
}
|
||||
|
||||
//再生成导入模块
|
||||
// generate module imports
|
||||
ostringstream ostr;
|
||||
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
|
||||
{
|
||||
|
@ -415,7 +414,7 @@ bool CodeGenerator::generateJS(const ContextPtr &pPtr)
|
|||
ostr << "var " << it->second.sModule << " = require(\"" << it->second.sFile << "\");" << endl;
|
||||
}
|
||||
|
||||
//生成文件内容
|
||||
// concat generated code
|
||||
ostringstream sstr;
|
||||
sstr << printHeaderRemark("Structure", DISABLE_ESLINT);
|
||||
sstr << "\"use strict\";" << endl << endl;
|
||||
|
|
|
@ -24,7 +24,6 @@ string CodeGenerator::generateDTS(const EnumPtr &pPtr, const string &sNamespace)
|
|||
s << TAB << (_bEnumReverseMappings ? "enum " : "const enum ") << pPtr->getId() << " {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
//成员变量
|
||||
int nenum = -1;
|
||||
bool bDependent = false;
|
||||
vector<TypeIdPtr>& member = pPtr->getAllMemberPtr();
|
||||
|
@ -39,7 +38,7 @@ string CodeGenerator::generateDTS(const EnumPtr &pPtr, const string &sNamespace)
|
|||
{
|
||||
nenum++;
|
||||
}
|
||||
s << TAB << "\"" << member[i]->getId() << "\" = " << TC_Common::tostr(nenum) << ((i < member.size() - 1) ? "," : "") << endl;
|
||||
s << TAB << member[i]->getId() << " = " << TC_Common::tostr(nenum) << ((i < member.size() - 1) ? "," : "") << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
|
||||
|
@ -68,7 +67,7 @@ string CodeGenerator::generateDTS(const ConstPtr &pPtr, const string &sNamespace
|
|||
|
||||
INC_TAB;
|
||||
s << TAB << "const " << pPtr->getTypeIdPtr()->getId() << ":"
|
||||
<< getDtsType(pPtr->getTypeIdPtr()->getTypePtr()) << ";"
|
||||
<< getTsType(pPtr->getTypeIdPtr()->getTypePtr()) << ";"
|
||||
<< endl;
|
||||
DEL_TAB;
|
||||
return s.str();
|
||||
|
@ -81,29 +80,9 @@ string CodeGenerator::generateDTS(const StructPtr &pPtr, const string &sNamespac
|
|||
return "";
|
||||
}
|
||||
|
||||
string sStructName = pPtr->getId() + "$OBJ";
|
||||
vector<TypeIdPtr> &member = pPtr->getAllMemberPtr();
|
||||
INC_TAB;
|
||||
|
||||
ostringstream istr;
|
||||
bool bNever = false;
|
||||
istr << TAB << "interface " << sStructName << " {" << endl;
|
||||
INC_TAB;
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
const string &sType = getDtsType(member[i]->getTypePtr(), false);
|
||||
if (!sType.empty())
|
||||
{
|
||||
istr << TAB << (member[i]->getId()) << (member[i]->isRequire()?": ":"?: ") << sType << ";" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
bNever = true;
|
||||
}
|
||||
}
|
||||
DEL_TAB;
|
||||
istr << TAB << "}" << endl;
|
||||
|
||||
|
||||
ostringstream s;
|
||||
s << TAB << "class " << pPtr->getId() << " {" << endl;
|
||||
|
@ -111,7 +90,7 @@ string CodeGenerator::generateDTS(const StructPtr &pPtr, const string &sNamespac
|
|||
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
s << TAB << (member[i]->getId()) << (member[i]->isRequire()?": ":"?: ") << getDtsType(member[i]->getTypePtr()) << ";" << endl;
|
||||
s << TAB << (member[i]->getId()) << ": " << getTsType(member[i]->getTypePtr()) << ";" << endl;
|
||||
}
|
||||
if (member.size() > 0)
|
||||
{
|
||||
|
@ -125,16 +104,28 @@ string CodeGenerator::generateDTS(const StructPtr &pPtr, const string &sNamespac
|
|||
*/
|
||||
if (_iOptimizeLevel != Os)
|
||||
{
|
||||
s << TAB << "toObject(): " << (bNever ? "never" : sStructName) << ";" << endl;
|
||||
s << TAB << "readFromObject(json: " << sStructName << "): " << pPtr->getId() << ";" << endl;
|
||||
s << TAB << "toObject(): " << pPtr->getId() << ".Object;" << endl;
|
||||
s << TAB << "readFromObject(json: " << pPtr->getId() << ".Object): " << pPtr->getId() << ";" << endl;
|
||||
s << TAB << "toBinBuffer(): " << IDL_NAMESPACE_STR << "Stream.BinBuffer;" << endl;
|
||||
s << TAB << "static new(): " << pPtr->getId() << ";" << endl;
|
||||
s << TAB << "static create(is: " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "InputStream): " << pPtr->getId() << ";" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
s << istr.str();
|
||||
s << TAB << "namespace " << pPtr->getId() << " {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "interface Object {" << endl;
|
||||
INC_TAB;
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
const string &sType = getTsType(member[i]->getTypePtr(), false);
|
||||
s << TAB << (member[i]->getId()) << (member[i]->isRequire() ? ": " : "?: ") << (!sType.empty() ? sType : "never") << ";" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
|
||||
|
@ -143,7 +134,7 @@ string CodeGenerator::generateDTS(const StructPtr &pPtr, const string &sNamespac
|
|||
|
||||
string CodeGenerator::generateDTS(const NamespacePtr &pPtr, bool &bNeedStream)
|
||||
{
|
||||
//结构
|
||||
// struct
|
||||
ostringstream sstr;
|
||||
vector<StructPtr> ss(pPtr->getAllStructPtr());
|
||||
for (size_t last = 0; last != ss.size() && ss.size() != 0;)
|
||||
|
@ -164,7 +155,7 @@ string CodeGenerator::generateDTS(const NamespacePtr &pPtr, bool &bNeedStream)
|
|||
}
|
||||
}
|
||||
|
||||
//常量
|
||||
// const
|
||||
ostringstream cstr;
|
||||
vector<ConstPtr> &cs = pPtr->getAllConstPtr();
|
||||
for (size_t i = 0; i < cs.size(); i++)
|
||||
|
@ -172,7 +163,7 @@ string CodeGenerator::generateDTS(const NamespacePtr &pPtr, bool &bNeedStream)
|
|||
cstr << generateDTS(cs[i], pPtr->getId(), bNeedStream);
|
||||
}
|
||||
|
||||
//枚举
|
||||
// enum
|
||||
ostringstream estr;
|
||||
vector<EnumPtr> &es = pPtr->getAllEnumPtr();
|
||||
for (size_t i = 0; i < es.size(); i++)
|
||||
|
@ -208,7 +199,7 @@ void CodeGenerator::generateDTS(const ContextPtr &pPtr)
|
|||
{
|
||||
vector<NamespacePtr> namespaces = pPtr->getNamespaces();
|
||||
|
||||
//先生成编解码体
|
||||
// generate encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedStream = false;
|
||||
for (size_t i = 0; i < namespaces.size(); i++)
|
||||
|
@ -220,7 +211,7 @@ void CodeGenerator::generateDTS(const ContextPtr &pPtr)
|
|||
return;
|
||||
}
|
||||
|
||||
//再生成导入模块
|
||||
// generate module imports
|
||||
ostringstream ostr;
|
||||
if (bNeedStream)
|
||||
{
|
||||
|
@ -236,7 +227,7 @@ void CodeGenerator::generateDTS(const ContextPtr &pPtr)
|
|||
ostr << "import * as " << it->second.sModule << " from \"" << TC_File::excludeFileExt(it->second.sFile) << "\";" << endl;
|
||||
}
|
||||
|
||||
//生成文件内容
|
||||
// concat generated code
|
||||
ostringstream sstr;
|
||||
sstr << printHeaderRemark("Structure", DISABLE_TSLINT);
|
||||
sstr << ostr.str() << endl;
|
||||
|
|
|
@ -51,7 +51,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
sParams += (sParams.empty()?"":", ") + vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
}
|
||||
|
||||
//SETP01 生成函数声明(Interface = IF)
|
||||
// generate function metadata (SharedFunctionInfo)
|
||||
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$IF = {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
|
@ -88,7 +88,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
|
||||
str << TAB << "};" << endl << endl;
|
||||
|
||||
//SETP02 生成 IDL 编码接口(IDL Encoder = IE)
|
||||
// generate IDL Encoder ($IE)
|
||||
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$IE = function (" << sParams << ") {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
|
@ -103,7 +103,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
<< (i + 1) << ", " << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
|
||||
// 写入 Dependent 列表
|
||||
// push the symbol into dependent list
|
||||
getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
|
||||
str << TAB << "};" << endl << endl;
|
||||
|
||||
//STEP03 生成 IDL 解码函数(IDL Decoder = ID)
|
||||
// generate IDL Decoder ($ID)
|
||||
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$ID = function (data) {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "try {" << endl;
|
||||
|
@ -205,7 +205,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
DEL_TAB;
|
||||
str << TAB << "};" << endl << endl;
|
||||
|
||||
//SETP04 生成 Protocol 编码接口(Protocol Encoder = PE)
|
||||
// generate Protocol Encoder ($PE)
|
||||
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$PE = function ("
|
||||
<< sParams << (sParams.empty() ? "" : ", ") << "__$PROTOCOL$VERSION) {" << endl;
|
||||
|
||||
|
@ -223,7 +223,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
<< vParamDecl[i]->getTypeIdPtr()->getId() << "\", " << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
|
||||
// 写入 Dependent 列表
|
||||
// push the symbol into dependent list
|
||||
getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
DEL_TAB;
|
||||
str << TAB << "};" << endl << endl;
|
||||
|
||||
// STEP05 生成 Protocol 解码函数(Protocol Decoder = PD)
|
||||
// generate Protocol Decoder ($PD)
|
||||
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$PD = function (data) {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "try {" << endl;
|
||||
|
@ -314,7 +314,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
str << TAB << "};" << endl << endl;
|
||||
|
||||
|
||||
//STEP03 生成框架调用错误处理函数(Error Response = ER)
|
||||
// generate error handler ($ER)
|
||||
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$ER = function (data) {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "throw _makeError(data, \"Call " << pPtr->getId() << "::" << oPtr->getId() << " failed\");" << endl;
|
||||
|
@ -322,7 +322,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
str << TAB << "};" << endl << endl;
|
||||
|
||||
|
||||
//SETP04 生成函数接口
|
||||
// generate function body
|
||||
str << TAB << nPtr->getId() << "." << pPtr->getId() << "Proxy.prototype." << oPtr->getId() << " = function ("
|
||||
<< sParams << ") {" << endl;
|
||||
|
||||
|
@ -344,7 +344,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
|
|||
|
||||
str << TAB << "};" << endl;
|
||||
|
||||
//SETP05 绑定函数声明
|
||||
// add the function into the prototype of the proxy class
|
||||
str << TAB << nPtr->getId() << "." << pPtr->getId() << "Proxy." << oPtr->getId() << " = "
|
||||
<< "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$IF;" << endl;
|
||||
|
||||
|
@ -445,7 +445,7 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
|
|||
}
|
||||
}
|
||||
|
||||
//先生成编解码 + 代理类
|
||||
// generate proxy classes with encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedAssert = false;
|
||||
bool bNeedStream = false;
|
||||
|
@ -466,7 +466,7 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
|
|||
return false;
|
||||
}
|
||||
|
||||
//再生成导入模块
|
||||
// generate module imports
|
||||
ostringstream ostr;
|
||||
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
|
||||
{
|
||||
|
@ -477,7 +477,7 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
|
|||
ostr << "var " << it->second.sModule << " = require(\"" << it->second.sFile << "\");" << endl;
|
||||
}
|
||||
|
||||
//生成文件内容
|
||||
// concat generated code
|
||||
ostringstream sstr;
|
||||
sstr << printHeaderRemark("Client", DISABLE_ESLINT);
|
||||
sstr << "\"use strict\";" << endl << endl;
|
||||
|
@ -496,7 +496,7 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
|
|||
|
||||
sstr << ostr.str() << endl;
|
||||
|
||||
//生成帮助函数
|
||||
// generate helper functions
|
||||
if (bQuickFunc)
|
||||
{
|
||||
sstr << "var _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
|
||||
|
|
|
@ -16,35 +16,6 @@
|
|||
|
||||
#include "code_generator.h"
|
||||
|
||||
string CodeGenerator::generateDTSProxyInfo()
|
||||
{
|
||||
ostringstream str;
|
||||
|
||||
INC_TAB;
|
||||
|
||||
// Argument
|
||||
str << TAB << "interface SharedArgumentInfo {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "name: string;" << endl;
|
||||
str << TAB << "class: string;" << endl;
|
||||
str << TAB << "direction: 'in' | 'out';" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
// Function
|
||||
str << TAB << "interface SharedFunctionInfo {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "name: string;" << endl;
|
||||
str << TAB << "return: string;" << endl;
|
||||
str << TAB << "arguments: SharedArgumentInfo[];" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateDTSProxy(const InterfacePtr &pPtr)
|
||||
{
|
||||
vector<OperationPtr> &vOperation = pPtr->getAllOperationPtr();
|
||||
|
@ -62,75 +33,47 @@ string CodeGenerator::generateDTSProxy(const InterfacePtr &pPtr)
|
|||
{
|
||||
OperationPtr &oPtr = vOperation[i];
|
||||
|
||||
string funcReturnGeneric = "<";
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
funcReturnGeneric += getTsType(oPtr->getReturnPtr()->getTypePtr()) + ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
funcReturnGeneric += "undefined, ";
|
||||
}
|
||||
|
||||
str << TAB << oPtr->getId() << "(";
|
||||
|
||||
string argType = "";
|
||||
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
if(vParamDecl[j]->isOut())
|
||||
{
|
||||
argType += (argType.empty() ? "" : ", ") + vParamDecl[j]->getTypeIdPtr()->getId() + ": " + getTsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
continue;
|
||||
}
|
||||
str << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getDtsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
str << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getTsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
str << ", ";
|
||||
}
|
||||
str << "property?: " << IDL_NAMESPACE_STR << "Rpc.InvokeProperty): Promise<" << pPtr->getId() << "$" << oPtr->getId() << "$DE>;" << endl;
|
||||
|
||||
str << TAB << "static " << oPtr->getId() << ": SharedFunctionInfo;" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
//interface
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
if (!argType.empty())
|
||||
{
|
||||
OperationPtr &oPtr = vOperation[i];
|
||||
|
||||
str << TAB << "interface " << pPtr->getId() << "$" << oPtr->getId() << "$DE {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "request: object;" << endl;
|
||||
str << TAB << "response: {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "costtime: number;" << endl;
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
str << TAB << "return: " << getDtsType(oPtr->getReturnPtr()->getTypePtr()) << ";" << endl;
|
||||
funcReturnGeneric += "{ " + argType + " }>";
|
||||
}
|
||||
else
|
||||
{
|
||||
str << TAB << "return: void;" << endl;
|
||||
funcReturnGeneric += "undefined>";
|
||||
}
|
||||
|
||||
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
bool hasArgs = false;
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
if(vParamDecl[j]->isOut()) {
|
||||
hasArgs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
str << "options?: " << IDL_NAMESPACE_STR << "Rpc.InvokeProperty): Promise<" << IDL_NAMESPACE_STR << "Rpc.ProxyResponse" << funcReturnGeneric << ">;" << endl;
|
||||
|
||||
if(hasArgs)
|
||||
{
|
||||
str << TAB << "arguments: {" << endl;
|
||||
INC_TAB;
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
if(!vParamDecl[j]->isOut()) {
|
||||
continue;
|
||||
}
|
||||
str << TAB << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getDtsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr()) << ";" << endl;
|
||||
str << TAB << "static " << oPtr->getId() << ": " << IDL_NAMESPACE_STR << "Rpc.SharedFunctionInfo" << ";" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
|
||||
return str.str();
|
||||
|
@ -144,8 +87,6 @@ string CodeGenerator::generateDTSProxy(const NamespacePtr &nPtr, bool &bNeedStre
|
|||
{
|
||||
bNeedStream = true;
|
||||
bNeedRpc = true;
|
||||
|
||||
str << generateDTSProxyInfo() << endl;
|
||||
}
|
||||
for (size_t i = 0; i < is.size(); i++)
|
||||
{
|
||||
|
@ -158,7 +99,7 @@ void CodeGenerator::generateDTSProxy(const ContextPtr &cPtr)
|
|||
{
|
||||
vector<NamespacePtr> namespaces = cPtr->getNamespaces();
|
||||
|
||||
//先生成编解码 + 代理类
|
||||
// generate proxy classes with encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedStream = false;
|
||||
bool bNeedRpc = false;
|
||||
|
@ -176,7 +117,7 @@ void CodeGenerator::generateDTSProxy(const ContextPtr &cPtr)
|
|||
return;
|
||||
}
|
||||
|
||||
//再生成导入模块
|
||||
// generate module imports
|
||||
ostringstream ostr;
|
||||
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
|
||||
{
|
||||
|
@ -187,7 +128,7 @@ void CodeGenerator::generateDTSProxy(const ContextPtr &cPtr)
|
|||
ostr << "import * as " << it->second.sModule << " from \"" << TC_File::excludeFileExt(it->second.sFile) << "\";" << endl;
|
||||
}
|
||||
|
||||
//生成文件内容
|
||||
// concat generated code
|
||||
ostringstream sstr;
|
||||
sstr << printHeaderRemark("Client", DISABLE_TSLINT);
|
||||
if (bNeedStream)
|
||||
|
|
513
src/gen_proxy_ts.cpp
Normal file
513
src/gen_proxy_ts.cpp
Normal file
|
@ -0,0 +1,513 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 "code_generator.h"
|
||||
|
||||
#define INVOKE_RETURN(protocol, prefix, params) \
|
||||
str << TAB << "return this._worker." << TC_Common::lower(protocol) << "_invoke(\"" << oPtr->getId() << "\", "; \
|
||||
str << prefix << "." << TC_Common::lower(protocol) << "Encoder"; \
|
||||
str << "(" << sParams << params << "), options, " << prefix << ").then("; \
|
||||
str << prefix << "." << TC_Common::lower(protocol) << "Decoder, "; \
|
||||
str << prefix << ".errorResponser);" << endl;
|
||||
#define PROTOCOL_PARAMS (sParams.empty() ? "" : ", ") << "version"
|
||||
|
||||
struct SortOperation
|
||||
{
|
||||
bool operator()(const OperationPtr &o1, const OperationPtr &o2)
|
||||
{
|
||||
return o1->getId() < o2->getId();
|
||||
}
|
||||
};
|
||||
|
||||
string CodeGenerator::generateTSProxy(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr)
|
||||
{
|
||||
ostringstream str;
|
||||
|
||||
vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
bool bHasParamOut = false;
|
||||
string sParams = "";
|
||||
string sParamsWithType = "";
|
||||
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (vParamDecl[i]->isOut())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sParams += (sParams.empty() ? "" : ", ")
|
||||
+ vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
|
||||
sParamsWithType += (sParamsWithType.empty() ? "" : ", ")
|
||||
+ vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
+ ": "
|
||||
+ getTsType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
// generate function metadata (SharedFunctionInfo)
|
||||
str << TAB << "static " << oPtr->getId() << " = _castFunctionInfo({" << endl;
|
||||
INC_TAB;
|
||||
|
||||
str << TAB << "name: \"" << oPtr->getId() << "\"," << endl;
|
||||
str << TAB << "return: \"" << getClassName(oPtr->getReturnPtr()->getTypePtr()) << "\"," << endl;
|
||||
str << TAB << "arguments: [";
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
str << (i > 0 ? ", {" : "{") << endl;
|
||||
INC_TAB;
|
||||
|
||||
str << TAB << "name: \"" << vParamDecl[i]->getTypeIdPtr()->getId() << "\"," << endl;
|
||||
str << TAB << "class: \"" << getClassName(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << "\"," << endl;
|
||||
|
||||
if (vParamDecl[i]->isOut())
|
||||
{
|
||||
bHasParamOut = true;
|
||||
str << TAB << "direction: \"out\"" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << TAB << "direction: \"in\"" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}";
|
||||
}
|
||||
str << "]," << endl;
|
||||
|
||||
// generate IDL Encoder ($IE)
|
||||
str << TAB << TC_Common::lower(IDL_NAMESPACE_STR) << "Encoder(" << sParamsWithType << ") {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
str << TAB << "const os = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "OutputStream();" << endl;
|
||||
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (vParamDecl[i]->isOut()) continue;
|
||||
|
||||
str << TAB << "os." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "("
|
||||
<< (i + 1) << ", " << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
|
||||
// push the symbol into dependent list
|
||||
getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
str << TAB << "return os.getBinBuffer();" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}," << endl;
|
||||
|
||||
// generate IDL Decoder ($ID)
|
||||
str << TAB << TC_Common::lower(IDL_NAMESPACE_STR) << "Decoder(data: " << IDL_NAMESPACE_STR << "Rpc.RpcResponse) {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
str << TAB << "try {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
if (oPtr->getReturnPtr()->getTypePtr() || bHasParamOut)
|
||||
{
|
||||
str << TAB << "var is = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "InputStream(data.response.sBuffer);" << endl;
|
||||
}
|
||||
|
||||
str << TAB << "return {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "request: data.request," << endl;
|
||||
str << TAB << "response: {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "costtime: data.request.costtime," << endl;
|
||||
|
||||
str << TAB << "return: ";
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
str << "is." << toFunctionName(oPtr->getReturnPtr(), "read") << "(0, true, ";
|
||||
|
||||
if (isSimple(oPtr->getReturnPtr()->getTypePtr()))
|
||||
{
|
||||
str << getDefault(oPtr->getReturnPtr(), oPtr->getReturnPtr()->def(), nPtr->getId())
|
||||
<< (isRawOrString(oPtr->getReturnPtr()->getTypePtr()) ? ", 1" : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
str << getDataType(oPtr->getReturnPtr()->getTypePtr(), true);
|
||||
}
|
||||
|
||||
str << ")," << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << "undefined as undefined," << endl;
|
||||
}
|
||||
|
||||
str << TAB << "arguments: ";
|
||||
if (bHasParamOut)
|
||||
{
|
||||
str << "{" << endl;
|
||||
INC_TAB;
|
||||
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (!vParamDecl[i]->isOut()) continue;
|
||||
|
||||
str << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< ": is." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "read") << "(" << (i + 1) << ", true, ";
|
||||
|
||||
if (isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
|
||||
{
|
||||
str << getDefault(vParamDecl[i]->getTypeIdPtr(), vParamDecl[i]->getTypeIdPtr()->def(), nPtr->getId())
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
str << getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr(), true);
|
||||
}
|
||||
|
||||
str << ")";
|
||||
|
||||
if (i == vParamDecl.size() - 1)
|
||||
{
|
||||
str << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << "," << endl;
|
||||
}
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << "undefined as undefined" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "};" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "} catch (e) {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "throw _makeError(data, e.message, " << IDL_NAMESPACE_STR << "Rpc.error.CLIENT.DECODE_ERROR);" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}," << endl;
|
||||
|
||||
// generate Protocol Encoder ($PE)
|
||||
str << TAB << TC_Common::lower(PROTOCOL_VAR) << "Encoder(" << sParamsWithType << (sParamsWithType.empty() ? "" : ", ") << "__$PROTOCOL$VERSION: number) {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
str << TAB << "const " << PROTOCOL_VAR << " = new " << IDL_NAMESPACE_STR << "Stream.UniAttribute();" << endl;
|
||||
|
||||
str << TAB << PROTOCOL_VAR << "." << PROTOCOL_VAR << "Version = __$PROTOCOL$VERSION;" << endl;
|
||||
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (vParamDecl[i]->isOut()) continue;
|
||||
|
||||
str << TAB << PROTOCOL_VAR << "." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "(\""
|
||||
<< vParamDecl[i]->getTypeIdPtr()->getId() << "\", " << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
|
||||
// push the symbol into dependent list
|
||||
getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
str << TAB << "return " << PROTOCOL_VAR << ";" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}," << endl;
|
||||
|
||||
// generate Protocol Decoder ($PD)
|
||||
str << TAB << TC_Common::lower(PROTOCOL_VAR) << "Decoder(data: " << IDL_NAMESPACE_STR << "Rpc.RpcResponse) {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
str << TAB << "try {" << endl;
|
||||
INC_TAB;
|
||||
if (oPtr->getReturnPtr()->getTypePtr() || bHasParamOut) {
|
||||
str << TAB << "const " << PROTOCOL_VAR << ": " << IDL_NAMESPACE_STR << "Stream.UniAttribute = (data.response as any)." << PROTOCOL_VAR << ";" << endl;
|
||||
}
|
||||
str << TAB << "return {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "request: data.request," << endl;
|
||||
str << TAB << "response: {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "costtime: data.request.costtime," << endl;
|
||||
|
||||
str << TAB << "return: ";
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
str << PROTOCOL_VAR << "." << toFunctionName(oPtr->getReturnPtr(), "read") << "(\"\"";
|
||||
|
||||
if (!isSimple(oPtr->getReturnPtr()->getTypePtr()) && !isBinBuffer(oPtr->getReturnPtr()->getTypePtr()))
|
||||
{
|
||||
str << ", " << getDataType(oPtr->getReturnPtr()->getTypePtr(), true);
|
||||
}
|
||||
|
||||
str << ", " << getDefault(oPtr->getReturnPtr(), "", nPtr->getId(), true)
|
||||
<< (isRawOrString(oPtr->getReturnPtr()->getTypePtr()) ? ", 1" : "");
|
||||
|
||||
str << ")," << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << "undefined as undefined," << endl;
|
||||
}
|
||||
|
||||
str << TAB << "arguments: ";
|
||||
if (bHasParamOut)
|
||||
{
|
||||
str << "{" << endl;
|
||||
INC_TAB;
|
||||
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (!vParamDecl[i]->isOut()) continue;
|
||||
|
||||
str << TAB << vParamDecl[i]->getTypeIdPtr()->getId() << ": "
|
||||
<< PROTOCOL_VAR << "." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "read")
|
||||
<< "(\"" << vParamDecl[i]->getTypeIdPtr()->getId() << "\"";
|
||||
|
||||
if (!isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) && !isBinBuffer(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
|
||||
{
|
||||
str << ", " << getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr(), true);
|
||||
}
|
||||
|
||||
str << ")";
|
||||
|
||||
if (i == vParamDecl.size() - 1)
|
||||
{
|
||||
str << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << "," << endl;
|
||||
}
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << "undefined as undefined" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "};" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "} catch (e) {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "throw _makeError(data, e.message, " << IDL_NAMESPACE_STR << "Rpc.error.CLIENT.DECODE_ERROR);" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}," << endl;
|
||||
|
||||
// generate error handler ($ER)
|
||||
str << TAB << "errorResponser(data: " << IDL_NAMESPACE_STR << "Rpc.RpcResponse) {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "throw _makeError(data, \"Call " << pPtr->getId() << "::" << oPtr->getId() << " failed\");" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "})" << endl << endl; // end of metadata
|
||||
|
||||
// generate function body
|
||||
str << TAB << oPtr->getId() << "(" << sParamsWithType << (sParamsWithType.empty() ? "" : ", ") << "options?: " << IDL_NAMESPACE_STR << ".InvokeProperty) {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
string sFuncFullName = pPtr->getId() + "Proxy." + oPtr->getId();
|
||||
str << TAB << "const version = this._worker.version;" << endl;
|
||||
|
||||
str << TAB << "if (version === " << PROTOCOL_SIMPLE << " || version === " << PROTOCOL_COMPLEX << ") {" << endl;
|
||||
INC_TAB;
|
||||
INVOKE_RETURN(PROTOCOL_VAR, sFuncFullName, PROTOCOL_PARAMS);
|
||||
DEL_TAB;
|
||||
str << TAB << "} else {" << endl;
|
||||
INC_TAB;
|
||||
INVOKE_RETURN(IDL_NAMESPACE_STR, sFuncFullName, "");
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl << endl;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTSProxy(const NamespacePtr &nPtr, const InterfacePtr &pPtr)
|
||||
{
|
||||
ostringstream str;
|
||||
|
||||
vector<OperationPtr> & vOperation = pPtr->getAllOperationPtr();
|
||||
sort(vOperation.begin(), vOperation.end(), SortOperation());
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
str << generateTSProxy(nPtr, pPtr, vOperation[i]);
|
||||
}
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTSProxy(const NamespacePtr &nPtr, bool &bNeedStream, bool &bNeedRpc)
|
||||
{
|
||||
ostringstream str;
|
||||
vector<InterfacePtr> &is = nPtr->getAllInterfacePtr();
|
||||
if (is.size() > 0)
|
||||
{
|
||||
bNeedStream = true;
|
||||
bNeedRpc = true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < is.size(); i++)
|
||||
{
|
||||
str << TAB << "export class " << is[i]->getId() << "Proxy {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
str << TAB << "protected _name!: string" << endl;
|
||||
str << TAB << "protected _worker!: " << IDL_NAMESPACE_STR << "Rpc.ObjectProxy" << endl << endl;
|
||||
|
||||
str << TAB << "setTimeout (iTimeout: number) { this._worker.timeout = iTimeout; }" << endl;
|
||||
str << TAB << "getTimeout () { return this._worker.timeout; }" << endl;
|
||||
str << TAB << "setVersion (iVersion: number) { this._worker.version = iVersion; }" << endl;
|
||||
str << TAB << "getVersion () { return this._worker.version; }" << endl << endl;
|
||||
|
||||
str << generateTSProxy(nPtr, is[i]) << endl;
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl << endl;
|
||||
}
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
bool CodeGenerator::generateTSProxy(const ContextPtr &cPtr)
|
||||
{
|
||||
vector<NamespacePtr> namespaces = cPtr->getNamespaces();
|
||||
|
||||
// generate proxy classes with encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedStream = false;
|
||||
bool bNeedRpc = false;
|
||||
bool bNeedAssert = false;
|
||||
bool bQuickFunc = false;
|
||||
for(size_t i = 0; i < namespaces.size(); i++)
|
||||
{
|
||||
ostringstream kstr;
|
||||
|
||||
kstr << generateTS(namespaces[i], bNeedStream, bNeedAssert, bQuickFunc);
|
||||
|
||||
INC_TAB;
|
||||
kstr << generateTSProxy(namespaces[i], bNeedStream, bNeedRpc);
|
||||
DEL_TAB;
|
||||
|
||||
estr << generateTS(namespaces[i], kstr.str());
|
||||
}
|
||||
if (estr.str().empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate module imports
|
||||
ostringstream sstr;
|
||||
sstr << printHeaderRemark("Client", DISABLE_TSLINT);
|
||||
sstr << "/// <reference types=\"node\" />" << endl;
|
||||
if (bNeedAssert)
|
||||
{
|
||||
sstr << TAB << "import assert = require(\"assert\");" << endl;
|
||||
}
|
||||
if (bNeedStream)
|
||||
{
|
||||
sstr << "import * as " << IDL_NAMESPACE_STR << "Stream from \"" << _sStreamPath << "\";" << endl;
|
||||
}
|
||||
if (bNeedRpc)
|
||||
{
|
||||
sstr << "import * as " << IDL_NAMESPACE_STR << "Rpc from \"" << _sRpcPath << "\";" << endl;
|
||||
}
|
||||
|
||||
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
|
||||
{
|
||||
if (it->second.sModule.empty()) continue;
|
||||
|
||||
if (estr.str().find(it->second.sModule + ".") == string::npos) continue;
|
||||
|
||||
sstr << "import * as " << it->second.sModule << " from \"" << TC_File::excludeFileExt(it->second.sFile) << "\";" << endl;
|
||||
}
|
||||
|
||||
// generate helper functions
|
||||
if (bQuickFunc || bNeedRpc)
|
||||
{
|
||||
sstr << endl;
|
||||
}
|
||||
if (bQuickFunc)
|
||||
{
|
||||
sstr << "const _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
|
||||
}
|
||||
if (bNeedRpc)
|
||||
{
|
||||
sstr << TAB << "function _castFunctionInfo<Ret, Arg>(data: SharedFunctionInfo<Ret, Arg>) { return data; }" << endl;
|
||||
sstr << TAB << "function _makeError(data: " << IDL_NAMESPACE_STR << "Rpc.RpcResponse, message: string, type?: number): " << IDL_NAMESPACE_STR << "Rpc.RpcError {" << endl;
|
||||
INC_TAB;
|
||||
sstr << TAB << "var error: any = new Error(message || \"\");" << endl;
|
||||
sstr << TAB << "error.request = data.request;" << endl;
|
||||
sstr << TAB << "error.response = {" << endl;
|
||||
INC_TAB;
|
||||
sstr << TAB << "costtime: data.request.costtime" << endl;
|
||||
DEL_TAB;
|
||||
sstr << TAB << "};" << endl;
|
||||
sstr << TAB << "if (type === " << IDL_NAMESPACE_STR << "Rpc.error.CLIENT.DECODE_ERROR) {" << endl;
|
||||
INC_TAB;
|
||||
sstr << TAB << "error.name = \"DECODE_ERROR\";" << endl;
|
||||
sstr << TAB << "error.response.error = {" << endl;
|
||||
INC_TAB;
|
||||
sstr << TAB << "code: type," << endl;
|
||||
sstr << TAB << "message: message" << endl;
|
||||
DEL_TAB;
|
||||
sstr << TAB << "};" << endl;
|
||||
DEL_TAB;
|
||||
sstr << TAB << "} else {" << endl;
|
||||
INC_TAB;
|
||||
sstr << TAB << "error.name = \"RPC_ERROR\";" << endl;
|
||||
sstr << TAB << "error.response.error = data.error;" << endl;
|
||||
DEL_TAB;
|
||||
sstr << TAB << "}" << endl;
|
||||
sstr << TAB << "return error;" << endl;
|
||||
DEL_TAB;
|
||||
sstr << TAB << "}" << endl << endl;
|
||||
|
||||
sstr << "export interface SharedFunctionInfo<Ret = any, Arg = any> extends " << IDL_NAMESPACE_STR << "Rpc.SharedFunctionInfo {" << endl;
|
||||
INC_TAB;
|
||||
sstr << TAB << TC_Common::lower(IDL_NAMESPACE_STR) << "Encoder (...args: any[]): " << IDL_NAMESPACE_STR << "Stream.BinBuffer," << endl;
|
||||
sstr << TAB << TC_Common::lower(IDL_NAMESPACE_STR) << "Decoder (data: " << IDL_NAMESPACE_STR << "Rpc.RpcResponse): " << IDL_NAMESPACE_STR << "Rpc.ProxyResponse<Ret, Arg>," << endl;
|
||||
sstr << TAB << TC_Common::lower(PROTOCOL_VAR) << "Encoder (...args: any[]): " << IDL_NAMESPACE_STR << "Stream.UniAttribute," << endl;
|
||||
sstr << TAB << TC_Common::lower(PROTOCOL_VAR) << "Decoder (data: " << IDL_NAMESPACE_STR << "Rpc.RpcResponse): " << IDL_NAMESPACE_STR << "Rpc.ProxyResponse<Ret, Arg>," << endl;
|
||||
sstr << TAB << "errorResponser (data: " << IDL_NAMESPACE_STR << "Rpc.RpcResponse): never" << endl;
|
||||
DEL_TAB;
|
||||
sstr << TAB << "}" << endl << endl;
|
||||
}
|
||||
|
||||
sstr << estr.str() << endl;
|
||||
|
||||
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(cPtr->getFileName())) + "Proxy.ts";
|
||||
TC_File::makeDirRecursive(_sToPath, 0755);
|
||||
makeUTF8File(sFileName, sstr.str());
|
||||
|
||||
return true;
|
||||
}
|
|
@ -58,7 +58,7 @@ string CodeGenerator::generateAsync(const NamespacePtr &nPtr, const InterfacePtr
|
|||
{
|
||||
sParams += "_ret";
|
||||
|
||||
// 写入 Dependent 列表
|
||||
// push the symbol into dependent list
|
||||
getDataType(oPtr->getReturnPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ string CodeGenerator::generateJSServer(const InterfacePtr &pPtr, const Namespace
|
|||
ostringstream str;
|
||||
vector<OperationPtr> & vOperation = pPtr->getAllOperationPtr();
|
||||
|
||||
//生成类
|
||||
// generate the implementation class
|
||||
str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp = function () { " << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "this._name = undefined;" << endl;
|
||||
|
@ -251,10 +251,10 @@ string CodeGenerator::generateJSServer(const InterfacePtr &pPtr, const Namespace
|
|||
DEL_TAB;
|
||||
str << TAB << "};" << endl << endl;
|
||||
|
||||
//生成初始化函数
|
||||
// generate the initialize function
|
||||
str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype.initialize = function () {};" << endl << endl;
|
||||
|
||||
//生成分发函数
|
||||
// generate the dispatch function
|
||||
str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype.onDispatch = function (current, funcName, binBuffer) { " << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "if (\"__\" + funcName in this) {" << endl;
|
||||
|
@ -269,10 +269,10 @@ string CodeGenerator::generateJSServer(const InterfacePtr &pPtr, const Namespace
|
|||
DEL_TAB;
|
||||
str << TAB << "};" << endl << endl;
|
||||
|
||||
//生成 PING 方法
|
||||
// generate the ping function
|
||||
str << generatePing(nPtr, pPtr) << endl;
|
||||
|
||||
//生成接口函数
|
||||
// generate functions
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
str << generateJSServer(nPtr, pPtr, vOperation[i]) << endl;
|
||||
|
@ -321,7 +321,7 @@ bool CodeGenerator::generateJSServer(const ContextPtr &pPtr)
|
|||
}
|
||||
}
|
||||
|
||||
//生成编解码 + 服务类
|
||||
// generate server classes with encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedAssert = false;
|
||||
bool bNeedStream = false;
|
||||
|
@ -342,7 +342,7 @@ bool CodeGenerator::generateJSServer(const ContextPtr &pPtr)
|
|||
return false;
|
||||
}
|
||||
|
||||
//再生成导入模块
|
||||
// generate module imports
|
||||
ostringstream ostr;
|
||||
if (bNeedAssert)
|
||||
{
|
||||
|
|
|
@ -25,34 +25,37 @@ string CodeGenerator::generateDTSServer(const NamespacePtr &nPtr, const Interfac
|
|||
INC_TAB;
|
||||
str << TAB << "class " << pPtr->getId() << "Imp {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "initialize(): Promise<any> | void;" << endl;
|
||||
str << TAB << "initialize(): PromiseLike<any> | void;" << endl;
|
||||
str << TAB << "protected onDispatch(current: " << IDL_NAMESPACE_STR << "Rpc." << IDL_TYPE << "Current, funcName: string, binBuffer: " << IDL_NAMESPACE_STR << "Stream.BinBuffer): number" << endl;
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
OperationPtr &oPtr = vOperation[i];
|
||||
str << TAB << oPtr->getId() << "(current: " << pPtr->getId() << "$" << oPtr->getId() << "$CUR";
|
||||
str << TAB << oPtr->getId() << "(current: " << pPtr->getId() << "Imp." << oPtr->getId() << "Current";
|
||||
|
||||
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
str << ", " << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getDtsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
str << ", " << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getTsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
str << "): void;" << endl;
|
||||
str << "): any;" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
//interface
|
||||
// Additional namespace
|
||||
str << TAB << "namespace " << pPtr->getId() << "Imp {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
OperationPtr &oPtr = vOperation[i];
|
||||
|
||||
str << TAB << "interface " << pPtr->getId() << "$" << oPtr->getId() << "$CUR extends " << IDL_NAMESPACE_STR << "Rpc." << IDL_TYPE << "Current {" <<endl;
|
||||
str << TAB << "interface " << oPtr->getId() << "Current extends " << IDL_NAMESPACE_STR << "Rpc." << IDL_TYPE << "Current {" <<endl;
|
||||
INC_TAB;
|
||||
str << TAB;
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
str << "sendResponse(ret: " << getDtsType(oPtr->getReturnPtr()->getTypePtr());
|
||||
str << "sendResponse(ret: " << getTsType(oPtr->getReturnPtr()->getTypePtr());
|
||||
|
||||
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
|
@ -60,7 +63,7 @@ string CodeGenerator::generateDTSServer(const NamespacePtr &nPtr, const Interfac
|
|||
if(!vParamDecl[j]->isOut()) {
|
||||
continue;
|
||||
}
|
||||
str << ", " << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getDtsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr()) ;
|
||||
str << ", " << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getTsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr()) ;
|
||||
}
|
||||
str << "): void;" << endl;
|
||||
}
|
||||
|
@ -72,8 +75,11 @@ string CodeGenerator::generateDTSServer(const NamespacePtr &nPtr, const Interfac
|
|||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
|
@ -100,7 +106,7 @@ void CodeGenerator::generateDTSServer(const ContextPtr &pPtr)
|
|||
{
|
||||
vector<NamespacePtr> namespaces = pPtr->getNamespaces();
|
||||
|
||||
//生成编解码 + 服务类
|
||||
// generate server classes with encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedStream = false;
|
||||
bool bNeedRpc = false;
|
||||
|
@ -118,7 +124,7 @@ void CodeGenerator::generateDTSServer(const ContextPtr &pPtr)
|
|||
return;
|
||||
}
|
||||
|
||||
//再生成导入模块
|
||||
// generate module imports
|
||||
ostringstream ostr;
|
||||
if (bNeedStream)
|
||||
{
|
||||
|
|
401
src/gen_server_ts.cpp
Normal file
401
src/gen_server_ts.cpp
Normal file
|
@ -0,0 +1,401 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 "code_generator.h"
|
||||
|
||||
string CodeGenerator::generateTSServerAsync(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr)
|
||||
{
|
||||
ostringstream str;
|
||||
|
||||
string sParams = "";
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
sParams += "_ret: " + getTsType(oPtr->getReturnPtr()->getTypePtr());
|
||||
|
||||
// push the symbol into dependent list
|
||||
getDataType(oPtr->getReturnPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (!vParamDecl[i]->isOut()) continue;
|
||||
|
||||
sParams += (sParams.empty() ? "": ", ") + vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
sParams += ": " + getTsType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
|
||||
str << TAB << "protected static __" << oPtr->getId() << "_responser(this: " << IDL_NAMESPACE_STR << "Rpc.JceCurrent, " << sParams << ") {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
|
||||
if (sParams.empty())
|
||||
{
|
||||
str << TAB << "this.doResponse(new " << IDL_NAMESPACE_STR << "Stream.BinBuffer());" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
str << TAB << "if (this.getRequestVersion() === " << PROTOCOL_SIMPLE << " || this.getRequestVersion() === " << PROTOCOL_COMPLEX << ") {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "const " << PROTOCOL_VAR << " = new " << IDL_NAMESPACE_STR << "Stream.UniAttribute();" << endl;
|
||||
str << TAB << PROTOCOL_VAR << "." << PROTOCOL_VAR << "Version = this.getRequestVersion();" << endl;
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
str << TAB << PROTOCOL_VAR << "." << toFunctionName(oPtr->getReturnPtr(), "write") << "(\"\", _ret"
|
||||
<< (isRawOrString(oPtr->getReturnPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
}
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (!vParamDecl[i]->isOut()) continue;
|
||||
|
||||
str << TAB << PROTOCOL_VAR << "." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "(\""
|
||||
<< vParamDecl[i]->getTypeIdPtr()->getId() << "\", " << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
}
|
||||
str << endl;
|
||||
str << TAB << "this.doResponse(" << PROTOCOL_VAR << ".encode());" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "} else {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
str << TAB << "const os = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "OutputStream();" << endl;
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
str << TAB << "os." << toFunctionName(oPtr->getReturnPtr(), "write") << "(0, _ret"
|
||||
<< (isRawOrString(oPtr->getReturnPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
}
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
if (!vParamDecl[i]->isOut()) continue;
|
||||
|
||||
str << TAB << "os." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "("
|
||||
<< (i + 1) << ", " << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
}
|
||||
str << endl;
|
||||
str << TAB << "this.doResponse(os.getBinBuffer());" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTSServerDispatch(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr)
|
||||
{
|
||||
ostringstream str;
|
||||
vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
|
||||
str << TAB << "protected __" << oPtr->getId() << "(current: " << IDL_NAMESPACE_STR << "Rpc.JceCurrent";
|
||||
if (vParamDecl.size() != 0) str << ", binBuffer: " << IDL_NAMESPACE_STR << "Stream.BinBuffer";
|
||||
str << ") {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
|
||||
ostringstream dstr;
|
||||
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
dstr << TAB << "let " << vParamDecl[i]->getTypeIdPtr()->getId() << ": " << getTsType(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ";" << endl;
|
||||
}
|
||||
if (vParamDecl.size() != 0)
|
||||
{
|
||||
dstr << endl;
|
||||
}
|
||||
|
||||
dstr << TAB << "if (current.getRequestVersion() === " << PROTOCOL_SIMPLE << " || current.getRequestVersion() === " << PROTOCOL_COMPLEX << ") {" << endl;
|
||||
INC_TAB;
|
||||
dstr << TAB << "const " << PROTOCOL_VAR << " = new " << IDL_NAMESPACE_STR << "Stream.UniAttribute();" << endl;
|
||||
dstr << TAB << PROTOCOL_VAR << "." << PROTOCOL_VAR << "Version = current.getRequestVersion();" << endl;
|
||||
dstr << TAB << PROTOCOL_VAR << ".decode(binBuffer);" << endl;
|
||||
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< " = " << PROTOCOL_VAR << "." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "read")
|
||||
<< "(\"" << vParamDecl[i]->getTypeIdPtr()->getId() << "\"";
|
||||
|
||||
if (!isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) && !isBinBuffer(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
|
||||
{
|
||||
dstr << ", " << getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr(), true);
|
||||
}
|
||||
|
||||
if (vParamDecl[i]->isOut())
|
||||
{
|
||||
dstr << ", " << getDefault(vParamDecl[i]->getTypeIdPtr(), "", nPtr->getId(), true)
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "");
|
||||
}
|
||||
|
||||
dstr << ");" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
dstr << TAB << "} else {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
dstr << TAB << "const is = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "InputStream(binBuffer);" << endl;
|
||||
string sParams = "";
|
||||
for (size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
sParams += ", " + vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
|
||||
dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
|
||||
<< " = is." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "read") << "("
|
||||
<< (i + 1) << ", " << (vParamDecl[i]->isOut() ? "false" : "true") << ", ";
|
||||
|
||||
if (isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
|
||||
{
|
||||
dstr << getDefault(vParamDecl[i]->getTypeIdPtr(), vParamDecl[i]->getTypeIdPtr()->def(), nPtr->getId())
|
||||
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
dstr << getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr(), true);
|
||||
}
|
||||
|
||||
dstr << ");" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
dstr << TAB << "}" << endl << endl;
|
||||
|
||||
if (!sParams.empty())
|
||||
{
|
||||
str << dstr.str();
|
||||
}
|
||||
|
||||
str << TAB << "current.sendResponse = " << pPtr->getId() << "Imp.__" << oPtr->getId() << "_responser;" << endl << endl;
|
||||
|
||||
str << TAB << "this." << oPtr->getId() << "(current" << sParams << ");" << endl << endl;
|
||||
|
||||
str << TAB << "return " << IDL_NAMESPACE_STR << "Rpc.error.SUCCESS;" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTSServer(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedRpc, bool &bNeedAssert)
|
||||
{
|
||||
ostringstream str;
|
||||
|
||||
vector<InterfacePtr> & is = pPtr->getAllInterfacePtr();
|
||||
for (size_t i = 0; i < is.size(); i++)
|
||||
{
|
||||
str << generateTSServer(is[i], pPtr) << endl;
|
||||
}
|
||||
if (is.size() != 0)
|
||||
{
|
||||
bNeedRpc = true;
|
||||
bNeedStream = true;
|
||||
bNeedAssert = true;
|
||||
}
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTSServer(const InterfacePtr &pPtr, const NamespacePtr &nPtr)
|
||||
{
|
||||
ostringstream str;
|
||||
vector<OperationPtr> & vOperation = pPtr->getAllOperationPtr();
|
||||
|
||||
// generate the implementation class
|
||||
str << TAB << "export abstract class " << pPtr->getId() << "Imp { " << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "_name!: string" << endl;
|
||||
str << TAB << "_worker!: any" << endl << endl;
|
||||
|
||||
// generate the initialize function
|
||||
str << TAB << "initialize(): PromiseLike<any> | void {}" << endl << endl;
|
||||
|
||||
// generate the dispatch function
|
||||
str << TAB << "onDispatch(current: " << IDL_NAMESPACE_STR << "Rpc.JceCurrent, funcName: string, binBuffer: " << IDL_NAMESPACE_STR << "Stream.BinBuffer) { " << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "if (\"__\" + funcName in this) {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "return (this as any)[\"__\" + funcName](current, binBuffer);" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "} else {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "return " << IDL_NAMESPACE_STR << "Rpc.error.SERVER.FUNC_NOT_FOUND;" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl << endl;
|
||||
|
||||
// generate the ping function
|
||||
str << TAB << "__" << TC_Common::lower(IDL_NAMESPACE_STR) << "_ping(current: " << IDL_NAMESPACE_STR << "Rpc.JceCurrent) { " << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "const _ret = 0;" << endl;
|
||||
str << TAB << "if (current.getRequestVersion() === " << PROTOCOL_SIMPLE << " || current.getRequestVersion() === " << PROTOCOL_COMPLEX << ") {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "const " << PROTOCOL_VAR << " = new " << IDL_NAMESPACE_STR << "Stream.UniAttribute();" << endl;
|
||||
str << TAB << PROTOCOL_VAR << "." << PROTOCOL_VAR << "Version = current.getRequestVersion();" << endl;
|
||||
str << TAB << PROTOCOL_VAR << ".writeInt32(\"\", _ret);" << endl << endl;
|
||||
str << TAB << "current.doResponse(" << PROTOCOL_VAR << ".encode());" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "} else {" << endl;
|
||||
INC_TAB;
|
||||
str << TAB << "const os = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "OutputStream();" << endl;
|
||||
str << TAB << "os.writeInt32(0, _ret);" << endl << endl;
|
||||
str << TAB << "current.doResponse(os.getBinBuffer());" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl << endl;
|
||||
str << TAB << "return " << IDL_NAMESPACE_STR << "Rpc.error.SUCCESS;" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl << endl;
|
||||
|
||||
// generate functions
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
const OperationPtr &oPtr = vOperation[i];
|
||||
|
||||
// generate function definition
|
||||
str << TAB << oPtr->getId() << "(current: " << pPtr->getId() << "Imp." << oPtr->getId() << "Current";
|
||||
|
||||
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
str << ", " << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getTsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
str << "): any { " << endl;
|
||||
|
||||
INC_TAB;
|
||||
str << TAB << "assert.fail(\"" << oPtr->getId() << " function not implemented\");" << endl;
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl << endl;
|
||||
|
||||
// generate encoder and decoder
|
||||
str << generateTSServerAsync(nPtr, pPtr, vOperation[i]) << endl;
|
||||
str << generateTSServerDispatch(nPtr, pPtr, vOperation[i]) << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl << endl; // end of class
|
||||
|
||||
// generate additional namespaces
|
||||
str << TAB << "export namespace " << pPtr->getId() << "Imp {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
OperationPtr &oPtr = vOperation[i];
|
||||
|
||||
str << TAB << "export interface " << oPtr->getId() << "Current extends " << IDL_NAMESPACE_STR << "Rpc." << IDL_TYPE << "Current {" <<endl;
|
||||
INC_TAB;
|
||||
str << TAB;
|
||||
if (oPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
str << "sendResponse(ret: " << getTsType(oPtr->getReturnPtr()->getTypePtr());
|
||||
|
||||
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
if(!vParamDecl[j]->isOut()) {
|
||||
continue;
|
||||
}
|
||||
str << ", " << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getTsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr()) ;
|
||||
}
|
||||
str << "): void;" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
str << "sendResponse(): void;" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
str << TAB << "}" << endl;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
bool CodeGenerator::generateTSServer(const ContextPtr &pPtr)
|
||||
{
|
||||
vector<NamespacePtr> namespaces = pPtr->getNamespaces();
|
||||
|
||||
// generate server classes with encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedStream = false;
|
||||
bool bNeedRpc = false;
|
||||
bool bNeedAssert = false;
|
||||
bool bQuickFunc = false;
|
||||
for(size_t i = 0; i < namespaces.size(); i++)
|
||||
{
|
||||
ostringstream kstr;
|
||||
kstr << generateTS(namespaces[i], bNeedStream, bNeedAssert, bQuickFunc);
|
||||
|
||||
INC_TAB;
|
||||
kstr << generateTSServer(namespaces[i], bNeedStream, bNeedRpc, bNeedAssert);
|
||||
DEL_TAB;
|
||||
|
||||
estr << generateTS(namespaces[i], kstr.str());
|
||||
}
|
||||
if (estr.str().empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ostringstream str;
|
||||
|
||||
// generate the source file
|
||||
str << printHeaderRemark("Server", DISABLE_TSLINT);
|
||||
str << "/// <reference types=\"node\" />" << endl;
|
||||
if (bNeedAssert)
|
||||
{
|
||||
str << TAB << "import assert = require(\"assert\");" << endl;
|
||||
}
|
||||
if (bNeedStream)
|
||||
{
|
||||
str << "import * as " << IDL_NAMESPACE_STR << "Stream from \"" << _sStreamPath << "\";" << endl;
|
||||
}
|
||||
if (bNeedRpc)
|
||||
{
|
||||
str << "import * as " << IDL_NAMESPACE_STR << "Rpc from \"" << _sRpcPath << "\";" << endl;
|
||||
}
|
||||
|
||||
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
|
||||
{
|
||||
if (it->second.sModule.empty()) continue;
|
||||
|
||||
if (estr.str().find(it->second.sModule + ".") == string::npos) continue;
|
||||
|
||||
str << "import * as " << it->second.sModule << " from \"" << TC_File::excludeFileExt(it->second.sFile) << "\";" << endl;
|
||||
}
|
||||
if (bQuickFunc)
|
||||
{
|
||||
str << endl;
|
||||
str << TAB << "const _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
|
||||
}
|
||||
|
||||
str << endl << estr.str() << endl;
|
||||
|
||||
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + ".ts";
|
||||
|
||||
TC_File::makeDirRecursive(_sToPath, 0755);
|
||||
makeUTF8File(sFileName, str.str());
|
||||
|
||||
return true;
|
||||
}
|
110
src/gen_server_ts_imp.cpp
Normal file
110
src/gen_server_ts_imp.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 "code_generator.h"
|
||||
|
||||
void CodeGenerator::generateTSServerImp(const ContextPtr &cPtr)
|
||||
{
|
||||
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(cPtr->getFileName())) + "Imp.ts";
|
||||
if (TC_File::isFileExist(sFileName))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
ostringstream str;
|
||||
str << printHeaderRemark("Imp");
|
||||
|
||||
vector<NamespacePtr> namespaces = cPtr->getNamespaces();
|
||||
|
||||
// generate the server implementation class
|
||||
ostringstream estr;
|
||||
set<string> setInterface;
|
||||
for(size_t i = 0; i < namespaces.size(); i++)
|
||||
{
|
||||
estr << "export namespace " << namespaces[i]->getId() << " {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
vector<InterfacePtr> & is = namespaces[i]->getAllInterfacePtr();
|
||||
for (size_t ii = 0; ii < is.size(); ii++)
|
||||
{
|
||||
if (setInterface.count(namespaces[i]->getId() + "::" + is[ii]->getId()) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
setInterface.insert(namespaces[i]->getId() + "::" + is[ii]->getId());
|
||||
|
||||
estr << TAB << "export class " << is[ii]->getId() << "Imp extends base." << namespaces[i]->getId() << "." << is[ii]->getId() << "Imp { " << endl;
|
||||
INC_TAB;
|
||||
|
||||
estr << TAB << "initialize() {" << endl;
|
||||
INC_TAB;
|
||||
estr << TAB << "// TODO: implement initialize" << endl;
|
||||
DEL_TAB;
|
||||
estr << TAB << "}" << endl << endl;
|
||||
|
||||
vector<OperationPtr> & vOperation = is[ii]->getAllOperationPtr();
|
||||
for (size_t iii = 0; iii < vOperation.size(); iii++)
|
||||
{
|
||||
const OperationPtr &oPtr = vOperation[iii];
|
||||
|
||||
// generate function entries
|
||||
estr << TAB << oPtr->getId() << "(current: base." << namespaces[i]->getId() << "." << is[ii]->getId() << "Imp." << oPtr->getId() << "Current";
|
||||
|
||||
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
estr << ", " << vParamDecl[j]->getTypeIdPtr()->getId() << ": " << getTsType(vParamDecl[j]->getTypeIdPtr()->getTypePtr(), true, true);
|
||||
}
|
||||
estr << ") { " << endl;
|
||||
|
||||
INC_TAB;
|
||||
estr << TAB << "// TODO: implement " << oPtr->getId() << "" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
estr << TAB << "}" << endl;
|
||||
if (iii != vOperation.size() - 1) estr << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
estr << TAB << "}" << endl;
|
||||
if (ii != is.size() - 1) estr << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
estr << "}" << endl;
|
||||
if (i != namespaces.size() - 1) estr << endl;
|
||||
}
|
||||
|
||||
// generate module imports
|
||||
str << "import * as " << IDL_NAMESPACE_STR << "Stream from \"" << _sStreamPath << "\";" << endl;
|
||||
str << "import * as base from \"./"
|
||||
<< TC_File::excludeFileExt(TC_File::extractFileName(cPtr->getFileName())) << "\";" << endl;
|
||||
|
||||
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
|
||||
{
|
||||
if (it->second.sModule.empty()) continue;
|
||||
|
||||
if (estr.str().find(it->second.sModule + ".") == string::npos) continue;
|
||||
|
||||
str << "import * as " << it->second.sModule << " from \"" << TC_File::excludeFileExt(it->second.sFile) << "\";" << endl;
|
||||
}
|
||||
|
||||
str << endl;
|
||||
str << estr.str();
|
||||
|
||||
TC_File::makeDirRecursive(_sToPath, 0755);
|
||||
makeUTF8File(sFileName, str.str());
|
||||
}
|
443
src/gen_ts.cpp
Normal file
443
src/gen_ts.cpp
Normal file
|
@ -0,0 +1,443 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 "code_generator.h"
|
||||
|
||||
string CodeGenerator::generateTS(const EnumPtr &pPtr, const string &sNamespace)
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
INC_TAB;
|
||||
s << TAB << "export enum " << pPtr->getId() << " {" << endl;
|
||||
|
||||
INC_TAB;
|
||||
int nenum = -1;
|
||||
bool bDependent = false;
|
||||
vector<TypeIdPtr>& member = pPtr->getAllMemberPtr();
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
bDependent |= isDependent(sNamespace, member[i]->getId());
|
||||
if (member[i]->hasDefault())
|
||||
{
|
||||
nenum = TC_Common::strto<int>(member[i]->def());
|
||||
}
|
||||
else
|
||||
{
|
||||
nenum++;
|
||||
}
|
||||
s << TAB << member[i]->getId() << " = " << TC_Common::tostr(nenum) << ((i < member.size() - 1) ? "," : "") << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
s << TAB << "export namespace " << pPtr->getId() << " {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "export const _classname = \"" << sNamespace << "." << pPtr->getId() << "\";" << endl;
|
||||
s << TAB << "export function _write(os: " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "OutputStream, tag: number, val: number) { return os.writeInt32(tag, val); }" << endl;
|
||||
s << TAB << "export function _read(is: " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "InputStream, tag: number, def?: number) { return is.readInt32(tag, true, def); }" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
DEL_TAB;
|
||||
|
||||
if (!_bMinimalMembers || _bEntry || bDependent || isDependent(sNamespace, pPtr->getId())) {
|
||||
return s.str();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTS(const ConstPtr &pPtr, const string &sNamespace, bool &bNeedStream)
|
||||
{
|
||||
if (_bMinimalMembers && !_bEntry && !isDependent(sNamespace, pPtr->getTypeIdPtr()->getId()))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
ostringstream s;
|
||||
if (_bStringBinaryEncoding && GET_CONST_GRAMMAR_PTR(pPtr)->t == CONST_GRAMMAR(STRING))
|
||||
{
|
||||
bNeedStream = true;
|
||||
}
|
||||
|
||||
INC_TAB;
|
||||
s << TAB << "export const " << pPtr->getTypeIdPtr()->getId() << ": "
|
||||
<< getTsType(pPtr->getTypeIdPtr()->getTypePtr()) << " = "
|
||||
<< getDefault(pPtr->getTypeIdPtr(), GET_CONST_GRAMMAR_PTR(pPtr)->v, sNamespace, false) << ";"
|
||||
<< endl;
|
||||
DEL_TAB;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTS(const StructPtr &pPtr, const string &sNamespace, bool &bNeedAssert, bool &bQuickFunc)
|
||||
{
|
||||
if (_bMinimalMembers && !_bEntry && !isDependent(sNamespace, pPtr->getId()))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string sStructName = pPtr->getId() + "$OBJ";
|
||||
vector<TypeIdPtr> &member = pPtr->getAllMemberPtr();
|
||||
INC_TAB;
|
||||
|
||||
// Struct
|
||||
ostringstream s;
|
||||
s << TAB << "export class " << pPtr->getId() << " {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
// class members
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
s << TAB << (member[i]->getId()) << ": "
|
||||
<< getTsType(member[i]->getTypePtr()) << " = "
|
||||
<< getDefault(member[i], member[i]->def(), sNamespace) << ";" << endl;
|
||||
}
|
||||
if (member.size() > 0)
|
||||
{
|
||||
s << endl;
|
||||
}
|
||||
|
||||
// _classname, _proto_struct_name_
|
||||
s << TAB << "protected _proto_struct_name_ = \"\";" << endl;
|
||||
s << TAB << "protected _classname = \"" << sNamespace << "." << pPtr->getId() << "\";" << endl;
|
||||
s << TAB << "protected static _classname = \"" << sNamespace << "." << pPtr->getId() << "\";" << endl;
|
||||
|
||||
// _write, _read
|
||||
s << TAB << "protected static _write(os: " << IDL_NAMESPACE_STR << "Stream.JceOutputStream, tag: number, val: any) { os.writeStruct(tag, val); }" << endl;
|
||||
s << TAB << "protected static _read(is: " << IDL_NAMESPACE_STR << "Stream.JceInputStream, tag: number, def?: any) { return is.readStruct(tag, true, def); }" << endl;
|
||||
|
||||
// _readFrom
|
||||
s << TAB << "protected static _readFrom(is: " << IDL_NAMESPACE_STR << "Stream.JceInputStream) {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
s << TAB << "const tmp = new " << pPtr->getId() << ";" << endl;
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
string sFuncName = toFunctionName(member[i], "read");
|
||||
s << TAB << "tmp." << member[i]->getId() << " = is." << sFuncName << "(" << member[i]->getTag()
|
||||
<< ", " << (member[i]->isRequire() ? "true" : "false") << ", ";
|
||||
|
||||
if (isSimple(member[i]->getTypePtr()))
|
||||
{
|
||||
s << getDefault(member[i], member[i]->def(), sNamespace)
|
||||
<< (isRawOrString(member[i]->getTypePtr()) ? ", 1" : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
s << getDataType(member[i]->getTypePtr(), true);
|
||||
}
|
||||
|
||||
s << ");" << endl;
|
||||
}
|
||||
s << TAB << "return tmp;" << endl;
|
||||
DEL_TAB; // end of _readFrom
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// _writeTo
|
||||
s << TAB << "protected _writeTo(os: " << IDL_NAMESPACE_STR << "Stream.JceOutputStream) {" << endl;
|
||||
INC_TAB;
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
string sFuncName = toFunctionName(member[i], "write");
|
||||
|
||||
s << TAB << "os." << sFuncName << "(" << member[i]->getTag() << ", this." << member[i]->getId()
|
||||
<< (isRawOrString(member[i]->getTypePtr()) ? ", 1" : "") << ");" << endl;
|
||||
}
|
||||
DEL_TAB; // end of _writeTo
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
/*
|
||||
* Size Optimize:
|
||||
* Remove <mutil_map> support.
|
||||
* Remove toBinBuffer, readFromObject, toObject, new, create members.
|
||||
*/
|
||||
if (_iOptimizeLevel != Os)
|
||||
{
|
||||
s << endl;
|
||||
|
||||
// _equal
|
||||
vector<string> key = pPtr->getKey();
|
||||
|
||||
s << TAB << "protected _equal(" << (key.size() > 0 ? "anItem: any" : "") << ")" << (key.size() > 0 ? ": boolean" : "") << " {" << endl;
|
||||
INC_TAB;
|
||||
|
||||
if (key.size() > 0)
|
||||
{
|
||||
s << TAB << "return ";
|
||||
|
||||
for (size_t i = 0; i < key.size(); i++)
|
||||
{
|
||||
for (size_t ii = 0; ii < member.size(); ii++)
|
||||
{
|
||||
if (key[i] != member[ii]->getId())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isSimple(member[i]->getTypePtr()))
|
||||
{
|
||||
s << (i==0?"":TAB + TAB) << "this." << key[i] << " === " << "anItem." << key[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
s << (i==0?"":TAB + TAB) << "this._equal(" << "anItem)";
|
||||
}
|
||||
}
|
||||
|
||||
if (i != key.size() - 1)
|
||||
{
|
||||
s << " && " << endl;
|
||||
}
|
||||
}
|
||||
|
||||
s << ";" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
bNeedAssert = true;
|
||||
s << TAB << "assert.fail(\"this structure not define key operation\");" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// _genKey
|
||||
s << TAB << "protected _genKey() {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "if (!this._proto_struct_name_) {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "this._proto_struct_name_ = \"STRUCT\" + Math.random();" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
s << TAB << "return this._proto_struct_name_;" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// toObject
|
||||
s << TAB << "toObject(): " << pPtr->getId() << ".Object { "<< endl;
|
||||
INC_TAB;
|
||||
s << TAB << "return {" << endl;
|
||||
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
INC_TAB;
|
||||
if (i > 0 && i < member.size()) {
|
||||
s << "," << endl;
|
||||
}
|
||||
|
||||
if (isSimple(member[i]->getTypePtr())) {
|
||||
s << TAB << member[i]->getId() << ": this." << member[i]->getId();
|
||||
}
|
||||
else {
|
||||
s << TAB << member[i]->getId() << ": this." << member[i]->getId() << ".toObject()";
|
||||
}
|
||||
DEL_TAB;
|
||||
}
|
||||
|
||||
s << endl;
|
||||
s << TAB << "};" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// readFromObject
|
||||
s << TAB << "readFromObject(json: " << pPtr->getId() << ".Object) { "<< endl;
|
||||
INC_TAB;
|
||||
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
if (isSimple(member[i]->getTypePtr())) {
|
||||
s << TAB << "_hasOwnProperty.call(json, \"" << member[i]->getId() << "\") && (this." << member[i]->getId() << " = json." << member[i]->getId() << (member[i]->isRequire() ? "" : "!") << ");" << endl;
|
||||
} else {
|
||||
s << TAB << "_hasOwnProperty.call(json, \"" << member[i]->getId() << "\") && (this." << member[i]->getId() << ".readFromObject(json." << member[i]->getId() << (member[i]->isRequire() ? "" : "!") << "));" << endl;
|
||||
}
|
||||
bQuickFunc = true;
|
||||
}
|
||||
|
||||
s << TAB << "return this;" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// toBinBuffer
|
||||
s << TAB << "toBinBuffer() {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "const os = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "OutputStream();" << endl;
|
||||
s << TAB << "this._writeTo(os);" << endl;
|
||||
s << TAB << "return os.getBinBuffer();" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// new
|
||||
s << TAB << "static new() {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "return new " << pPtr->getId() << "();" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// create
|
||||
s << TAB << "static create(is: " << IDL_NAMESPACE_STR << "Stream.JceInputStream) {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "return " << sNamespace << "." << pPtr->getId() << "._readFrom(is);" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB; // end of Struct
|
||||
s << TAB << "}" << endl << endl;
|
||||
|
||||
// Additional namespace
|
||||
s << TAB << "export namespace " << pPtr->getId() << " {" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "export interface Object {" << endl;
|
||||
INC_TAB;
|
||||
for (size_t i = 0; i < member.size(); i++)
|
||||
{
|
||||
const string &sType = getTsType(member[i]->getTypePtr(), false);
|
||||
s << TAB << (member[i]->getId()) << (member[i]->isRequire() ? ": " : "?: ") << (!sType.empty() ? sType : "never") << ";" << endl;
|
||||
}
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTS(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedAssert, bool &bQuickFunc)
|
||||
{
|
||||
// struct
|
||||
ostringstream sstr;
|
||||
vector<StructPtr> ss(pPtr->getAllStructPtr());
|
||||
for (size_t last = 0; last != ss.size() && ss.size() != 0;)
|
||||
{
|
||||
last = ss.size();
|
||||
for (vector<StructPtr>::iterator iter=ss.begin(); iter!=ss.end();)
|
||||
{
|
||||
string str = generateTS(*iter, pPtr->getId(), bNeedAssert, bQuickFunc);
|
||||
if (!str.empty())
|
||||
{
|
||||
sstr << str << endl;
|
||||
iter = ss.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// const
|
||||
ostringstream cstr;
|
||||
vector<ConstPtr> &cs = pPtr->getAllConstPtr();
|
||||
for (size_t i = 0; i < cs.size(); i++)
|
||||
{
|
||||
cstr << generateTS(cs[i], pPtr->getId(), bNeedStream);
|
||||
}
|
||||
|
||||
// enum
|
||||
ostringstream estr;
|
||||
vector<EnumPtr> &es = pPtr->getAllEnumPtr();
|
||||
for (size_t i = 0; i < es.size(); i++)
|
||||
{
|
||||
estr << generateTS(es[i], pPtr->getId());
|
||||
}
|
||||
|
||||
ostringstream kstr;
|
||||
if (!estr.str().empty())
|
||||
{
|
||||
bNeedStream = true;
|
||||
kstr << estr.str() << endl;
|
||||
}
|
||||
if (!cstr.str().empty()) kstr << cstr.str() << endl;
|
||||
if (!sstr.str().empty())
|
||||
{
|
||||
bNeedStream = true;
|
||||
kstr << sstr.str();
|
||||
}
|
||||
|
||||
return kstr.str();
|
||||
}
|
||||
|
||||
string CodeGenerator::generateTS(const NamespacePtr &pPtr, const string &sContent)
|
||||
{
|
||||
ostringstream str;
|
||||
if (!sContent.empty())
|
||||
{
|
||||
str << "export namespace " << pPtr->getId() << " {" << endl;
|
||||
str << sContent;
|
||||
str << "}" << endl << endl;
|
||||
}
|
||||
return str.str();
|
||||
}
|
||||
|
||||
void CodeGenerator::generateTS(const ContextPtr &pPtr)
|
||||
{
|
||||
vector<NamespacePtr> namespaces = pPtr->getNamespaces();
|
||||
|
||||
// generate encoders and decoders
|
||||
ostringstream estr;
|
||||
bool bNeedAssert = false;
|
||||
bool bNeedStream = false;
|
||||
bool bQuickFunc = false;
|
||||
for (size_t i = 0; i < namespaces.size(); i++)
|
||||
{
|
||||
estr << generateTS(namespaces[i], generateTS(namespaces[i], bNeedStream, bNeedAssert, bQuickFunc));
|
||||
}
|
||||
if (estr.str().empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// generate module imports
|
||||
ostringstream ostr;
|
||||
if (bNeedAssert)
|
||||
{
|
||||
ostr << "import assert = require(\"assert\");" << endl;
|
||||
}
|
||||
if (bNeedStream)
|
||||
{
|
||||
ostr << "import * as " << IDL_NAMESPACE_STR << "Stream from \"" << _sStreamPath << "\";" << endl;
|
||||
}
|
||||
|
||||
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
|
||||
{
|
||||
if (it->second.sModule.empty()) continue;
|
||||
|
||||
if (estr.str().find(it->second.sModule + ".") == string::npos) continue;
|
||||
|
||||
ostr << "import * as " << it->second.sModule << " from \"" << TC_File::excludeFileExt(it->second.sFile) << "\";" << endl;
|
||||
}
|
||||
|
||||
if (bQuickFunc)
|
||||
{
|
||||
ostr << endl;
|
||||
ostr << "const _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
|
||||
}
|
||||
|
||||
// concat generated code
|
||||
ostringstream sstr;
|
||||
sstr << printHeaderRemark("Structure", DISABLE_TSLINT);
|
||||
sstr << "/// <reference types=\"node\" />" << endl;
|
||||
sstr << ostr.str() << endl;
|
||||
sstr << estr.str() << endl;
|
||||
|
||||
string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + IDL_TYPE + ".ts";
|
||||
|
||||
TC_File::makeDirRecursive(_sToPath, 0755);
|
||||
makeUTF8File(sFileName, sstr.str());
|
||||
}
|
|
@ -46,7 +46,7 @@ bool CodeGenerator::isDependent(const string& sNamespace, const string& sName) c
|
|||
return _depMembers.find(sNamespace + "::" + sName) != _depMembers.end();
|
||||
}
|
||||
|
||||
string CodeGenerator::findName(const string& sNamespace, const string& sName)
|
||||
string CodeGenerator::findName(const string& sNamespace, const string& sName, const bool &bBase)
|
||||
{
|
||||
#ifdef DUMP_FIND_NAME
|
||||
cout << "FINDNAME BEGIN:" << sNamespace << "|" << sName << endl;
|
||||
|
@ -71,17 +71,24 @@ string CodeGenerator::findName(const string& sNamespace, const string& sName)
|
|||
cout << "DEPMEMBER:" << it->first << "|" << inIter->second.sNamespace << "::" << inIter->second.sName << endl;
|
||||
#endif
|
||||
_depMembers.insert(inIter->second.sNamespace + "::" + inIter->second.sName);
|
||||
string prefix;
|
||||
|
||||
if (bBase && it->second.sModule.empty()) {
|
||||
prefix = "base.";
|
||||
} else if (!it->second.sModule.empty()) {
|
||||
prefix = it->second.sModule + ".";
|
||||
}
|
||||
|
||||
switch (inIter->second.iType)
|
||||
{
|
||||
case ImportFileType::EN_ENUM : // [[fallthrough]]
|
||||
case ImportFileType::EN_STRUCT :
|
||||
{
|
||||
return it->second.sModule + (it->second.sModule.empty()?"":".") + inIter->second.sNamespace + "." + inIter->second.sName;
|
||||
return prefix + inIter->second.sNamespace + "." + inIter->second.sName;
|
||||
}
|
||||
case ImportFileType::EN_ENUM_VALUE :
|
||||
{
|
||||
return it->second.sModule + (it->second.sModule.empty()?"":".") + inIter->second.sNamespace + "." + inIter->second.sTypeName + "." + inIter->second.sName;
|
||||
return prefix + inIter->second.sNamespace + "." + inIter->second.sTypeName + "." + inIter->second.sName;
|
||||
}
|
||||
default :
|
||||
{
|
||||
|
|
|
@ -136,7 +136,7 @@ string CodeGenerator::getClassName(const TypePtr& pPtr)
|
|||
return "void";
|
||||
}
|
||||
|
||||
string CodeGenerator::getDataType(const TypePtr& pPtr)
|
||||
string CodeGenerator::getDataType(const TypePtr& pPtr, const bool &bCastEnumAsAny)
|
||||
{
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
|
||||
if (bPtr)
|
||||
|
@ -164,7 +164,7 @@ string CodeGenerator::getDataType(const TypePtr& pPtr)
|
|||
return IDL_NAMESPACE_STR + "Stream.BinBuffer";
|
||||
}
|
||||
|
||||
return IDL_NAMESPACE_STR + "Stream.List(" + getDataType(vPtr->getTypePtr()) + (isRawOrString(vPtr->getTypePtr()) ? ", 1" : "") + ")";
|
||||
return IDL_NAMESPACE_STR + "Stream.List(" + getDataType(vPtr->getTypePtr(), bCastEnumAsAny) + (isRawOrString(vPtr->getTypePtr()) ? ", 1" : "") + ")";
|
||||
}
|
||||
|
||||
StructPtr sPtr = StructPtr::dynamicCast(pPtr);
|
||||
|
@ -183,13 +183,13 @@ string CodeGenerator::getDataType(const TypePtr& pPtr)
|
|||
bool bRight = isRawOrString(mPtr->getRightTypePtr());
|
||||
|
||||
if (!bRight && !bLeft) {
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ")";
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr(), bCastEnumAsAny) + ", " + getDataType(mPtr->getRightTypePtr(), bCastEnumAsAny) + ")";
|
||||
} else if (bRight && bLeft) {
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ", 1, 1)";
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr(), bCastEnumAsAny) + ", " + getDataType(mPtr->getRightTypePtr(), bCastEnumAsAny) + ", 1, 1)";
|
||||
} else if (bRight) {
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ", 0, 1)";
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr(), bCastEnumAsAny) + ", " + getDataType(mPtr->getRightTypePtr(), bCastEnumAsAny) + ", 0, 1)";
|
||||
} else if (bLeft) {
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ", 1)";
|
||||
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr(), bCastEnumAsAny) + ", " + getDataType(mPtr->getRightTypePtr(), bCastEnumAsAny) + ", 1)";
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
@ -200,15 +200,16 @@ string CodeGenerator::getDataType(const TypePtr& pPtr)
|
|||
{
|
||||
vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
|
||||
assert(vecNames.size() == 2);
|
||||
string suffix = bCastEnumAsAny ? " as any" : "";
|
||||
|
||||
return findName(vecNames[0], vecNames[1]);
|
||||
return findName(vecNames[0], vecNames[1]) + suffix;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
string CodeGenerator::getDtsType(const TypePtr &pPtr, const bool bStream)
|
||||
string CodeGenerator::getTsType(const TypePtr &pPtr, const bool bStream, const bool bBase)
|
||||
{
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
|
||||
if (bPtr)
|
||||
|
@ -216,7 +217,7 @@ string CodeGenerator::getDtsType(const TypePtr &pPtr, const bool bStream)
|
|||
switch (bPtr->kind())
|
||||
{
|
||||
case Builtin::KindBool : return "boolean";
|
||||
case Builtin::KindString : return _bStringBinaryEncoding ? (bStream ? (IDL_NAMESPACE_STR + "Stream.BinBuffer") : "Buffer") : "string";
|
||||
case Builtin::KindString : return _bStringBinaryEncoding ? "Buffer" : "string";
|
||||
case Builtin::KindByte : return "number";
|
||||
case Builtin::KindShort : return "number";
|
||||
case Builtin::KindInt : return "number";
|
||||
|
@ -235,7 +236,7 @@ string CodeGenerator::getDtsType(const TypePtr &pPtr, const bool bStream)
|
|||
{
|
||||
return bStream ? (IDL_NAMESPACE_STR + "Stream.BinBuffer") : "Buffer";
|
||||
}
|
||||
return (bStream ? (IDL_NAMESPACE_STR + "Stream.List") : "Array") + string("<") + getDtsType(vPtr->getTypePtr(), bStream) + string(">");
|
||||
return (bStream ? (IDL_NAMESPACE_STR + "Stream.List") : "Array") + string("<") + getTsType(vPtr->getTypePtr(), bStream, bBase) + string(">");
|
||||
}
|
||||
|
||||
StructPtr sPtr = StructPtr::dynamicCast(pPtr);
|
||||
|
@ -244,7 +245,7 @@ string CodeGenerator::getDtsType(const TypePtr &pPtr, const bool bStream)
|
|||
vector<string> vecNames = TC_Common::sepstr<string>(sPtr->getSid(), "::");
|
||||
assert(vecNames.size() == 2);
|
||||
|
||||
return findName(vecNames[0], vecNames[1]) + (bStream ? "" : "$OBJ");
|
||||
return findName(vecNames[0], vecNames[1], bBase) + (bStream ? "" : ".Object");
|
||||
}
|
||||
|
||||
MapPtr mPtr = MapPtr::dynamicCast(pPtr);
|
||||
|
@ -252,18 +253,22 @@ string CodeGenerator::getDtsType(const TypePtr &pPtr, const bool bStream)
|
|||
{
|
||||
if (bStream)
|
||||
{
|
||||
return IDL_NAMESPACE_STR + "Stream.Map<" + getDtsType(mPtr->getLeftTypePtr(), bStream) + ", " + getDtsType(mPtr->getRightTypePtr(), bStream) + ">";
|
||||
// In current version (20190311) of the streaming library,
|
||||
// TypeScript cannot infer enum type over conditional type correctly.
|
||||
// So use `HeroMap` instead of `Map` to solve this problem.
|
||||
EnumPtr keyTypePtr = EnumPtr::dynamicCast(mPtr->getLeftTypePtr());
|
||||
string mapName = keyTypePtr ? "HeroMap" : "Map";
|
||||
|
||||
return IDL_NAMESPACE_STR + "Stream." + mapName + "<" + getTsType(mPtr->getLeftTypePtr(), bStream) + ", " + getTsType(mPtr->getRightTypePtr(), bStream, bBase) + ">";
|
||||
}
|
||||
else
|
||||
{
|
||||
const string& sLeftType = getDtsType(mPtr->getLeftTypePtr(), bStream);
|
||||
if (sLeftType == "number" || sLeftType == "string")
|
||||
const string& sLeftType = getTsType(mPtr->getLeftTypePtr(), bStream, bBase);
|
||||
const string& sRightType = getTsType(mPtr->getRightTypePtr(), bStream, bBase);
|
||||
if (isSimple(mPtr->getLeftTypePtr()))
|
||||
{
|
||||
return "{[key: " + getDtsType(mPtr->getLeftTypePtr(), bStream) + "]: " + getDtsType(mPtr->getRightTypePtr(), bStream) + "}";
|
||||
}
|
||||
else if (isSimple(mPtr->getLeftTypePtr()) && sLeftType != "Buffer")
|
||||
{
|
||||
return "object";
|
||||
const string& recordKeyType = sLeftType == "number" ? "number" : "string";
|
||||
return "Record<" + recordKeyType + ", " + sRightType + ">";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -278,7 +283,7 @@ string CodeGenerator::getDtsType(const TypePtr &pPtr, const bool bStream)
|
|||
vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
|
||||
assert(vecNames.size() == 2);
|
||||
|
||||
return findName(vecNames[0], vecNames[1]);
|
||||
return findName(vecNames[0], vecNames[1], bBase);
|
||||
}
|
||||
|
||||
assert(false);
|
||||
|
@ -357,7 +362,7 @@ string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault,
|
|||
{
|
||||
if (TC_Common::tostr(TC_Common::strto<long>(sTemp)) != sTemp)
|
||||
{
|
||||
//有可能是枚举值,在枚举值中查找
|
||||
// lookup in the enum when it is a enum
|
||||
vector<string> vecNames = TC_Common::sepstr<string>(sDefault, "::");
|
||||
if (vecNames.size() == 2)
|
||||
{
|
||||
|
@ -433,7 +438,7 @@ string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault,
|
|||
|
||||
if (bGlobal)
|
||||
{
|
||||
return "new " + getDataType(pPtr->getTypePtr());
|
||||
return "new " + getDataType(pPtr->getTypePtr(), true);
|
||||
}
|
||||
|
||||
return sDefault;
|
||||
|
|
|
@ -38,6 +38,7 @@ void usage()
|
|||
cout << " --r-reserved list of names(split by \",\") that should be keeped." << endl;
|
||||
cout << " --client just for client side source file." << endl;
|
||||
cout << " --server just for server side source file." << endl;
|
||||
cout << " --ts generate typescript file." << endl;
|
||||
cout << " --dts generate d.ts file." << endl;
|
||||
cout << " --use-string-represent use <string> represent <long> type." << endl;
|
||||
cout << " --string-binary-encoding get string raw bytes <BinBuffer>." << endl;
|
||||
|
@ -132,6 +133,7 @@ int main(int argc, char* argv[])
|
|||
generator.setUseStringRepresent(option.hasParam("use-string-represent"));
|
||||
generator.setStringBinaryEncoding(option.hasParam("string-binary-encoding"));
|
||||
generator.setEnumReverseMappings(option.hasParam("enum-reverse-mappings"));
|
||||
generator.setEnableTS(option.hasParam("ts"));
|
||||
generator.setEnableDTS(option.hasParam("dts"));
|
||||
|
||||
if (option.hasParam("optimize"))
|
||||
|
|
Loading…
Reference in New Issue
Block a user