mirror of
https://github.com/opencv/opencv.git
synced 2025-01-21 08:37:57 +08:00
Merge pull request #18801 from alalek:java_improve_nested_classes_namespaces
This commit is contained in:
commit
71db9d3b57
@ -123,7 +123,8 @@ T_CPP_MODULE = Template(read_contents(os.path.join(SCRIPT_DIR, 'templates/cpp_mo
|
||||
|
||||
class GeneralInfo():
|
||||
def __init__(self, type, decl, namespaces):
|
||||
self.symbol_id, self.namespace, self.classpath, self.classname, self.name = self.parseName(decl[0], namespaces)
|
||||
self.symbol_id, self.parent_id, self.namespace, self.classpath, self.classname, self.name = self.parseName(decl[0], namespaces)
|
||||
self.cname = get_cname(self.symbol_id)
|
||||
|
||||
# parse doxygen comments
|
||||
self.params={}
|
||||
@ -150,6 +151,9 @@ class GeneralInfo():
|
||||
returns: (namespace, classpath, classname, name)
|
||||
'''
|
||||
name = name[name.find(" ")+1:].strip() # remove struct/class/const prefix
|
||||
parent = name[:name.rfind('.')].strip()
|
||||
if len(parent) == 0:
|
||||
parent = None
|
||||
spaceName = ""
|
||||
localName = name # <classes>.<name>
|
||||
for namespace in sorted(namespaces, key=len, reverse=True):
|
||||
@ -159,31 +163,44 @@ class GeneralInfo():
|
||||
break
|
||||
pieces = localName.split(".")
|
||||
if len(pieces) > 2: # <class>.<class>.<class>.<name>
|
||||
return name, spaceName, ".".join(pieces[:-1]), pieces[-2], pieces[-1]
|
||||
return name, parent, spaceName, ".".join(pieces[:-1]), pieces[-2], pieces[-1]
|
||||
elif len(pieces) == 2: # <class>.<name>
|
||||
return name, spaceName, pieces[0], pieces[0], pieces[1]
|
||||
return name, parent, spaceName, pieces[0], pieces[0], pieces[1]
|
||||
elif len(pieces) == 1: # <name>
|
||||
return name, spaceName, "", "", pieces[0]
|
||||
return name, parent, spaceName, "", "", pieces[0]
|
||||
else:
|
||||
return name, spaceName, "", "" # error?!
|
||||
return name, parent, spaceName, "", "" # error?!
|
||||
|
||||
def fullName(self, isCPP=False):
|
||||
result = ".".join([self.fullClass(), self.name])
|
||||
return result if not isCPP else get_cname(result)
|
||||
def fullNameOrigin(self):
|
||||
result = self.symbol_id
|
||||
return result
|
||||
|
||||
def fullClass(self, isCPP=False):
|
||||
def fullNameJAVA(self):
|
||||
result = '.'.join([self.fullParentNameJAVA(), self.jname])
|
||||
return result
|
||||
|
||||
def fullNameCPP(self):
|
||||
result = self.cname
|
||||
return result
|
||||
|
||||
def fullParentNameJAVA(self):
|
||||
result = ".".join([f for f in [self.namespace] + self.classpath.split(".") if len(f)>0])
|
||||
return result if not isCPP else get_cname(result)
|
||||
return result
|
||||
|
||||
def fullParentNameCPP(self):
|
||||
result = get_cname(self.parent_id)
|
||||
return result
|
||||
|
||||
class ConstInfo(GeneralInfo):
|
||||
def __init__(self, decl, addedManually=False, namespaces=[], enumType=None):
|
||||
GeneralInfo.__init__(self, "const", decl, namespaces)
|
||||
self.cname = get_cname(self.name)
|
||||
self.value = decl[1]
|
||||
self.enumType = enumType
|
||||
self.addedManually = addedManually
|
||||
if self.namespace in namespaces_dict:
|
||||
self.name = '%s_%s' % (namespaces_dict[self.namespace], self.name)
|
||||
prefix = namespaces_dict[self.namespace]
|
||||
if prefix:
|
||||
self.name = '%s_%s' % (prefix, self.name)
|
||||
|
||||
def __repr__(self):
|
||||
return Template("CONST $name=$value$manual").substitute(name=self.name,
|
||||
@ -227,7 +244,6 @@ class ClassPropInfo():
|
||||
class ClassInfo(GeneralInfo):
|
||||
def __init__(self, decl, namespaces=[]): # [ 'class/struct cname', ': base', [modlist] ]
|
||||
GeneralInfo.__init__(self, "class", decl, namespaces)
|
||||
self.cname = get_cname(self.name)
|
||||
self.methods = []
|
||||
self.methods_suffixes = {}
|
||||
self.consts = [] # using a list to save the occurrence order
|
||||
@ -242,6 +258,18 @@ class ClassInfo(GeneralInfo):
|
||||
for m in decl[2]:
|
||||
if m.startswith("="):
|
||||
self.jname = m[1:]
|
||||
|
||||
if self.classpath:
|
||||
prefix = self.classpath.replace('.', '_')
|
||||
self.name = '%s_%s' % (prefix, self.name)
|
||||
self.jname = '%s_%s' % (prefix, self.jname)
|
||||
|
||||
if self.namespace in namespaces_dict:
|
||||
prefix = namespaces_dict[self.namespace]
|
||||
if prefix:
|
||||
self.name = '%s_%s' % (prefix, self.name)
|
||||
self.jname = '%s_%s' % (prefix, self.jname)
|
||||
|
||||
self.base = ''
|
||||
if decl[1]:
|
||||
#self.base = re.sub(r"\b"+self.jname+r"\b", "", decl[1].replace(":", "")).strip()
|
||||
@ -358,11 +386,26 @@ class FuncInfo(GeneralInfo):
|
||||
self.isconstructor = self.name == self.classname
|
||||
if "[" in self.name:
|
||||
self.jname = "getelem"
|
||||
if self.namespace in namespaces_dict:
|
||||
self.jname = '%s_%s' % (namespaces_dict[self.namespace], self.jname)
|
||||
for m in decl[2]:
|
||||
if m.startswith("="):
|
||||
if m.startswith("="): # alias from WRAP_AS
|
||||
self.jname = m[1:]
|
||||
if self.classpath and self.classname != self.classpath:
|
||||
prefix = self.classpath.replace('.', '_')
|
||||
self.classname = prefix #'%s_%s' % (prefix, self.classname)
|
||||
if self.isconstructor:
|
||||
self.name = prefix #'%s_%s' % (prefix, self.name)
|
||||
self.jname = prefix #'%s_%s' % (prefix, self.jname)
|
||||
|
||||
if self.namespace in namespaces_dict:
|
||||
prefix = namespaces_dict[self.namespace]
|
||||
if prefix:
|
||||
if self.classname:
|
||||
self.classname = '%s_%s' % (prefix, self.classname)
|
||||
if self.isconstructor:
|
||||
self.jname = '%s_%s' % (prefix, self.jname)
|
||||
else:
|
||||
self.jname = '%s_%s' % (prefix, self.jname)
|
||||
|
||||
self.static = ["","static"][ "/S" in decl[2] ]
|
||||
self.ctype = re.sub(r"^CvTermCriteria", "TermCriteria", decl[1] or "")
|
||||
self.args = []
|
||||
@ -374,6 +417,12 @@ class FuncInfo(GeneralInfo):
|
||||
arg[3] = arg_fix_map.get('attrib', arg[3]) #fixing arg attrib
|
||||
self.args.append(ArgInfo(arg))
|
||||
|
||||
def fullClassJAVA(self):
|
||||
return self.fullParentNameJAVA()
|
||||
|
||||
def fullClassCPP(self):
|
||||
return self.fullParentNameCPP()
|
||||
|
||||
def __repr__(self):
|
||||
return Template("FUNC <$ctype $namespace.$classpath.$name $args>").substitute(**self.__dict__)
|
||||
|
||||
@ -388,7 +437,8 @@ class JavaWrapperGenerator(object):
|
||||
|
||||
def clear(self):
|
||||
self.namespaces = ["cv"]
|
||||
self.classes = { "Mat" : ClassInfo([ 'class Mat', '', [], [] ], self.namespaces) }
|
||||
classinfo_Mat = ClassInfo([ 'class cv.Mat', '', [], [] ], self.namespaces)
|
||||
self.classes = { "Mat" : classinfo_Mat }
|
||||
self.module = ""
|
||||
self.Module = ""
|
||||
self.ported_func_list = []
|
||||
@ -411,7 +461,7 @@ class JavaWrapperGenerator(object):
|
||||
type_dict.setdefault(name, {}).update(
|
||||
{ "j_type" : classinfo.jname,
|
||||
"jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),
|
||||
"jni_name" : "(*("+classinfo.fullName(isCPP=True)+"*)%(n)s_nativeObj)", "jni_type" : "jlong",
|
||||
"jni_name" : "(*("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj)", "jni_type" : "jlong",
|
||||
"suffix" : "J",
|
||||
"j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname)
|
||||
}
|
||||
@ -419,7 +469,7 @@ class JavaWrapperGenerator(object):
|
||||
type_dict.setdefault(name+'*', {}).update(
|
||||
{ "j_type" : classinfo.jname,
|
||||
"jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),
|
||||
"jni_name" : "("+classinfo.fullName(isCPP=True)+"*)%(n)s_nativeObj", "jni_type" : "jlong",
|
||||
"jni_name" : "("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj", "jni_type" : "jlong",
|
||||
"suffix" : "J",
|
||||
"j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname)
|
||||
}
|
||||
@ -446,7 +496,7 @@ class JavaWrapperGenerator(object):
|
||||
type_dict.setdefault("Ptr_"+name, {}).update(
|
||||
{ "j_type" : classinfo.jname,
|
||||
"jn_type" : "long", "jn_args" : (("__int64", ".getNativeObjAddr()"),),
|
||||
"jni_name" : "*((Ptr<"+classinfo.fullName(isCPP=True)+">*)%(n)s_nativeObj)", "jni_type" : "jlong",
|
||||
"jni_name" : "*((Ptr<"+classinfo.fullNameCPP()+">*)%(n)s_nativeObj)", "jni_type" : "jlong",
|
||||
"suffix" : "J",
|
||||
"j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname)
|
||||
}
|
||||
@ -489,14 +539,15 @@ class JavaWrapperGenerator(object):
|
||||
def add_func(self, decl):
|
||||
fi = FuncInfo(decl, namespaces=self.namespaces)
|
||||
classname = fi.classname or self.Module
|
||||
class_symbol_id = classname if self.isWrapped(classname) else fi.classpath.replace('.', '_') #('.'.join([fi.namespace, fi.classpath])[3:])
|
||||
if classname in class_ignore_list:
|
||||
logging.info('ignored: %s', fi)
|
||||
elif classname in ManualFuncs and fi.jname in ManualFuncs[classname]:
|
||||
logging.info('manual: %s', fi)
|
||||
elif not self.isWrapped(classname):
|
||||
elif not self.isWrapped(class_symbol_id):
|
||||
logging.warning('not found: %s', fi)
|
||||
else:
|
||||
self.getClass(classname).addMethod(fi)
|
||||
self.getClass(class_symbol_id).addMethod(fi)
|
||||
logging.info('ok: %s', fi)
|
||||
# calc args with def val
|
||||
cnt = len([a for a in fi.args if a.defval])
|
||||
@ -521,7 +572,7 @@ class JavaWrapperGenerator(object):
|
||||
# TODO: support UMat versions of declarations (implement UMat-wrapper for Java)
|
||||
parser = hdr_parser.CppHeaderParser(generate_umat_decls=False)
|
||||
|
||||
self.add_class( ['class ' + self.Module, '', [], []] ) # [ 'class/struct cname', ':bases', [modlist] [props] ]
|
||||
self.add_class( ['class cv.' + self.Module, '', [], []] ) # [ 'class/struct cname', ':bases', [modlist] [props] ]
|
||||
|
||||
# scan the headers and build more descriptive maps of classes, consts, functions
|
||||
includes = []
|
||||
@ -582,9 +633,9 @@ class JavaWrapperGenerator(object):
|
||||
report.write("\n%i def args - %i funcs" % (i, self.def_args_hist[i]))
|
||||
return report.getvalue()
|
||||
|
||||
def fullTypeName(self, t):
|
||||
def fullTypeNameCPP(self, t):
|
||||
if self.isWrapped(t):
|
||||
return self.getClass(t).fullName(isCPP=True)
|
||||
return self.getClass(t).fullNameCPP()
|
||||
else:
|
||||
return cast_from(t)
|
||||
|
||||
@ -897,7 +948,7 @@ class JavaWrapperGenerator(object):
|
||||
default = ""
|
||||
elif not fi.ctype: # c-tor
|
||||
if self.isSmartClass(ci):
|
||||
ret = "return (jlong)(new Ptr<%(ctype)s>(_retval_));" % { 'ctype': fi.fullClass(isCPP=True) }
|
||||
ret = "return (jlong)(new Ptr<%(ctype)s>(_retval_));" % { 'ctype': fi.fullClassCPP() }
|
||||
else:
|
||||
ret = "return (jlong) _retval_;"
|
||||
elif "v_type" in type_dict[fi.ctype]: # c-tor
|
||||
@ -907,9 +958,9 @@ class JavaWrapperGenerator(object):
|
||||
ret = "return env->NewStringUTF(_retval_.c_str());"
|
||||
default = 'return env->NewStringUTF("");'
|
||||
elif self.isWrapped(fi.ctype): # wrapped class:
|
||||
ret = "return (jlong) new %s(_retval_);" % self.fullTypeName(fi.ctype)
|
||||
ret = "return (jlong) new %s(_retval_);" % self.fullTypeNameCPP(fi.ctype)
|
||||
elif fi.ctype.startswith('Ptr_'):
|
||||
c_prologue.append("typedef Ptr<%s> %s;" % (self.fullTypeName(fi.ctype[4:]), fi.ctype))
|
||||
c_prologue.append("typedef Ptr<%s> %s;" % (self.fullTypeNameCPP(fi.ctype[4:]), fi.ctype))
|
||||
ret = "return (jlong)(new %(ctype)s(_retval_));" % { 'ctype':fi.ctype }
|
||||
elif self.isWrapped(ret_type): # pointer to wrapped class:
|
||||
ret = "return (jlong) _retval_;"
|
||||
@ -924,12 +975,12 @@ class JavaWrapperGenerator(object):
|
||||
else:
|
||||
name = prop_name + ";//"
|
||||
|
||||
cvname = fi.fullName(isCPP=True)
|
||||
retval = self.fullTypeName(fi.ctype) + " _retval_ = " if ret else "return "
|
||||
cvname = fi.fullNameCPP()
|
||||
retval = self.fullTypeNameCPP(fi.ctype) + " _retval_ = " if ret else "return "
|
||||
if fi.ctype == "void":
|
||||
retval = ""
|
||||
elif fi.ctype == "String":
|
||||
retval = "cv::" + self.fullTypeName(fi.ctype) + " _retval_ = "
|
||||
retval = "cv::" + self.fullTypeNameCPP(fi.ctype) + " _retval_ = "
|
||||
elif fi.ctype == "string":
|
||||
retval = "std::string _retval_ = "
|
||||
elif "v_type" in type_dict[fi.ctype]: # vector is returned
|
||||
@ -945,18 +996,18 @@ class JavaWrapperGenerator(object):
|
||||
if fi.classname:
|
||||
if not fi.ctype: # c-tor
|
||||
if self.isSmartClass(ci):
|
||||
retval = self.smartWrap(ci, fi.fullClass(isCPP=True)) + " _retval_ = "
|
||||
cvname = "makePtr<" + fi.fullClass(isCPP=True) +">"
|
||||
retval = self.smartWrap(ci, fi.fullClassCPP()) + " _retval_ = "
|
||||
cvname = "makePtr<" + fi.fullClassCPP() +">"
|
||||
else:
|
||||
retval = fi.fullClass(isCPP=True) + "* _retval_ = "
|
||||
cvname = "new " + fi.fullClass(isCPP=True)
|
||||
retval = fi.fullClassCPP() + "* _retval_ = "
|
||||
cvname = "new " + fi.fullClassCPP()
|
||||
elif fi.static:
|
||||
cvname = fi.fullName(isCPP=True)
|
||||
cvname = fi.fullNameCPP()
|
||||
else:
|
||||
cvname = ("me->" if not self.isSmartClass(ci) else "(*me)->") + name
|
||||
c_prologue.append(
|
||||
"%(cls)s* me = (%(cls)s*) self; //TODO: check for NULL"
|
||||
% { "cls" : self.smartWrap(ci, fi.fullClass(isCPP=True))}
|
||||
% { "cls" : self.smartWrap(ci, fi.fullClassCPP())}
|
||||
)
|
||||
cvargs = []
|
||||
for a in args:
|
||||
@ -981,13 +1032,12 @@ class JavaWrapperGenerator(object):
|
||||
clazz = ci.jname
|
||||
cpp_code.write ( Template(
|
||||
"""
|
||||
${namespace}
|
||||
|
||||
JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname ($argst);
|
||||
|
||||
JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname
|
||||
($args)
|
||||
{
|
||||
${namespace}
|
||||
static const char method_name[] = "$module::$fname()";
|
||||
try {
|
||||
LOGD("%s", method_name);$prologue
|
||||
@ -1014,7 +1064,7 @@ JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname
|
||||
cvargs = " " + ", ".join(cvargs) + " " if cvargs else "",
|
||||
default = "\n " + default if default else "",
|
||||
retval = retval,
|
||||
namespace = ('using namespace ' + ci.namespace.replace('.', '::') + ';') if ci.namespace else ''
|
||||
namespace = ('using namespace ' + ci.namespace.replace('.', '::') + ';') if ci.namespace and ci.namespace != 'cv' else ''
|
||||
) )
|
||||
|
||||
# adding method signature to dictionary
|
||||
@ -1081,13 +1131,14 @@ JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname
|
||||
self.gen_func(ci, fi)
|
||||
# props
|
||||
for pi in ci.props:
|
||||
basename = ci.fullNameOrigin()
|
||||
# getter
|
||||
getter_name = ci.fullName() + ".get_" + pi.name
|
||||
getter_name = basename + ".get_" + pi.name
|
||||
fi = FuncInfo( [getter_name, pi.ctype, [], []], self.namespaces ) # [ funcname, return_ctype, [modifiers], [args] ]
|
||||
self.gen_func(ci, fi, pi.name)
|
||||
if pi.rw:
|
||||
#setter
|
||||
setter_name = ci.fullName() + ".set_" + pi.name
|
||||
setter_name = basename + ".set_" + pi.name
|
||||
fi = FuncInfo( [ setter_name, "void", [], [ [pi.ctype, pi.name, "", [], ""] ] ], self.namespaces)
|
||||
self.gen_func(ci, fi, pi.name)
|
||||
|
||||
@ -1131,7 +1182,7 @@ JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete
|
||||
delete (%(cls)s*) self;
|
||||
}
|
||||
|
||||
""" % {"module" : module.replace('_', '_1'), "cls" : self.smartWrap(ci, ci.fullName(isCPP=True)), "j_cls" : ci.jname.replace('_', '_1')}
|
||||
""" % {"module" : module.replace('_', '_1'), "cls" : self.smartWrap(ci, ci.fullNameCPP()), "j_cls" : ci.jname.replace('_', '_1')}
|
||||
)
|
||||
|
||||
def getClass(self, classname):
|
||||
|
Loading…
Reference in New Issue
Block a user