< prev index next >

src/jdk.jextract/share/classes/com/sun/tools/jextract/parser/Parser.java

Print this page




  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.parser;
  24 
  25 import java.nio.file.Path;
  26 import java.nio.file.Paths;
  27 import java.io.PrintWriter;
  28 import java.util.Arrays;
  29 import java.util.ArrayList;
  30 import java.util.Collection;
  31 import java.util.Collections;
  32 import java.util.LinkedHashMap;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.Optional;
  36 import java.util.function.Predicate;
  37 import java.util.logging.Logger;
  38 import java.util.stream.Collectors;
  39 import jdk.internal.clang.Cursor;
  40 import jdk.internal.clang.CursorKind;
  41 import jdk.internal.clang.Diagnostic;
  42 import jdk.internal.clang.Index;
  43 import jdk.internal.clang.LibClang;
  44 import jdk.internal.clang.SourceLocation;
  45 import jdk.internal.clang.SourceRange;
  46 import jdk.internal.clang.TranslationUnit;
  47 import com.sun.tools.jextract.tree.HeaderTree;
  48 import com.sun.tools.jextract.tree.MacroTree;
  49 import com.sun.tools.jextract.tree.SimpleTreeVisitor;
  50 import com.sun.tools.jextract.tree.Tree;
  51 import com.sun.tools.jextract.tree.TreeMaker;
  52 import com.sun.tools.jextract.tree.TreePrinter;
  53 
  54 public class Parser {
  55     private final PrintWriter out;
  56     private final PrintWriter err;
  57     private final TreeMaker treeMaker;
  58     private final boolean supportMacros;
  59     private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
  60 
  61     public Parser(PrintWriter out, PrintWriter err, boolean supportMacros) {
  62         this.out = out;
  63         this.err = err;
  64         this.treeMaker = new TreeMaker();
  65         this.supportMacros = supportMacros;
  66     }
  67 
  68     public Parser(boolean supportMacros) {
  69         this(new PrintWriter(System.out, true),
  70             new PrintWriter(System.err, true), supportMacros);
  71     }
  72 
  73     public List<HeaderTree> parse(Collection<Path> paths, Collection<String> args, Predicate<Cursor> include) {
  74         final List<HeaderTree> headers = new ArrayList<>();
  75         final Index index = LibClang.createIndex();
  76         for (Path path : paths) {
  77             logger.info(() -> {
  78                 StringBuilder sb = new StringBuilder(
  79                         "Parsing header file " + path + " with following args:\n");
  80                 int i = 0;
  81                 for (String arg : args) {
  82                     sb.append("arg[");
  83                     sb.append(i++);
  84                     sb.append("] = ");
  85                     sb.append(arg);
  86                     sb.append("\n");
  87                 }
  88                 return sb.toString();
  89             });
  90 
  91             Cursor tuCursor = index.parse(path.toString(),
  92                 d -> {
  93                     err.println(d);
  94                     if (d.severity() >  Diagnostic.CXDiagnostic_Warning) {
  95                         throw new RuntimeException(d.toString());
  96                     }
  97                 },
  98                 supportMacros, args.toArray(new String[0]));
  99 
 100             MacroParser macroParser = new MacroParser();
 101             List<Tree> decls = new ArrayList<>();
 102             tuCursor.children().
 103                 filter(c -> include.test(c)).
 104                 peek(c -> logger.finest(
 105                     () -> "Cursor: " + c.spelling() + "@" + c.USR() + "?" + c.isDeclaration())).
 106                 forEach(c -> {
 107                     SourceLocation loc = c.getSourceLocation();
 108                     if (loc == null) {
 109                         logger.info(() -> "Ignore Cursor " + c.spelling() + "@" + c.USR() + " has no SourceLocation");
 110                         return;
 111                     }
 112 
 113                     SourceLocation.Location src = loc.getFileLocation();
 114                     if (src == null) {
 115                         logger.info(() -> "Cursor " + c.spelling() + "@" + c.USR() + " has no FileLocation");
 116                         return;
 117                     }
 118 
 119                     logger.fine(() -> "Do cursor: " + c.spelling() + "@" + c.USR());
 120 
 121                     if (c.isDeclaration()) {
 122                         if (c.kind() == CursorKind.UnexposedDecl ||
 123                             c.kind() == CursorKind.Namespace) {


 169         SourceRange range = cursor.getExtent();
 170         String[] tokens = tu.tokens(range);
 171 
 172         macroParser.parse(cursor, tokens);
 173     }
 174 
 175     private boolean isMacro(Cursor c) {
 176         return c.isPreprocessing() && c.kind() == CursorKind.MacroDefinition;
 177     }
 178 
 179     public static void main(String[] args) {
 180         if (args.length == 0) {
 181             System.err.println("Expected a header file");
 182             return;
 183         }
 184 
 185         Parser p = new Parser(true);
 186         List<Path> paths = Arrays.stream(args).map(Paths::get).collect(Collectors.toList());
 187         Path builtinInc = Paths.get(System.getProperty("java.home"), "conf", "jextract");
 188         List<String> clangArgs = List.of("-I" + builtinInc);
 189         List<HeaderTree> headers = p.parse(paths, clangArgs, c->true);
 190         TreePrinter printer = new TreePrinter();
 191         for (HeaderTree ht : headers) {
 192             ht.accept(printer, null);
 193         }
 194     }
 195 }


  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.parser;
  24 
  25 import java.nio.file.Path;
  26 import java.nio.file.Paths;
  27 import java.io.PrintWriter;
  28 import java.util.Arrays;
  29 import java.util.ArrayList;
  30 import java.util.Collection;
  31 import java.util.Collections;
  32 import java.util.LinkedHashMap;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.Optional;

  36 import java.util.logging.Logger;
  37 import java.util.stream.Collectors;
  38 import jdk.internal.clang.Cursor;
  39 import jdk.internal.clang.CursorKind;
  40 import jdk.internal.clang.Diagnostic;
  41 import jdk.internal.clang.Index;
  42 import jdk.internal.clang.LibClang;
  43 import jdk.internal.clang.SourceLocation;
  44 import jdk.internal.clang.SourceRange;
  45 import jdk.internal.clang.TranslationUnit;
  46 import com.sun.tools.jextract.tree.HeaderTree;
  47 import com.sun.tools.jextract.tree.MacroTree;
  48 import com.sun.tools.jextract.tree.SimpleTreeVisitor;
  49 import com.sun.tools.jextract.tree.Tree;
  50 import com.sun.tools.jextract.tree.TreeMaker;
  51 import com.sun.tools.jextract.tree.TreePrinter;
  52 
  53 public class Parser {
  54     private final PrintWriter out;
  55     private final PrintWriter err;
  56     private final TreeMaker treeMaker;
  57     private final boolean supportMacros;
  58     private final Logger logger = Logger.getLogger(getClass().getPackage().getName());
  59 
  60     public Parser(PrintWriter out, PrintWriter err, boolean supportMacros) {
  61         this.out = out;
  62         this.err = err;
  63         this.treeMaker = new TreeMaker();
  64         this.supportMacros = supportMacros;
  65     }
  66 
  67     public Parser(boolean supportMacros) {
  68         this(new PrintWriter(System.out, true),
  69             new PrintWriter(System.err, true), supportMacros);
  70     }
  71 
  72     public List<HeaderTree> parse(Collection<Path> paths, Collection<String> args) {
  73         final List<HeaderTree> headers = new ArrayList<>();
  74         final Index index = LibClang.createIndex();
  75         for (Path path : paths) {
  76             logger.info(() -> {
  77                 StringBuilder sb = new StringBuilder(
  78                         "Parsing header file " + path + " with following args:\n");
  79                 int i = 0;
  80                 for (String arg : args) {
  81                     sb.append("arg[");
  82                     sb.append(i++);
  83                     sb.append("] = ");
  84                     sb.append(arg);
  85                     sb.append("\n");
  86                 }
  87                 return sb.toString();
  88             });
  89 
  90             Cursor tuCursor = index.parse(path.toString(),
  91                 d -> {
  92                     err.println(d);
  93                     if (d.severity() >  Diagnostic.CXDiagnostic_Warning) {
  94                         throw new RuntimeException(d.toString());
  95                     }
  96                 },
  97                 supportMacros, args.toArray(new String[0]));
  98 
  99             MacroParser macroParser = new MacroParser();
 100             List<Tree> decls = new ArrayList<>();
 101             tuCursor.children().

 102                 peek(c -> logger.finest(
 103                     () -> "Cursor: " + c.spelling() + "@" + c.USR() + "?" + c.isDeclaration())).
 104                 forEach(c -> {
 105                     SourceLocation loc = c.getSourceLocation();
 106                     if (loc == null) {
 107                         logger.info(() -> "Ignore Cursor " + c.spelling() + "@" + c.USR() + " has no SourceLocation");
 108                         return;
 109                     }
 110 
 111                     SourceLocation.Location src = loc.getFileLocation();
 112                     if (src == null) {
 113                         logger.info(() -> "Cursor " + c.spelling() + "@" + c.USR() + " has no FileLocation");
 114                         return;
 115                     }
 116 
 117                     logger.fine(() -> "Do cursor: " + c.spelling() + "@" + c.USR());
 118 
 119                     if (c.isDeclaration()) {
 120                         if (c.kind() == CursorKind.UnexposedDecl ||
 121                             c.kind() == CursorKind.Namespace) {


 167         SourceRange range = cursor.getExtent();
 168         String[] tokens = tu.tokens(range);
 169 
 170         macroParser.parse(cursor, tokens);
 171     }
 172 
 173     private boolean isMacro(Cursor c) {
 174         return c.isPreprocessing() && c.kind() == CursorKind.MacroDefinition;
 175     }
 176 
 177     public static void main(String[] args) {
 178         if (args.length == 0) {
 179             System.err.println("Expected a header file");
 180             return;
 181         }
 182 
 183         Parser p = new Parser(true);
 184         List<Path> paths = Arrays.stream(args).map(Paths::get).collect(Collectors.toList());
 185         Path builtinInc = Paths.get(System.getProperty("java.home"), "conf", "jextract");
 186         List<String> clangArgs = List.of("-I" + builtinInc);
 187         List<HeaderTree> headers = p.parse(paths, clangArgs);
 188         TreePrinter printer = new TreePrinter();
 189         for (HeaderTree ht : headers) {
 190             ht.accept(printer, null);
 191         }
 192     }
 193 }
< prev index next >