15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package com.sun.tools.jextract; 25 26 import com.sun.tools.jextract.parser.Parser; 27 import com.sun.tools.jextract.tree.FlexibleArrayWarningVisitor; 28 import com.sun.tools.jextract.tree.Tree; 29 30 import java.io.IOException; 31 import java.io.UncheckedIOException; 32 import java.nio.file.Files; 33 import java.nio.file.Path; 34 import java.util.Collection; 35 import java.util.HashSet; 36 import java.util.LinkedHashMap; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.Set; 40 import java.util.function.Function; 41 import java.util.stream.Collectors; 42 import java.util.stream.Stream; 43 44 public class JextractTool { 45 private final HeaderResolver headerResolver; 46 private final Parser parser; 47 private final Function<HeaderFile, AsmCodeFactory> codeFactory; 48 private final Collection<String> clangArgs; 49 private final Collection<Path> sources; 50 private final Context ctx; 51 52 public JextractTool(Context ctx) { 53 this.headerResolver = new HeaderResolver(ctx); 54 this.parser = new Parser(ctx, Options.INCLUDE_MACROS); 55 this.codeFactory = ctx.options.genStaticForwarder ? 56 hf -> new AsmCodeFactoryExt(ctx, hf) : 57 hf -> new AsmCodeFactory(ctx, hf); 58 this.clangArgs = ctx.options.clangArgs; 59 this.sources = ctx.sources; 60 this.ctx = ctx; 61 assert sources.size() > 0; 62 } 63 64 /** This is the main jextract entry point */ 65 public Writer processHeaders() { 66 Path source = sources.size() > 1? generateTmpSource() : sources.iterator().next(); 67 Map<HeaderFile, List<Tree>> headerMap = Stream.of(parser.parse(source, clangArgs)) 68 .map(new SymbolFilter(ctx)) 69 .map(new LibraryLookupFilter(ctx)) 70 .map(new DependencyFilter(ctx)) 71 .map(new BuiltinTypesHandler(ctx)) 72 .map(new TypedefHandler(ctx)) 73 .map(new EmptyNameHandler()) 74 .map(new DuplicateDeclarationHandler()) 75 .flatMap(h -> h.declarations().stream()) 76 .peek(new FlexibleArrayWarningVisitor(ctx)) 77 .collect(Collectors.groupingBy(this::headerFromDecl)); 78 79 //generate classes 80 Map<String, byte[]> results = new LinkedHashMap<>(); 81 headerMap.forEach((hf, decls) -> generateHeader(hf, decls, results)); 82 return new Writer(ctx, results); 83 } 84 85 private void generateHeader(HeaderFile hf, List<Tree> decls, Map<String, byte[]> results) { 86 TypeEnter enter = new TypeEnter(hf.dictionary()); 87 decls.forEach(t -> t.accept(enter, null)); 88 if (ctx.options.srcDumpDir != null) { 89 JavaSourceFactory jsb = ctx.options.genStaticForwarder ? 90 new JavaSourceFactoryExt(ctx, hf) : new JavaSourceFactory(ctx, hf); 91 jsb.generate(decls); 92 } 93 AsmCodeFactory cf = codeFactory.apply(hf); 94 results.putAll(cf.generateNativeHeader(decls)); 95 } 96 97 private HeaderFile headerFromDecl(Tree tree) { 98 Path path = tree.cursor().getSourceLocation().getFileLocation().path(); 99 return headerResolver.headerFor(path); 100 } 101 102 private Path generateTmpSource() { 103 assert sources.size() > 1; 104 try { 105 Path tmpFile = Files.createTempFile("jextract", ".h"); 106 tmpFile.toFile().deleteOnExit(); 107 Files.write(tmpFile, sources.stream(). 108 map(src -> "#include \"" + src + "\""). 109 collect(Collectors.toList())); 110 return tmpFile; 111 } catch (IOException ioExp) { 112 throw new UncheckedIOException(ioExp); 113 } 114 } | 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package com.sun.tools.jextract; 25 26 import com.sun.tools.jextract.parser.Parser; 27 import com.sun.tools.jextract.tree.FlexibleArrayWarningVisitor; 28 import com.sun.tools.jextract.tree.Tree; 29 30 import java.io.IOException; 31 import java.io.UncheckedIOException; 32 import java.nio.file.Files; 33 import java.nio.file.Path; 34 import java.util.Collection; 35 import java.util.HashMap; 36 import java.util.HashSet; 37 import java.util.LinkedHashMap; 38 import java.util.List; 39 import java.util.Map; 40 import java.util.Set; 41 import java.util.function.Function; 42 import java.util.stream.Collectors; 43 import java.util.stream.Stream; 44 45 public class JextractTool { 46 private final HeaderResolver headerResolver; 47 private final Parser parser; 48 private final Collection<String> clangArgs; 49 private final Collection<Path> sources; 50 private final Context ctx; 51 52 public JextractTool(Context ctx) { 53 this.headerResolver = new HeaderResolver(ctx); 54 this.parser = new Parser(ctx, Options.INCLUDE_MACROS); 55 this.clangArgs = ctx.options.clangArgs; 56 this.sources = ctx.sources; 57 this.ctx = ctx; 58 assert sources.size() > 0; 59 } 60 61 /** This is the main jextract entry point */ 62 public Writer processHeaders() { 63 Path source = sources.size() > 1? generateTmpSource() : sources.iterator().next(); 64 Map<HeaderFile, List<Tree>> headerMap = Stream.of(parser.parse(source, clangArgs)) 65 .map(new SymbolFilter(ctx)) 66 .map(new LibraryLookupFilter(ctx)) 67 .map(new DependencyFilter(ctx)) 68 .map(new BuiltinTypesHandler(ctx)) 69 .map(new TypedefHandler(ctx)) 70 .map(new EmptyNameHandler()) 71 .map(new DuplicateDeclarationHandler()) 72 .flatMap(h -> h.declarations().stream()) 73 .peek(new FlexibleArrayWarningVisitor(ctx)) 74 .collect(Collectors.groupingBy(this::headerFromDecl)); 75 76 //generate classes 77 Map<String, String> srcMap = new HashMap<>(); 78 headerMap.forEach((hf, decls) -> generateHeader(hf, decls,srcMap)); 79 Map<String, byte[]> classMap = !srcMap.isEmpty()? InMemoryJavaCompiler.compile(srcMap) : Map.of(); 80 return new Writer(ctx, classMap); 81 } 82 83 private void generateHeader(HeaderFile hf, List<Tree> decls, Map<String, String> srcMap) { 84 TypeEnter enter = new TypeEnter(hf.dictionary()); 85 decls.forEach(t -> t.accept(enter, null)); 86 JavaSourceFactory jsb = ctx.options.genStaticForwarder ? 87 new JavaSourceFactoryExt(ctx, hf) : new JavaSourceFactory(ctx, hf); 88 srcMap.putAll(jsb.generate(decls)); 89 } 90 91 private HeaderFile headerFromDecl(Tree tree) { 92 Path path = tree.cursor().getSourceLocation().getFileLocation().path(); 93 return headerResolver.headerFor(path); 94 } 95 96 private Path generateTmpSource() { 97 assert sources.size() > 1; 98 try { 99 Path tmpFile = Files.createTempFile("jextract", ".h"); 100 tmpFile.toFile().deleteOnExit(); 101 Files.write(tmpFile, sources.stream(). 102 map(src -> "#include \"" + src + "\""). 103 collect(Collectors.toList())); 104 return tmpFile; 105 } catch (IOException ioExp) { 106 throw new UncheckedIOException(ioExp); 107 } 108 } |