Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First attempt at Java side automatic downcast feature #548

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/main/java/org/bytedeco/javacpp/annotation/Downcast.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.bytedeco.javacpp.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface Downcast {
String downcaster() default "";
}
18 changes: 18 additions & 0 deletions src/main/java/org/bytedeco/javacpp/annotation/Renamed.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.bytedeco.javacpp.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.Buffer;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.javacpp.tools.Generator;

/**
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface Renamed {
}
21 changes: 21 additions & 0 deletions src/main/java/org/bytedeco/javacpp/tools/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import org.bytedeco.javacpp.annotation.Opaque;
import org.bytedeco.javacpp.annotation.Platform;
import org.bytedeco.javacpp.annotation.Raw;
import org.bytedeco.javacpp.annotation.Renamed;
import org.bytedeco.javacpp.annotation.ValueGetter;
import org.bytedeco.javacpp.annotation.ValueSetter;
import org.bytedeco.javacpp.annotation.Virtual;
Expand Down Expand Up @@ -3513,6 +3514,17 @@ static Method[] functionMethods(Class<?> cls, boolean[] callbackAllocators) {
functionMethods : null;
}

String removeSuffix(String name, MethodInformation info) {
if (info.annotations != null) {
for (Annotation a : info.annotations) {
if (a instanceof Renamed) {
return name.substring(0, name.length() - Parser.RENAMED_SUFFIX.length());
}
}
}
return name;
}

MethodInformation methodInformation(Method method) {
MethodInformation info = new MethodInformation();
info.cls = method.getDeclaringClass();
Expand All @@ -3521,6 +3533,7 @@ MethodInformation methodInformation(Method method) {
info.modifiers = method.getModifiers();
info.returnType = method.getReturnType();
info.name = method.getName();
info.name = removeSuffix(info.name, info);
Name name = method.getAnnotation(Name.class);
info.memberName = name != null ? name.value() : new String[] { info.name };
Index index = method.getAnnotation(Index.class);
Expand Down Expand Up @@ -3565,6 +3578,14 @@ MethodInformation methodInformation(Method method) {
info2.parameterTypes = method2.getParameterTypes();
info2.annotations = method2.getAnnotations();
info2.parameterAnnotations = method2.getParameterAnnotations();

for (Annotation a:info2.annotations) {
if (a instanceof Renamed) {
info2.name = info2.name.substring(0, info2.name.length() - Parser.RENAMED_SUFFIX.length());
break;
}
}

}
int skipParameters = info.parameterTypes.length > 0 && info.parameterTypes[0] == Class.class ? 1 : 0;
int skipParameters2 = info2.parameterTypes.length > 0 && info2.parameterTypes[0] == Class.class ? 1 : 0;
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/org/bytedeco/javacpp/tools/Info.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public Info(Info i) {
base = i.base;
cppText = i.cppText;
javaText = i.javaText;
}
downCaster = i.downCaster;
}

/** A list of C++ identifiers, expressions, or header filenames to which this info is to be bound.
* Usually set via the constructor parameter of {@link #Info(String...)}. */
Expand Down Expand Up @@ -120,7 +121,10 @@ public Info(Info i) {
String cppText = null;
/** Outputs the given code, instead of the result parsed from the declaration of C++ identifiers. */
String javaText = null;
/** Contains the name of the downcaster function */
String downCaster = null;

public Info downCaster(String downCaster) { this.downCaster = downCaster; return this; }
public Info cppNames(String... cppNames) { this.cppNames = cppNames; return this; }
public Info javaNames(String... javaNames) { this.javaNames = javaNames; return this; }
public Info annotations(String... annotations) { this.annotations = annotations; return this; }
Expand Down
92 changes: 89 additions & 3 deletions src/main/java/org/bytedeco/javacpp/tools/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
* @author Samuel Audet
*/
public class Parser {
final static String RENAMED_SUFFIX = "__";

public Parser(Logger logger, Properties properties) {
this(logger, properties, null, null);
Expand Down Expand Up @@ -671,7 +672,7 @@ Type type(Context context, boolean definition) throws ParserException {
}
type.cppName += separator;
Info info = infoMap.getFirst(t.cppName);
String s = info != null && info.cppTypes != null ? info.cppTypes[0] : t.cppName;
String s = info != null && info.cppTypes != null && info.cppTypes.length > 0 ? info.cppTypes[0] : t.cppName;
if (t.constValue && !s.startsWith("const ")) {
s = "const " + s;
}
Expand Down Expand Up @@ -988,6 +989,7 @@ Type type(Context context, boolean definition) throws ParserException {
for (String s : info.annotations) {
type.annotations += s + " ";
}
type.downCaster = info.downCaster;
}
if (context.cppName != null && type.javaName.length() > 0) {
String cppName = type.cppName;
Expand Down Expand Up @@ -1398,6 +1400,7 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole
for (String s : info2.annotations) {
type.annotations += s + " ";
}
type.downCaster = info2.downCaster;
info = infoMap.getFirst(type.cppName, false);
break;
}
Expand Down Expand Up @@ -2517,7 +2520,11 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
decl.text += "public " + context.shorten(context.javaName) + dcl.parameters.list + " { super((Pointer)null); allocate" + params.names + "; }\n" +
type.annotations + "private native void allocate" + dcl.parameters.list + ";\n";
} else {
decl.text += modifiers + type.annotations + context.shorten(type.javaName) + " " + dcl.javaName + dcl.parameters.list + ";\n";
String paramList = dcl.parameters.list.replaceAll("@Downcast", "");
if (type.annotations.contains("@Downcast"))
decl.text += modifiers + type.annotations + "@Renamed " + context.shorten(type.javaName) + " " + dcl.javaName + RENAMED_SUFFIX + paramList + ";\n";
else
decl.text += modifiers + type.annotations + context.shorten(type.javaName) + " " + dcl.javaName + paramList + ";\n";
}
decl.signature = dcl.signature;

Expand Down Expand Up @@ -2560,8 +2567,69 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
prevDcl.add(dcl);
}
declList.spacing = null;
Declaration dcli2 = null;
for (Declaration dcli : declList) {
if (dcli.function) {
if (dcli.text.contains("@Renamed")) {

dcli2 = new Declaration();

//List<Info> infos = context.infoMap.get(dcli.declarator.type.cppName,false);

dcli2.type = dcli.type;
dcli2.declarator = dcli.declarator;
dcli2.constMember = dcli.constMember;
dcli2.inaccessible = dcli.inaccessible;
dcli2.incomplete = dcli.incomplete;
dcli2.function = dcli.function;
dcli2.variable = dcli.variable;
dcli2.comment = dcli.comment;
dcli2.text = fixFun(dcli.text, info, dcli.declarator.type.downCaster);
dcli2.signature = dcli2.text;
}
}

}
if (dcli2 != null) {
declList.add(dcli2);
}
return true;
}

