Skip to content
36 changes: 22 additions & 14 deletions JsonGenerator/source/class_emitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ def ProcessEnums(log, action=None):
return count

def EmitEnumRegs(log, root, emit, header_file, if_file):
log.Info("Emitting enum conversion tables... ")

def _EmitEnumRegistration(log, enum):
name = enum.original_type if enum.original_type else (Scoped(root, enum) + enum.cpp_class)

Expand Down Expand Up @@ -274,6 +276,7 @@ def EmitObjects(log, root, emit, if_file, additional_includes, emitCommon = Fals
emittedItems = 0

def _EmitEnumConversionHandler(root, enum):
log.Info("Emitting enum conversion handler for '{}'".format(enum.cpp_class))
name = enum.original_type if enum.original_type else (Scoped(root, enum) + enum.cpp_class)
emit.Line("ENUM_CONVERSION_HANDLER(%s)" % name)

Expand Down Expand Up @@ -705,23 +708,25 @@ def _EmitNoPushWarnings(prologue = True):
emit.Indent()
emit.Line()

if emitCommon and trackers.enum_tracker.CommonObjects():
if emitCommon and trackers.enum_tracker.common_objects:
log.Info("Emitting common enums...")
emittedPrologue = False
for obj in trackers.enum_tracker.CommonObjects():
if obj.do_create and not obj.is_duplicate and not obj.included_from:
for obj in trackers.enum_tracker.common_objects:
if obj.do_create and not obj.included_from:
assert not obj.is_duplicate
if not emittedPrologue:
emit.Line("// Common enums")
emit.Line("//")
emit.Line()
emittedPrologue = True
_EmitEnum(obj)

if emitCommon and trackers.object_tracker.CommonObjects():
if emitCommon and trackers.object_tracker.common_objects:
log.Info("Emitting common classes...")
emittedPrologue = False
for obj in trackers.object_tracker.CommonObjects():
for obj in trackers.object_tracker.common_objects:
if not obj.included_from:
assert not obj.is_duplicate
if not emittedPrologue:
emit.Line("// Common classes")
emit.Line("//")
Expand Down Expand Up @@ -751,16 +756,19 @@ def _EmitNoPushWarnings(prologue = True):
emit.Line("} // namespace %s" % config.DATA_NAMESPACE)
emit.Line()

emittedPrologue = False

for obj in trackers.enum_tracker.objects:
if not obj.is_duplicate and not obj.included_from:
if not emittedPrologue:
emit.Line("// Enum conversion handlers")
emittedPrologue = True

_EmitEnumConversionHandler(root, obj)
emittedItems += 1
log.Info("Emitting enum conversion handlers...")
if trackers.enum_tracker.objects:
emittedPrologue = False
for obj in trackers.enum_tracker.objects:
if not obj.is_duplicate and not obj.included_from:
assert not obj.is_duplicate
if not emittedPrologue:
emit.Line("// Enum conversion handlers")
emittedPrologue = True

_EmitEnumConversionHandler(root, obj)
emittedItems += 1

emit.Line()
emit.Line("}")
Expand Down
19 changes: 12 additions & 7 deletions JsonGenerator/source/documentation_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ def ParamTable(name, object):

def _TableObj(name, obj, parentName="", parent=None, prefix="", parentOptional=False):
# determine if the attribute is optional
optional = parentOptional or (obj["optional"] if "optional" in obj else False)
deprecated = obj["deprecated"] if "deprecated" in obj else False
obsolete = obj["obsolete"] if "obsolete" in obj else False
optional = parentOptional or obj.get("optional") or obj.get("@optionaltype")
deprecated = obj.get("deprecated")
obsolete = obj.get("obsolete")
restricted = obj.get("range")

name = name.replace(' ','-')
Expand All @@ -123,7 +123,7 @@ def _TableObj(name, obj, parentName="", parent=None, prefix="", parentOptional=F
endmarker = obj.get("@endmarker")
for i,e in enumerate(obj["ids"]):
if e == endmarker:
break;
break
enums.append(str(obj["enum"][i]))
if "default" in obj and e == obj["default"]:
default_enum = enums[-1]
Expand Down Expand Up @@ -237,10 +237,15 @@ def _TableObj(name, obj, parentName="", parent=None, prefix="", parentOptional=F
if obj.get("@async"):
if row:
row += "<br>"

obj_type = "string (async ID)"
elif obj.get("opaque"):
obj_type = "opaque object"
elif obj.get("encode"):
obj_type = "string (%s)" % obj.get("encode")
elif obj.get("time"):
obj_type = "string (%s time)" % obj.get("time").upper()
else:
obj_type = "opaque object" if obj.get("opaque") else ("string (%s)" % obj.get("encode")) if obj.get("encode") else obj["type"]
obj_type = obj["type"]

if obj.get("@lookup"):
if row == "...":
Expand All @@ -260,7 +265,7 @@ def _TableObj(name, obj, parentName="", parent=None, prefix="", parentOptional=F
_TableObj(pname, props, parentName + "/" + name, obj, prefix, False)

elif obj["type"] == "array":
_TableObj("", obj["items"], parentName + "/" + name, obj, (prefix + "[#]") if name else "", False)
_TableObj("", obj["items"], parentName + "/" + name, obj, (prefix + "[#]") if name else "", optional)

_TableObj(name, object, "")
MdBr()
Expand Down
16 changes: 10 additions & 6 deletions JsonGenerator/source/header_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def handle_optional(var, var_type, properties, quiet=False):
is_iterator = isinstance(var_type.type, CppParser.Class) and var_type.type.is_iterator

if not var.meta.output:
if isinstance(var_type.type, (CppParser.Integer, CppParser.Int24, CppParser.Enum)):
if isinstance(var_type.type, (CppParser.Integer, CppParser.Int24, CppParser.Enum, CppParser.Bool)):
if not var.meta.default and not quiet:
log.WarnLine(var, "%s: default value is assumed to be (%s)0 (use @default with @optional)" % (var.name, var.type.TypeName()))
elif not isinstance(var_type.type, (CppParser.String, CppParser.Vector, CppParser.Class)) or (var_type.IsPointer() and not is_iterator):
Expand Down Expand Up @@ -935,9 +935,6 @@ def BuildParameters(obj, vars, rpc_format, is_property=False, is_index=False, te

converted["@position"] = vars.index(var)

if not handle_optional(var, ResolveTypedef(var.type), converted, test):
required.append(var_name)

if converted["type"] == "string" and not var.type.IsReference() and not var.type.IsPointer() \
and not "enum" in converted and not "time" in converted:
log.WarnLine(var, "'%s': passing input string by value (forgot &?)" % var.name)
Expand All @@ -952,6 +949,8 @@ def BuildParameters(obj, vars, rpc_format, is_property=False, is_index=False, te
raise CppParseError(var, "@extract not allowed on this parameter")

properties = converted["properties"]
params["@originaltype"] = converted["@originaltype"]
required = converted["required"]
extracted = var
elif converted["type"] != "array":
raise CppParseError(var, "@extract not supported for this type")
Expand All @@ -962,6 +961,9 @@ def BuildParameters(obj, vars, rpc_format, is_property=False, is_index=False, te
else:
properties[var_name] = converted

if not handle_optional(var, ResolveTypedef(var.type), converted, test):
required.append(var_name)


params["properties"] = properties
params["required"] = required
Expand Down Expand Up @@ -1026,6 +1028,7 @@ def BuildResult(method, vars, is_property=False, test=False):
raise CppParseError(var, "@extract not allowed on property parameters")

properties = converted["properties"]
params["@originaltype"] = converted["@originaltype"]
extracted = var
elif converted["type"] != "array":
raise CppParseError(var, "@extract not supported for this type")
Expand Down Expand Up @@ -1446,7 +1449,7 @@ def MaybeWarning():
for e in interfaces:
for m in e.obj.methods:
for p in m.vars:
if isinstance(p.type.type, CppParser.Class) and p.type.type.is_event:
if isinstance(p.type.type, CppParser.Class) and p.type.type.is_event and p.type.type.full_name == f.obj.full_name:
log.WarnLine(method, "%s: @index is not recommended here, declare in event registration method instead: %s()" % (method.vars[0].name, m.full_name))
return
MaybeWarning()
Expand All @@ -1457,7 +1460,7 @@ def MaybeWarning():

if obj["id"]:
obj["id"]["name"] = method.vars[0].name
obj["id"]["@originalname"] = "designatorId_" if deprecated else "index_"
obj["id"]["@originalname"] = "index_"
obj["id"]["@generated"] = True

if deprecated:
Expand Down Expand Up @@ -1604,6 +1607,7 @@ def MaybeWarning():
return schemas, []

def LoadInterface(file, log, all = False, include_paths = []):

try:
schemas = []
includes = []
Expand Down
32 changes: 28 additions & 4 deletions JsonGenerator/source/json_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ def cpp_type(self): # C++ type of the object (e.g. may be array)
def short_cpp_type(self):
return self.cpp_type.replace("%s::%s::" % (config.DATA_NAMESPACE, self.root.cpp_class), "")

@property
def typed_print_name(self):
return self.print_name

@property
def cpp_class(self): # C++ class type of the object
raise RuntimeError("Can't instantiate '%s'" % self.print_name)
Expand All @@ -255,6 +259,8 @@ def cpp_native_type(self):
def cpp_native_type_cv(self):
if self.schema.get("@cv"):
return self.schema.get("@cv") + " " + self.cpp_native_type
else:
return self.cpp_native_type

@property
def cpp_native_type_opt(self):
Expand Down Expand Up @@ -293,8 +299,10 @@ def cpp_native_type_opt_v(self, toggle=False):

@property
def local_proto(self):
assert self.schema.get("@proto")
return self.cpp_native_type_proto.replace('@', self.local_name)
if "@proto" in self.schema:
return self.cpp_native_type_proto.replace('@', self.local_name)
else:
return "%s %s" % (self.cpp_native_type_opt_cv, self.local_name)

@property
def cpp_concrete_type(self):
Expand Down Expand Up @@ -443,7 +451,6 @@ def AddRef(self, obj):
def RefCount(self):
return len(self.refs)


class JsonTime(JsonNative, JsonType):
def __init__(self, name, parent, schema, time_type):
JsonType.__init__(self, name, parent, schema)
Expand Down Expand Up @@ -946,6 +953,10 @@ def cpp_name(self): # C++ name of the object

return (_name[0].upper() + _name[1:])

@property
def typed_print_name(self):
return "method " + super().print_name

def Headline(self):
return "'%s'%s%s" % (self.json_name, (" - " + self.summary.split(".", 1)[0]) if self.summary else "",
" (DEPRECATED)" if self.deprecated else " (OBSOLETE)" if self.obsolete else "")
Expand All @@ -967,6 +978,10 @@ def __init__(self, name, parent, schema, included=None):
log.Info("'%s': notification parameter '%s' refers to generated JSON objects" % (name, param.name))
break

@property
def typed_print_name(self):
return "event " + super().print_name

def _Check(self):
pass

Expand All @@ -977,6 +992,11 @@ def __init__(self, name, parent, notification, schema, included=None):
self.notification.sendif_type = JsonItem("id", self, { "type": "string", "@originalname": "index_", "@generated": True})
self.notification.sendif_deprecated = False

@property
def typed_print_name(self):
return "callback " + super().print_name

Comment thread
sebaszm marked this conversation as resolved.

class JsonProperty(JsonMethod):
def __init__(self, name, parent, schema, included=None):
self.readonly = "readonly" in schema and schema["readonly"]
Expand Down Expand Up @@ -1004,6 +1024,10 @@ def __init__(self, name, parent, schema, included=None):
else:
self.index = None

@property
def typed_print_name(self):
return "property " + super().print_name

Comment thread
sebaszm marked this conversation as resolved.

class JsonRpcSchema(JsonType):
def __init__(self, name, schema):
Expand Down Expand Up @@ -1071,7 +1095,7 @@ def _AddMethods(section, schema, ctor):
_AddMethods("events", schema, lambda name, obj, method: JsonNotification(name, obj, method))

if not self.methods:
raise JsonParseError("no methods, properties or events defined in %s" % self.schema["@fullname"] if "@fullname" in self.schema else self.name)
raise JsonParseError("no methods, properties or events defined in %s" % (self.schema["@fullname"] if "@fullname" in self.schema else self.name))

@property
def root(self):
Expand Down
Loading
Loading