< prev index next >

src/jdk.jextract/share/classes/com/sun/tools/jextract/JavaSourceFactory.java

Print this page




  73     protected final String headerClassName;
  74     protected final HeaderFile headerFile;
  75     private final Map<String, JavaSourceBuilder> types;
  76     private final List<String> libraryNames;
  77     private final List<String> libraryPaths;
  78     private final boolean noNativeLocations;
  79     private final JavaSourceBuilder global_jsb;
  80     protected final Path srcDir;
  81     protected final Log log;
  82 
  83     JavaSourceFactory(Context ctx, HeaderFile header) {
  84         this.log = ctx.log;
  85         log.print(Level.INFO, () -> "Instantiate JavaSourceFactory for " + header.path);
  86         this.headerFile = header;
  87         this.headerClassName = headerFile.pkgName + "." + headerFile.headerClsName;
  88         this.types = new HashMap<>();
  89         this.libraryNames = ctx.options.libraryNames;
  90         this.libraryPaths = ctx.options.recordLibraryPath? ctx.options.libraryPaths : null;
  91         this.noNativeLocations = ctx.options.noNativeLocations;
  92         this.global_jsb = new JavaSourceBuilder();
  93         this.srcDir = Paths.get(ctx.options.srcDumpDir)
  94             .resolve(headerFile.pkgName.replace('.', File.separatorChar));

  95     }
  96 
  97     // main entry point that generates & saves .java files for the header file
  98     public void generate(List<Tree> decls) {
  99         global_jsb.addPackagePrefix(headerFile.pkgName);
 100 
 101         Map<String, Object> header = new HashMap<>();
 102         header.put("path", headerFile.path.toAbsolutePath().toString());
 103         if (!libraryNames.isEmpty()) {
 104             header.put("libraries", libraryNames.toArray(new String[0]));
 105             if (libraryPaths != null && !libraryPaths.isEmpty()) {
 106                 header.put("libraryPaths", libraryPaths.toArray(new String[0]));
 107             }
 108         }
 109 
 110         JType.ClassType[] classes = headerFile.dictionary().resolutionRoots()
 111               .toArray(JType.ClassType[]::new);
 112         if (classes.length != 0) {
 113             header.put("resolutionContext", classes);
 114         }
 115 
 116         Set<Layout> global_layouts = new LinkedHashSet<>();
 117         for (Tree tr : decls) {
 118             if (tr instanceof VarTree) {


 124             String[] globals = global_layouts.stream().map(Object::toString).toArray(String[]::new);
 125             header.put("globals", globals);
 126         }
 127 
 128         global_jsb.addAnnotation(false, NATIVE_HEADER, header);
 129         String clsName = headerFile.headerClsName;
 130         global_jsb.interfaceBegin(clsName, false);
 131 
 132         //generate all decls
 133         decls.forEach(this::generateDecl);
 134         //generate functional interfaces
 135         headerFile.dictionary().functionalInterfaces()
 136                 .forEach(fi -> createFunctionalInterface((JType.FunctionalInterfaceType)fi));
 137 
 138         for (JavaSourceBuilder jsb : types.values()) {
 139             global_jsb.addNestedType(jsb);
 140         }
 141 
 142         global_jsb.interfaceEnd();
 143         String src = global_jsb.build();

 144         try {
 145             Files.createDirectories(srcDir);
 146             Path srcPath = srcDir.resolve(clsName + ".java");
 147             Files.write(srcPath, List.of(src));
 148         } catch (Exception ex) {
 149             handleException(ex);
 150         }
 151     }
 152 





 153     protected void handleException(Exception ex) {
 154         log.printError("cannot.write.class.file", headerFile.pkgName + "." + headerFile.headerClsName, ex);
 155         log.printStackTrace(ex);
 156     }
 157 
 158     private void addNativeLocation(JavaSourceBuilder jsb, Tree tree) {
 159         addNativeLocation(jsb, tree.location());
 160     }
 161 
 162     private void addNativeLocation(JavaSourceBuilder jsb, SourceLocation src) {
 163         addNativeLocation(true, jsb, src);
 164     }
 165 
 166     private void addNativeLocation(boolean align, JavaSourceBuilder jsb, SourceLocation src) {
 167         if (! noNativeLocations) {
 168             SourceLocation.Location loc = src.getFileLocation();
 169             Path p = loc.path();
 170             Map<String, Object> fields = new HashMap<>();
 171             fields.put("file", p == null ? "<builtin>" :  p.toAbsolutePath().toString());
 172             fields.put("line", loc.line());


 333         addClassIfNeeded(headerClassName + "." + intf, jsb);
 334     }
 335 
 336     @Override
 337     public Boolean visitTypedef(TypedefTree typedefTree, JType jt) {
 338         createAnnotationCls(typedefTree);
 339         return true;
 340     }
 341 
 342     @Override
 343     public Boolean visitTree(Tree tree, JType jt) {
 344         log.print(Level.WARNING, () -> "Unsupported declaration tree:");
 345         log.print(Level.WARNING, () -> tree.toString());
 346         return true;
 347     }
 348 
 349     @Override
 350     public Boolean visitFunction(FunctionTree funcTree, JType jt) {
 351         assert (jt instanceof JType.Function);
 352         JType.Function fn = (JType.Function)jt;
 353         log.print(Level.FINE, () -> "Add method: " + fn.getSignature(false));
 354 
 355         addNativeLocation(global_jsb, funcTree);
 356         Type type = funcTree.type();
 357         final String descStr = Utils.getFunction(type).toString();
 358         global_jsb.addAnnotation(NATIVE_FUNCTION, Map.of("value", descStr));
 359         global_jsb.addMethod(funcTree, fn);
 360 
 361         return true;
 362     }
 363 
 364     private void generateDecl(Tree tree) {
 365         try {
 366             log.print(Level.FINE, () -> "Process tree " + tree.name());
 367             tree.accept(this, tree.isPreprocessing() ? null : headerFile.dictionary().lookup(tree.type()));
 368         } catch (Exception ex) {
 369             handleException(ex);
 370             log.print(Level.WARNING, () -> "Tree causing above exception is: " + tree.name());
 371             log.print(Level.WARNING, () -> tree.toString());
 372         }
 373     }


  73     protected final String headerClassName;
  74     protected final HeaderFile headerFile;
  75     private final Map<String, JavaSourceBuilder> types;
  76     private final List<String> libraryNames;
  77     private final List<String> libraryPaths;
  78     private final boolean noNativeLocations;
  79     private final JavaSourceBuilder global_jsb;
  80     protected final Path srcDir;
  81     protected final Log log;
  82 
  83     JavaSourceFactory(Context ctx, HeaderFile header) {
  84         this.log = ctx.log;
  85         log.print(Level.INFO, () -> "Instantiate JavaSourceFactory for " + header.path);
  86         this.headerFile = header;
  87         this.headerClassName = headerFile.pkgName + "." + headerFile.headerClsName;
  88         this.types = new HashMap<>();
  89         this.libraryNames = ctx.options.libraryNames;
  90         this.libraryPaths = ctx.options.recordLibraryPath? ctx.options.libraryPaths : null;
  91         this.noNativeLocations = ctx.options.noNativeLocations;
  92         this.global_jsb = new JavaSourceBuilder();
  93         this.srcDir = ctx.options.srcDumpDir != null?
  94             Paths.get(ctx.options.srcDumpDir).resolve(headerFile.pkgName.replace('.', File.separatorChar)) :
  95             null;
  96     }
  97 
  98     // main entry point that generates & saves .java files for the header file
  99     public Map<String, String> generate(List<Tree> decls) {
 100         global_jsb.addPackagePrefix(headerFile.pkgName);
 101 
 102         Map<String, Object> header = new HashMap<>();
 103         header.put("path", headerFile.path.toAbsolutePath().toString());
 104         if (!libraryNames.isEmpty()) {
 105             header.put("libraries", libraryNames.toArray(new String[0]));
 106             if (libraryPaths != null && !libraryPaths.isEmpty()) {
 107                 header.put("libraryPaths", libraryPaths.toArray(new String[0]));
 108             }
 109         }
 110 
 111         JType.ClassType[] classes = headerFile.dictionary().resolutionRoots()
 112               .toArray(JType.ClassType[]::new);
 113         if (classes.length != 0) {
 114             header.put("resolutionContext", classes);
 115         }
 116 
 117         Set<Layout> global_layouts = new LinkedHashSet<>();
 118         for (Tree tr : decls) {
 119             if (tr instanceof VarTree) {


 125             String[] globals = global_layouts.stream().map(Object::toString).toArray(String[]::new);
 126             header.put("globals", globals);
 127         }
 128 
 129         global_jsb.addAnnotation(false, NATIVE_HEADER, header);
 130         String clsName = headerFile.headerClsName;
 131         global_jsb.interfaceBegin(clsName, false);
 132 
 133         //generate all decls
 134         decls.forEach(this::generateDecl);
 135         //generate functional interfaces
 136         headerFile.dictionary().functionalInterfaces()
 137                 .forEach(fi -> createFunctionalInterface((JType.FunctionalInterfaceType)fi));
 138 
 139         for (JavaSourceBuilder jsb : types.values()) {
 140             global_jsb.addNestedType(jsb);
 141         }
 142 
 143         global_jsb.interfaceEnd();
 144         String src = global_jsb.build();
 145         if (srcDir != null) {
 146             try {
 147                 Files.createDirectories(srcDir);
 148                 Path srcPath = srcDir.resolve(clsName + ".java");
 149                 Files.write(srcPath, List.of(src));
 150             } catch (Exception ex) {
 151                 handleException(ex);
 152             }
 153         }
 154 
 155         Map<String, String> srcMap = new HashMap<>();
 156         srcMap.put(headerClassName, src);
 157         return srcMap;
 158     }
 159 
 160     protected void handleException(Exception ex) {
 161         log.printError("cannot.write.class.file", headerFile.pkgName + "." + headerFile.headerClsName, ex);
 162         log.printStackTrace(ex);
 163     }
 164 
 165     private void addNativeLocation(JavaSourceBuilder jsb, Tree tree) {
 166         addNativeLocation(jsb, tree.location());
 167     }
 168 
 169     private void addNativeLocation(JavaSourceBuilder jsb, SourceLocation src) {
 170         addNativeLocation(true, jsb, src);
 171     }
 172 
 173     private void addNativeLocation(boolean align, JavaSourceBuilder jsb, SourceLocation src) {
 174         if (! noNativeLocations) {
 175             SourceLocation.Location loc = src.getFileLocation();
 176             Path p = loc.path();
 177             Map<String, Object> fields = new HashMap<>();
 178             fields.put("file", p == null ? "<builtin>" :  p.toAbsolutePath().toString());
 179             fields.put("line", loc.line());


 340         addClassIfNeeded(headerClassName + "." + intf, jsb);
 341     }
 342 
 343     @Override
 344     public Boolean visitTypedef(TypedefTree typedefTree, JType jt) {
 345         createAnnotationCls(typedefTree);
 346         return true;
 347     }
 348 
 349     @Override
 350     public Boolean visitTree(Tree tree, JType jt) {
 351         log.print(Level.WARNING, () -> "Unsupported declaration tree:");
 352         log.print(Level.WARNING, () -> tree.toString());
 353         return true;
 354     }
 355 
 356     @Override
 357     public Boolean visitFunction(FunctionTree funcTree, JType jt) {
 358         assert (jt instanceof JType.Function);
 359         JType.Function fn = (JType.Function)jt;
 360         log.print(Level.FINE, () -> "Add method: " + fn.getSourceSignature(false));
 361 
 362         addNativeLocation(global_jsb, funcTree);
 363         Type type = funcTree.type();
 364         final String descStr = Utils.getFunction(type).toString();
 365         global_jsb.addAnnotation(NATIVE_FUNCTION, Map.of("value", descStr));
 366         global_jsb.addMethod(funcTree, fn);
 367 
 368         return true;
 369     }
 370 
 371     private void generateDecl(Tree tree) {
 372         try {
 373             log.print(Level.FINE, () -> "Process tree " + tree.name());
 374             tree.accept(this, tree.isPreprocessing() ? null : headerFile.dictionary().lookup(tree.type()));
 375         } catch (Exception ex) {
 376             handleException(ex);
 377             log.print(Level.WARNING, () -> "Tree causing above exception is: " + tree.name());
 378             log.print(Level.WARNING, () -> tree.toString());
 379         }
 380     }
< prev index next >