Skip to content

Commit

Permalink
* Add @Properties(global=...) value to allow Parser to target Ja…
Browse files Browse the repository at this point in the history
…va packages (pull #252)
  • Loading branch information
saudet committed Oct 24, 2018
1 parent c03cd9d commit f89f1c3
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

* Add `@Properties(global=...)` value to allow `Parser` to target Java packages ([pull #252](https://github.com/bytedeco/javacpp/pull/252))
* Fix `Generator` output for `@Const` parameters of function pointers

### October 15, 2018 version 1.4.3
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,6 @@ And instead of `Loader.load()`, the library should be loaded with `System.load("


----
Project lead: Samuel Audet [samuel.audet `at` gmail.com](mailto:samuel.audet at gmail.com)
Project lead: Samuel Audet [samuel.audet `at` gmail.com](mailto:samuel.audet at gmail.com)
Developer site: https://github.com/bytedeco/javacpp
Discussion group: http://groups.google.com/group/javacpp-project
11 changes: 10 additions & 1 deletion src/main/java/org/bytedeco/javacpp/ClassProperties.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2017 Samuel Audet
* Copyright (C) 2011-2018 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -167,6 +167,15 @@ public void load(Class cls, boolean inherit) {
if (target.length() > 0) {
addAll("target", target);
}
String global = classProperties.global();
if (global.length() == 0) {
global = target;
} else if (target.length() > 0 && !global.startsWith(target)) {
global = target + "." + global;
}
if (global.length() > 0) {
addAll("global", global);
}
String helper = classProperties.helper();
if (helper.length() > 0) {
addAll("helper", helper);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/bytedeco/javacpp/Loader.java
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ public static String load(Class cls, Properties properties, boolean pathsFirst)
ClassProperties p = loadProperties(cls, properties, true);

// Force initialization of all the target classes in case they need it
List<String> targets = p.get("target");
List<String> targets = p.get("global");
if (targets.isEmpty()) {
if (p.getInheritedClasses() != null) {
for (Class c : p.getInheritedClasses()) {
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/bytedeco/javacpp/annotation/Properties.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@
String[] names() default {};
/** A list of properties for different platforms. */
Platform[] value() default {};
/** The target Java source code file of the {@link Parser}. */
/** The target Java source code file of the {@link Parser}, unless {@link #global()} is set,
in which case this specifies the target Java package. */
String target() default "";
/** An optional helper class the {@link Parser} should use as base of the target.
/** The name of a class where to output any global declarations that are not in classes.
If left empty, considers the {@link #target()} as a class where to put everything. */
String global() default "";
/** An optional helper class the {@link Parser} should use as base for the global class.
Defaults to the class where this annotation was found. */
String helper() default "";
}
15 changes: 11 additions & 4 deletions src/main/java/org/bytedeco/javacpp/tools/Builder.java
Original file line number Diff line number Diff line change
Expand Up @@ -936,11 +936,18 @@ public File[] build() throws IOException, InterruptedException, ParserException
} catch (ClassCastException | InstantiationException | IllegalAccessException e) {
// fail silently as if the interface wasn't implemented
}
String target = p.getProperty("target");
String target = p.getProperty("global");
if (target != null && !c.getName().equals(target)) {
File f = parse(classScanner.getClassLoader().getPaths(), c);
if (f != null) {
outputFiles.add(f);
boolean found = false;
for (Class c2 : classScanner.getClasses()) {
// do not try to regenerate classes that are already loaded
found |= c2.getName().equals(target);
}
if (!found) {
File f = parse(classScanner.getClassLoader().getPaths(), c);
if (f != null) {
outputFiles.add(f);
}
}
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/bytedeco/javacpp/tools/Declaration.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 Samuel Audet
* Copyright (C) 2014-2018 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -30,6 +30,6 @@ class Declaration {
Type type = null;
Declarator declarator = null;
boolean abstractMember = false, constMember = false, inaccessible = false,
incomplete = false, function = false, variable = false;
incomplete = false, function = false, variable = false, comment = false;
String signature = "", text = "";
}
58 changes: 49 additions & 9 deletions src/main/java/org/bytedeco/javacpp/tools/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -225,6 +226,7 @@ void containers(Context context, DeclarationList declList) throws ParserExceptio
for (int i = 0; i < dim - 1; i++) {
arrayBrackets += "[]";
}
decl.type = new Type(containerType.javaName);
decl.text += (dim == 0 ? "\n@NoOffset " : "\n")
+ "@Name(\"" + containerType.cppName + "\") public static class " + containerType.javaName + " extends Pointer {\n"
+ " static { Loader.load(); }\n"
Expand Down Expand Up @@ -1352,6 +1354,7 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole
}
functionType = functionType.substring(functionType.lastIndexOf(' ') + 1); // get rid of pointer annotations
if (!functionType.equals("Pointer")) {
definition.type = new Type(functionType);
definition.text += (tokens.get().match(Token.CONST, Token.__CONST, Token.CONSTEXPR) ? "@Const " : "") +
"public static class " + functionType + " extends FunctionPointer {\n" +
" static { Loader.load(); }\n" +
Expand Down Expand Up @@ -2541,6 +2544,7 @@ boolean typedef(Context context, DeclarationList declList) throws ParserExceptio
} else if (context.namespace != null && context.javaName == null) {
decl.text += "@Namespace(\"" + context.namespace + "\") ";
}
decl.type = new Type(dcl.javaName);
decl.text += "@Opaque public static class " + dcl.javaName + " extends Pointer {\n" +
" /** Empty constructor. Calls {@code super((Pointer)null)}. */\n" +
" public " + dcl.javaName + "() { super((Pointer)null); }\n" +
Expand Down Expand Up @@ -2820,6 +2824,7 @@ boolean group(Context context, DeclarationList declList) throws ParserException
} else if (context.namespace != null && context.javaName == null) {
decl.text += "@Namespace(\"" + context.namespace + "\") ";
}
decl.type = new Type(name);
decl.text += "@Opaque public static class " + name + " extends " + base.javaName + " {\n" +
" /** Empty constructor. Calls {@code super((Pointer)null)}. */\n" +
" public " + name + "() { super((Pointer)null); }\n" +
Expand Down Expand Up @@ -3365,6 +3370,7 @@ void declarations(Context context, DeclarationList declList) throws ParserExcept
if (comment != null && comment.length() > 0) {
decl.inaccessible = ctx.inaccessible;
decl.text = comment;
decl.comment = true;
declList.add(decl);
}
int startIndex = tokens.index;
Expand Down Expand Up @@ -3433,6 +3439,7 @@ void declarations(Context context, DeclarationList declList) throws ParserExcept
Declaration decl = new Declaration();
if (comment != null && comment.length() > 0) {
decl.text = comment;
decl.comment = true;
declList.add(decl);
}
}
Expand Down Expand Up @@ -3521,9 +3528,12 @@ public File parse(File outputDirectory, String[] classPath, Class cls) throws IO
allIncludes.addAll(allProperties.get("platform.include"));
allIncludes.addAll(allProperties.get("platform.cinclude"));
List<String> allTargets = allProperties.get("target");
List<String> allGlobals = allProperties.get("global");
List<String> clsTargets = clsProperties.get("target");
List<String> clsGlobals = clsProperties.get("global");
List<String> clsHelpers = clsProperties.get("helper");
String target = clsTargets.get(0); // there can only be one
String global = clsGlobals.get(0);
List<Class> allInherited = allProperties.getInheritedClasses();

infoMap = new InfoMap();
Expand Down Expand Up @@ -3555,9 +3565,11 @@ public File parse(File outputDirectory, String[] classPath, Class cls) throws IO
version = "unknown";
}
String text = "// Targeted by JavaCPP version " + version + ": DO NOT EDIT THIS FILE\n\n";
int n = target.lastIndexOf('.');
String targetPackage = "";
int n = global.lastIndexOf('.');
if (n >= 0) {
text += "package " + target.substring(0, n) + ";\n\n";
targetPackage = global.substring(0, n);
text += "package " + targetPackage + ";\n\n";
}
List<Info> infoList = leafInfoMap.get(null);
for (Info info : infoList) {
Expand All @@ -3568,19 +3580,24 @@ public File parse(File outputDirectory, String[] classPath, Class cls) throws IO
text += "import java.nio.*;\n"
+ "import org.bytedeco.javacpp.*;\n"
+ "import org.bytedeco.javacpp.annotation.*;\n\n";
for (String s : allTargets) {
if (!target.equals(s)) {
text += "import static " + s + ".*;\n";
for (int i = 0; i < allTargets.size(); i++) {
if (!target.equals(allTargets.get(i))) {
if (allTargets.get(i).equals(allGlobals.get(i))) {
text += "import static " + allTargets.get(i) + ".*;\n";
} else {
text += "import " + allTargets.get(i) + ".*;\n"
+ "import static " + allGlobals.get(i) + ".*;\n";
}
}
}
if (allTargets.size() > 1) {
text += "\n";
}
text += "public class " + target.substring(n + 1) + " extends "
String globalText = text + "public class " + global.substring(n + 1) + " extends "
+ (clsHelpers.size() > 0 && clsIncludes.size() > 0 ? clsHelpers.get(0) : cls.getCanonicalName()) + " {\n"
+ " static { Loader.load(); }\n";

String targetPath = target.replace('.', File.separatorChar);
String targetPath = global.replace('.', File.separatorChar);
File targetFile = new File(outputDirectory, targetPath + ".java");
logger.info("Targeting " + targetFile);
Context context = new Context();
Expand Down Expand Up @@ -3636,14 +3653,37 @@ public File parse(File outputDirectory, String[] classPath, Class cls) throws IO
}
try (Writer out = encoding != null ? new EncodingFileWriter(targetFile, encoding, lineSeparator)
: new EncodingFileWriter(targetFile, lineSeparator)) {
out.append(text);
out.append(globalText);
for (Info info : infoList) {
if (info.javaText != null && !info.javaText.startsWith("import")) {
out.append(info.javaText + "\n");
}
}
Declaration prevd = null;
for (Declaration d : declList) {
out.append(d.text);
if (!target.equals(global) && d.type != null && d.type.javaName != null && d.type.javaName.length() > 0) {
// if the user gave us a class name for "global", we're targeting a package, so output global classes into their own files
File javaFile = new File(targetDir, d.type.javaName + ".java");
if (prevd != null && !prevd.comment) {
out.append(prevd.text);
}
out.append("\n// Targeting " + d.type.javaName + ".java" + "\n\n");
logger.info("Targeting " + javaFile);
String javaText = text + "import static " + global + ".*;\n"
+ "@Platform(library = \"" + clsProperties.getProperty("platform.library") + "\")\n"
+ (prevd != null && prevd.comment ? prevd.text : "")
+ d.text.replace("public static class " + d.type.javaName + " ", "public class " + d.type.javaName + " ");
Files.write(javaFile.toPath(), encoding != null ? javaText.getBytes(encoding) : javaText.getBytes());
prevd = null;
} else {
if (prevd != null) {
out.append(prevd.text);
}
prevd = d;
}
}
if (prevd != null) {
out.append(prevd.text);
}
out.append("\n}\n").close();
}
Expand Down

0 comments on commit f89f1c3

Please sign in to comment.