# HG changeset patch # User Benjamin Golinvaux # Date 1552392678 -3600 # Node ID 17106b29ed6d993f3ff99c9c3a4bec4a64d18c6a # Parent 40bb5eb247a521c80b2f3f0e03b379f5e2dd4fda Changed the metadata system for structs. A __handler entry is now required (with "cpp", "ts" or both: ["cpp","ts"]). Changed the enumerations to string-based values. Adapted the integrated wasm test. diff -r 40bb5eb247a5 -r 17106b29ed6d Resources/CodeGeneration/stonegentool.py --- a/Resources/CodeGeneration/stonegentool.py Tue Mar 12 09:19:06 2019 +0100 +++ b/Resources/CodeGeneration/stonegentool.py Tue Mar 12 13:11:18 2019 +0100 @@ -211,8 +211,8 @@ return (True, m.group(1), listOfDependentTypes) def GetStructFields(struct): - """This filters out the __meta__ key from the struct fields""" - return [k for k in struct.keys() if k != '__meta__'] + """This filters out the special metadata key from the struct fields""" + return [k for k in struct.keys() if k != '__handler'] def ComputeOrderFromTypeTree( ancestors, @@ -350,39 +350,49 @@ return genOrder def GetStructFields(fieldDict): - """Returns the regular (non __meta__) struct fields""" + """Returns the regular (non __handler) struct fields""" # the following happens for empty structs if fieldDict == None: return fieldDict ret = {} for k,v in fieldDict.items(): - if k != "__meta__": + if k != "__handler": ret[k] = v + if k.startswith("__") and k != "__handler": + raise RuntimeError("Fields starting with __ (double underscore) are reserved names!") return ret def GetStructMetadata(fieldDict): - """Returns the __meta__ struct fields (there are default values that + """Returns the __handler struct fields (there are default values that can be overridden by entries in the schema - Not tested because it's a fail-safe: if something is broken in meta, + Not tested because it's a fail-safe: if something is broken in this, dependent projects will not build.""" metadataDict = {} - metadataDict['handleInCpp'] = True - metadataDict['handleInTypescript'] = True + metadataDict['handleInCpp'] = False + metadataDict['handleInTypescript'] = False - # Empty types are allowed if fieldDict != None: for k,v in fieldDict.items(): - if k == "__meta__": - # let's examine the various metadata entries - for metaKey,metaValue in v.items(): - # we only accept overriding EXISTING entries - if metaKey in metadataDict: - # simple check, valid for now - if type(metaValue) != bool: - raise RuntimeError("Wrong value for metadata key") - metadataDict[metaKey] = metaValue + if k.startswith("__") and k != "__handler": + raise RuntimeError("Fields starting with __ (double underscore) are reserved names") + if k == "__handler": + if type(v) == list: + for i in v: + if i == "cpp": + metadataDict['handleInCpp'] = True + elif i == "ts": + metadataDict['handleInTypescript'] = True + else: + raise RuntimeError("Error in schema. Allowed values for __handler are \"cpp\" or \"ts\"") + elif type(v) == str: + if v == "cpp": + metadataDict['handleInCpp'] = True + elif v == "ts": + metadataDict['handleInTypescript'] = True else: - raise RuntimeError("Wrong key \"{metaKey}\" in metadata. Allowed keys are \"{metadataDict.keys()}\"") + raise RuntimeError("Error in schema. Allowed values for __handler are \"cpp\" or \"ts\" (or a list of both)") + else: + raise RuntimeError("Error in schema. Allowed values for __handler are \"cpp\" or \"ts\" (or a list of both)") return metadataDict def ProcessSchema(schema, genOrder): @@ -465,7 +475,7 @@ if ch == ':': if not (nextCh == ' ' or nextCh == '\n'): lineNumber = schemaText.count("\n",0,i) + 1 - raise RuntimeError(f"Error at line {lineNumber} in the schema: colons must be followed by a space or a newline!") + raise RuntimeError("Error at line " + str(lineNumber) + " in the schema: colons must be followed by a space or a newline!") schema = yaml.load(schemaText) return schema diff -r 40bb5eb247a5 -r 17106b29ed6d Resources/CodeGeneration/template.in.h.j2 --- a/Resources/CodeGeneration/template.in.h.j2 Tue Mar 12 09:19:06 2019 +0100 +++ b/Resources/CodeGeneration/template.in.h.j2 Tue Mar 12 13:11:18 2019 +0100 @@ -232,17 +232,6 @@ {% for key in enum['fields']%} {{enum['name']}}_{{key}}, {%endfor%} }; - inline void _StoneDeserializeValue( - {{enum['name']}}& destValue, const Json::Value& jsonValue) - { - destValue = static_cast<{{enum['name']}}>(jsonValue.asInt64()); - } - - inline Json::Value _StoneSerializeValue(const {{enum['name']}}& value) - { - return Json::Value(static_cast(value)); - } - inline std::string ToString(const {{enum['name']}}& value) { {% for key in enum['fields']%} if( value == {{enum['name']}}_{{key}}) @@ -262,14 +251,28 @@ {% for key in enum['fields']%} if( strValue == std::string("{{key}}") ) { value = {{enum['name']}}_{{key}}; + return; } {%endfor%} std::stringstream ss; - ss << "String \"" << strValue << "\" cannot be converted to {{enum['name']}}. Possible values are: {% for key in enum['fields']%}{{key}}{% endfor %}"; + ss << "String \"" << strValue << "\" cannot be converted to {{enum['name']}}. Possible values are: {% for key in enum['fields']%}{{key}} {% endfor %}"; std::string msg = ss.str(); throw std::runtime_error(msg); } + + inline void _StoneDeserializeValue( + {{enum['name']}}& destValue, const Json::Value& jsonValue) + { + FromString(destValue, jsonValue.asString()); + } + + inline Json::Value _StoneSerializeValue(const {{enum['name']}}& value) + { + std::string strValue = ToString(value); + return Json::Value(strValue); + } + inline std::ostream& StoneDumpValue(std::ostream& out, const {{enum['name']}}& value, int indent = 0) { {% for key in enum['fields']%} if( value == {{enum['name']}}_{{key}}) diff -r 40bb5eb247a5 -r 17106b29ed6d Resources/CodeGeneration/template.in.ts.j2 --- a/Resources/CodeGeneration/template.in.ts.j2 Tue Mar 12 09:19:06 2019 +0100 +++ b/Resources/CodeGeneration/template.in.ts.j2 Tue Mar 12 13:11:18 2019 +0100 @@ -39,10 +39,37 @@ // end of generic methods {% for enum in enums%} export enum {{enum['name']}} { - {% for key in enum['fields']%}{{key}}, - {%endfor%} -}; +{% for key in enum['fields']%} {{key}} = "{{key}}"{% if not loop.last %},{%endif%} +{%endfor%}}; + +export function {{enum['name']}}_FromString(strValue:string) : {{enum['name']}} +{ +{% for key in enum['fields'] %} if( strValue == "{{key}}" ) + { + return {{enum['name']}}.{{key}}; + } {%endfor%} + let msg : string = `String ${strValue} cannot be converted to {{enum['name']}}. Possible values are: {% for key in enum['fields']%}{{key}}{% if not loop.last %}, {%endif%}{% endfor %}`; + throw new Error(msg); +} + +export function {{enum['name']}}_ToString(value:{{enum['name']}}) : string +{ +{% for key in enum['fields'] %} if( value == {{enum['name']}}.{{key}} ) + { + return "{{key}}"; + } +{%endfor%} + let msg : string = `Value ${value} cannot be converted to {{enum['name']}}. Possible values are: `; +{% for key in enum['fields']%} { + let _{{key}}_enumValue : string = {{enum['name']}}.{{key}}; // enums are strings in stonecodegen, so this will work. + let msg_{{key}} : string = `{{key}} (${_{{key}}_enumValue}){% if not loop.last %}, {%endif%}`; + msg = msg + msg_{{key}}; + } +{%endfor%} throw new Error(msg); +} +{%endfor%} + {% for struct in structs%}export class {{struct['name']}} { {% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%} {{key}}:{{CanonToTs(struct['fields'][key])}}; diff -r 40bb5eb247a5 -r 17106b29ed6d Resources/CodeGeneration/testWasmIntegrated/CMakeLists.txt --- a/Resources/CodeGeneration/testWasmIntegrated/CMakeLists.txt Tue Mar 12 09:19:06 2019 +0100 +++ b/Resources/CodeGeneration/testWasmIntegrated/CMakeLists.txt Tue Mar 12 13:11:18 2019 +0100 @@ -23,7 +23,7 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/testWasmIntegratedCpp_generated.hpp ${CMAKE_CURRENT_BINARY_DIR}/testWasmIntegratedCpp_generated.ts COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/../stonegentool.py -o ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/testWasmIntegratedCpp_api.yaml - DEPENDS ${testCppHandler_Codegen_Deps} + DEPENDS ${testCppHandler_Codegen_Deps} ${CMAKE_CURRENT_LIST_DIR}/testWasmIntegratedCpp_api.yaml ) add_executable(testWasmIntegratedCpp diff -r 40bb5eb247a5 -r 17106b29ed6d Resources/CodeGeneration/testWasmIntegrated/testWasmIntegrated.ts --- a/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegrated.ts Tue Mar 12 09:19:06 2019 +0100 +++ b/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegrated.ts Tue Mar 12 13:11:18 2019 +0100 @@ -108,14 +108,14 @@ { "a" : 43, "b" : "Sandrine", - "c" : 2, + "c" : "March", "d" : true }, "55" : { "a" : 42, "b" : "Benjamin", - "c" : 0, + "c" : "January", "d" : false } }, @@ -124,13 +124,13 @@ { "a" : 42, "b" : "Benjamin", - "c" : 0, + "c" : "March", "d" : false }, { "a" : 43, "b" : "Sandrine", - "c" : 2, + "c" : "January", "d" : false } ], diff -r 40bb5eb247a5 -r 17106b29ed6d Resources/CodeGeneration/testWasmIntegrated/testWasmIntegratedCpp_api.yaml --- a/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegratedCpp_api.yaml Tue Mar 12 09:19:06 2019 +0100 +++ b/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegratedCpp_api.yaml Tue Mar 12 13:11:18 2019 +0100 @@ -42,10 +42,17 @@ enum CrispType: - SaltAndPepper - CreamAndChives + - Barbecue - Paprika - - Barbecue enum EnumMonth0: - January - February - March + +enum Tata: + - Lolo + - Rrrrrrrrrrrr + + +