123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- /**
- * 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::toFunctionName(const TypeIdPtr& pPtr, const string& sAction)
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
- if (bPtr)
- {
- switch (bPtr->kind())
- {
- case Builtin::KindBool : return sAction + "Boolean";
- case Builtin::KindString : return sAction + "String";
- case Builtin::KindByte : return sAction + "Int8";
- case Builtin::KindShort : return sAction + (bPtr->isUnsigned() ? "UInt8" : "Int16");
- case Builtin::KindInt : return sAction + (bPtr->isUnsigned() ? "UInt16" : "Int32");
- case Builtin::KindLong : return sAction + (bPtr->isUnsigned() ? "UInt32" : "Int64");
- case Builtin::KindFloat : return sAction + "Float";
- case Builtin::KindDouble : return sAction + "Double";
- default : assert(false);
- }
- }
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return sAction + "Bytes";
- }
- return sAction + "List";
- }
- StructPtr sPtr = StructPtr::dynamicCast(pPtr->getTypePtr());
- if (sPtr)
- {
- return sAction + "Struct";
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
- if (ePtr)
- {
- return sAction + "Int32";
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
- if (mPtr)
- {
- return sAction + "Map";
- }
- return "";
- }
- string CodeGenerator::toObjectString(const TypeIdPtr &pPtr)
- {
- string nameId = pPtr->getId();
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
- if (vPtr)
- {
- return nameId + ".toObject()";
- }
- StructPtr sPtr = StructPtr::dynamicCast(pPtr->getTypePtr());
- if (sPtr)
- {
- return nameId + ".toObject()";
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
- if (mPtr)
- {
- return nameId + ".toObject()";
- }
- return nameId;
- }
- string CodeGenerator::representArgument(const TypePtr& pPtr) const
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
- if (bPtr)
- {
- if (bPtr->kind() == Builtin::KindLong && _iLongType != CodeGenerator::Number)
- {
- stringstream str;
- str << ", " << _iLongType;
- return str.str();
- }
- if (_bStringBinaryEncoding && bPtr->kind() == Builtin::KindString)
- {
- return ", 1";
- }
- }
- return "";
- }
- 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)
- {
- switch (bPtr->kind())
- {
- case Builtin::KindBool : return IDL_NAMESPACE_STR + "Stream.Boolean";
- case Builtin::KindString : return IDL_NAMESPACE_STR + "Stream.String";
- case Builtin::KindByte : return IDL_NAMESPACE_STR + "Stream.Int8";
- case Builtin::KindShort : return IDL_NAMESPACE_STR + "Stream.Int16";
- case Builtin::KindInt : return IDL_NAMESPACE_STR + "Stream.Int32";
- case Builtin::KindLong : return IDL_NAMESPACE_STR + "Stream.Int64";
- case Builtin::KindFloat : return IDL_NAMESPACE_STR + "Stream.Float";
- case Builtin::KindDouble : return IDL_NAMESPACE_STR + "Stream.Double";
- default : assert(false);
- }
- }
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return IDL_NAMESPACE_STR + "Stream.BinBuffer";
- }
- return IDL_NAMESPACE_STR + "Stream.List(" + getDataType(vPtr->getTypePtr(), bCastEnumAsAny) + representArgument(vPtr->getTypePtr()) + ")";
- }
- StructPtr sPtr = StructPtr::dynamicCast(pPtr);
- if (sPtr)
- {
- vector<string> vecNames = TC_Common::sepstr<string>(sPtr->getSid(), "::");
- assert(vecNames.size() == 2);
- return findName(vecNames[0], vecNames[1]);
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr);
- if (mPtr)
- {
- string sLeft = representArgument(mPtr->getLeftTypePtr());
- string sRight = representArgument(mPtr->getRightTypePtr());
- 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);
- if (ePtr)
- {
- vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
- assert(vecNames.size() == 2);
- string suffix = bCastEnumAsAny ? " as any" : "";
- return findName(vecNames[0], vecNames[1]) + suffix;
- }
- assert(false);
- return "";
- }
- string CodeGenerator::getTsType(const TypePtr &pPtr, const bool bStream, const bool bBase)
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
- if (bPtr)
- {
- switch (bPtr->kind())
- {
- case Builtin::KindBool : return "boolean";
- case Builtin::KindString : return _bStringBinaryEncoding ? "Buffer" : "string";
- case Builtin::KindByte : return "number";
- case Builtin::KindShort : return "number";
- case Builtin::KindInt : return "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);
- }
- }
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return bStream ? (IDL_NAMESPACE_STR + "Stream.BinBuffer") : "Buffer";
- }
- return (bStream ? (IDL_NAMESPACE_STR + "Stream.List") : "Array") + string("<") + getTsType(vPtr->getTypePtr(), bStream, bBase) + string(">");
- }
- StructPtr sPtr = StructPtr::dynamicCast(pPtr);
- if (sPtr)
- {
- vector<string> vecNames = TC_Common::sepstr<string>(sPtr->getSid(), "::");
- assert(vecNames.size() == 2);
- return findName(vecNames[0], vecNames[1], bBase) + (bStream ? "" : ".Object");
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr);
- if (mPtr)
- {
- if (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 = getTsType(mPtr->getLeftTypePtr(), bStream, bBase);
- const string& sRightType = getTsType(mPtr->getRightTypePtr(), bStream, bBase);
- if (isSimple(mPtr->getLeftTypePtr()))
- {
- const string& recordKeyType = sLeftType == "number" ? "number" : "string";
- return "Record<" + recordKeyType + ", " + sRightType + ">";
- }
- else
- {
- return "";
- }
- }
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
- if (ePtr)
- {
- vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
- assert(vecNames.size() == 2);
- return findName(vecNames[0], vecNames[1], bBase);
- }
- assert(false);
- return "";
- }
- bool CodeGenerator::isSimple(const TypePtr & pPtr) const
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
- if (bPtr)
- {
- return true;
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
- if (ePtr)
- {
- return true;
- }
- return false;
- }
- bool CodeGenerator::isBinBuffer(const TypePtr & pPtr) const
- {
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return true;
- }
- }
- return false;
- }
- 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 :
- return sDefault.empty() ? "false" : sDefault;
- case Builtin::KindString :
- {
- if (_bStringBinaryEncoding)
- {
- return IDL_NAMESPACE_STR + "Stream.BinBuffer.from(\"" + TC_Common::replace(sDefault, "\"", "\\\"") + "\").toNodeBufferUnSafe()";
- }
- else
- {
- return "\"" + TC_Common::replace(sDefault, "\"", "\\\"") + "\"";
- }
- }
- case Builtin::KindByte : // [[fallthrough]]
- case Builtin::KindShort : // [[fallthrough]]
- case Builtin::KindInt : // [[fallthrough]]
- case Builtin::KindLong :
- {
- string sTemp = TC_Common::trim(sDefault);
- if (sTemp.empty())
- {
- sTemp = "0";
- }
- else
- {
- 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
- {
- sTemp = findName(sNamespace, sDefault);
- }
- }
- }
- if (sTemp.empty())
- {
- sTemp = "0";
- }
- if (bPtr->kind() == Builtin::KindLong)
- {
- switch (_iLongType)
- {
- case CodeGenerator::String:
- {
- sTemp = "\"" + sTemp + "\"";
- break;
- }
- case CodeGenerator::BigInt:
- {
- sTemp = sTemp + "n";
- break;
- }
- }
- }
- return sTemp;
- }
- case Builtin::KindFloat : // [[fallthrough]]
- case Builtin::KindDouble :
- return sDefault.empty()?"0.0":sDefault;
- default :
- assert(false);
- }
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
- if (ePtr)
- {
- if (sDefault.empty())
- {
- vector<TypeIdPtr>& eMember = ePtr->getAllMemberPtr();
- if (eMember.size() > 0)
- {
- vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
- string sModule = findName(vecNames[0], eMember[0]->getId());
- return sModule;
- }
- }
- if (!TC_Common::isdigit(sDefault))
- {
- string s1 = sNamespace;
- string s2 = sDefault;
- string::size_type index = sDefault.find("::");
- if (index != string::npos)
- {
- s1 = sDefault.substr(0, index);
- s2 = sDefault.substr(index + 2);
- }
- string sModule = findName(s1, s2);
- assert(!sModule.empty());
- return sModule;
- }
- return sDefault;
- }
- if (bGlobal)
- {
- return "new " + getDataType(pPtr->getTypePtr(), bCastEnumAsAny);
- }
- return sDefault;
- }
|