String fixFun(String text, Info info, String downCaster) {
if (text.endsWith("};"))
return text;
String decl = text;
decl = decl.replace(RENAMED_SUFFIX, "");
decl = decl.replace("@Renamed", "");
decl = decl.replace(" native ", " ");
decl = decl.replace(";", "");
String name = decl.substring(0, decl.indexOf("(")).trim();
name = name.substring(name.lastIndexOf(" "));
String retype = decl.substring(0, decl.indexOf("(")).trim();
retype = retype.substring(0, retype.lastIndexOf(" ")).trim();
retype = retype.substring(retype.lastIndexOf(" ")).trim();

String params = decl.substring(decl.indexOf("(") + 1, decl.lastIndexOf(")"));
String[] alist = params.split(",");
String args = "";
if (alist != null) {
for (String a : alist) {
String a1 = a.trim();
String a2 = a1.substring(a1.lastIndexOf(" ") + 1);
if (args.length() > 0)
args += ", ";
args += a2;
}
}
//String n=f.substring(0,f.indexOf("("))-1).sub

String x = "\n" + decl + "{" + "return " + "(" + retype + ")" + downCaster + "(" + name + RENAMED_SUFFIX + "(" + args + ")" + ")" + ";" + "};";
// System.out.println("KUSTI>>> " + text);
// System.out.println(" >>> " + x);
return x;
}


boolean variable(Context context, DeclarationList declList) throws ParserException {
int backIndex = tokens.index;
Expand Down Expand Up @@ -4384,7 +4452,25 @@ public File[] parse(File outputDirectory, String[] classPath, Class cls) throws
if (prevd != null) {
out.append(prevd.text);
}
out.append("\n}\n").close();

// Inject target level Java
for (Info i : infoMap.get("@" + target)) {
if (i.javaText != null) {
out.append("\n");
out.append(i.javaText);
out.append("\n");
}
}

for (Info i : infoMap.get("@")) {
if (i.javaText != null) {
out.append("\n");
out.append(i.javaText);
out.append("\n");
}
}

out.append("\n}\n").close();
}

return outputFiles.toArray(new File[outputFiles.size()]);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/bytedeco/javacpp/tools/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class Type {
String annotations = "", cppName = "", javaName = "", javaNames[] = null;
Type[] arguments = null;
Attribute[] attributes = null;

String downCaster = null;

@Override public boolean equals(Object obj) {
if (obj == this) {
return true;
Expand Down