diff --git a/src/main/java/xyz/naofal/jtags/Jtags.java b/src/main/java/xyz/naofal/jtags/Jtags.java index b54a479..5ad4612 100644 --- a/src/main/java/xyz/naofal/jtags/Jtags.java +++ b/src/main/java/xyz/naofal/jtags/Jtags.java @@ -3,7 +3,6 @@ package xyz.naofal.jtags; import static xyz.naofal.jtags.JtagsLogger.logger; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -12,8 +11,11 @@ import java.util.List; public class Jtags { static class Options { List sources = new ArrayList<>(); + Path output = Path.of("tags"); boolean absolutePaths = false; - Path output = Paths.get("tags"); + boolean excludeNonPublic = false; + boolean excludeAnonymous = false; + boolean excludeStaticField = false; } public static void main(String[] args) { @@ -38,6 +40,29 @@ public class Jtags { options.absolutePaths = true; break; + case "-no-static": + logger.config("Excluding 'file:' field in tags"); + options.excludeStaticField = true; + break; + + case "-no-non-public": + logger.config("Excluding non-public elements"); + options.excludeNonPublic = true; + break; + + case "-no-anonymous": + logger.config("Excluding anonymous classes"); + options.excludeAnonymous = true; + break; + + case "-lib": + logger.config("Third-party library mode"); + options.absolutePaths = true; + options.excludeStaticField = true; + options.excludeNonPublic = true; + options.excludeAnonymous = true; + break; + case "-o", "-output": options.output = switch (arguments.poll()) { @@ -47,7 +72,7 @@ public class Jtags { System.exit(1); yield null; } - case String output -> Paths.get(output); + case String output -> Path.of(output); }; logger.config("Writing tags to " + options.output.toString()); break; @@ -73,8 +98,13 @@ public class Jtags { """ Usage: jtags [options] Options: - -absolute Use absolute paths for tag locations -o, -output Write tags to specified + -lib Treat sources as third-party libraries + (alias for -absolute -no-non-public -no-anonymous) + -absolute Use absolute paths for tag locations + -no-static Exclude the "file:" field from tags + -no-anonymous Exclude anonymous classes + -no-anonymous Exclude anonymous classes -h, -help Show this message """); } diff --git a/src/main/java/xyz/naofal/jtags/Tag.java b/src/main/java/xyz/naofal/jtags/Tag.java index b0211dd..a381f7f 100644 --- a/src/main/java/xyz/naofal/jtags/Tag.java +++ b/src/main/java/xyz/naofal/jtags/Tag.java @@ -1,6 +1,7 @@ package xyz.naofal.jtags; import java.nio.file.Path; +import java.util.Comparator; public record Tag(TagKind kind, String name, Path location, String line, boolean isStatic) implements Comparable { @@ -11,6 +12,9 @@ public record Tag(TagKind kind, String name, Path location, String line, boolean @Override public int compareTo(Tag o) { - return String.CASE_INSENSITIVE_ORDER.compare(name, o.name()); + return Comparator.comparing(Tag::name, String.CASE_INSENSITIVE_ORDER) + .thenComparing(Tag::location) + .thenComparing(Tag::kind) + .compare(this, o); } } diff --git a/src/main/java/xyz/naofal/jtags/TagCollector.java b/src/main/java/xyz/naofal/jtags/TagCollector.java index 03d017b..5825850 100644 --- a/src/main/java/xyz/naofal/jtags/TagCollector.java +++ b/src/main/java/xyz/naofal/jtags/TagCollector.java @@ -27,7 +27,7 @@ public class TagCollector { (JavacTask) compiler.getTask(null, fileManager, null, null, null, compilationUnits); Iterable trees = task.parse(); TreeVisitorContext context = new TreeVisitorContext(Trees.instance(task)); - TreeVisitor treeVisitor = new TreeVisitor(); + TreeVisitor treeVisitor = new TreeVisitor(options); for (CompilationUnitTree compilationUnitTree : trees) { treeVisitor.scan(compilationUnitTree, context); } diff --git a/src/main/java/xyz/naofal/jtags/TagsWriter.java b/src/main/java/xyz/naofal/jtags/TagsWriter.java index 6e1076f..5e7763a 100644 --- a/src/main/java/xyz/naofal/jtags/TagsWriter.java +++ b/src/main/java/xyz/naofal/jtags/TagsWriter.java @@ -6,6 +6,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; +import java.nio.file.Path; import java.util.PriorityQueue; import xyz.naofal.jtags.Jtags.Options; @@ -42,8 +43,8 @@ public record TagsWriter(Options options) { writer.write('\t'); writer.write( options().absolutePaths - ? tag.location().toAbsolutePath().toString() - : tag.location().toString()); + ? tag.location().toString() + : Path.of(".").toAbsolutePath().relativize(tag.location()).toString()); writer.write("\t/^"); writer.write(tag.line().substring(0, Math.min(tag.line().length(), MAX_PATTERN_LENGTH))); writer.write("$/;\"\t"); @@ -59,7 +60,7 @@ public record TagsWriter(Options options) { case ENUM_CONSTANT -> 'e'; case METHOD -> 'm'; }); - if (tag.isStatic()) { + if (!options().excludeStaticField && tag.isStatic()) { writer.write("\tfile:"); } diff --git a/src/main/java/xyz/naofal/jtags/TreeVisitor.java b/src/main/java/xyz/naofal/jtags/TreeVisitor.java index d9fd05d..fbb43a2 100644 --- a/src/main/java/xyz/naofal/jtags/TreeVisitor.java +++ b/src/main/java/xyz/naofal/jtags/TreeVisitor.java @@ -12,17 +12,23 @@ import com.sun.source.util.TreePathScanner; import java.util.List; import java.util.PriorityQueue; import javax.lang.model.element.Modifier; +import xyz.naofal.jtags.Jtags.Options; public class TreeVisitor extends TreePathScanner { + public final Options options; public final PriorityQueue tags = new PriorityQueue<>(); + public TreeVisitor(Options options) { + this.options = options; + } + @Override public Void visitCompilationUnit(CompilationUnitTree node, TreeVisitorContext p) { p.compilationUnitTree = node; logger.fine(() -> "Collecting tags in file: " + p.getLocation()); - return super.visitCompilationUnit(node, p); + return scan(node.getTypeDecls(), p); } @Override @@ -40,6 +46,17 @@ public class TreeVisitor extends TreePathScanner { @Override public Void visitClass(ClassTree node, TreeVisitorContext p) { + if (options.excludeAnonymous && node.getSimpleName().isEmpty()) { + return null; + } + if (options.excludeNonPublic && !node.getModifiers().getFlags().contains(Modifier.PUBLIC)) { + return null; + } + + if (node.getSimpleName().isEmpty()) { + return scan(node.getMembers(), p); + } + Tag tag = new Tag( switch (node.getKind()) { @@ -62,11 +79,15 @@ public class TreeVisitor extends TreePathScanner { tags.add(tag); - return super.visitClass(node, p); + return scan(node.getMembers(), p); } @Override public Void visitMethod(MethodTree node, TreeVisitorContext p) { + if (options.excludeNonPublic && !node.getModifiers().getFlags().contains(Modifier.PUBLIC)) { + return null; + } + Tag tag = new Tag( switch (node.getKind()) { @@ -89,15 +110,19 @@ public class TreeVisitor extends TreePathScanner { tags.add(tag); - return super.visitMethod(node, p); + return scan(node.getBody(), p); } @Override public Void visitVariable(VariableTree node, TreeVisitorContext p) { + if (options.excludeNonPublic && !node.getModifiers().getFlags().contains(Modifier.PUBLIC)) { + return null; + } + Tree parent = getCurrentPath().getParentPath().getLeaf(); if (!(parent instanceof ClassTree enclosingType)) { - return null; + return scan(node.getInitializer(), p); } Tag tag = @@ -117,6 +142,6 @@ public class TreeVisitor extends TreePathScanner { tags.add(tag); - return null; + return scan(node.getInitializer(), p); } } diff --git a/src/main/java/xyz/naofal/jtags/TreeVisitorContext.java b/src/main/java/xyz/naofal/jtags/TreeVisitorContext.java index 89f329b..b4ef522 100644 --- a/src/main/java/xyz/naofal/jtags/TreeVisitorContext.java +++ b/src/main/java/xyz/naofal/jtags/TreeVisitorContext.java @@ -11,7 +11,6 @@ import com.sun.source.util.SourcePositions; import com.sun.source.util.Trees; import java.io.BufferedReader; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Optional; public class TreeVisitorContext { @@ -26,9 +25,7 @@ public class TreeVisitorContext { public Path getLocation() { assert compilationUnitTree != null; - return Paths.get(".") - .toAbsolutePath() - .relativize(Paths.get(compilationUnitTree.getSourceFile().toUri()).toAbsolutePath()); + return Path.of(compilationUnitTree.getSourceFile().toUri()).toAbsolutePath(); } public String getLine(Tree node) { diff --git a/src/main/java/xyz/naofal/jtags/example/Example.java b/src/main/java/xyz/naofal/jtags/example/Example.java index 78a4390..3aefb39 100644 --- a/src/main/java/xyz/naofal/jtags/example/Example.java +++ b/src/main/java/xyz/naofal/jtags/example/Example.java @@ -12,10 +12,18 @@ public class Example { String string3, String string4, String string5, - String string6) {} + String string6) { - enum T { - A; - int a; + Object o = + new Object() { + void f() {} + ; + }; + + class T { + void f() {} + + private void fp() {} + } } }