modify demo CMakeLists.txt

close TARS_SSL TARS_HTTP2 default
This commit is contained in:
ruanshudong 2020-03-18 17:09:27 +08:00
parent ad39ed3dfd
commit d2488da313
14 changed files with 774 additions and 342 deletions

View File

@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8)
project(Demo-DemoServer)
option(TARS_MYSQL "option for mysql" ON)
option(TARS_SSL "option for ssl" ON)
option(TARS_HTTP2 "option for http2" ON)
option(TARS_SSL "option for ssl" OFF)
option(TARS_HTTP2 "option for http2" OFF)
if(WIN32)
include (c:\\tars\\cpp\\makefile\\tars-tools.cmake)

View File

@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8)
project(Demo-DemoServer)
option(TARS_MYSQL "option for mysql" ON)
option(TARS_SSL "option for ssl" ON)
option(TARS_HTTP2 "option for http2" ON)
option(TARS_SSL "option for ssl" OFF)
option(TARS_HTTP2 "option for http2" OFF)
if(WIN32)
include (c:\\tars\\cpp\\makefile\\tars-tools.cmake)

View File

@ -21,8 +21,8 @@ string CodeGenerator::printHeaderRemark(const string &sTypeName)
ostringstream s;
s << "// **********************************************************************" << endl;
s << "// Parsed By " << IDL_NAMESPACE_STR << "Parser(" << PARSER_VERSION << "), Generated By " << EXECUTE_FILENAME << "(" << GENERATOR_VERSION << ")" << endl;
s << "// " << IDL_NAMESPACE_STR << "Parser Maintained By <WSRD> and " << EXECUTE_FILENAME << " Maintained By <superzheng>" << endl;
s << "// Generated from \"" << TC_File::extractFileName(_sIdlFile) << "\" by " <<
s << "// " << IDL_NAMESPACE_STR << "Parser Maintained By <" << TC_Common::upper(IDL_NAMESPACE_STR) << "> and " << EXECUTE_FILENAME << " Maintained By <superzheng>" << endl;
s << "// Generated from \"" << TC_File::extractFileName(_sIdlFile) << "\" by " <<
(_bEntry ? sTypeName : (_bMinimalMembers ? "Minimal" : "Relation")) << " Mode" << endl;
s << "// **********************************************************************" << endl;
s << endl;
@ -43,26 +43,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)
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 (_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();
@ -74,10 +95,11 @@ void CodeGenerator::createFile(const string &file, const bool bEntry)
node.setTargetPath(_sToPath);
node.setRecursive(_bRecursive);
node.setUseSpecialPath(_bUseSpecialPath);
node.setUseStringRepresent(_bUseStringRepresent);
node.setLongType(_iLongType);
node.setStringBinaryEncoding(_bStringBinaryEncoding);
node.setMinimalMembers(_bMinimalMembers);
node.setDependent(_depMembers);
node.setEnableTS(_bTS);
node.setEnableDTS(_bDTS);
node.createFile(files[ii], false);

View File

@ -60,6 +60,9 @@
#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
@ -74,10 +77,13 @@ public:
_bServer(false),
_bRecursive(false),
_bUseSpecialPath(false),
_bUseStringRepresent(false),
_iLongType(Number),
_bStringBinaryEncoding(false),
_bEnumReverseMappings(false),
_bMinimalMembers(false),
_bDTS(false) {}
_bTS(false),
_bDTS(false),
_iOptimizeLevel(O0) {}
void createFile(const string &file, const bool bEntry = true);
@ -95,16 +101,26 @@ public:
void setUseSpecialPath(bool bEnable) { _bUseSpecialPath = bEnable; }
void setUseStringRepresent(bool bEnable) { _bUseStringRepresent = bEnable; }
void setLongType(int iLongType) { _iLongType = iLongType; }
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 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};
enum LONG_TYPE {Number = 0, String, BigInt};
private:
struct ImportFileType
{
@ -132,29 +148,43 @@ private:
string makeName();
string findName(const string & sNamespace, const string & sName);
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);
string getDataType(const TypePtr& pPtr, const bool &bCastEnumAsAny = false);
string getDtsType(const TypePtr &pPtr, const bool bStream = true);
string getClassName(const TypePtr& pPtr);
string getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string & sNamespace);
string getTsType(const TypePtr &pPtr, const bool bStream = true, const bool bBase = false);
string getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string & sNamespace, const bool bGlobal);
string getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string & sNamespace, const bool &bGlobal = true, const bool &bCastEnumAsAny = false);
string generateJS(const StructPtr & pPtr, const string &sNamespace, bool &bNeedAssert);
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);
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);
@ -164,6 +194,15 @@ private:
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);
@ -179,6 +218,17 @@ private:
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);
@ -188,6 +238,9 @@ private:
void generateJSServerImp(const ContextPtr &cPtr);
private:
void generateTSServerImp(const ContextPtr &cPtr);
private:
string generateDTS(const StructPtr &pPtr, const string &sNamespace);
@ -222,7 +275,7 @@ private:
bool isBinBuffer(const TypePtr & pPtr) const;
bool isRawOrString(const TypePtr & pPtr) const;
string representArgument(const TypePtr& pPtr) const;
bool isDependent(const string & sNamespace, const string & sName) const;
@ -245,17 +298,23 @@ private:
bool _bUseSpecialPath;
bool _bUseStringRepresent;
int _iLongType;
bool _bStringBinaryEncoding;
bool _bEnumReverseMappings;
bool _bMinimalMembers;
bool _bEntry;
string _sIdlFile;
bool _bTS;
bool _bDTS;
int _iOptimizeLevel;
};
#endif

View File

