java: generated code to have javadoc

pull/14667/head
Ahmed Ashour 6 years ago
parent d6d4571628
commit 5c56b8ce92
  1. 2
      CMakeLists.txt
  2. 2
      doc/CMakeLists.txt
  3. 23
      modules/calib3d/include/opencv2/calib3d.hpp
  4. 6
      modules/core/include/opencv2/core.hpp
  5. 6
      modules/cudaarithm/include/opencv2/cudaarithm.hpp
  6. 2
      modules/features2d/include/opencv2/features2d.hpp
  7. 197
      modules/java/generator/gen_java.py
  8. 3
      modules/java/generator/templates/java_class.prolog
  9. 3
      modules/java/generator/templates/java_class_inherited.prolog
  10. 3
      modules/java/generator/templates/java_module.prolog
  11. 21
      modules/java/jar/build.xml.in
  12. 2
      modules/ml/include/opencv2/ml.hpp
  13. 2
      modules/python/src2/hdr_parser.py
  14. 4
      modules/videoio/include/opencv2/videoio.hpp

@ -32,6 +32,8 @@ endif()
option(ENABLE_PIC "Generate position independent code (necessary for shared libraries)" TRUE)
set(CMAKE_POSITION_INDEPENDENT_CODE ${ENABLE_PIC})
set(OPENCV_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0" CACHE STRING "URI to a MathJax installation")
# Following block can break build in case of cross-compiling
# but CMAKE_CROSSCOMPILING variable will be set only on project(OpenCV) command
# so we will try to detect cross-compiling by the presence of CMAKE_TOOLCHAIN_FILE

@ -19,8 +19,6 @@ if(DOXYGEN_FOUND)
unset(CMAKE_DOXYGEN_TUTORIAL_CONTRIB_ROOT)
unset(CMAKE_DOXYGEN_TUTORIAL_JS_ROOT)
set(OPENCV_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0" CACHE STRING "URI to a MathJax installation")
# gathering headers
set(paths_include)
set(paths_doc)

@ -476,15 +476,14 @@ CV_EXPORTS_W void matMulDeriv( InputArray A, InputArray B, OutputArray dABdA, Ou
@param tvec2 Second translation vector.
@param rvec3 Output rotation vector of the superposition.
@param tvec3 Output translation vector of the superposition.
@param dr3dr1
@param dr3dt1
@param dr3dr2
@param dr3dt2
@param dt3dr1
@param dt3dt1
@param dt3dr2
@param dt3dt2 Optional output derivatives of rvec3 or tvec3 with regard to rvec1, rvec2, tvec1 and
tvec2, respectively.
@param dr3dr1 Optional output derivative of rvec3 with regard to rvec1
@param dr3dt1 Optional output derivative of rvec3 with regard to tvec1
@param dr3dr2 Optional output derivative of rvec3 with regard to rvec2
@param dr3dt2 Optional output derivative of rvec3 with regard to tvec2
@param dt3dr1 Optional output derivative of tvec3 with regard to rvec1
@param dt3dt1 Optional output derivative of tvec3 with regard to tvec1
@param dt3dr2 Optional output derivative of tvec3 with regard to rvec2
@param dt3dt2 Optional output derivative of tvec3 with regard to tvec2
The functions compute:
@ -2754,7 +2753,7 @@ namespace fisheye
@param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
@param Knew Camera matrix of the distorted image. By default, it is the identity matrix but you
may additionally scale and shift the result by using a different matrix.
@param new_size
@param new_size the new size
The function transforms an image to compensate radial and tangential lens distortion.
@ -2780,14 +2779,14 @@ namespace fisheye
/** @brief Estimates new camera matrix for undistortion or rectification.
@param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$.
@param image_size
@param image_size Size of the image
@param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$.
@param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3
1-channel or 1x1 3-channel
@param P New camera matrix (3x3) or new projection matrix (3x4)
@param balance Sets the new focal length in range between the min focal length and the max focal
length. Balance is in range of [0, 1].
@param new_size
@param new_size the new size
@param fov_scale Divisor for new focal length.
*/
CV_EXPORTS_W void estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R,

@ -311,9 +311,9 @@ if src was not a ROI, use borderType | #BORDER_ISOLATED.
@param src Source image.
@param dst Destination image of the same type as src and the size Size(src.cols+left+right,
src.rows+top+bottom) .
@param top
@param bottom
@param left
@param top the top pixels
@param bottom the bottom pixels
@param left the left pixels
@param right Parameter specifying how many pixels in each direction from the source image rectangle
to extrapolate. For example, top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs
to be built.

@ -505,9 +505,9 @@ CV_EXPORTS Ptr<LookUpTable> createLookUpTable(InputArray lut);
@param src Source image. CV_8UC1 , CV_8UC4 , CV_32SC1 , and CV_32FC1 types are supported.
@param dst Destination image with the same type as src. The size is
Size(src.cols+left+right, src.rows+top+bottom) .
@param top
@param bottom
@param left
@param top Number of top pixels
@param bottom Number of bottom pixels
@param left Number of left pixels
@param right Number of pixels in each direction from the source image rectangle to extrapolate.
For example: top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs to be built.
@param borderType Border type. See borderInterpolate for details. BORDER_REFLECT101 ,

@ -328,7 +328,7 @@ public:
but it is a little faster to compute.
@param patchSize size of the patch used by the oriented BRIEF descriptor. Of course, on smaller
pyramid layers the perceived image area covered by a feature will be larger.
@param fastThreshold
@param fastThreshold the fast threshold
*/
CV_WRAP static Ptr<ORB> create(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31,
int firstLevel=0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31, int fastThreshold=20);

@ -3,6 +3,7 @@
import sys, re, os.path, errno, fnmatch
import json
import logging
import codecs
from shutil import copyfile
from pprint import pformat
from string import Template
@ -105,14 +106,19 @@ class GeneralInfo():
self.params={}
self.annotation=[]
if type == "class":
docstring="// C++: class " + self.name + "\n//javadoc: " + self.name
docstring="// C++: class " + self.name + "\n"
else:
docstring=""
if len(decl)>5 and decl[5]:
#logging.info('docstring: %s', decl[5])
if re.search("(@|\\\\)deprecated", decl[5]):
doc = decl[5]
#logging.info('docstring: %s', doc)
if re.search("(@|\\\\)deprecated", doc):
self.annotation.append("@Deprecated")
docstring += sanitize_java_documentation_string(doc, type)
self.docstring = docstring
def parseName(self, name, namespaces):
@ -263,7 +269,7 @@ class ClassInfo(GeneralInfo):
def initCodeStreams(self, Module):
self.j_code = StringIO()
self.jn_code = StringIO()
self.cpp_code = StringIO();
self.cpp_code = StringIO()
if self.base:
self.j_code.write(T_JAVA_START_INHERITED)
else:
@ -293,7 +299,7 @@ class ClassInfo(GeneralInfo):
jname = self.jname,
imports = "\n".join(self.getAllImports(M)),
docs = self.docstring,
annotation = "\n".join(self.annotation),
annotation = "\n" + "\n".join(self.annotation) if self.annotation else "",
base = self.base)
def generateCppCode(self):
@ -481,7 +487,7 @@ class JavaWrapperGenerator(object):
content = f.read()
if content == buf:
return
with open(path, "wt") as f:
with codecs.open(path, "w", "utf-8") as f:
f.write(buf)
updated_files += 1
@ -495,7 +501,7 @@ class JavaWrapperGenerator(object):
self.add_class( ['class ' + self.Module, '', [], []] ) # [ 'class/struct cname', ':bases', [modlist] [props] ]
# scan the headers and build more descriptive maps of classes, consts, functions
includes = [];
includes = []
for hdr in common_headers:
logging.info("\n===== Common header : %s =====", hdr)
includes.append('#include "' + hdr + '"')
@ -714,7 +720,7 @@ class JavaWrapperGenerator(object):
fi.jname + "(" + ", ".join(j_args) + ")"
logging.info("java: " + j_signature)
if(j_signature in j_signatures):
if j_signature in j_signatures:
if args:
args.pop()
continue
@ -730,20 +736,51 @@ class JavaWrapperGenerator(object):
type = type_dict[fi.ctype].get("jn_type", "double[]"),
name = fi.jname + '_' + str(suffix_counter),
args = ", ".join(["%s %s" % (type_dict[a.ctype]["jn_type"], normalize_field_name(a.name)) for a in jn_args])
) );
) )
# java part:
#java doc comment
f_name = fi.jname
if fi.classname:
f_name = fi.classname + "::" + fi.jname
java_doc = "//javadoc: " + f_name + "(%s)" % ", ".join([a.name for a in args if a.ctype])
j_code.write(" "*4 + java_doc + "\n")
if fi.docstring:
lines = StringIO(fi.docstring)
for line in lines:
lines = fi.docstring.splitlines()
returnTag = False
javadocParams = []
toWrite = []
inCode = False
for index, line in enumerate(lines):
p0 = line.find("@param")
if p0 != -1:
p0 += 7
p1 = line.find(' ', p0)
p1 = len(line) if p1 == -1 else p1
name = line[p0:p1]
javadocParams.append(name)
for arg in j_args:
if arg.endswith(" " + name):
toWrite.append(line);
break
else:
if "<code>" in line:
inCode = True
if "</code>" in line:
inCode = False
if "@return " in line:
returnTag = True
if (not inCode and toWrite and not toWrite[-1] and
line and not line.startswith("\\") and not line.startswith("<ul>") and not line.startswith("@param")):
toWrite.append("<p>");
if index == len(lines) - 1:
for arg in j_args:
name = arg[arg.rfind(' ') + 1:]
if not name in javadocParams:
toWrite.append(" * @param " + name + " automatically generated");
if type_dict[fi.ctype]["j_type"] and not returnTag and fi.ctype != "void":
toWrite.append(" * @return automatically generated");
toWrite.append(line);
for line in toWrite:
j_code.write(" "*4 + line + "\n")
if fi.annotation:
j_code.write(" "*4 + "\n".join(fi.annotation) + "\n")
@ -770,7 +807,7 @@ class JavaWrapperGenerator(object):
j_epilogue.append('Converters.Mat_to_' + ret_type + '(retValMat, retVal);')
ret = "return retVal;"
elif ret_type.startswith("Ptr_"):
constructor = type_dict[ret_type]["j_type"] + ".__fromPtr__(";
constructor = type_dict[ret_type]["j_type"] + ".__fromPtr__("
if j_epilogue:
ret_val = type_dict[fi.ctype]["j_type"] + " retVal = " + constructor
else:
@ -787,14 +824,14 @@ class JavaWrapperGenerator(object):
ret_val = "nativeObj = "
ret = ""
elif self.isWrapped(ret_type): # wrapped class
constructor = self.getClass(ret_type).jname + "(";
constructor = self.getClass(ret_type).jname + "("
if j_epilogue:
ret_val = type_dict[ret_type]["j_type"] + " retVal = new " + constructor
else:
ret_val = "return new " + constructor
tail = ")"
elif "jn_type" not in type_dict[ret_type]:
constructor = type_dict[ret_type]["j_type"] + "(";
constructor = type_dict[ret_type]["j_type"] + "("
if j_epilogue:
ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + constructor
else:
@ -806,7 +843,7 @@ class JavaWrapperGenerator(object):
static = fi.static
j_code.write( Template(
""" public $static$j_type $j_name($j_args) {$prologue
""" public $static$j_type$j_name($j_args) {$prologue
$ret_val$jn_name($jn_args_call)$tail;$epilogue$ret
}
@ -818,7 +855,7 @@ class JavaWrapperGenerator(object):
prologue = "\n " + "\n ".join(j_prologue) if j_prologue else "",
epilogue = "\n " + "\n ".join(j_epilogue) if j_epilogue else "",
static = static + " " if static else "",
j_type=type_dict[fi.ctype]["j_type"],
j_type=type_dict[fi.ctype]["j_type"] + " " if type_dict[fi.ctype]["j_type"] else "",
j_name=fi.jname,
j_args=", ".join(j_args),
jn_name=fi.jname + '_' + str(suffix_counter),
@ -1129,6 +1166,122 @@ def copy_java_files(java_files_dir, java_base_path, default_package_path='org/op
copyfile(src, dest)
updated_files += 1
def sanitize_java_documentation_string(doc, type):
if type == "class":
doc = doc.replace("@param ", "")
doc = re.sub(re.compile('\\\\f\\$(.*?)\\\\f\\$', re.DOTALL), '\\(' + r'\1' + '\\)', doc)
doc = re.sub(re.compile('\\\\f\\[(.*?)\\\\f\\]', re.DOTALL), '\\(' + r'\1' + '\\)', doc)
doc = re.sub(re.compile('\\\\f\\{(.*?)\\\\f\\}', re.DOTALL), '\\(' + r'\1' + '\\)', doc)
doc = doc.replace("&", "&amp;") \
.replace("\\<", "&lt;") \
.replace("\\>", "&gt;") \
.replace("<", "&lt;") \
.replace(">", "&gt;") \
.replace("$", "$$") \
.replace("@anchor", "") \
.replace("@brief ", "").replace("\\brief ", "") \
.replace("@cite", "CITE:") \
.replace("@code{.cpp}", "<code>") \
.replace("@code{.txt}", "<code>") \
.replace("@code", "<code>") \
.replace("@copydoc", "") \
.replace("@copybrief", "") \
.replace("@date", "") \
.replace("@defgroup", "") \
.replace("@details ", "") \
.replace("@endcode", "</code>") \
.replace("@endinternal", "") \
.replace("@file", "") \
.replace("@include", "INCLUDE:") \
.replace("@ingroup", "") \
.replace("@internal", "") \
.replace("@overload", "") \
.replace("@param[in]", "@param") \
.replace("@param[out]", "@param") \
.replace("@ref", "REF:") \
.replace("@returns", "@return") \
.replace("@sa", "SEE:") \
.replace("@see", "SEE:") \
.replace("@snippet", "SNIPPET:") \
.replace("@todo", "TODO:") \
.replace("@warning ", "WARNING: ")
doc = re.sub(re.compile('\\*\\*([^\\*]+?)\\*\\*', re.DOTALL), '<b>' + r'\1' + '</b>', doc)
lines = doc.splitlines()
lines = list(map(lambda x: x[x.find('*'):].strip() if x.lstrip().startswith("*") else x, lines))
listInd = [];
indexDiff = 0;
for index, line in enumerate(lines[:]):
if line.strip().startswith("-"):
i = line.find("-")
if not listInd or i > listInd[-1]:
lines.insert(index + indexDiff, " "*len(listInd) + "<ul>")
indexDiff += 1
listInd.append(i);
lines.insert(index + indexDiff, " "*len(listInd) + "<li>")
indexDiff += 1
elif i == listInd[-1]:
lines.insert(index + indexDiff, " "*len(listInd) + "</li>")
indexDiff += 1
lines.insert(index + indexDiff, " "*len(listInd) + "<li>")
indexDiff += 1
elif len(listInd) > 1 and i == listInd[-2]:
lines.insert(index + indexDiff, " "*len(listInd) + "</li>")
indexDiff += 1
del listInd[-1]
lines.insert(index + indexDiff, " "*len(listInd) + "</ul>")
indexDiff += 1
lines.insert(index + indexDiff, " "*len(listInd) + "<li>")
indexDiff += 1
else:
lines.insert(index + indexDiff, " "*len(listInd) + "</li>")
indexDiff += 1
del listInd[-1]
lines.insert(index + indexDiff, " "*len(listInd) + "</ul>")
indexDiff += 1
lines.insert(index + indexDiff, " "*len(listInd) + "<ul>")
indexDiff += 1
listInd.append(i);
lines.insert(index + indexDiff, " "*len(listInd) + "<li>")
indexDiff += 1
lines[index + indexDiff] = lines[index + indexDiff][0:i] + lines[index + indexDiff][i + 1:]
else:
if listInd and (not line or line == "*" or line.startswith("@note")):
lines.insert(index + indexDiff, " "*len(listInd) + "</li>")
indexDiff += 1
del listInd[-1]
lines.insert(index + indexDiff, " "*len(listInd) + "</ul>")
indexDiff += 1
i = len(listInd) - 1
for value in enumerate(listInd):
lines.append(" "*i + " </li>")
lines.append(" "*i + "</ul>")
i -= 1;
lines = list(map(lambda x: "* " + x[1:].strip() if x.startswith("*") and x != "*" else x, lines))
lines = list(map(lambda x: x if x.startswith("*") else "* " + x if x and x != "*" else "*", lines))
lines = list(map(lambda x: x
.replace("@note", "<b>Note:</b>")
, lines))
lines = list(map(lambda x: re.sub('@b ([\\w:]+?)\\b', '<b>' + r'\1' + '</b>', x), lines))
lines = list(map(lambda x: re.sub('@c ([\\w:]+?)\\b', '<tt>' + r'\1' + '</tt>', x), lines))
lines = list(map(lambda x: re.sub('`(.*?)`', "{@code " + r'\1' + '}', x), lines))
lines = list(map(lambda x: re.sub('@p ([\\w:]+?)\\b', '{@code ' + r'\1' + '}', x), lines))
hasValues = False
for line in lines:
if line != "*":
hasValues = True
break
return "/**\n " + "\n ".join(lines) + "\n */" if hasValues else ""
if __name__ == "__main__":
# initialize logger

@ -5,8 +5,7 @@ package org.opencv.$module;
$imports
$docs
$annotation
$docs$annotation
public class $jname {
protected final long nativeObj;

@ -5,8 +5,7 @@ package org.opencv.$module;
$imports
$docs
$annotation
$docs$annotation
public class $jname extends $base {
protected $jname(long addr) { super(addr); }

@ -5,6 +5,5 @@ package org.opencv.$module;
$imports
$docs
$annotation
$docs$annotation
public class $jname {

@ -29,6 +29,9 @@
</target>
<target name="javadoc">
<copy file="@OpenCV_SOURCE_DIR@/doc/mymath.js"
todir="@OpenCV_BINARY_DIR@/doc/doxygen/html/javadoc" />
<javadoc
packagenames="org.opencv.*"
sourcepath="java"
@ -36,7 +39,23 @@
Windowtitle="OpenCV @OPENCV_VERSION_PLAIN@ Java documentation"
Doctitle="OpenCV Java documentation (@OPENCV_VERSION@)"
bottom="Generated on ${timestamp} / OpenCV @OPENCV_VCSVERSION@"
/>
failonerror="true"
encoding="UTF-8" charset="UTF-8" docencoding="UTF-8"
link="https://docs.oracle.com/javase/6/docs/api/"
additionalparam="--allow-script-in-comments"
>
<Header>
<![CDATA[
<script>
var url = window.location.href;
url = url.substring(0, url.lastIndexOf('/', url.indexOf('.html'))) + '/../../../mymath.js';
var script = document.createElement('script');
script.src = '@OPENCV_MATHJAX_RELPATH@/MathJax.js?config=TeX-AMS-MML_HTMLorMML,' + url;
document.getElementsByTagName('head')[0].appendChild(script);
</script>
]]>
</Header>
</javadoc>
</target>
</project>

@ -1004,7 +1004,7 @@ public:
@param samples Samples from which the Gaussian mixture model will be estimated. It should be a
one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type
it will be converted to the inner matrix of such type for the further computing.
@param probs0
@param probs0 the probabilities
@param logLikelihoods The optional output matrix that contains a likelihood logarithm value for
each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type.
@param labels The optional output "class label" for each sample:

@ -827,7 +827,7 @@ class CppHeaderParser(object):
if state == DOCSTRING:
pos = l.find("*/")
if pos < 0:
docstring += l + "\n"
docstring += l0
continue
docstring += l[:pos] + "\n"
l = l[pos+2:]

@ -803,8 +803,8 @@ public:
@note Reading / writing properties involves many layers. Some unexpected result might happens
along this chain.
@code {.txt}
`VideoCapture -> API Backend -> Operating System -> Device Driver -> Device Hardware`
@code{.txt}
VideoCapture -> API Backend -> Operating System -> Device Driver -> Device Hardware
@endcode
The returned value might be different from what really used by the device or it could be encoded
using device dependent rules (eg. steps or percentage). Effective behaviour depends from device

Loading…
Cancel
Save