Skip to content

Commit

Permalink
[StubGen/JsonGen/LuaGen] Support POD inheritance (#54)
Browse files Browse the repository at this point in the history
* [StubGen/JsonGen/LuaGen] Support POD inheritance

* No need to consider non-PODs
  • Loading branch information
sebaszm authored Nov 12, 2023
1 parent 2a3a1d5 commit dde1b13
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 17 deletions.
19 changes: 12 additions & 7 deletions JsonGenerator/source/header_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,16 @@ def __init__(self, obj, msg):
super(CppParseError, self).__init__(msg)


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

def StripFrameworkNamespace(identifier):
return str(identifier).replace("::" + config.FRAMEWORK_NAMESPACE + "::", "")

def StripInterfaceNamespace(identifier):
return str(identifier).replace(config.INTERFACE_NAMESPACE + "::", "")

try:
tree = CppParser.ParseFiles([os.path.join(os.path.dirname(os.path.realpath(__file__)),
posixpath.normpath(config.DEFAULT_DEFINITIONS_FILE)), file], includePaths, log)
except CppParser.ParserError as ex:
raise CppParseError(None, str(ex))
tree = CppParser.ParseFiles([os.path.join(os.path.dirname(os.path.realpath(__file__)),
posixpath.normpath(config.DEFAULT_DEFINITIONS_FILE)), file], includePaths, log)

interfaces = [i for i in CppInterface.FindInterfaceClasses(tree, config.INTERFACE_NAMESPACE, file) if (i.obj.is_json or (all and not i.obj.is_event))]

Expand Down Expand Up @@ -222,7 +219,9 @@ def ConvertType(var):
def GenerateObject(ctype, was_typdef):
properties = dict()

for p in ctype.vars:
kind = ctype.Merge()

for p in kind.vars:
name = p.name.lower()

if isinstance(ResolveTypedef(p.type).Type(), CppParser.Class):
Expand Down Expand Up @@ -758,3 +757,9 @@ def BuildResult(vars, is_property=False):
log.Info("No interfaces found")

return schemas, []

def LoadInterface(file, log, all = False, includePaths = []):
try:
return LoadInterfaceInternal(file, log, all, includePaths)
except CppParser.ParserError as ex:
raise CppParseError(None, str(ex))
42 changes: 39 additions & 3 deletions ProxyStubGenerator/CppParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,42 @@ def Inherits(self, class_name):
def Proto(self):
return self.full_name

def _Merge(self, vars, methods, do_methods=False, virtual=False):
for a in self.ancestors:
if isinstance(a[0].type, Class):
access = a[1]
kind = a[0].type
is_virtual = "virtual" in a[2]

if access == "public":
kind._Merge(vars, methods, do_methods, is_virtual)
else:
raise ParserError("public inheritance of %s is required" % kind.full_name)

def Populate(array, are_methods=False):
for v in array:
if v.access == "public":
found = list(filter(lambda x: x.name == v.name, vars))
assert(len(found)<=1)

if not found:
vars.append(v)
v._virtual = virtual
elif not found[0]._virtual or not virtual:
raise ParserError("ambiguous %s %s (use virtual inhertiance?)" % ("method" if are_methods else "attributes", v.full_name))
else:
raise ParserError("all members are reqired to be public, non-public member %s" % v.full_name)

Populate(self.vars)

if do_methods:
Populate(self.methods, True)

def Merge(self, do_methods=False):
new_class = Class(self.parent, self.name)
result = self._Merge(new_class.vars, new_class.methods, do_methods)
return new_class

def __str__(self):
return "class " + self.Proto()

Expand Down Expand Up @@ -1467,7 +1503,7 @@ def __Tokenize(contents,log = None):
r"|([\r\n\t ])" # whitespace
)

tokens = [s.strip() for s in re.split(formula, contents, flags=(re.MULTILINE)) if s]
tokens = [s.strip() for s in re.split(formula, contents, flags=(re.MULTILINE)) if s and s.strip()]

tagtokens = []
# check for special metadata within comments
Expand Down Expand Up @@ -2035,14 +2071,14 @@ def Parse(contents,log = None):
if tokens[i + 1] == ':':
i += 1
parent_class = ""
parent_access = "private"
parent_access = new_class._current_access
specifiers = []
while True:
if tokens[i + 1] in ['{', ',']:
# try to find a reference to an already found type
parent_ref = Identifier(current_block[-1], current_block[-1], [parent_class], [])
new_class.ancestors.append([parent_ref.type, parent_access, specifiers])
parent_access = "private"
parent_class = ""
if tokens[i + 1] == '{':
break
elif tokens[i + 1] in ["public", "private", "protected"]:
Expand Down
19 changes: 12 additions & 7 deletions ProxyStubGenerator/StubGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ def Convert(paramtype, retval, vars, hresult=False):
return ["type = Type.BOOL"]

elif isinstance(p, CppParser.Float):
print(p)
if p.type == "float":
return ["type = Type.FLOAT32"]
elif p.type == "double":
Expand All @@ -387,8 +386,10 @@ def Convert(paramtype, retval, vars, hresult=False):
value = ["type = Type.POD", "class = \"%s\"" % Flatten(param.type.full_name)]
pod_params = []

for v in p.vars:
param_info = Convert(v, None, p.vars)
kind = p.vars.Merge()

for v in kind.vars:
param_info = Convert(v, None, kind.vars)
text = []
text.append("name = " + v.name)

Expand Down Expand Up @@ -1220,10 +1221,11 @@ def EmitStubMethodImplementation(index, method, interface_name, interface, retva

def ReadParameter(p):
if p.is_compound:
kind = p.kind.Merge()
if not p.suppress_type:
emit.Line("%s{};" % p.as_temporary_no_cv)

params = [EmitParam(interface, v, (p.name + "." + v.name), True) for v in p.kind.vars]
params = [EmitParam(interface, v, (p.name + "." + v.name), True) for v in kind.vars]

for pp in params:
ReadParameter(pp)
Expand Down Expand Up @@ -1349,7 +1351,8 @@ def ReleaseBuffer(p, large_buffer):

def WriteParameter(p):
if p.is_compound:
params = [EmitParam(interface, v, (p.name + "." + v.name)) for v in p.kind.vars]
kind = p.kind.Merge()
params = [EmitParam(interface, v, (p.name + "." + v.name)) for v in kind.vars]
for pp in params:
WriteParameter(pp)
else:
Expand Down Expand Up @@ -1619,7 +1622,8 @@ def EmitProxyMethodImplementation(index, method, interface_name, interface, retv

def WriteParameter(p):
if p.is_compound:
params = [EmitParam(interface, v, (p.name + "." + v.name), True) for v in p.kind.vars]
kind = p.kind.Merge()
params = [EmitParam(interface, v, (p.name + "." + v.name), True) for v in kind.vars]

for pp in params:
WriteParameter(pp)
Expand All @@ -1628,7 +1632,8 @@ def WriteParameter(p):

def ReadParameter(p):
if p.is_compound:
params = [EmitParam(interface, v, (p.name + "." + v.name), True) for v in p.kind.vars]
kind = p.kind.Merge()
params = [EmitParam(interface, v, (p.name + "." + v.name), True) for v in kind.vars]
for pp in params:
ReadParameter(pp)

Expand Down

0 comments on commit dde1b13

Please sign in to comment.