< prev index next >

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

Print this page




   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  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 package com.sun.tools.jextract;
  24 
  25 import jdk.internal.clang.*;
  26 import jdk.internal.foreign.LibrariesHelper;
  27 

  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.io.OutputStream;
  31 import java.io.PrintWriter;
  32 import java.io.UncheckedIOException;
  33 import java.lang.invoke.MethodHandles;
  34 import java.foreign.Library;
  35 import java.nio.file.Files;
  36 import java.nio.file.Path;
  37 import java.util.ArrayList;
  38 import java.util.Arrays;
  39 import java.util.Collections;
  40 import java.util.HashMap;
  41 import java.util.List;
  42 import java.util.Map;

  43 import java.util.Set;
  44 import java.util.TreeSet;
  45 import java.util.function.Function;
  46 import java.util.function.Predicate;
  47 import java.util.jar.JarOutputStream;
  48 import java.util.logging.Logger;
  49 import java.util.regex.Pattern;
  50 import java.util.stream.Collectors;
  51 import java.util.zip.ZipEntry;
  52 
  53 import static java.nio.file.StandardOpenOption.CREATE;
  54 import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
  55 import static java.nio.file.StandardOpenOption.WRITE;
  56 
  57 /**
  58  * The setup for the tool execution
  59  */
  60 public final class Context {
  61     // package name to TypeDictionary
  62     private final Map<String, TypeDictionary> tdMap;


 419                 logger.config(() -> "File " + header + " code generation is not activated!");
 420                 return;
 421             }
 422             List<AsmCodeFactory> l = mapPkgCf.computeIfAbsent(pkg, k -> new ArrayList<>());
 423             l.add(cf);
 424             logger.config(() -> "Add cf " + cf + " to pkg " + pkg + ", size is now " + l.size());
 425         });
 426         return Collections.unmodifiableMap(mapPkgCf);
 427     }
 428 
 429     public Map<String, byte[]> collectClasses(String... pkgs) {
 430         final Map<String, byte[]> rv = new HashMap<>();
 431         final Map<String, List<AsmCodeFactory>> mapPkgCf = getPkgCfMap();
 432         for (String pkg_name : pkgs) {
 433             mapPkgCf.getOrDefault(pkg_name, Collections.emptyList())
 434                     .forEach(cf -> rv.putAll(cf.collect()));
 435         }
 436         return Collections.unmodifiableMap(rv);
 437     }
 438 
 439     void collectClassFiles(Path destDir, String... pkgs) throws IOException {














 440         try {
 441             collectClasses(pkgs).entrySet().stream().forEach(e -> {
 442                 try {
 443                     String path = e.getKey().replace('.', File.separatorChar) + ".class";
 444                     logger.fine(() -> "Writing " + path);
 445                     Path fullPath = destDir.resolve(path).normalize();
 446                     Files.createDirectories(fullPath.getParent());
 447                     try (OutputStream fos = Files.newOutputStream(fullPath)) {
 448                         fos.write(e.getValue());
 449                         fos.flush();
 450                     }
 451                 } catch (IOException ioe) {
 452                     throw new UncheckedIOException(ioe);
 453                 }
 454             });







 455         } catch (UncheckedIOException uioe) {
 456             throw uioe.getCause();
 457         }
 458     }
 459 
 460     private void writeJar(AsmCodeFactory cf, JarOutputStream jar) {
 461         cf.collect().entrySet().stream().forEach(e -> {
 462             try {
 463                 String path = e.getKey().replace('.', File.separatorChar) + ".class";
 464                 logger.fine(() -> "Add " + path);
 465                 jar.putNextEntry(new ZipEntry(path));
 466                 jar.write(e.getValue());
 467                 jar.closeEntry();
 468             } catch (IOException ioe) {
 469                 throw new UncheckedIOException(ioe);
 470             }
 471         });
 472     }
 473 
 474     public void collectJarFile(final JarOutputStream jos, String... pkgs) {
 475         final Map<String, List<AsmCodeFactory>> mapPkgCf = getPkgCfMap();
 476 
 477         for (String pkg_name : pkgs) {
 478             // convert '.' to '/' to use as a path
 479             String entryName = Utils.toInternalName(pkg_name, "");
 480             // package folder
 481             if (!entryName.isEmpty()) {
 482                 try {
 483                     jos.putNextEntry(new ZipEntry(entryName));
 484                 } catch (IOException ex) {
 485                     throw new UncheckedIOException(ex);
 486                 }
 487             }
 488             logger.fine(() -> "Produce for package " + pkg_name);
 489             mapPkgCf.getOrDefault(pkg_name, Collections.emptyList())
 490                     .forEach(cf -> writeJar(cf, jos));








 491         }
 492     }
 493 
 494     void collectJarFile(final Path jar, String... pkgs) throws IOException {
 495         logger.info(() -> "Collecting jar file " + jar);
 496         try (OutputStream os = Files.newOutputStream(jar, CREATE, TRUNCATE_EXISTING, WRITE);
 497                 JarOutputStream jo = new JarOutputStream(os)) {
 498             collectJarFile(jo, pkgs);
 499         } catch (UncheckedIOException uioe) {
 500             throw uioe.getCause();
 501         }
 502     }
 503 
 504     /**
 505      * Perform a local lookup, any undefined type will cause a JType
 506      * be defined within origin scope.
 507      *
 508      * @param type   The libclang type
 509      * @param origin The path of the file where type is encountered
 510      * @return The JType
 511      */
 512     JType getJType(final Type type, Path origin) {
 513         Path p = origin.normalize().toAbsolutePath();
 514 
 515         HeaderFile hf = headerMap.get(p);
 516         // We should not encounter a type if the header file reference to it is not yet processed
 517         assert(null != hf);
 518         if (hf == null) {




   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  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 package com.sun.tools.jextract;
  24 
  25 import jdk.internal.clang.*;
  26 import jdk.internal.foreign.LibrariesHelper;
  27 
  28 import java.io.ByteArrayOutputStream;
  29 import java.io.File;
  30 import java.io.IOException;
  31 import java.io.OutputStream;
  32 import java.io.PrintWriter;
  33 import java.io.UncheckedIOException;
  34 import java.lang.invoke.MethodHandles;
  35 import java.foreign.Library;
  36 import java.nio.file.Files;
  37 import java.nio.file.Path;
  38 import java.util.ArrayList;
  39 import java.util.Arrays;
  40 import java.util.Collections;
  41 import java.util.HashMap;
  42 import java.util.List;
  43 import java.util.Map;
  44 import java.util.Properties;
  45 import java.util.Set;
  46 import java.util.TreeSet;
  47 import java.util.function.Function;
  48 import java.util.function.Predicate;
  49 import java.util.jar.JarOutputStream;
  50 import java.util.logging.Logger;
  51 import java.util.regex.Pattern;
  52 import java.util.stream.Collectors;
  53 import java.util.zip.ZipEntry;
  54 
  55 import static java.nio.file.StandardOpenOption.CREATE;
  56 import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
  57 import static java.nio.file.StandardOpenOption.WRITE;
  58 
  59 /**
  60  * The setup for the tool execution
  61  */
  62 public final class Context {
  63     // package name to TypeDictionary
  64     private final Map<String, TypeDictionary> tdMap;


 421                 logger.config(() -> "File " + header + " code generation is not activated!");
 422                 return;
 423             }
 424             List<AsmCodeFactory> l = mapPkgCf.computeIfAbsent(pkg, k -> new ArrayList<>());
 425             l.add(cf);
 426             logger.config(() -> "Add cf " + cf + " to pkg " + pkg + ", size is now " + l.size());
 427         });
 428         return Collections.unmodifiableMap(mapPkgCf);
 429     }
 430 
 431     public Map<String, byte[]> collectClasses(String... pkgs) {
 432         final Map<String, byte[]> rv = new HashMap<>();
 433         final Map<String, List<AsmCodeFactory>> mapPkgCf = getPkgCfMap();
 434         for (String pkg_name : pkgs) {
 435             mapPkgCf.getOrDefault(pkg_name, Collections.emptyList())
 436                     .forEach(cf -> rv.putAll(cf.collect()));
 437         }
 438         return Collections.unmodifiableMap(rv);
 439     }
 440 
 441     private static final String JEXTRACT_MANIFEST = "META-INFO" + File.separatorChar + "jextract.properties";
 442 
 443     @SuppressWarnings("deprecation")
 444     private byte[] getJextractProperties(String[] args) {
 445         Properties props = new Properties();
 446         props.setProperty("os.name", System.getProperty("os.name"));
 447         props.setProperty("os.version", System.getProperty("os.version"));
 448         props.setProperty("os.arch", System.getProperty("os.arch"));
 449         props.setProperty("jextract.args", Arrays.toString(args));
 450         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 451         props.save(baos, "jextract meta data");
 452         return baos.toByteArray();
 453     }
 454 
 455     void collectClassFiles(Path destDir, String[] args, String... pkgs) throws IOException {
 456         try {
 457             collectClasses(pkgs).entrySet().stream().forEach(e -> {
 458                 try {
 459                     String path = e.getKey().replace('.', File.separatorChar) + ".class";
 460                     logger.fine(() -> "Writing " + path);
 461                     Path fullPath = destDir.resolve(path).normalize();
 462                     Files.createDirectories(fullPath.getParent());
 463                     try (OutputStream fos = Files.newOutputStream(fullPath)) {
 464                         fos.write(e.getValue());
 465                         fos.flush();
 466                     }
 467                 } catch (IOException ioe) {
 468                     throw new UncheckedIOException(ioe);
 469                 }
 470             });
 471 
 472             Path propsPath = destDir.resolve(JEXTRACT_MANIFEST).normalize();
 473             Files.createDirectories(propsPath.getParent());
 474             try (OutputStream fos = Files.newOutputStream(propsPath)) {
 475                 fos.write(getJextractProperties(args));
 476                 fos.flush();
 477             }
 478         } catch (UncheckedIOException uioe) {
 479             throw uioe.getCause();
 480         }
 481     }
 482 
 483     private void writeJar(AsmCodeFactory cf, JarOutputStream jar, String[] args) {
 484         cf.collect().entrySet().stream().forEach(e -> {
 485             try {
 486                 String path = e.getKey().replace('.', File.separatorChar) + ".class";
 487                 logger.fine(() -> "Add " + path);
 488                 jar.putNextEntry(new ZipEntry(path));
 489                 jar.write(e.getValue());
 490                 jar.closeEntry();
 491             } catch (IOException ioe) {
 492                 throw new UncheckedIOException(ioe);
 493             }
 494         });
 495     }
 496 
 497     public void collectJarFile(final JarOutputStream jos, String[] args, String... pkgs) {
 498         final Map<String, List<AsmCodeFactory>> mapPkgCf = getPkgCfMap();
 499 
 500         for (String pkg_name : pkgs) {
 501             // convert '.' to '/' to use as a path
 502             String entryName = Utils.toInternalName(pkg_name, "");
 503             // package folder
 504             if (!entryName.isEmpty()) {
 505                 try {
 506                     jos.putNextEntry(new ZipEntry(entryName));
 507                 } catch (IOException ex) {
 508                     throw new UncheckedIOException(ex);
 509                 }
 510             }
 511             logger.fine(() -> "Produce for package " + pkg_name);
 512             mapPkgCf.getOrDefault(pkg_name, Collections.emptyList())
 513                     .forEach(cf -> writeJar(cf, jos, args));
 514         }
 515 
 516         try {
 517             jos.putNextEntry(new ZipEntry(JEXTRACT_MANIFEST));
 518             jos.write(getJextractProperties(args));
 519             jos.closeEntry();
 520         } catch (IOException ioe) {
 521             throw new UncheckedIOException(ioe);
 522         }
 523     }
 524 
 525     void collectJarFile(final Path jar, String[] args, String... pkgs) throws IOException {
 526         logger.info(() -> "Collecting jar file " + jar);
 527         try (OutputStream os = Files.newOutputStream(jar, CREATE, TRUNCATE_EXISTING, WRITE);
 528                 JarOutputStream jo = new JarOutputStream(os)) {
 529             collectJarFile(jo, args, pkgs);
 530         } catch (UncheckedIOException uioe) {
 531             throw uioe.getCause();
 532         }
 533     }
 534 
 535     /**
 536      * Perform a local lookup, any undefined type will cause a JType
 537      * be defined within origin scope.
 538      *
 539      * @param type   The libclang type
 540      * @param origin The path of the file where type is encountered
 541      * @return The JType
 542      */
 543     JType getJType(final Type type, Path origin) {
 544         Path p = origin.normalize().toAbsolutePath();
 545 
 546         HeaderFile hf = headerMap.get(p);
 547         // We should not encounter a type if the header file reference to it is not yet processed
 548         assert(null != hf);
 549         if (hf == null) {


< prev index next >