Write to tags file

This commit is contained in:
naofal.helal
2025-03-25 11:39:37 +03:00
parent c3c4a1fbcb
commit a1e9e261f9
6 changed files with 194 additions and 9 deletions

View File

@@ -1,5 +1,9 @@
package xyz.naofal.jtags;
import static xyz.naofal.jtags.JtagsLogger.logger;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayDeque;
import java.util.Arrays;
@@ -23,7 +27,16 @@ public class Jtags {
}
static boolean run(Options options) {
return TagCollector.run(options);
var tags = TagCollector.collectTags(options);
try {
TagsWriter.writeTagsFile(tags, new FileOutputStream("tags"));
} catch (FileNotFoundException ex) {
logger.severe(ex.toString());
return false;
}
return true;
}
static void printUsage() {

View File

@@ -1,8 +1,12 @@
package xyz.naofal.jtags;
public record Tag(TagKind kind, String name, String location, String line)
public record Tag(TagKind kind, String name, String location, String line, boolean isStatic)
implements Comparable<Tag> {
public Tag(TagKind kind, String name, String location, String line) {
this(kind, name, location, line, false);
}
@Override
public int compareTo(Tag o) {
return String.CASE_INSENSITIVE_ORDER.compare(name, o.name());

View File

@@ -6,6 +6,7 @@ import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.Trees;
import java.io.IOException;
import java.util.PriorityQueue;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
@@ -16,7 +17,7 @@ public class TagCollector {
static JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
public static boolean run(Options options) {
public static PriorityQueue<Tag> collectTags(Options options) {
try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {
Iterable<? extends JavaFileObject> compilationUnits =
@@ -30,11 +31,12 @@ public class TagCollector {
for (CompilationUnitTree compilationUnitTree : trees) {
treeVisitor.scan(compilationUnitTree, context);
}
return treeVisitor.tags;
} catch (IOException ex) {
logger.severe(ex.toString());
System.exit(1);
return null;
}
return true;
}
}

View File

@@ -0,0 +1,59 @@
package xyz.naofal.jtags;
import static xyz.naofal.jtags.JtagsLogger.logger;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.PriorityQueue;
public class TagsWriter {
private static final int MAX_PATTERN_LENGTH = 96;
public static void writeTagsFile(PriorityQueue<Tag> tags, OutputStream outputStream) {
var writer = new OutputStreamWriter(outputStream);
try {
writer.write(
"""
!_TAG_FILE_ENCODING\tutf-8\t
!_TAG_FILE_SORTED\t2\t/0=unsorted, 1=sorted, 2=foldcase/
""");
Tag tag;
while ((tag = tags.poll()) != null) {
writeTag(writer, tag);
}
writer.flush();
} catch (IOException ex) {
logger.severe(ex.toString());
}
}
private static void writeTag(Writer writer, Tag tag) throws IOException {
writer.write(tag.name());
writer.write('\t');
writer.write(tag.location());
writer.write("\t/^");
writer.write(tag.line().substring(0, Math.min(tag.line().length(), MAX_PATTERN_LENGTH)));
writer.write("$/;\"\t");
writer.write(
switch (tag.kind()) {
case PACKAGE -> 'P';
case CLASS -> 'C';
case RECORD -> 'R';
case INTERFACE -> 'I';
case ANNOTATION -> 'A';
case ENUM -> 'E';
case FIELD -> 'f';
case ENUM_CONSTANT -> 'e';
case METHOD -> 'm';
});
if (tag.isStatic()) {
writer.write("\tfile:");
}
writer.write('\n');
}
}

View File

@@ -14,7 +14,7 @@ import java.util.PriorityQueue;
import javax.lang.model.element.Modifier;
public class TreeVisitor extends TreePathScanner<Void, TreeVisitorContext> {
public PriorityQueue<Tag> tags = new PriorityQueue<>();
public final PriorityQueue<Tag> tags = new PriorityQueue<>();
@Override
public Void visitCompilationUnit(CompilationUnitTree node, TreeVisitorContext p) {
@@ -55,7 +55,8 @@ public class TreeVisitor extends TreePathScanner<Void, TreeVisitorContext> {
},
node.getSimpleName().toString(),
p.getLocation(),
p.getLine(node));
p.getLine(node),
node.getModifiers().getFlags().contains(Modifier.STATIC));
logger.finer(() -> "Type: " + tag);
@@ -66,7 +67,19 @@ public class TreeVisitor extends TreePathScanner<Void, TreeVisitorContext> {
@Override
public Void visitMethod(MethodTree node, TreeVisitorContext p) {
Tag tag = new Tag(TagKind.METHOD, node.getName().toString(), p.getLocation(), p.getLine(node));
Tag tag =
new Tag(
switch (node.getKind()) {
case METHOD -> TagKind.METHOD;
default -> {
logger.warning("Unknown method kind " + node.getKind());
yield TagKind.METHOD;
}
},
node.getName().toString(),
p.getLocation(),
p.getLine(node),
node.getModifiers().getFlags().contains(Modifier.STATIC));
logger.finer(() -> "Method: " + tag);
tags.add(tag);
@@ -91,7 +104,8 @@ public class TreeVisitor extends TreePathScanner<Void, TreeVisitorContext> {
: TagKind.FIELD,
node.getName().toString(),
p.getLocation(),
p.getLine(node));
p.getLine(node),
node.getModifiers().getFlags().contains(Modifier.STATIC));
logger.finer(() -> "Variable: " + tag);
tags.add(tag);

93
ttt Normal file
View File

@@ -0,0 +1,93 @@
!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/
!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/
!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/
!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/
!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/
!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/
!_TAG_FIELD_DESCRIPTION input /input file/
!_TAG_FIELD_DESCRIPTION name /tag name/
!_TAG_FIELD_DESCRIPTION pattern /pattern/
!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_KIND_DESCRIPTION!Java a,annotation /annotation declarations/
!_TAG_KIND_DESCRIPTION!Java c,class /classes/
!_TAG_KIND_DESCRIPTION!Java e,enumConstant /enum constants/
!_TAG_KIND_DESCRIPTION!Java f,field /fields/
!_TAG_KIND_DESCRIPTION!Java g,enum /enum types/
!_TAG_KIND_DESCRIPTION!Java i,interface /interfaces/
!_TAG_KIND_DESCRIPTION!Java m,method /methods/
!_TAG_KIND_DESCRIPTION!Java p,package /packages/
!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/
!_TAG_OUTPUT_FILESEP slash /slash or backslash/
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
!_TAG_OUTPUT_VERSION 0.0 /current.age/
!_TAG_PARSER_VERSION!Java 0.0 /current.age/
!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
!_TAG_PROC_CWD /home/noon/code/java/jtags/ //
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
!_TAG_PROGRAM_VERSION 6.1.0 /v6.1.0/
!_TAG_ROLE_DESCRIPTION!Java!package imported /imported package/
A src/main/java/xyz/naofal/jtags/example/Example.java /^ A;$/;" e enum:Example.T file:
ANNOTATION src/main/java/xyz/naofal/jtags/TagKind.java /^ ANNOTATION,$/;" e enum:TagKind file:
CLASS src/main/java/xyz/naofal/jtags/TagKind.java /^ CLASS,$/;" e enum:TagKind file:
ENUM src/main/java/xyz/naofal/jtags/TagKind.java /^ ENUM,$/;" e enum:TagKind file:
ENUM_CONSTANT src/main/java/xyz/naofal/jtags/TagKind.java /^ ENUM_CONSTANT,$/;" e enum:TagKind file:
Example src/main/java/xyz/naofal/jtags/example/Example.java /^public class Example {$/;" c
FIELD src/main/java/xyz/naofal/jtags/TagKind.java /^ FIELD,$/;" e enum:TagKind file:
INTERFACE src/main/java/xyz/naofal/jtags/TagKind.java /^ INTERFACE,$/;" e enum:TagKind file:
Jtags src/main/java/xyz/naofal/jtags/Jtags.java /^public class Jtags {$/;" c
JtagsLogger src/main/java/xyz/naofal/jtags/JtagsLogger.java /^public class JtagsLogger {$/;" c
LogHandler src/main/java/xyz/naofal/jtags/JtagsLogger.java /^ public static class LogHandler extends Handler {$/;" c class:JtagsLogger
METHOD src/main/java/xyz/naofal/jtags/TagKind.java /^ METHOD;$/;" e enum:TagKind file:
Options src/main/java/xyz/naofal/jtags/Jtags.java /^ static class Options {$/;" c class:Jtags
PACKAGE src/main/java/xyz/naofal/jtags/TagKind.java /^ PACKAGE,$/;" e enum:TagKind file:
RECORD src/main/java/xyz/naofal/jtags/TagKind.java /^ RECORD,$/;" e enum:TagKind file:
T src/main/java/xyz/naofal/jtags/example/Example.java /^ enum T {$/;" g class:Example
T src/main/java/xyz/naofal/jtags/example/Example.java /^@interface T {$/;" a
TagCollector src/main/java/xyz/naofal/jtags/TagCollector.java /^public class TagCollector {$/;" c
TagKind src/main/java/xyz/naofal/jtags/TagKind.java /^public enum TagKind {$/;" g
TagsWriter src/main/java/xyz/naofal/jtags/TagsWriter.java /^public class TagsWriter {$/;" c
TreeVisitor src/main/java/xyz/naofal/jtags/TreeVisitor.java /^public class TreeVisitor extends TreePathScanner<Void, TreeVisitorContext> {$/;" c
TreeVisitorContext src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^ public TreeVisitorContext(Trees trees) {$/;" m class:TreeVisitorContext
TreeVisitorContext src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^public class TreeVisitorContext {$/;" c
a src/main/java/xyz/naofal/jtags/example/Example.java /^ int a;$/;" f class:Example.T
close src/main/java/xyz/naofal/jtags/JtagsLogger.java /^ public void close() {$/;" m class:JtagsLogger.LogHandler
collectTags src/main/java/xyz/naofal/jtags/TagCollector.java /^ public static PriorityQueue<Tag> collectTags(Options options) {$/;" m class:TagCollector
colors src/main/java/xyz/naofal/jtags/JtagsLogger.java /^ public static Map<Level, Integer> colors =$/;" f class:JtagsLogger.LogHandler
compilationUnitTree src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^ public CompilationUnitTree compilationUnitTree;$/;" f class:TreeVisitorContext
compiler src/main/java/xyz/naofal/jtags/TagCollector.java /^ static JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();$/;" f class:TagCollector
flush src/main/java/xyz/naofal/jtags/JtagsLogger.java /^ public void flush() {$/;" m class:JtagsLogger.LogHandler
getLine src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^ public String getLine(Tree node) {$/;" m class:TreeVisitorContext
getLocation src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^ public String getLocation() {$/;" m class:TreeVisitorContext
getOffsetInSource src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^ private long getOffsetInSource(CompilationUnitTree compilationUnitTree, Tree node) {$/;" m class:TreeVisitorContext file:
logger src/main/java/xyz/naofal/jtags/JtagsLogger.java /^ public static Logger logger = Logger.getLogger("logger");$/;" f class:JtagsLogger
loggingHandler src/main/java/xyz/naofal/jtags/JtagsLogger.java /^ public static Handler loggingHandler = new LogHandler();$/;" f class:JtagsLogger
lorem src/main/java/xyz/naofal/jtags/example/Example.java /^ public static void lorem($/;" m class:Example
main src/main/java/xyz/naofal/jtags/Jtags.java /^ public static void main(String[] args) {$/;" m class:Jtags
printUsage src/main/java/xyz/naofal/jtags/Jtags.java /^ static void printUsage() {$/;" m class:Jtags
publish src/main/java/xyz/naofal/jtags/JtagsLogger.java /^ public void publish(LogRecord record) {$/;" m class:JtagsLogger.LogHandler
run src/main/java/xyz/naofal/jtags/Jtags.java /^ static boolean run(Options options) {$/;" m class:Jtags
sourcePositions src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^ final SourcePositions sourcePositions;$/;" f class:TreeVisitorContext
sources src/main/java/xyz/naofal/jtags/Jtags.java /^ String[] sources;$/;" f class:Jtags.Options
t src/main/java/xyz/naofal/jtags/example/Example.java /^ static int t = 1;$/;" f annotation:T
tags src/main/java/xyz/naofal/jtags/TreeVisitor.java /^ public final PriorityQueue<Tag> tags = new PriorityQueue<>();$/;" f class:TreeVisitor
trees src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^ final Trees trees;$/;" f class:TreeVisitorContext
visitClass src/main/java/xyz/naofal/jtags/TreeVisitor.java /^ public Void visitClass(ClassTree node, TreeVisitorContext p) {$/;" m class:TreeVisitor
visitCompilationUnit src/main/java/xyz/naofal/jtags/TreeVisitor.java /^ public Void visitCompilationUnit(CompilationUnitTree node, TreeVisitorContext p) {$/;" m class:TreeVisitor
visitMethod src/main/java/xyz/naofal/jtags/TreeVisitor.java /^ public Void visitMethod(MethodTree node, TreeVisitorContext p) {$/;" m class:TreeVisitor
visitPackage src/main/java/xyz/naofal/jtags/TreeVisitor.java /^ public Void visitPackage(PackageTree node, TreeVisitorContext p) {$/;" m class:TreeVisitor
visitVariable src/main/java/xyz/naofal/jtags/TreeVisitor.java /^ public Void visitVariable(VariableTree node, TreeVisitorContext p) {$/;" m class:TreeVisitor
writeTag src/main/java/xyz/naofal/jtags/TagsWriter.java /^ private static void writeTag(Writer writer, Tag tag) throws IOException {$/;" m class:TagsWriter file:
writeTagsFile src/main/java/xyz/naofal/jtags/TagsWriter.java /^ public static void writeTagsFile(PriorityQueue<Tag> tags, OutputStream outputStream) {$/;" m class:TagsWriter
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/Jtags.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/JtagsLogger.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/Tag.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/TagCollector.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/TagKind.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/TagsWriter.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/TreeVisitor.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags src/main/java/xyz/naofal/jtags/TreeVisitorContext.java /^package xyz.naofal.jtags;$/;" p
xyz.naofal.jtags.example src/main/java/xyz/naofal/jtags/example/Example.java /^package xyz.naofal.jtags.example;$/;" p