@ -18,13 +18,14 @@
void CodeGenerator::makeUTF8File(const string& sFileName, const string& sFileContent)
{
char header[3] = {(char)(0xef), (char)(0xbb), (char)(0xbf)};
try {
string sData = TC_Encoder::gbk2utf8(sFileContent);
string sData(header, 3);
sData += TC_Encoder::gbk2utf8(sFileContent);
TC_File::save2file(sFileName, sData.c_str());
TC_File::save2file(sFileName, sData.c_str());
} catch (...) {
cout << "Convert GBK to UTF8 failed, current encoding is GBK.";
TC_File::save2file(sFileName, sFileContent.c_str());
}
}
string CodeGenerator::getRealFileInfo(const string& sPath)

View File

@ -19,33 +19,61 @@
string CodeGenerator::generateJS(const EnumPtr &pPtr, const string &sNamespace)
{
ostringstream s;
s << TAB << sNamespace << "." << 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++)
if (_bEnumReverseMappings)
{
bDependent |= isDependent(sNamespace, member[i]->getId());
s << TAB << "(function(" << pPtr->getId() << ") {" << endl;
INC_TAB;
if (member[i]->hasDefault())
{
nenum = TC_Common::strto<int>(member[i]->def());
}
else
{
nenum++;
}
int nenum = -1;
vector<TypeIdPtr>& member = pPtr->getAllMemberPtr();
for (size_t i = 0; i < member.size(); i++)
{
bDependent |= isDependent(sNamespace, member[i]->getId());
s << TAB << "\"" << member[i]->getId() << "\" : " << TC_Common::tostr(nenum) << "," << endl;
if (member[i]->hasDefault())
{
nenum = TC_Common::strto<int>(member[i]->def());
}
else
{
nenum++;
}
s << TAB << pPtr->getId() << "[" << pPtr->getId() << "[\"" << member[i]->getId() << "\"] = " << TC_Common::tostr(nenum) << "] = "
<< "\"" << member[i]->getId() << "\";" << endl;
}
DEL_TAB;
s << TAB << "}(" << sNamespace << "." << pPtr->getId() << " = {}));" << endl;
}
s << TAB << "\"_classname\" : \"" << sNamespace << "." << pPtr->getId() << "\"" << endl;
DEL_TAB;
s << TAB << "};" << endl;
else
{
s << TAB << sNamespace << "." << pPtr->getId() << " = {" << endl;
INC_TAB;
//函数
int nenum = -1;
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;
}
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;
@ -75,7 +103,7 @@ string CodeGenerator::generateJS(const ConstPtr &pPtr, const string &sNamespace,
return s.str();
}
string CodeGenerator::generateJS(const StructPtr & pPtr, const string &sNamespace, bool &bNeedAssert)
string CodeGenerator::generateJS(const StructPtr &pPtr, const string &sNamespace, bool &bNeedAssert, bool &bQuickFunc)
{
if (_bMinimalMembers && !_bEntry && !isDependent(sNamespace, pPtr->getId()))
{
@ -110,7 +138,7 @@ string CodeGenerator::generateJS(const StructPtr & pPtr, const string &sNamespac
//_readFrom
s << TAB << sNamespace << "." << pPtr->getId() << "._readFrom = function (is) {" << endl;
INC_TAB;
s << TAB << "var tmp = new " << sNamespace << "." << pPtr->getId() << "();" << endl;
s << TAB << "var tmp = new " << sNamespace << "." << pPtr->getId() << ";" << endl;
for (size_t i = 0; i < member.size(); i++)
{
string sFuncName = toFunctionName(member[i], "read");
@ -120,7 +148,7 @@ string CodeGenerator::generateJS(const StructPtr & pPtr, const string &sNamespac
if (isSimple(member[i]->getTypePtr()))
{
s << getDefault(member[i], member[i]->def(), sNamespace)
<< (isRawOrString(member[i]->getTypePtr()) ? ", 1" : "");
<< representArgument(member[i]->getTypePtr());
}
else
{
@ -142,11 +170,21 @@ string CodeGenerator::generateJS(const StructPtr & pPtr, const string &sNamespac
string sFuncName = toFunctionName(member[i], "write");
s << TAB << "os." << sFuncName << "(" << member[i]->getTag() << ", this." << member[i]->getId()
<< (isRawOrString(member[i]->getTypePtr()) ? ", 1" : "") << ");" << endl;
<< representArgument(member[i]->getTypePtr()) << ");" << endl;
}
DEL_TAB;
s << TAB << "};" << endl;
/*
* Size Optimize:
* Remove <mutil_map> support.
* Remove toBinBuffer, readFromObject, toObject, new, create members.
*/
if (_iOptimizeLevel == Os)
{
return s.str();
}
//_equal
vector<string> key = pPtr->getKey();
@ -233,19 +271,22 @@ string CodeGenerator::generateJS(const StructPtr & pPtr, const string &sNamespac
DEL_TAB;
s << TAB << "};" << endl;
//readFromJson
//readFromObject
s << TAB << sNamespace << "." << pPtr->getId() << ".prototype.readFromObject = function(json) { "<< endl;
INC_TAB;
for (size_t i = 0; i < member.size(); i++)
{
if (isSimple(member[i]->getTypePtr())) {
s << TAB << "json.hasOwnProperty(\"" << member[i]->getId() << "\") && (this." << member[i]->getId() << " = json." << member[i]->getId() << ");" << endl;
s << TAB << "_hasOwnProperty.call(json, \"" << member[i]->getId() << "\") && (this." << member[i]->getId() << " = json." << member[i]->getId() << ");" << endl;
} else {
s << TAB << "json.hasOwnProperty(\"" << member[i]->getId() << "\") && (this." << member[i]->getId() << ".readFromObject(json." << member[i]->getId() << "));" << endl;
s << TAB << "_hasOwnProperty.call(json, \"" << member[i]->getId() << "\") && (this." << member[i]->getId() << ".readFromObject(json." << member[i]->getId() << "));" << endl;
}
bQuickFunc = true;
}
s << TAB << "return this;" << endl;
DEL_TAB;
s << TAB << "};" << endl;
@ -275,7 +316,7 @@ string CodeGenerator::generateJS(const StructPtr & pPtr, const string &sNamespac
return s.str();
}
string CodeGenerator::generateJS(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedAssert)
string CodeGenerator::generateJS(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedAssert, bool &bQuickFunc)
{
ostringstream sstr;
vector<StructPtr> ss(pPtr->getAllStructPtr());
@ -285,7 +326,7 @@ string CodeGenerator::generateJS(const NamespacePtr &pPtr, bool &bNeedStream, bo
for (vector<StructPtr>::iterator iter=ss.begin(); iter!=ss.end();)
{
string str = generateJS(*iter, pPtr->getId(), bNeedAssert);
string str = generateJS(*iter, pPtr->getId(), bNeedAssert, bQuickFunc);
if (!str.empty()) {
sstr << str << endl;
@ -301,23 +342,31 @@ string CodeGenerator::generateJS(const NamespacePtr &pPtr, bool &bNeedStream, bo
vector<ConstPtr> &cs = pPtr->getAllConstPtr();
for (size_t i = 0; i < cs.size(); i++)
{
cstr << generateJS(cs[i], pPtr->getId(), bNeedStream);
string str = generateJS(cs[i], pPtr->getId(), bNeedStream);
if (!str.empty()) {
cstr << str << endl;
}
}
ostringstream estr;
vector<EnumPtr> & es = pPtr->getAllEnumPtr();
for (size_t i = 0; i < es.size(); i++)
{
estr << generateJS(es[i], pPtr->getId());
string str = generateJS(es[i], pPtr->getId());
if (!str.empty()) {
estr << str << endl;
}
}
ostringstream str;
if (!estr.str().empty()) str << estr.str() << endl;
if (!cstr.str().empty()) str << cstr.str() << endl;
if (!estr.str().empty()) str << estr.str();
if (!cstr.str().empty()) str << cstr.str();
if (!sstr.str().empty())
{
bNeedStream = true;
str << sstr.str() << endl;
str << sstr.str();
}
return str.str();
@ -340,20 +389,21 @@ bool CodeGenerator::generateJS(const ContextPtr &pPtr)
}
}
//先生成编解码体
// 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 << generateJS(namespaces[i], bNeedStream, bNeedAssert);
estr << generateJS(namespaces[i], bNeedStream, bNeedAssert, bQuickFunc);
}
if (estr.str().empty())
{
return false;
}
//再生成导入模块
// generate module imports
ostringstream ostr;
for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
{
@ -364,9 +414,11 @@ bool CodeGenerator::generateJS(const ContextPtr &pPtr)
ostr << "var " << it->second.sModule << " = require(\"" << it->second.sFile << "\");" << endl;
}
//生成文件内容
// concat generated code
ostringstream sstr;
sstr << printHeaderRemark("Structure");
sstr << DISABLE_ESLINT << endl;
sstr << endl;
sstr << "\"use strict\";" << endl << endl;
if (bNeedAssert)
{
@ -376,6 +428,11 @@ bool CodeGenerator::generateJS(const ContextPtr &pPtr)
{
sstr << "var " << IDL_NAMESPACE_STR << "Stream = require(\"" << _sStreamPath << "\");" << endl;
}
if (bQuickFunc)
{
sstr << endl;
sstr << "var _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
}
sstr << ostr.str() << endl;
sstr << istr.str();
sstr << estr.str() << endl;

View File

@ -21,10 +21,9 @@ string CodeGenerator::generateDTS(const EnumPtr &pPtr, const string &sNamespace)
ostringstream s;
INC_TAB;
s << TAB << "enum " << pPtr->getId() << " {" << endl;
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;
@ -67,8 +66,8 @@ string CodeGenerator::generateDTS(const ConstPtr &pPtr, const string &sNamespace
}
INC_TAB;
s << TAB << "const " << pPtr->getTypeIdPtr()->getId() << ":"
<< getDtsType(pPtr->getTypeIdPtr()->getTypePtr()) << ";"
s << TAB << "const " << pPtr->getTypeIdPtr()->getId() << ":"
<< getTsType(pPtr->getTypeIdPtr()->getTypePtr()) << ";"
<< endl;
DEL_TAB;
return s.str();
@ -81,51 +80,61 @@ string CodeGenerator::generateDTS(const StructPtr &pPtr, const string &sNamespac
return "";
}
string sStructName = pPtr->getId() + "$OBJ";
vector<TypeIdPtr> &member = pPtr->getAllMemberPtr();
ostringstream s;
INC_TAB;
ostringstream s;
s << TAB << "class " << pPtr->getId() << " {" << endl;
INC_TAB;
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)
{
s << endl;
}
s << TAB << "toObject(): " << sStructName << ";" << endl;
s << TAB << "readFromObject(json: " << sStructName << "): void;" << 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;
/*
* Size Optimize:
* Remove <mutil_map> support.
* Remove toBinBuffer, readFromObject, toObject, new, create members.
*/
if (_iOptimizeLevel != Os)
{
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 << TAB << "interface " << sStructName << " {" << endl;
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 = getDtsType(member[i]->getTypePtr(), false);
if (!sType.empty())
{
s << TAB << (member[i]->getId()) << (member[i]->isRequire()?": ":"?: ") << sType << ";" << endl;
}
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::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;)
@ -134,19 +143,19 @@ string CodeGenerator::generateDTS(const NamespacePtr &pPtr, bool &bNeedStream)
for (vector<StructPtr>::iterator iter=ss.begin(); iter!=ss.end();)
{
string str = generateDTS(*iter, pPtr->getId());
if (!str.empty())
if (!str.empty())
{
sstr << str << endl;
iter = ss.erase(iter);
}
else
}
else
{
iter++;
}
}
}
//常量
// const
ostringstream cstr;
vector<ConstPtr> &cs = pPtr->getAllConstPtr();
for (size_t i = 0; i < cs.size(); i++)
@ -154,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++)
@ -179,7 +188,7 @@ string CodeGenerator::generateDTS(const NamespacePtr &pPtr, const string &sConte
ostringstream str;
if (!sContent.empty())
{
str << "export declare namespace " << pPtr->getId() << " {" << endl;
str << "export namespace " << pPtr->getId() << " {" << endl;
str << sContent;
str << "}" << endl << endl;
}
@ -189,8 +198,8 @@ string CodeGenerator::generateDTS(const NamespacePtr &pPtr, const string &sConte
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++)
@ -202,7 +211,7 @@ void CodeGenerator::generateDTS(const ContextPtr &pPtr)
return;
}
//再生成导入模块
// generate module imports
ostringstream ostr;
if (bNeedStream)
{
@ -212,15 +221,18 @@ void CodeGenerator::generateDTS(const ContextPtr &pPtr)
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;
}
//生成文件内容
// concat generated code
ostringstream sstr;
sstr << printHeaderRemark("Structure");
sstr << DISABLE_TSLINT << endl;
sstr << DISABLE_ESLINT << endl;
sstr << endl;
sstr << ostr.str() << endl;
sstr << estr.str() << endl;

View File

@ -16,6 +16,15 @@
#include "code_generator.h"
#define INVOKE_RETURN(protocol, prefix, params) \
str << TAB << "return this._worker." << TC_Common::lower(protocol) << "_invoke(\"" << oPtr->getId() << "\", "; \
str << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$" << prefix << "E"; \
str << "(" << sParams << params << "), arguments[arguments.length - 1], "; \
str << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$IF" << ").then("; \
str << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$" << prefix << "D, "; \
str << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$ER);" << endl;
#define PROTOCOL_PARAMS (sParams.empty() ? "" : ", ") << "version"
struct SortOperation
{
bool operator()(const OperationPtr &o1, const OperationPtr &o2)
@ -28,9 +37,10 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
{
ostringstream str;
//SETP01 生成编码接口
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$EN = function (";
vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr();
bool bHasParamOut = false;
string sParams = "";
for (size_t i = 0; i < vParamDecl.size(); i++)
{
if (vParamDecl[i]->isOut())
@ -38,9 +48,48 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
continue;
}
str << (i == 0?"":", ") << vParamDecl[i]->getTypeIdPtr()->getId();
sParams += (sParams.empty()?"":", ") + vParamDecl[i]->getTypeIdPtr()->getId();
}
str << ") {" << endl;
// generate function metadata (SharedFunctionInfo)
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$IF = {" << 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;
DEL_TAB;
str << TAB << "};" << endl << endl;
// generate IDL Encoder ($IE)
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$IE = function (" << sParams << ") {" << endl;
INC_TAB;
@ -51,10 +100,10 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
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;
<< (i + 1) << ", " << vParamDecl[i]->getTypeIdPtr()->getId()
<< representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ");" << endl;
// 写入 Dependent 列表
// push the symbol into dependent list
getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
}
@ -64,9 +113,8 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
str << TAB << "};" << endl << endl;
//STEP02 生成解码函数
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$DE = function (data) {" << endl;
// generate IDL Decoder ($ID)
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$ID = function (data) {" << endl;
INC_TAB;
str << TAB << "try {" << endl;
INC_TAB;
@ -104,7 +152,7 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
if (isSimple(oPtr->getReturnPtr()->getTypePtr()))
{
str << getDefault(oPtr->getReturnPtr(), oPtr->getReturnPtr()->def(), nPtr->getId())
<< (isRawOrString(oPtr->getReturnPtr()->getTypePtr()) ? ", 1" : "");
<< representArgument(oPtr->getReturnPtr()->getTypePtr());
}
else
{
@ -130,8 +178,8 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
if (isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
{
str << getDefault(vParamDecl[i]->getTypeIdPtr(), vParamDecl[i]->getTypeIdPtr()->def(), nPtr->getId())
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "");
str << getDefault(vParamDecl[i]->getTypeIdPtr(), vParamDecl[i]->getTypeIdPtr()->def(), nPtr->getId())
<< representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
}
else
{
@ -163,80 +211,155 @@ string CodeGenerator::generateJSProxy(const NamespacePtr &nPtr, const InterfaceP
DEL_TAB;
str << TAB << "} catch (e) {" << endl;
INC_TAB;
str << TAB << "throw {" << endl;
str << TAB << "throw _makeError(data, e.message, " << IDL_NAMESPACE_STR << "Error.CLIENT.DECODE_ERROR);" << endl;
DEL_TAB;
str << TAB << "}" << endl;
DEL_TAB;
str << TAB << "};" << endl << endl;
// generate Protocol Encoder ($PE)
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$PE = function ("
<< sParams << (sParams.empty() ? "" : ", ") << "__$PROTOCOL$VERSION) {" << endl;
INC_TAB;
str << TAB << "var " << 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()
<< representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ");" << endl;
// push the symbol into dependent list
getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
}
str << TAB << "return " << PROTOCOL_VAR << ";" << endl;
DEL_TAB;
str << TAB << "};" << endl << endl;
// generate Protocol Decoder ($PD)
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$PD = function (data) {" << endl;
INC_TAB;
str << TAB << "try {" << endl;
INC_TAB;
if (oPtr->getReturnPtr()->getTypePtr() || bHasParamOut) {
str << TAB << "var " << PROTOCOL_VAR << " = data.response." << 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 << "\"error\" : {" << endl;
INC_TAB;
str << TAB << "\"code\" : " << IDL_NAMESPACE_STR << "Error.CLIENT.DECODE_ERROR," << endl;
str << TAB << "\"message\" : e.message" << endl;
DEL_TAB;
str << TAB << "}" << endl;
str << TAB << "\"costtime\" : data.request.costtime";
if (oPtr->getReturnPtr()->getTypePtr())
{
str << "," << endl;
str << TAB << "\"return\" : " << PROTOCOL_VAR << "." << toFunctionName(oPtr->getReturnPtr(), "read") << "(\"\"";
if (!isSimple(oPtr->getReturnPtr()->getTypePtr()) && !isBinBuffer(oPtr->getReturnPtr()->getTypePtr()))
{
str << ", " << getDataType(oPtr->getReturnPtr()->getTypePtr());
}
str << ", " << getDefault(oPtr->getReturnPtr(), "", nPtr->getId(), true)
<< representArgument(oPtr->getReturnPtr()->getTypePtr());
str << ")";
}
if (bHasParamOut)
{
str << "," << endl;
str << TAB << "\"arguments\" : {" << 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());
}
str << ")";
if (i == vParamDecl.size() - 1)
{
str << endl;
}
else
{
str << "," << endl;
}
}
DEL_TAB;
str << TAB << "}";
}
str << 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 << "Error.CLIENT.DECODE_ERROR);" << endl;
DEL_TAB;
str << TAB << "}" << endl;
DEL_TAB;
str << TAB << "};" << endl << endl;
//STEP03 生成框架调用错误处理函数
// generate error handler ($ER
str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$ER = function (data) {" << endl;
INC_TAB;
str << TAB << "throw {" << endl;
INC_TAB;
str << TAB << "\"request\" : data.request," << endl;
str << TAB << "\"response\" : {" << endl;
INC_TAB;
str << TAB << "\"costtime\" : data.request.costtime," << endl;
str << TAB << "\"error\" : data.error" << endl;
DEL_TAB;
str << TAB << "}" << endl;
DEL_TAB;
str << TAB << "}" << endl;
str << TAB << "throw _makeError(data, \"Call " << pPtr->getId() << "::" << oPtr->getId() << " failed\");" << endl;
DEL_TAB;
str << TAB << "};" << endl << endl;
//SETP04 生成函数接口
str << TAB << nPtr->getId() << "." << pPtr->getId() << "Proxy.prototype." << oPtr->getId() << " = function (";
for (size_t i = 0; i < vParamDecl.size(); i++)
{
if (vParamDecl[i]->isOut())
{
continue;
}
str << (i == 0?"":", ") << vParamDecl[i]->getTypeIdPtr()->getId();
}
str << ") {" << endl;
// generate function body
str << TAB << nPtr->getId() << "." << pPtr->getId() << "Proxy.prototype." << oPtr->getId() << " = function ("
<< sParams << ") {" << endl;
INC_TAB;
str << TAB << "return this._worker." << TC_Common::lower(IDL_NAMESPACE_STR) << "_invoke(\"" << oPtr->getId() << "\", ";
str << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$EN(";
for (size_t i = 0; i < vParamDecl.size(); i++)
{
if (vParamDecl[i]->isOut())
{
continue;
}
str << TAB << "var version = this._worker.version;" << endl;
str << (i == 0?"":", ") << vParamDecl[i]->getTypeIdPtr()->getId();
}
str << "), arguments[arguments.length - 1]).then(";
str << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$DE, ";
str << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$ER);" << endl;
str << TAB << "if (version === " << PROTOCOL_SIMPLE << " || version === " << PROTOCOL_COMPLEX << ") {" << endl;
INC_TAB;
INVOKE_RETURN(PROTOCOL_VAR, "P", PROTOCOL_PARAMS);
DEL_TAB;
str << TAB << "} else {" << endl;
INC_TAB;
INVOKE_RETURN(IDL_NAMESPACE_STR, "I", "");
DEL_TAB;
str << TAB << "}" << endl;
DEL_TAB;
str << TAB << "};" << endl;
// 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;
return str.str();
}
@ -303,8 +426,8 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
istr << TAB << namespaces[i]->getId() << "." << is[ii]->getId() << "Proxy = function () {" << endl;
INC_TAB;
istr << TAB << "this._name = undefined;" << endl;
istr << TAB << "this._worker = undefined;" << endl;
istr << TAB << "this._name = undefined;" << endl;
istr << TAB << "this._worker = undefined;" << endl;
DEL_TAB;
istr << TAB << "};" << endl << endl;
@ -319,16 +442,29 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
istr << TAB << "return this._worker.timeout;" << endl;
DEL_TAB;
istr << TAB << "};" << endl << endl;
istr << TAB << namespaces[i]->getId() << "." << is[ii]->getId() << "Proxy.prototype.setVersion = function (iVersion) {" << endl;
INC_TAB;
istr << TAB << "this._worker.version = iVersion;" << endl;
DEL_TAB;
istr << TAB << "};" << endl << endl;
istr << TAB << namespaces[i]->getId() << "." << is[ii]->getId() << "Proxy.prototype.getVersion = function () {" << endl;
INC_TAB;
istr << TAB << "return this._worker.version;" << endl;
DEL_TAB;
istr << TAB << "};" << endl;
}
}
//先生成编解码 + 代理类
// generate proxy classes with encoders and decoders
ostringstream estr;
bool bNeedAssert = false;
bool bNeedStream = false;
bool bQuickFunc = false;
for(size_t i = 0; i < namespaces.size(); i++)
{
estr << generateJS(namespaces[i], bNeedStream, bNeedAssert);
estr << generateJS(namespaces[i], bNeedStream, bNeedAssert, bQuickFunc);
}
bool bNeedRpc = false;
@ -342,7 +478,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++)
{
@ -353,9 +489,11 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
ostr << "var " << it->second.sModule << " = require(\"" << it->second.sFile << "\");" << endl;
}
//生成文件内容
// concat generated code
ostringstream sstr;
sstr << printHeaderRemark("Client");
sstr << DISABLE_ESLINT << endl;
sstr << endl;
sstr << "\"use strict\";" << endl << endl;
if (bNeedAssert)
{
@ -371,6 +509,48 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
}
sstr << ostr.str() << endl;
// generate helper functions
if (bQuickFunc)
{
sstr << "var _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
}
if (bNeedRpc)
{
sstr << TAB << "var _makeError = function (data, message, type) {" << endl;
INC_TAB;
sstr << TAB << "var error = 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 << "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;
}
if (bQuickFunc || bNeedRpc)
{
sstr << endl;
}
sstr << istr.str() << endl;
sstr << estr.str() << endl;
@ -380,4 +560,7 @@ bool CodeGenerator::generateJSProxy(const ContextPtr &cPtr)
makeUTF8File(sFileName, sstr.str());
return true;
}
}
#undef INVOKE_RETURN
#undef PROTOCOL_PARAMS

View File

@ -25,79 +25,55 @@ string CodeGenerator::generateDTSProxy(const InterfacePtr &pPtr)
INC_TAB;
str << TAB << "class " << pPtr->getId() << "Proxy {" << endl;
INC_TAB;
str << TAB << "setTimeout(timeout: number): void;" << endl;
str << TAB << "setTimeout(iTimeout: number): void;" << endl;
str << TAB << "getTimeout(): number;" << endl;
str << TAB << "setVersion(iVersion: number): void;" << endl;
str << TAB << "getVersion(): number;" << endl;
for (size_t i = 0; i < vOperation.size(); i++)
{
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++)
for (size_t j = 0; j < vParamDecl.size(); j++)
{
if(vParamDecl[j]->isOut())
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;
if (!argType.empty())
{
funcReturnGeneric += "{ " + argType + " }>";
}
else
{
funcReturnGeneric += "undefined>";
}
str << "options?: " << IDL_NAMESPACE_STR << "Rpc.InvokeProperty): Promise<" << IDL_NAMESPACE_STR << "Rpc.ProxyResponse" << funcReturnGeneric << ">;" << endl;
str << TAB << "static " << oPtr->getId() << ": " << IDL_NAMESPACE_STR << "Rpc.SharedFunctionInfo" << ";" << endl;
}
DEL_TAB;
str << TAB << "}" << endl;
//interface
for (size_t i = 0; i < vOperation.size(); i++)
{
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;
}
else
{
str << TAB << "return: void;" << endl;
}
vector<ParamDeclPtr> &vParamDecl = oPtr->getAllParamDeclPtr();
bool hasArgs = false;
for (size_t j = 0; j < vParamDecl.size(); j++)
{
if(vParamDecl[j]->isOut()) {
hasArgs = true;
break;
}
}
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;
}
DEL_TAB;
str << TAB << "}" << endl;
}
DEL_TAB;
str << TAB << "}" << endl;
DEL_TAB;
str << TAB << "}" << endl;
}
DEL_TAB;
return str.str();
@ -107,15 +83,15 @@ string CodeGenerator::generateDTSProxy(const NamespacePtr &nPtr, bool &bNeedStre
{
ostringstream str;
vector<InterfacePtr> &is = nPtr->getAllInterfacePtr();
for (size_t i = 0; i < is.size(); i++)
{
str << generateDTSProxy(is[i]) << endl;
}
if (is.size() != 0)
if (is.size() > 0)
{
bNeedStream = true;
bNeedRpc = true;
}
for (size_t i = 0; i < is.size(); i++)
{
str << generateDTSProxy(is[i]) << endl;
}
return str.str();
}
@ -123,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;
@ -141,20 +117,23 @@ void CodeGenerator::generateDTSProxy(const ContextPtr &cPtr)
return;
}
//再生成导入模块
// generate module imports
ostringstream ostr;
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;
}
//生成文件内容
// concat generated code
ostringstream sstr;
sstr << printHeaderRemark("Client");
sstr << DISABLE_TSLINT << endl;
sstr << DISABLE_ESLINT << endl;
sstr << endl;
if (bNeedStream)
{
sstr << "import * as " << IDL_NAMESPACE_STR << "Stream from \"" << _sStreamPath << "\";" << endl;

View File

@ -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());
}
@ -89,8 +89,8 @@ string CodeGenerator::generateAsync(const NamespacePtr &nPtr, const InterfacePtr
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;
str << TAB << PROTOCOL_VAR << "." << toFunctionName(oPtr->getReturnPtr(), "write") << "(\"\", _ret"
<< representArgument(oPtr->getReturnPtr()->getTypePtr()) << ");" << endl;
}
for (size_t i = 0; i < vParamDecl.size(); i++)
{
@ -98,7 +98,7 @@ string CodeGenerator::generateAsync(const NamespacePtr &nPtr, const InterfacePtr
str << TAB << PROTOCOL_VAR << "." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "(\""
<< vParamDecl[i]->getTypeIdPtr()->getId() << "\", " << vParamDecl[i]->getTypeIdPtr()->getId()
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
<< representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ");" << endl;
}
str << endl;
str << TAB << "this.doResponse(" << PROTOCOL_VAR << ".encode());" << endl;
@ -109,8 +109,8 @@ string CodeGenerator::generateAsync(const NamespacePtr &nPtr, const InterfacePtr
str << TAB << "var 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;
str << TAB << "os." << toFunctionName(oPtr->getReturnPtr(), "write") << "(0, _ret"
<< representArgument(oPtr->getReturnPtr()->getTypePtr()) << ");" << endl;
}
for (size_t i = 0; i < vParamDecl.size(); i++)
{
@ -118,7 +118,7 @@ string CodeGenerator::generateAsync(const NamespacePtr &nPtr, const InterfacePtr
str << TAB << "os." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "("
<< (i + 1) << ", " << vParamDecl[i]->getTypeIdPtr()->getId()
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "") << ");" << endl;
<< representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ");" << endl;
}
str << endl;
str << TAB << "this.doResponse(os.getBinBuffer());" << endl;
@ -172,7 +172,7 @@ string CodeGenerator::generateDispatch(const NamespacePtr &nPtr, const Interface
if (vParamDecl[i]->isOut())
{
dstr << ", " << getDefault(vParamDecl[i]->getTypeIdPtr(), "", nPtr->getId(), true)
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "");
<< representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
}
dstr << ");" << endl;
@ -194,7 +194,7 @@ string CodeGenerator::generateDispatch(const NamespacePtr &nPtr, const Interface
if (isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
{
dstr << getDefault(vParamDecl[i]->getTypeIdPtr(), vParamDecl[i]->getTypeIdPtr()->def(), nPtr->getId())
<< (isRawOrString(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) ? ", 1" : "");
<< representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
}
else
{
@ -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,13 +321,14 @@ bool CodeGenerator::generateJSServer(const ContextPtr &pPtr)
}
}
//生成编解码 + 服务类
// generate server classes with encoders and decoders
ostringstream estr;
bool bNeedAssert = false;
bool bNeedStream = false;
bool bQuickFunc = false;
for(size_t i = 0; i < namespaces.size(); i++)
{
estr << generateJS(namespaces[i], bNeedStream, bNeedAssert);
estr << generateJS(namespaces[i], bNeedStream, bNeedAssert, bQuickFunc);
}
bool bNeedRpc = false;
@ -341,7 +342,7 @@ bool CodeGenerator::generateJSServer(const ContextPtr &pPtr)
return false;
}
//再生成导入模块
// generate module imports
ostringstream ostr;
if (bNeedAssert)
{
@ -363,10 +364,17 @@ bool CodeGenerator::generateJSServer(const ContextPtr &pPtr)
ostr << TAB << "var " << it->second.sModule << " = require(\"" << it->second.sFile << "\");" << endl;
}
if (bQuickFunc)
{
ostr << endl;
ostr << TAB << "var _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
}
ostringstream str;
str << printHeaderRemark("Server");
str << DISABLE_ESLINT << endl;
str << endl;
str << "\"use strict\";" << endl << endl;
str << ostr.str() << endl;
str << istr.str();

View File

@ -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++)
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;
@ -110,7 +116,7 @@ void CodeGenerator::generateDTSServer(const ContextPtr &pPtr)
kstr << generateDTS(namespaces[i], bNeedStream);
kstr << generateDTSServer(namespaces[i], bNeedStream, bNeedRpc);
estr << generateDTS(namespaces[i], kstr.str());
}
if(estr.str().empty())
@ -118,7 +124,7 @@ void CodeGenerator::generateDTSServer(const ContextPtr &pPtr)
return;
}
//再生成导入模块
// generate module imports
ostringstream ostr;
if (bNeedStream)
{
@ -131,7 +137,7 @@ void CodeGenerator::generateDTSServer(const ContextPtr &pPtr)
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;
@ -139,6 +145,9 @@ void CodeGenerator::generateDTSServer(const ContextPtr &pPtr)
ostringstream str;
str << printHeaderRemark("Server");
str << DISABLE_TSLINT << endl;
str << DISABLE_ESLINT << endl;
str << endl;
str << ostr.str() << endl;
str << estr.str() << endl;

View File

@ -29,7 +29,7 @@ string CodeGenerator::makeName()
if (iHigh != 0)
{
s << string(1, (char)(iHigh + 65)) << string(1, (char)(iLow + 65));
s << string(1, (char)(iHigh + 65)) << string(1, (char)(iLow + 65));
}
else
{
@ -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 :
{

View File

@ -68,26 +68,77 @@ string CodeGenerator::toFunctionName(const TypeIdPtr& pPtr, const string& sActio
return "";
}
bool CodeGenerator::isRawOrString(const TypePtr& pPtr) const
string CodeGenerator::representArgument(const TypePtr& pPtr) const
{
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
if (bPtr)
{
if (_bUseStringRepresent && bPtr->kind() == Builtin::KindLong)
if (bPtr->kind() == Builtin::KindLong && _iLongType != CodeGenerator::Number)
{
return true;
stringstream str;
str << ", " << _iLongType;
return str.str();
}
if (_bStringBinaryEncoding && bPtr->kind() == Builtin::KindString)
{
return true;
return ", 1";
}
}
return false;
return "";
}
string CodeGenerator::getDataType(const TypePtr & pPtr)
string CodeGenerator::getClassName(const TypePtr& pPtr)
{
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
if (bPtr)
{
switch (bPtr->kind())
{
case Builtin::KindBool : return "bool";
case Builtin::KindString : return "string";
case Builtin::KindByte : return "char";
case Builtin::KindShort : return "short";
case Builtin::KindInt : return "int32";
case Builtin::KindLong : return "int64";
case Builtin::KindFloat : return "float";
case Builtin::KindDouble : return "double";
default : assert(false);
}
}
VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
if (vPtr)
{
return "list(" + getClassName(vPtr->getTypePtr()) + ")";
}
StructPtr sPtr = StructPtr::dynamicCast(pPtr);
if (sPtr)
{
vector<string> vecNames = TC_Common::sepstr<string>(sPtr->getSid(), "::");
assert(vecNames.size() == 2);
return vecNames[0] + "." + vecNames[1];
}
MapPtr mPtr = MapPtr::dynamicCast(pPtr);
if (mPtr)
{
return "map(" + getClassName(mPtr->getLeftTypePtr()) + ", " + getClassName(mPtr->getRightTypePtr()) + ")";
}
EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
if (ePtr)
{
return "int32";
}
return "void";
}
string CodeGenerator::getDataType(const TypePtr& pPtr, const bool &bCastEnumAsAny)
{
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
if (bPtr)
@ -114,8 +165,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) + representArgument(vPtr->getTypePtr()) + ")";
}
StructPtr sPtr = StructPtr::dynamicCast(pPtr);
@ -130,20 +180,16 @@ string CodeGenerator::getDataType(const TypePtr & pPtr)
MapPtr mPtr = MapPtr::dynamicCast(pPtr);
if (mPtr)
{
bool bLeft = isRawOrString(mPtr->getLeftTypePtr());
bool bRight = isRawOrString(mPtr->getRightTypePtr());
string sLeft = representArgument(mPtr->getLeftTypePtr());
string sRight = representArgument(mPtr->getRightTypePtr());
if (!bRight && !bLeft) {
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ")";
} else if (bRight && bLeft) {
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ", 1, 1)";
} else if (bRight) {
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ", 0, 1)";
} else if (bLeft) {
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr()) + ", " + getDataType(mPtr->getRightTypePtr()) + ", 1)";
} else {
assert(false);
if (sLeft.empty() && !sRight.empty())
{
sLeft = ", 0";
}
return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr(), bCastEnumAsAny) + ", " +
getDataType(mPtr->getRightTypePtr(), bCastEnumAsAny) + sLeft + sRight + ")";
}
EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
@ -151,15 +197,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)
@ -167,13 +214,22 @@ 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";
case Builtin::KindLong : return _bUseStringRepresent ? "string" : "number";
case Builtin::KindFloat : return "number";
case Builtin::KindDouble : return "number";
case Builtin::KindLong :
{
switch (_iLongType)
{
case CodeGenerator::Number : return "number";
case CodeGenerator::String : return "string";
case CodeGenerator::BigInt : return "bigint";
default : assert(false);
}
}
default : assert(false);
}
}
@ -186,7 +242,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);
@ -195,7 +251,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);
@ -203,20 +259,24 @@ 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) + "}";
const string& recordKeyType = sLeftType == "number" ? "number" : "string";
return "Record<" + recordKeyType + ", " + sRightType + ">";
}
else if (isSimple(mPtr->getLeftTypePtr()) && sLeftType != "Buffer")
{
return "object";
}
else
else
{
return "";
}
@ -229,7 +289,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);
@ -269,21 +329,16 @@ bool CodeGenerator::isBinBuffer(const TypePtr & pPtr) const
return false;
}
string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string& sNamespace)
{
return getDefault(pPtr, sDefault, sNamespace, true);
}
string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string& sNamespace, const bool bGlobal)
string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string& sNamespace, const bool &bGlobal, const bool &bCastEnumAsAny)
{
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
if (bPtr)
{
switch (bPtr->kind())
{
case Builtin::KindBool :
case Builtin::KindBool :
return sDefault.empty() ? "false" : sDefault;
case Builtin::KindString :
case Builtin::KindString :
{
if (_bStringBinaryEncoding)
{
@ -308,13 +363,13 @@ 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)
{
sTemp = findName(vecNames[0], vecNames[1]);
}
else
else
{
sTemp = findName(sNamespace, sDefault);
}
@ -326,18 +381,27 @@ string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault,
sTemp = "0";
}
if (_bUseStringRepresent)
if (bPtr->kind() == Builtin::KindLong)
{
if (bPtr->kind() == Builtin::KindLong)
switch (_iLongType)
{
sTemp = "\"" + sTemp + "\"";
case CodeGenerator::String:
{
sTemp = "\"" + sTemp + "\"";
break;
}
case CodeGenerator::BigInt:
{
sTemp = sTemp + "n";
break;
}
}
}
return sTemp;
}
case Builtin::KindFloat : // [[fallthrough]]
case Builtin::KindDouble :
case Builtin::KindDouble :
return sDefault.empty()?"0.0":sDefault;
default :
assert(false);
@ -384,7 +448,7 @@ string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault,
if (bGlobal)
{
return "new " + getDataType(pPtr->getTypePtr());
return "new " + getDataType(pPtr->getTypePtr(), bCastEnumAsAny);
}
return sDefault;

View File

@ -26,21 +26,24 @@ void usage()
{
cout << "Version : " << GENERATOR_VERSION << endl;
cout << "Usage : " << EXECUTE_FILENAME << " [OPTION] " << "*." << TC_Common::lower(IDL_TYPE) << " file" << endl;
cout << " --version print " << EXECUTE_FILENAME << " version" << endl;
cout << " --rpc-path=DIRECTORY specify the path of rpc module." << endl;
cout << " --stream-path=DIRECTORY specify the path of stream module." << endl;
cout << " --allow-reserved-namespace allow you to use reserved word as a namespace." << endl;
cout << " --dir=DIRECTORY generate source file to DIRECTORY." << endl;
cout << " --relative use current path." << endl;
cout << " --base=DIRECTORY where to search " << IDL_TYPE << " files." << endl;
cout << " --r generate source all " << IDL_TYPE << " files." << endl;
cout << " --r-minimal minimize the dependent members." << endl;
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 << " --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;
cout << " --version print " << EXECUTE_FILENAME << " version" << endl;
cout << " --rpc-path=[DIRECTORY] specify the path of rpc module." << endl;
cout << " --stream-path=[DIRECTORY] specify the path of stream module." << endl;
cout << " --allow-reserved-namespace allow you to use reserved word as a namespace." << endl;
cout << " --dir=DIRECTORY generate source file to DIRECTORY." << endl;
cout << " --relative use current path." << endl;
cout << " --base=DIRECTORY where to search " << IDL_TYPE << " files." << endl;
cout << " --r generate source all " << IDL_TYPE << " files." << endl;
cout << " --r-minimal minimize the dependent members." << endl;
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 << " --long-type=[number|string|bigint] use <Number|String|BigInt> represent <long> type, default is <Number>." << endl;
cout << " --string-binary-encoding get string raw bytes <BinBuffer>." << endl;
cout << " --enum-reverse-mappings reverse mapping from enum values to enum names." << endl;
cout << " --optimize=[0|s] support \"s\" to reduce code size, default is 0." << endl;
cout << endl;
cout << EXECUTE_FILENAME << " support type: boolean char short int long float double list map" << endl;
@ -128,10 +131,38 @@ int main(int argc, char* argv[])
generator.setEnableServer(option.hasParam("server"));
generator.setTargetPath(option.hasParam("dir")?option.getValue("dir"):"./");
generator.setUseSpecialPath(option.hasParam("relative"));
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("long-type"))
{
string longType = TC_Common::lower(option.getValue("long-type"));
if (longType == "string")
{
generator.setLongType(CodeGenerator::String);
}
else if (longType == "bigint")
{
generator.setLongType(CodeGenerator::BigInt);
}
}
if (option.hasParam("optimize"))
{
string level = TC_Common::lower(option.getValue("optimize"));
if (level == "s")
{
generator.setOptimize(CodeGenerator::Os);
}
else
{
generator.setOptimize(CodeGenerator::O0);
}
}
bool _bRecursive = option.hasParam("r");
bool _bMinimalMembers = option.hasParam("r-minimal");