Skip to content

Commit db6ca9a

Browse files
committedOct 4, 2022
7903344: refactor OutputFactory to introduce various Declaration Visitor classes
Reviewed-by: mcimadamore
1 parent 1b204eb commit db6ca9a

20 files changed

+1012
-510
lines changed
 

‎samples/libffmpeg/compile.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
jextract -t libffmpeg \
22
-I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include \
3-
-I /usr/local/Cellar/ffmpeg@4/4.4.2_3/include \
3+
-I /usr/local/Cellar/ffmpeg@4/4.4.2_4/include \
44
-l avcodec \
55
-l avformat \
66
-l avutil \

‎samples/libffmpeg/run.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
java --enable-native-access=ALL-UNNAMED \
22
--enable-preview --source=20 \
3-
-Djava.library.path=/usr/local/Cellar/ffmpeg@4/4.4.2_3/lib LibffmpegMain.java $*
3+
-Djava.library.path=/usr/local/Cellar/ffmpeg@4/4.4.2_4/lib LibffmpegMain.java $*

‎src/main/java/org/openjdk/jextract/JextractTool.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import org.openjdk.jextract.impl.ClangException;
3030
import org.openjdk.jextract.impl.CommandLine;
3131
import org.openjdk.jextract.impl.IncludeHelper;
32-
import org.openjdk.jextract.impl.OutputFactory;
32+
import org.openjdk.jextract.impl.CodeGenerator;
3333
import org.openjdk.jextract.impl.Parser;
3434
import org.openjdk.jextract.impl.Options;
3535
import org.openjdk.jextract.impl.Writer;
@@ -118,12 +118,12 @@ public static Declaration.Scoped parse(List<Path> headers, String... parserOptio
118118

119119
public static List<JavaFileObject> generate(Declaration.Scoped decl, String headerName,
120120
String targetPkg, List<String> libNames) {
121-
return List.of(OutputFactory.generateWrapped(decl, headerName, targetPkg, new IncludeHelper(), libNames));
121+
return List.of(CodeGenerator.generate(decl, headerName, targetPkg, new IncludeHelper(), libNames));
122122
}
123123

124124
private static List<JavaFileObject> generateInternal(Declaration.Scoped decl, String headerName,
125125
String targetPkg, IncludeHelper includeHelper, List<String> libNames) {
126-
return List.of(OutputFactory.generateWrapped(decl, headerName, targetPkg, includeHelper, libNames));
126+
return List.of(CodeGenerator.generate(decl, headerName, targetPkg, includeHelper, libNames));
127127
}
128128

129129
/**

‎src/main/java/org/openjdk/jextract/Position.java

+22
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
package org.openjdk.jextract;
2828

2929
import java.nio.file.Path;
30+
import java.util.Objects;
3031

3132
/**
3233
* Instances of this class model are used to model source code positions.
@@ -70,5 +71,26 @@ public int line() {
7071
public int col() {
7172
return 0;
7273
}
74+
75+
@Override
76+
public boolean equals(Object obj) {
77+
if (this == obj) return true;
78+
if (obj instanceof Position pos) {
79+
return Objects.equals(path(), pos.path()) &&
80+
Objects.equals(line(), pos.line()) &&
81+
Objects.equals(col(), pos.col());
82+
}
83+
return false;
84+
}
85+
86+
@Override
87+
public int hashCode() {
88+
return 0;
89+
}
90+
91+
@Override
92+
public String toString() {
93+
return "NO_POSITION";
94+
}
7395
};
7496
}

‎src/main/java/org/openjdk/jextract/impl/ClassSourceBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ enum Kind {
6161
this.align = (enclosing instanceof ClassSourceBuilder classSourceBuilder)
6262
? classSourceBuilder.align : 0;
6363
this.kind = kind;
64-
this.desc = ClassDesc.of(enclosing.packageName(), enclosing.uniqueNestedClassName(name));
64+
this.desc = ClassDesc.of(enclosing.packageName(), name);
6565
}
6666

6767
boolean isNested() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.openjdk.jextract.impl;
26+
27+
import org.openjdk.jextract.Declaration;
28+
import java.util.List;
29+
import java.util.stream.Stream;
30+
import javax.tools.JavaFileObject;
31+
32+
public final class CodeGenerator {
33+
private CodeGenerator() {}
34+
35+
public static JavaFileObject[] generate(Declaration.Scoped decl, String headerName,
36+
String targetPkg, IncludeHelper includeHelper,
37+
List<String> libNames) {
38+
var nameMangler = new NameMangler(headerName);
39+
var transformedDecl = Stream.of(decl).
40+
map(new IncludeFilter(includeHelper)::transform).
41+
map(new EnumConstantLifter()::transform).
42+
map(new DuplicateFilter()::transform).
43+
map(nameMangler::scan).
44+
findFirst().get();
45+
return OutputFactory.generateWrapped(transformedDecl, targetPkg, libNames, nameMangler);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.openjdk.jextract.impl;
26+
27+
import org.openjdk.jextract.Declaration;
28+
import java.util.ArrayList;
29+
import java.util.HashSet;
30+
import java.util.List;
31+
import java.util.Set;
32+
33+
/*
34+
* This visitor filters duplicate top-level variables, constants and functions.
35+
*/
36+
final class DuplicateFilter implements TreeTransformer, Declaration.Visitor<Void, Void> {
37+
// To detect duplicate Variable and Function declarations.
38+
private final Set<String> constants = new HashSet<>();
39+
private final Set<String> variables = new HashSet<>();
40+
private final Set<Declaration.Typedef> typedefs = new HashSet<>();
41+
private final Set<Declaration.Function> functions = new HashSet<>();
42+
private final List<Declaration> decls = new ArrayList<>();
43+
44+
// have we seen this Constant earlier?
45+
private boolean constantSeen(Declaration.Constant tree) {
46+
return !constants.add(tree.name());
47+
}
48+
49+
// have we seen this Variable earlier?
50+
private boolean variableSeen(Declaration.Variable tree) {
51+
return !variables.add(tree.name());
52+
}
53+
54+
// have we seen this Function earlier?
55+
private boolean functionSeen(Declaration.Function tree) {
56+
return !functions.add(tree);
57+
}
58+
59+
// have we seen this Function earlier?
60+
private boolean typedefSeen(Declaration.Typedef tree) {
61+
return !typedefs.add(tree);
62+
}
63+
64+
DuplicateFilter() {
65+
}
66+
67+
@Override
68+
public Declaration.Scoped transform(Declaration.Scoped header) {
69+
// Process all header declarations are collect potential
70+
// declarations that will go into transformed HeaderTree
71+
// into the this.decls field.
72+
header.members().forEach(fieldTree -> fieldTree.accept(this, null));
73+
return createHeader(header, decls);
74+
}
75+
76+
@Override
77+
public Void visitConstant(Declaration.Constant constant, Void ignored) {
78+
if (constantSeen(constant)) {
79+
//skip
80+
return null;
81+
}
82+
83+
decls.add(constant);
84+
return null;
85+
}
86+
87+
@Override
88+
public Void visitFunction(Declaration.Function funcTree, Void ignored) {
89+
if (functionSeen(funcTree)) {
90+
//skip
91+
return null;
92+
}
93+
94+
decls.add(funcTree);
95+
return null;
96+
}
97+
98+
@Override
99+
public Void visitTypedef(Declaration.Typedef tree, Void ignored) {
100+
if (typedefSeen(tree)) {
101+
//skip
102+
return null;
103+
}
104+
105+
decls.add(tree);
106+
return null;
107+
}
108+
109+
@Override
110+
public Void visitVariable(Declaration.Variable tree, Void ignored) {
111+
if (variableSeen(tree)) {
112+
//skip
113+
return null;
114+
}
115+
116+
decls.add(tree);
117+
return null;
118+
}
119+
120+
@Override
121+
public Void visitDeclaration(Declaration decl, Void ignored) {
122+
decls.add(decl);
123+
return null;
124+
}
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.openjdk.jextract.impl;
26+
27+
import org.openjdk.jextract.Declaration;
28+
import org.openjdk.jextract.Type;
29+
import java.util.ArrayList;
30+
import java.util.List;
31+
32+
/*
33+
* This visitor lifts enum constants to the top level and removes enum Trees.
34+
*/
35+
final class EnumConstantLifter implements TreeTransformer, Declaration.Visitor<Void, Void> {
36+
private final List<Declaration> decls = new ArrayList<>();
37+
EnumConstantLifter() {
38+
}
39+
40+
@Override
41+
public Declaration.Scoped transform(Declaration.Scoped header) {
42+
// Process all header declarations are collect potential
43+
// declarations that will go into transformed HeaderTree
44+
// into the this.decls field.
45+
header.members().forEach(fieldTree -> fieldTree.accept(this, null));
46+
return createHeader(header, decls);
47+
}
48+
49+
@Override
50+
public Void visitScoped(Declaration.Scoped scoped, Void ignored) {
51+
if (liftEnumConstants(scoped)) {
52+
return null;
53+
}
54+
decls.add(scoped);
55+
return null;
56+
}
57+
58+
@Override
59+
public Void visitTypedef(Declaration.Typedef tree, Void ignored) {
60+
Type type = tree.type();
61+
if (type instanceof Type.Declared declared) {
62+
if (liftEnumConstants(declared.tree())) {
63+
return null;
64+
}
65+
}
66+
decls.add(tree);
67+
return null;
68+
}
69+
70+
@Override
71+
public Void visitDeclaration(Declaration decl, Void ignored) {
72+
decls.add(decl);
73+
return null;
74+
}
75+
76+
private boolean liftEnumConstants(Declaration.Scoped scoped) {
77+
boolean isEnum = scoped.kind() == Declaration.Scoped.Kind.ENUM;
78+
if (isEnum) {
79+
scoped.members().forEach(fieldTree -> fieldTree.accept(this, null));
80+
}
81+
return isEnum;
82+
}
83+
}

‎src/main/java/org/openjdk/jextract/impl/FunctionalInterfaceBuilder.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.lang.foreign.*;
2929

3030
import org.openjdk.jextract.impl.ConstantBuilder.Constant;
31+
import org.openjdk.jextract.Type;
3132

3233
import java.lang.invoke.MethodType;
3334
import java.util.List;
@@ -45,7 +46,7 @@ public class FunctionalInterfaceBuilder extends ClassSourceBuilder {
4546
private final FunctionDescriptor fiDesc;
4647
private final Optional<List<String>> parameterNames;
4748

48-
FunctionalInterfaceBuilder(JavaSourceBuilder enclosing, String className,
49+
FunctionalInterfaceBuilder(JavaSourceBuilder enclosing, Type.Function funcType, String className,
4950
FunctionDescriptor descriptor, Optional<List<String>> parameterNames) {
5051
super(enclosing, Kind.INTERFACE, className);
5152
this.fiType = descriptor.toMethodType();
@@ -69,7 +70,7 @@ private String parameterName(int i) {
6970
if (parameterNames.isPresent()) {
7071
name = parameterNames.get().get(i);
7172
}
72-
return name.isEmpty()? "_x" + i : Utils.javaSafeIdentifier(name);
73+
return name.isEmpty()? "_x" + i : name;
7374
}
7475

7576
private void emitFunctionalInterfaceMethod() {

0 commit comments

Comments
 (0)
Please sign in to comment.