Ver código fonte

Merge pull request #103 from jplag/java-9-rework

Improve code quality of Java 9+ frontend
Timur Sağlam 5 anos atrás
pai
commit
ba57b2b8ce

+ 0 - 2
README.md

@@ -4,8 +4,6 @@
 [![Latest Release](https://img.shields.io/github/release/jplag/jplag.svg)](https://github.com/jplag/jplag/releases/latest)
 [![License](https://img.shields.io/github/license/jplag/jplag.svg)](https://github.com/jplag/jplag/blob/master/LICENSE)
 
-This fork focuses on the development of a new Java API for JPlag.
-
 ## Download and Installation
 
 ### Building from sources 

+ 171 - 165
jplag.frontend.java-1.9/src/main/java/jplag/java19/JavaToken.java

@@ -1,180 +1,186 @@
 package jplag.java19;
 
 public class JavaToken extends jplag.Token implements JavaTokenConstants {
-	private static final long serialVersionUID = -383581430479870696L;
-	private int line, column, length;
+    private static final long serialVersionUID = -383581430479870696L;
+    private int line, column, length;
 
-	public JavaToken(int type, String file, int col,int line,int length) {
-		super(type, file, col,line,length);
-	}
+    public JavaToken(int type, String file, int col, int line, int length) {
+        super(type, file, col, line, length);
+    }
 
-	public int getLine() {
-		return line;
-	}
+    @Override
+    public int getLine() {
+        return line;
+    }
 
-	public int getColumn() {
-		return column;
-	}
+    @Override
+    public int getColumn() {
+        return column;
+    }
 
-	public int getLength() {
-		return length;
-	}
+    @Override
+    public int getLength() {
+        return length;
+    }
 
-	public void setLine(int line) {
-		this.line = line;
-	}
+    @Override
+    public void setLine(int line) {
+        this.line = line;
+    }
 
-	public void setColumn(int column) {
-		this.column = column;
-	}
+    @Override
+    public void setColumn(int column) {
+        this.column = column;
+    }
 
-	public void setLength(int length) {
-		this.length = length;
-	}
+    @Override
+    public void setLength(int length) {
+        this.length = length;
+    }
 
-	public static String type2string(int type) {
-		switch (type) {
-		case JavaTokenConstants.FILE_END:
-			return "********";
-		case JavaTokenConstants.SEPARATOR_TOKEN:
-			return "METHOD_SEPARATOR";
-		case J_PACKAGE:
-			return "PACKAGE ";
-		case J_IMPORT:
-			return "IMPORT  ";
-		case J_CLASS_BEGIN:
-			return "CLASS{  ";
-		case J_CLASS_END:
-			return "}CLASS  ";
-		case J_METHOD_BEGIN:
-			return "METHOD{ ";
-		case J_METHOD_END:
-			return "}METHOD ";
-		case J_VARDEF:
-			return "VARDEF  ";
-		case J_SYNC_BEGIN:
-			return "SYNC{   ";
-		case J_SYNC_END:
-			return "}SYNC   ";
-		case J_DO_BEGIN:
-			return "DO{     ";
-		case J_DO_END:
-			return "}DO     ";
-		case J_WHILE_BEGIN:
-			return "WHILE{  ";
-		case J_WHILE_END:
-			return "}WHILE  ";
-		case J_FOR_BEGIN:
-			return "FOR{    ";
-		case J_FOR_END:
-			return "}FOR    ";
-		case J_SWITCH_BEGIN:
-			return "SWITCH{ ";
-		case J_SWITCH_END:
-			return "}SWITCH ";
-		case J_CASE:
-			return "CASE    ";
-		case J_TRY_BEGIN:
-			return "TRY{    ";
-		case J_CATCH_BEGIN:
-			return "CATCH{  ";
-		case J_CATCH_END:
-			return "}CATCH  ";
-		case J_FINALLY:
-			return "FINALLY ";
-		case J_IF_BEGIN:
-			return "IF{     ";
-		case J_ELSE:
-			return "ELSE    ";
-		case J_IF_END:
-			return "}IF     ";
-		case J_COND:
-			return "COND    ";
-		case J_BREAK:
-			return "BREAK   ";
-		case J_CONTINUE:
-			return "CONTINUE";
-		case J_RETURN:
-			return "RETURN  ";
-		case J_THROW:
-			return "THROW   ";
-		case J_IN_CLASS_BEGIN:
-			return "INCLASS{";
-		case J_IN_CLASS_END:
-			return "}INCLASS";
-		case J_APPLY:
-			return "APPLY   ";
-		case J_NEWCLASS:
-			return "NEWCLASS";
-		case J_NEWARRAY:
-			return "NEWARRAY";
-		case J_ASSIGN:
-			return "ASSIGN  ";
-		case J_INTERFACE_BEGIN:
-			return "INTERF{ ";
-		case J_INTERFACE_END:
-			return "}INTERF ";
-		case J_CONSTR_BEGIN:
-			return "CONSTR{ ";
-		case J_CONSTR_END:
-			return "}CONSTR ";
-		case J_INIT_BEGIN:
-			return "INIT{   ";
-		case J_INIT_END:
-			return "}INIT   ";
-		case J_VOID:
-			return "VOID    ";
-		case J_ARRAY_INIT_BEGIN:
-			return "ARRINIT{";
-		case J_ARRAY_INIT_END:
-			return "ARRINIT}";
-		case J_ENUM_BEGIN:
-			return "ENUM{   ";
-		case J_ENUM_CLASS_BEGIN:
-			return "ENUM_CLA";
-		case J_ENUM_END:
-			return "}ENUM   ";
-		case J_GENERIC:
-			return "GENERIC ";
-		case J_ASSERT:
-			return "ASSERT  ";
-		case J_ANNO:
-			return "ANNO    ";
-		case J_ANNO_MARKER:
-			return "ANNOMARK";
-		case J_ANNO_M_BEGIN:
-			return "ANNO_M{ ";
-		case J_ANNO_M_END:
-			return "}ANNO_M ";
-		case J_ANNO_T_BEGIN:
-			return "ANNO_T{ ";
-		case J_ANNO_T_END:
-			return "}ANNO_T ";
-		case J_ANNO_C_BEGIN:
-			return "ANNO_C{ ";
-		case J_ANNO_C_END:
-			return "}ANNO_C ";
-		case J_MODULE_BEGIN:
-			return "MODULE{ ";
-		case J_MODULE_END:
-			return "}MODULE ";
-		case J_EXPORTS:
-			return "EXPORTS ";
-		case J_PROVIDES:
-			return "PROVIDES";
-		case J_REQUIRES:
-			return "REQUIRES";
+    public static String type2string(int type) {
+        switch (type) {
+        case JavaTokenConstants.FILE_END:
+            return "********";
+        case JavaTokenConstants.SEPARATOR_TOKEN:
+            return "METHOD_SEPARATOR";
+        case J_PACKAGE:
+            return "PACKAGE ";
+        case J_IMPORT:
+            return "IMPORT  ";
+        case J_CLASS_BEGIN:
+            return "CLASS{  ";
+        case J_CLASS_END:
+            return "}CLASS  ";
+        case J_METHOD_BEGIN:
+            return "METHOD{ ";
+        case J_METHOD_END:
+            return "}METHOD ";
+        case J_VARDEF:
+            return "VARDEF  ";
+        case J_SYNC_BEGIN:
+            return "SYNC{   ";
+        case J_SYNC_END:
+            return "}SYNC   ";
+        case J_DO_BEGIN:
+            return "DO{     ";
+        case J_DO_END:
+            return "}DO     ";
+        case J_WHILE_BEGIN:
+            return "WHILE{  ";
+        case J_WHILE_END:
+            return "}WHILE  ";
+        case J_FOR_BEGIN:
+            return "FOR{    ";
+        case J_FOR_END:
+            return "}FOR    ";
+        case J_SWITCH_BEGIN:
+            return "SWITCH{ ";
+        case J_SWITCH_END:
+            return "}SWITCH ";
+        case J_CASE:
+            return "CASE    ";
+        case J_TRY_BEGIN:
+            return "TRY{    ";
+        case J_CATCH_BEGIN:
+            return "CATCH{  ";
+        case J_CATCH_END:
+            return "}CATCH  ";
+        case J_FINALLY:
+            return "FINALLY ";
+        case J_IF_BEGIN:
+            return "IF{     ";
+        case J_ELSE:
+            return "ELSE    ";
+        case J_IF_END:
+            return "}IF     ";
+        case J_COND:
+            return "COND    ";
+        case J_BREAK:
+            return "BREAK   ";
+        case J_CONTINUE:
+            return "CONTINUE";
+        case J_RETURN:
+            return "RETURN  ";
+        case J_THROW:
+            return "THROW   ";
+        case J_IN_CLASS_BEGIN:
+            return "INCLASS{";
+        case J_IN_CLASS_END:
+            return "}INCLASS";
+        case J_APPLY:
+            return "APPLY   ";
+        case J_NEWCLASS:
+            return "NEWCLASS";
+        case J_NEWARRAY:
+            return "NEWARRAY";
+        case J_ASSIGN:
+            return "ASSIGN  ";
+        case J_INTERFACE_BEGIN:
+            return "INTERF{ ";
+        case J_INTERFACE_END:
+            return "}INTERF ";
+        case J_CONSTR_BEGIN:
+            return "CONSTR{ ";
+        case J_CONSTR_END:
+            return "}CONSTR ";
+        case J_INIT_BEGIN:
+            return "INIT{   ";
+        case J_INIT_END:
+            return "}INIT   ";
+        case J_VOID:
+            return "VOID    ";
+        case J_ARRAY_INIT_BEGIN:
+            return "ARRINIT{";
+        case J_ARRAY_INIT_END:
+            return "ARRINIT}";
+        case J_ENUM_BEGIN:
+            return "ENUM{   ";
+        case J_ENUM_CLASS_BEGIN:
+            return "ENUM_CLA";
+        case J_ENUM_END:
+            return "}ENUM   ";
+        case J_GENERIC:
+            return "GENERIC ";
+        case J_ASSERT:
+            return "ASSERT  ";
+        case J_ANNO:
+            return "ANNO    ";
+        case J_ANNO_MARKER:
+            return "ANNOMARK";
+        case J_ANNO_M_BEGIN:
+            return "ANNO_M{ ";
+        case J_ANNO_M_END:
+            return "}ANNO_M ";
+        case J_ANNO_T_BEGIN:
+            return "ANNO_T{ ";
+        case J_ANNO_T_END:
+            return "}ANNO_T ";
+        case J_ANNO_C_BEGIN:
+            return "ANNO_C{ ";
+        case J_ANNO_C_END:
+            return "}ANNO_C ";
+        case J_MODULE_BEGIN:
+            return "MODULE{ ";
+        case J_MODULE_END:
+            return "}MODULE ";
+        case J_EXPORTS:
+            return "EXPORTS ";
+        case J_PROVIDES:
+            return "PROVIDES";
+        case J_REQUIRES:
+            return "REQUIRES";
 
-		case J_TRY_WITH_RESOURCE:
-			return "TRY_RES ";
+        case J_TRY_WITH_RESOURCE:
+            return "TRY_RES ";
 
-		default:
-			System.err.println("*UNKNOWN: " + type);
-			return "*UNKNOWN" + type;
-		}
-	}
+        default:
+            System.err.println("*UNKNOWN: " + type);
+            return "*UNKNOWN" + type;
+        }
+    }
 
-	public static int numberOfTokens() {
-		return NUM_DIFF_TOKENS;
-	}
+    public static int numberOfTokens() {
+        return NUM_DIFF_TOKENS;
+    }
 }

+ 72 - 73
jplag.frontend.java-1.9/src/main/java/jplag/java19/JavaTokenConstants.java

@@ -1,83 +1,82 @@
 package jplag.java19;
 
 public interface JavaTokenConstants extends jplag.TokenConstants {
-	final static int FILE_END = 0;
+    final static int FILE_END = 0;
 
-	// check used to mark tokens that are actually generated by the adapter
-	final static int SEPARATOR_TOKEN = 1;// @formatter:off
+    // check used to mark tokens that are actually generated by the adapter
+    final static int SEPARATOR_TOKEN = 1;// @formatter:off
 
-	final static int J_PACKAGE = 2;				// check
-	final static int J_IMPORT = 3;				// check
-	final static int J_CLASS_BEGIN = 4;			// check
-	final static int J_CLASS_END = 5;			// check
-	final static int J_METHOD_BEGIN = 6;		// check
-	final static int J_METHOD_END = 7;			// check
-	final static int J_VARDEF = 8;				// check
-	final static int J_SYNC_BEGIN = 9;			// check
-	final static int J_SYNC_END = 10;			// check
-	final static int J_DO_BEGIN = 11;			// check
-	final static int J_DO_END = 12;				// check
-	final static int J_WHILE_BEGIN = 13;		// check
-	final static int J_WHILE_END = 14;			// check
-	final static int J_FOR_BEGIN = 15;			// check
-	final static int J_FOR_END = 16;			// check
-	final static int J_SWITCH_BEGIN = 17;		// check
-	final static int J_SWITCH_END = 18;			// check
-	final static int J_CASE = 19;				// check
-	final static int J_TRY_BEGIN = 20;			// check
-	final static int J_CATCH_BEGIN = 21;    	// check
-	final static int J_CATCH_END = 22;      	// check
-	final static int J_FINALLY = 23;			// check
-	final static int J_IF_BEGIN = 24;			// check
-	final static int J_ELSE = 25;				// check
-	final static int J_IF_END = 26;				// check
-	final static int J_COND = 27;				// check
-	final static int J_BREAK = 28;				// check
-	final static int J_CONTINUE = 29;			// check
-	final static int J_RETURN = 30;				// check
-	final static int J_THROW = 31;				// check
-	final static int J_IN_CLASS_BEGIN = 32;		//
-	final static int J_IN_CLASS_END = 33;		//
-	final static int J_APPLY = 34;				// check
-	final static int J_NEWCLASS = 35;			// check
-	final static int J_NEWARRAY = 36;			// check
-	final static int J_ASSIGN = 37;				// check
-	final static int J_INTERFACE_BEGIN = 38;	// check
-	final static int J_INTERFACE_END = 39;		// check
-	final static int J_CONSTR_BEGIN = 40;		// 
-	final static int J_CONSTR_END = 41;			//
-	final static int J_INIT_BEGIN = 42;			// check
-	final static int J_INIT_END = 43;			// check
-	final static int J_VOID = 44;				//
-	final static int J_ARRAY_INIT_BEGIN = 45;	// check
-	final static int J_ARRAY_INIT_END = 46; 	// check
+    final static int J_PACKAGE = 2;				// check
+    final static int J_IMPORT = 3;				// check
+    final static int J_CLASS_BEGIN = 4;			// check
+    final static int J_CLASS_END = 5;			// check
+    final static int J_METHOD_BEGIN = 6;		// check
+    final static int J_METHOD_END = 7;			// check
+    final static int J_VARDEF = 8;				// check
+    final static int J_SYNC_BEGIN = 9;			// check
+    final static int J_SYNC_END = 10;			// check
+    final static int J_DO_BEGIN = 11;			// check
+    final static int J_DO_END = 12;				// check
+    final static int J_WHILE_BEGIN = 13;		// check
+    final static int J_WHILE_END = 14;			// check
+    final static int J_FOR_BEGIN = 15;			// check
+    final static int J_FOR_END = 16;			// check
+    final static int J_SWITCH_BEGIN = 17;		// check
+    final static int J_SWITCH_END = 18;			// check
+    final static int J_CASE = 19;				// check
+    final static int J_TRY_BEGIN = 20;			// check
+    final static int J_CATCH_BEGIN = 21;    	// check
+    final static int J_CATCH_END = 22;      	// check
+    final static int J_FINALLY = 23;			// check
+    final static int J_IF_BEGIN = 24;			// check
+    final static int J_ELSE = 25;				// check
+    final static int J_IF_END = 26;				// check
+    final static int J_COND = 27;				// check
+    final static int J_BREAK = 28;				// check
+    final static int J_CONTINUE = 29;			// check
+    final static int J_RETURN = 30;				// check
+    final static int J_THROW = 31;				// check
+    final static int J_IN_CLASS_BEGIN = 32;		//
+    final static int J_IN_CLASS_END = 33;		//
+    final static int J_APPLY = 34;				// check
+    final static int J_NEWCLASS = 35;			// check
+    final static int J_NEWARRAY = 36;			// check
+    final static int J_ASSIGN = 37;				// check
+    final static int J_INTERFACE_BEGIN = 38;	// check
+    final static int J_INTERFACE_END = 39;		// check
+    final static int J_CONSTR_BEGIN = 40;		//
+    final static int J_CONSTR_END = 41;			//
+    final static int J_INIT_BEGIN = 42;			// check
+    final static int J_INIT_END = 43;			// check
+    final static int J_VOID = 44;				//
+    final static int J_ARRAY_INIT_BEGIN = 45;	// check
+    final static int J_ARRAY_INIT_END = 46; 	// check
 
-	// new in 1.5:
-	final static int J_ENUM_BEGIN = 47;			// check 
-	final static int J_ENUM_CLASS_BEGIN = 48;	// ?? doesn't exist in JAVAC
-	final static int J_ENUM_END = 49;			// check
-	final static int J_GENERIC = 50;			// check
-	final static int J_ASSERT = 51;				// check
+    // new in 1.5:
+    final static int J_ENUM_BEGIN = 47;			// check
+    final static int J_ENUM_CLASS_BEGIN = 48;	// ?? doesn't exist in JAVAC
+    final static int J_ENUM_END = 49;			// check
+    final static int J_GENERIC = 50;			// check
+    final static int J_ASSERT = 51;				// check
 
-	final static int J_ANNO = 52;				// check
-	final static int J_ANNO_MARKER = 53;		// ??
-	final static int J_ANNO_M_BEGIN = 54;		// ??
-	final static int J_ANNO_M_END = 55;			// ??
-	final static int J_ANNO_T_BEGIN = 56;		// check
-	final static int J_ANNO_T_END = 57;			// check
-	final static int J_ANNO_C_BEGIN = 58;		// ??
-	final static int J_ANNO_C_END = 59;			// ??
+    final static int J_ANNO = 52;				// check
+    final static int J_ANNO_MARKER = 53;		// ??
+    final static int J_ANNO_M_BEGIN = 54;		// ??
+    final static int J_ANNO_M_END = 55;			// ??
+    final static int J_ANNO_T_BEGIN = 56;		// check
+    final static int J_ANNO_T_END = 57;			// check
+    final static int J_ANNO_C_BEGIN = 58;		// ??
+    final static int J_ANNO_C_END = 59;			// ??
 
-	// new in 1.7
-	final static int J_TRY_WITH_RESOURCE = 60; 	// check
-	
-	// new in 1.9
-	final static int J_REQUIRES = 61; 	       // check
-	final static int J_PROVIDES = 62; 	       // check
-	final static int J_EXPORTS  = 63; 	       // check
-	final static int J_MODULE_BEGIN  = 64;     // check
-	final static int J_MODULE_END  = 65; 	       // check
-	
+    // new in 1.7
+    final static int J_TRY_WITH_RESOURCE = 60; 	// check
 
-	final static int NUM_DIFF_TOKENS = 66;		// @formatter:on
+    // new in 1.9
+    final static int J_REQUIRES = 61; 	       // check
+    final static int J_PROVIDES = 62; 	       // check
+    final static int J_EXPORTS = 63; 	       // check
+    final static int J_MODULE_BEGIN = 64;     // check
+    final static int J_MODULE_END = 65; 	       // check
+
+    final static int NUM_DIFF_TOKENS = 66;		// @formatter:on
 }

+ 32 - 336
jplag.frontend.java-1.9/src/main/java/jplag/java19/JavacAdapter.java

@@ -11,350 +11,46 @@ import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.ToolProvider;
 
-import com.sun.source.tree.AnnotationTree;
-import com.sun.source.tree.AssertTree;
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.BlockTree;
-import com.sun.source.tree.BreakTree;
-import com.sun.source.tree.CaseTree;
-import com.sun.source.tree.CatchTree;
-import com.sun.source.tree.ClassTree;
 import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ConditionalExpressionTree;
-import com.sun.source.tree.ContinueTree;
-import com.sun.source.tree.DoWhileLoopTree;
-import com.sun.source.tree.EnhancedForLoopTree;
-import com.sun.source.tree.ErroneousTree;
-import com.sun.source.tree.ExportsTree;
-import com.sun.source.tree.ForLoopTree;
-import com.sun.source.tree.IfTree;
-import com.sun.source.tree.ImportTree;
 import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.ModuleTree;
-import com.sun.source.tree.NewArrayTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.tree.PackageTree;
-import com.sun.source.tree.ProvidesTree;
-import com.sun.source.tree.RequiresTree;
-import com.sun.source.tree.ReturnTree;
-import com.sun.source.tree.SwitchTree;
-import com.sun.source.tree.SynchronizedTree;
-import com.sun.source.tree.ThrowTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.TryTree;
-import com.sun.source.tree.TypeParameterTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.tree.WhileLoopTree;
 import com.sun.source.util.JavacTask;
 import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreeScanner;
 import com.sun.source.util.Trees;
 
 public class JavacAdapter {
-	private static final JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
 
-	public int parseFiles(File dir,File[] pathedFiles, final Parser parser) {
-		final StandardJavaFileManager jfm = javac.getStandardFileManager(null, null, null);
-		DiagnosticCollector<? super JavaFileObject> diagListen = new DiagnosticCollector<>();
-		final JavaCompiler.CompilationTask task = javac.getTask(null, jfm, diagListen, null, null,
-				jfm.getJavaFileObjects(pathedFiles));
-		Iterable<? extends CompilationUnitTree> asts = null;
-		try {
-			asts = ((JavacTask) task).parse();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		final Trees trees = Trees.instance(task);
-		final SourcePositions positions = trees.getSourcePositions();
-		for (final CompilationUnitTree ast : asts) {
-			final String filename;
-			if (dir==null)
-				filename=ast.getSourceFile().getName();
-			else {
-				filename=Paths.get(dir.toURI()).relativize(Paths.get(ast.getSourceFile().toUri())).toString();
-			}
-			final LineMap map = ast.getLineMap();
-			ast.accept(new TreeScanner<Object,Object>() {
-				@Override
-				public Object visitBlock(BlockTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_INIT_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),1);
-					Object ret = super.visitBlock(node, p);
-					parser.add(JavaTokenConstants.J_INIT_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitClass(ClassTree node, Object p) {
-					boolean enu = false;
-					boolean interf = false;
-					boolean anno = false;
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
+    private static final JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
 
-					if (node.getKind()==Tree.Kind.ENUM)	enu=true;
-					if (node.getKind()==Tree.Kind.INTERFACE) interf=true;
-					if (node.getKind()==Tree.Kind.ANNOTATION_TYPE) anno = true;
-					if (enu)  parser.add(JavaTokenConstants.J_ENUM_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),4);
-					if (interf)  parser.add(JavaTokenConstants.J_INTERFACE_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),9);
-					if (anno)  parser.add(JavaTokenConstants.J_ANNO_T_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),10);
-					if (!enu && !interf && !anno) parser.add(JavaTokenConstants.J_CLASS_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),5);
-					Object ret=  super.visitClass(node, p);
-					if (!enu && !interf && !anno) parser.add(JavaTokenConstants.J_CLASS_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					if (anno)  parser.add(JavaTokenConstants.J_ANNO_T_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					if (enu)  parser.add(JavaTokenConstants.J_ENUM_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					if (interf)  parser.add(JavaTokenConstants.J_INTERFACE_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitImport(ImportTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_IMPORT,filename,map.getLineNumber(n),map.getColumnNumber(n),6);
-					return super.visitImport(node, p);
-				}
-				@Override
-				public Object visitPackage(PackageTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_PACKAGE,filename,map.getLineNumber(n),map.getColumnNumber(n),7);
-					return super.visitPackage(node, p);
-				}
-				@Override
-				public Object visitMethod(MethodTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_METHOD_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),node.getName().length());
-					Object ret = super.visitMethod(node, p);
-					parser.add(JavaTokenConstants.J_METHOD_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitSynchronized(SynchronizedTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_SYNC_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),12);
-					Object ret = super.visitSynchronized(node, p);
-					parser.add(JavaTokenConstants.J_SYNC_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitDoWhileLoop(DoWhileLoopTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_DO_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),2);
-					Object ret = super.visitDoWhileLoop(node, p);
-					parser.add(JavaTokenConstants.J_DO_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitWhileLoop(WhileLoopTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_WHILE_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),5);
-					Object ret = super.visitWhileLoop(node, p);
-					parser.add(JavaTokenConstants.J_WHILE_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitForLoop(ForLoopTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_FOR_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),3);
-					Object ret = super.visitForLoop(node, p);
-					parser.add(JavaTokenConstants.J_FOR_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);					
-					return ret;
-				}
-				@Override
-				public Object visitEnhancedForLoop(EnhancedForLoopTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_FOR_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),3);
-					Object ret = super.visitEnhancedForLoop(node, p);
-					parser.add(JavaTokenConstants.J_FOR_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);					
-					return ret;
-				}
-				@Override
-				public Object visitSwitch(SwitchTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_SWITCH_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),6);
-					Object ret = super.visitSwitch(node, p);
-					parser.add(JavaTokenConstants.J_SWITCH_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitCase(CaseTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_CASE,filename,map.getLineNumber(n),map.getColumnNumber(n),4);
-					return super.visitCase(node, p);
-				}
-				@Override
-				public Object visitTry(TryTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					if (node.getResources().isEmpty())
-						parser.add(JavaTokenConstants.J_TRY_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),3);
-					else
-						parser.add(JavaTokenConstants.J_TRY_WITH_RESOURCE,filename,map.getLineNumber(n),map.getColumnNumber(n),3);
-					if (node.getFinallyBlock()!=null)
-						parser.add(JavaTokenConstants.J_FINALLY,filename,map.getLineNumber(n),map.getColumnNumber(n),3);
-					return super.visitTry(node, p);
-				}
-				@Override
-				public Object visitCatch(CatchTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_CATCH_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),5);
-					Object ret = super.visitCatch(node, p);
-					parser.add(JavaTokenConstants.J_CATCH_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);					
-					return ret;
-				}
-				@Override
-				public Object visitIf(IfTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_IF_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),2);
-					node.getCondition().accept(this,p);
-					node.getThenStatement().accept(this, p);
-					if (node.getElseStatement()!=null) {
-						n = positions.getStartPosition(ast, node.getElseStatement());
-						parser.add(JavaTokenConstants.J_ELSE,filename,map.getLineNumber(n),map.getColumnNumber(n),4);
-						node.getElseStatement().accept(this,p);
-					}
-					parser.add(JavaTokenConstants.J_IF_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return null;
-				}
-				@Override
-				public Object visitBreak(BreakTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_BREAK,filename,map.getLineNumber(n),map.getColumnNumber(n),5);
-					return super.visitBreak(node, p);
-				}
-				@Override
-				public Object visitContinue(ContinueTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_CONTINUE,filename,map.getLineNumber(n),map.getColumnNumber(n),8);
-					return super.visitContinue(node, p);
-				}
-				@Override
-				public Object visitReturn(ReturnTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_RETURN,filename,map.getLineNumber(n),map.getColumnNumber(n),6);
-					return super.visitReturn(node, p);
-				}
-				@Override
-				public Object visitThrow(ThrowTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_THROW,filename,map.getLineNumber(n),map.getColumnNumber(n),5);
-					return super.visitThrow(node, p);
-				}
-				@Override
-				public Object visitNewClass(NewClassTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					if (node.getTypeArguments().size()>0) {
-						parser.add(JavaTokenConstants.J_GENERIC,filename,map.getLineNumber(n),map.getColumnNumber(n),3+node.getIdentifier().toString().length());
-					}
-					parser.add(JavaTokenConstants.J_NEWCLASS,filename,map.getLineNumber(n),map.getColumnNumber(n),3);
-					return super.visitNewClass(node, p);
-				}
-				@Override
-				public Object visitTypeParameter(TypeParameterTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					// This is odd, but also done like this in Java17
-					parser.add(JavaTokenConstants.J_GENERIC,filename,map.getLineNumber(n),map.getColumnNumber(n),1);
-					return super.visitTypeParameter(node, p);
-				}
-				@Override
-				public Object visitNewArray(NewArrayTree node, Object arg1) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_NEWARRAY,filename,map.getLineNumber(n),map.getColumnNumber(n),3);
-					if (node.getInitializers()!=null && !node.getInitializers().isEmpty()) {
-						n = positions.getStartPosition(ast, node.getInitializers().get(0));
-						parser.add(JavaTokenConstants.J_ARRAY_INIT_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),1);;
-						parser.add(JavaTokenConstants.J_ARRAY_INIT_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);;
-					}
-					return super.visitNewArray(node, arg1);
-				}
-				@Override
-				public Object visitAssignment(AssignmentTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_ASSIGN,filename,map.getLineNumber(n),map.getColumnNumber(n),1);
-					return super.visitAssignment(node, p);
-				}
-				@Override
-				public Object visitAssert(AssertTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_ASSERT,filename,map.getLineNumber(n),map.getColumnNumber(n),6);
-					return super.visitAssert(node, p);
-				}
-				@Override
-				public Object visitVariable(VariableTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_VARDEF,filename,map.getLineNumber(n),map.getColumnNumber(n),node.toString().length());
-					return super.visitVariable(node, p);
-				}
-				@Override
-				public Object visitConditionalExpression(ConditionalExpressionTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_COND,filename,map.getLineNumber(n),map.getColumnNumber(n),1);
-					return super.visitConditionalExpression(node, p);
-				}
-				@Override
-				public Object visitMethodInvocation(MethodInvocationTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_APPLY,filename,map.getLineNumber(n),map.getColumnNumber(n),positions.getEndPosition(ast,node.getMethodSelect())-n);
-					return super.visitMethodInvocation(node, p);
-				}
-				@Override
-				public Object visitAnnotation(AnnotationTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_ANNO,filename,map.getLineNumber(n),map.getColumnNumber(n),1);
-					return super.visitAnnotation(node, p);
-				}
-				@Override
-				public Object visitModule(ModuleTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					long m = positions.getEndPosition(ast, node);
-					parser.add(JavaTokenConstants.J_MODULE_BEGIN,filename,map.getLineNumber(n),map.getColumnNumber(n),6);
-					Object ret =  super.visitModule(node, p);
-					parser.add(JavaTokenConstants.J_MODULE_END,filename,map.getLineNumber(m-1),map.getColumnNumber(m-1),1);
-					return ret;
-				}
-				@Override
-				public Object visitRequires(RequiresTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_REQUIRES,filename,map.getLineNumber(n),map.getColumnNumber(n),8);
-					return super.visitRequires(node, p);
-				}
-				@Override
-				public Object visitProvides(ProvidesTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_PROVIDES,filename,map.getLineNumber(n),map.getColumnNumber(n),8);
-					return super.visitProvides(node, p);
-				}
-				@Override
-				public Object visitExports(ExportsTree node, Object p) {
-					long n = positions.getStartPosition(ast, node);
-					parser.add(JavaTokenConstants.J_EXPORTS,filename,map.getLineNumber(n),map.getColumnNumber(n),7);
-					return super.visitExports(node, p);
-				}
-				@Override
-				public Object visitErroneous(ErroneousTree node, Object p) {
-					parser.errorsInc();
-					return super.visitErroneous(node, p);
-				}
-			}, null);
-			parser.add(JavaTokenConstants.FILE_END,filename,1,-1,-1);
-		}
-		int errors = 0;
-		for ( Diagnostic<?> diagItem : diagListen.getDiagnostics())
-		{
-			if (diagItem.getKind() == javax.tools.Diagnostic.Kind.ERROR) {
-				errors++;
-			}
-		}
-		return errors;
-	}
+    public int parseFiles(File dir, File[] pathedFiles, final Parser parser) {
+        final StandardJavaFileManager jfm = javac.getStandardFileManager(null, null, null);
+        DiagnosticCollector<? super JavaFileObject> diagListen = new DiagnosticCollector<>();
+        final JavaCompiler.CompilationTask task = javac.getTask(null, jfm, diagListen, null, null, jfm.getJavaFileObjects(pathedFiles));
+        Iterable<? extends CompilationUnitTree> asts = null;
+        try {
+            asts = ((JavacTask) task).parse();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        final Trees trees = Trees.instance(task);
+        final SourcePositions positions = trees.getSourcePositions();
+        for (final CompilationUnitTree ast : asts) {
+            final String filename;
+            if (dir == null)
+                filename = ast.getSourceFile().getName();
+            else {
+                filename = Paths.get(dir.toURI()).relativize(Paths.get(ast.getSourceFile().toUri())).toString();
+            }
+            final LineMap map = ast.getLineMap();
+            ast.accept(new TokenGeneratingTreeScanner(filename, parser, map, positions, ast), null);
+            parser.add(JavaTokenConstants.FILE_END, filename, 1, -1, -1);
+        }
+        int errors = 0;
+        for (Diagnostic<?> diagItem : diagListen.getDiagnostics()) {
+            if (diagItem.getKind() == javax.tools.Diagnostic.Kind.ERROR) {
+                errors++;
+            }
+        }
+        return errors;
+    }
 
 }

+ 65 - 55
jplag.frontend.java-1.9/src/main/java/jplag/java19/Language.java

@@ -6,65 +6,75 @@ import jplag.ProgramI;
 import jplag.Structure;
 
 /**
- * Hello world!
- *
+ * Language for Java 9 and newer.
  */
 public class Language implements jplag.Language {
-	private Parser parser;
+    private Parser parser;
 
-	public Language(ProgramI program) {
-		this.parser = new Parser();
-		this.parser.setProgram(program);
+    public Language(ProgramI program) {
+        this.parser = new Parser();
+        this.parser.setProgram(program);
+    }
 
-	}
-	
+    @Override
     public String[] suffixes() {
-    	String[] res = { ".java", ".JAVA" };
-		return res;
-	}
-
-	public String name() {
-		return "Javac 1.9+ based AST plugin";
-	}
-
-	public String getShortName() {
-		return "java19";
-	}
-
-	public int min_token_match() {
-		return 9;
-	}
-	public boolean supportsColumns() {
-		return true;
-	}
-
-	public boolean isPreformatted() {
-		return true;
-	}
-
-	public boolean usesIndex() {
-		return false;
-	}
-
-	public int noOfTokens() {
-		return JavaToken.numberOfTokens();
-	}
-
-	public String type2string(int type) {
-		return JavaToken.type2string(type);
-	}
-
-
-	public Structure parse(File dir, String[] files) {
-		return this.parser.parse(dir, files);
-	}
-
-	public boolean errors() {
-		return this.parser.getErrors();
-	}
-
-	public int errorsCount() {
-		return this.parser.errorsCount();
-	}
+        String[] res = {".java", ".JAVA"};
+        return res;
+    }
+
+    @Override
+    public String name() {
+        return "Javac 1.9+ based AST plugin";
+    }
+
+    @Override
+    public String getShortName() {
+        return "java19";
+    }
+
+    @Override
+    public int min_token_match() {
+        return 9;
+    }
+
+    @Override
+    public boolean supportsColumns() {
+        return true;
+    }
+
+    @Override
+    public boolean isPreformatted() {
+        return true;
+    }
+
+    @Override
+    public boolean usesIndex() {
+        return false;
+    }
+
+    @Override
+    public int noOfTokens() {
+        return JavaToken.numberOfTokens();
+    }
+
+    @Override
+    public String type2string(int type) {
+        return JavaToken.type2string(type);
+    }
+
+    @Override
+    public Structure parse(File dir, String[] files) {
+        return this.parser.parse(dir, files);
+    }
+
+    @Override
+    public boolean errors() {
+        return this.parser.getErrors();
+    }
+
+    @Override
+    public int errorsCount() {
+        return this.parser.errorsCount();
+    }
 
 }

+ 21 - 23
jplag.frontend.java-1.9/src/main/java/jplag/java19/Parser.java

@@ -2,29 +2,27 @@ package jplag.java19;
 
 import java.io.File;
 
-public class Parser  extends jplag.Parser {
-	private jplag.Structure struct;
+public class Parser extends jplag.Parser {
+    private jplag.Structure struct;
 
-	public jplag.Structure parse(File dir, String files[]) {
-		struct = new jplag.Structure();
-		errors = 0;
-		File pathedFiles[] = new File[files.length];
-		for (int i = 0; i < files.length; i++) {
-			pathedFiles[i]=new File(dir,files[i]); 
-		}
-		JavacAdapter javac = new JavacAdapter();
-		errors += javac.parseFiles(dir,pathedFiles,this);
-		
-		
-		this.parseEnd();
-		return struct;
-	}
-	
-	public void add(int type,String filename, long line, long col, long length) {
-		struct.addToken(new JavaToken(type, filename, (int) line, (int)col,(int)length));
-	}
+    public jplag.Structure parse(File dir, String files[]) {
+        struct = new jplag.Structure();
+        errors = 0;
+        File pathedFiles[] = new File[files.length];
+        for (int i = 0; i < files.length; i++) {
+            pathedFiles[i] = new File(dir, files[i]);
+        }
+        JavacAdapter javac = new JavacAdapter();
+        errors += javac.parseFiles(dir, pathedFiles, this);
+        this.parseEnd();
+        return struct;
+    }
 
-	public void errorsInc() {
-		errors++;
-	}
+    public void add(int type, String filename, long line, long col, long length) {
+        struct.addToken(new JavaToken(type, filename, (int) line, (int) col, (int) length));
+    }
+
+    public void errorsInc() {
+        errors++;
+    }
 }

+ 371 - 0
jplag.frontend.java-1.9/src/main/java/jplag/java19/TokenGeneratingTreeScanner.java

@@ -0,0 +1,371 @@
+package jplag.java19;
+
+import com.sun.source.tree.AnnotationTree;
+import com.sun.source.tree.AssertTree;
+import com.sun.source.tree.AssignmentTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.BreakTree;
+import com.sun.source.tree.CaseTree;
+import com.sun.source.tree.CatchTree;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.ConditionalExpressionTree;
+import com.sun.source.tree.ContinueTree;
+import com.sun.source.tree.DoWhileLoopTree;
+import com.sun.source.tree.EnhancedForLoopTree;
+import com.sun.source.tree.ErroneousTree;
+import com.sun.source.tree.ExportsTree;
+import com.sun.source.tree.ForLoopTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.ImportTree;
+import com.sun.source.tree.LineMap;
+import com.sun.source.tree.MethodInvocationTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.ModuleTree;
+import com.sun.source.tree.NewArrayTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.PackageTree;
+import com.sun.source.tree.ProvidesTree;
+import com.sun.source.tree.RequiresTree;
+import com.sun.source.tree.ReturnTree;
+import com.sun.source.tree.SwitchTree;
+import com.sun.source.tree.SynchronizedTree;
+import com.sun.source.tree.ThrowTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.TryTree;
+import com.sun.source.tree.TypeParameterTree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.tree.WhileLoopTree;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.TreeScanner;
+
+final class TokenGeneratingTreeScanner extends TreeScanner<Object, Object> {
+    private final String filename;
+    private final Parser parser;
+    private final LineMap map;
+    private final SourcePositions positions;
+    private final CompilationUnitTree ast;
+
+    public TokenGeneratingTreeScanner(String filename, Parser parser, LineMap map, SourcePositions positions, CompilationUnitTree ast) {
+        this.filename = filename;
+        this.parser = parser;
+        this.map = map;
+        this.positions = positions;
+        this.ast = ast;
+    }
+
+    @Override
+    public Object visitBlock(BlockTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_INIT_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 1);
+        Object ret = super.visitBlock(node, p);
+        parser.add(JavaTokenConstants.J_INIT_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitClass(ClassTree node, Object p) {
+        boolean isEnum = false;
+        boolean isInterface = false;
+        boolean isAnnotation = false;
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+
+        if (node.getKind() == Tree.Kind.ENUM)
+            isEnum = true;
+        if (node.getKind() == Tree.Kind.INTERFACE)
+            isInterface = true;
+        if (node.getKind() == Tree.Kind.ANNOTATION_TYPE)
+            isAnnotation = true;
+        if (isEnum)
+            parser.add(JavaTokenConstants.J_ENUM_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 4);
+        if (isInterface)
+            parser.add(JavaTokenConstants.J_INTERFACE_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 9);
+        if (isAnnotation)
+            parser.add(JavaTokenConstants.J_ANNO_T_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 10);
+        if (!isEnum && !isInterface && !isAnnotation)
+            parser.add(JavaTokenConstants.J_CLASS_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 5);
+        Object result = super.visitClass(node, p);
+        if (!isEnum && !isInterface && !isAnnotation)
+            parser.add(JavaTokenConstants.J_CLASS_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        if (isAnnotation)
+            parser.add(JavaTokenConstants.J_ANNO_T_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        if (isEnum)
+            parser.add(JavaTokenConstants.J_ENUM_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        if (isInterface)
+            parser.add(JavaTokenConstants.J_INTERFACE_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return result;
+    }
+
+    @Override
+    public Object visitImport(ImportTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_IMPORT, filename, map.getLineNumber(n), map.getColumnNumber(n), 6);
+        return super.visitImport(node, p);
+    }
+
+    @Override
+    public Object visitPackage(PackageTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_PACKAGE, filename, map.getLineNumber(n), map.getColumnNumber(n), 7);
+        return super.visitPackage(node, p);
+    }
+
+    @Override
+    public Object visitMethod(MethodTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_METHOD_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), node.getName().length());
+        Object ret = super.visitMethod(node, p);
+        parser.add(JavaTokenConstants.J_METHOD_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitSynchronized(SynchronizedTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_SYNC_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 12);
+        Object ret = super.visitSynchronized(node, p);
+        parser.add(JavaTokenConstants.J_SYNC_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitDoWhileLoop(DoWhileLoopTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_DO_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 2);
+        Object ret = super.visitDoWhileLoop(node, p);
+        parser.add(JavaTokenConstants.J_DO_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitWhileLoop(WhileLoopTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_WHILE_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 5);
+        Object ret = super.visitWhileLoop(node, p);
+        parser.add(JavaTokenConstants.J_WHILE_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitForLoop(ForLoopTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_FOR_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 3);
+        Object ret = super.visitForLoop(node, p);
+        parser.add(JavaTokenConstants.J_FOR_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitEnhancedForLoop(EnhancedForLoopTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_FOR_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 3);
+        Object ret = super.visitEnhancedForLoop(node, p);
+        parser.add(JavaTokenConstants.J_FOR_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitSwitch(SwitchTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_SWITCH_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 6);
+        Object ret = super.visitSwitch(node, p);
+        parser.add(JavaTokenConstants.J_SWITCH_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitCase(CaseTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_CASE, filename, map.getLineNumber(n), map.getColumnNumber(n), 4);
+        return super.visitCase(node, p);
+    }
+
+    @Override
+    public Object visitTry(TryTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        if (node.getResources().isEmpty())
+            parser.add(JavaTokenConstants.J_TRY_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 3);
+        else
+            parser.add(JavaTokenConstants.J_TRY_WITH_RESOURCE, filename, map.getLineNumber(n), map.getColumnNumber(n), 3);
+        if (node.getFinallyBlock() != null)
+            parser.add(JavaTokenConstants.J_FINALLY, filename, map.getLineNumber(n), map.getColumnNumber(n), 3);
+        return super.visitTry(node, p);
+    }
+
+    @Override
+    public Object visitCatch(CatchTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_CATCH_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 5);
+        Object ret = super.visitCatch(node, p);
+        parser.add(JavaTokenConstants.J_CATCH_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitIf(IfTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_IF_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 2);
+        node.getCondition().accept(this, p);
+        node.getThenStatement().accept(this, p);
+        if (node.getElseStatement() != null) {
+            n = positions.getStartPosition(ast, node.getElseStatement());
+            parser.add(JavaTokenConstants.J_ELSE, filename, map.getLineNumber(n), map.getColumnNumber(n), 4);
+            node.getElseStatement().accept(this, p);
+        }
+        parser.add(JavaTokenConstants.J_IF_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return null;
+    }
+
+    @Override
+    public Object visitBreak(BreakTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_BREAK, filename, map.getLineNumber(n), map.getColumnNumber(n), 5);
+        return super.visitBreak(node, p);
+    }
+
+    @Override
+    public Object visitContinue(ContinueTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_CONTINUE, filename, map.getLineNumber(n), map.getColumnNumber(n), 8);
+        return super.visitContinue(node, p);
+    }
+
+    @Override
+    public Object visitReturn(ReturnTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_RETURN, filename, map.getLineNumber(n), map.getColumnNumber(n), 6);
+        return super.visitReturn(node, p);
+    }
+
+    @Override
+    public Object visitThrow(ThrowTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_THROW, filename, map.getLineNumber(n), map.getColumnNumber(n), 5);
+        return super.visitThrow(node, p);
+    }
+
+    @Override
+    public Object visitNewClass(NewClassTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        if (node.getTypeArguments().size() > 0) {
+            parser.add(JavaTokenConstants.J_GENERIC, filename, map.getLineNumber(n), map.getColumnNumber(n),
+                    3 + node.getIdentifier().toString().length());
+        }
+        parser.add(JavaTokenConstants.J_NEWCLASS, filename, map.getLineNumber(n), map.getColumnNumber(n), 3);
+        return super.visitNewClass(node, p);
+    }
+
+    @Override
+    public Object visitTypeParameter(TypeParameterTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        // This is odd, but also done like this in Java17
+        parser.add(JavaTokenConstants.J_GENERIC, filename, map.getLineNumber(n), map.getColumnNumber(n), 1);
+        return super.visitTypeParameter(node, p);
+    }
+
+    @Override
+    public Object visitNewArray(NewArrayTree node, Object arg1) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_NEWARRAY, filename, map.getLineNumber(n), map.getColumnNumber(n), 3);
+        if (node.getInitializers() != null && !node.getInitializers().isEmpty()) {
+            n = positions.getStartPosition(ast, node.getInitializers().get(0));
+            parser.add(JavaTokenConstants.J_ARRAY_INIT_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 1);
+            ;
+            parser.add(JavaTokenConstants.J_ARRAY_INIT_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+            ;
+        }
+        return super.visitNewArray(node, arg1);
+    }
+
+    @Override
+    public Object visitAssignment(AssignmentTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_ASSIGN, filename, map.getLineNumber(n), map.getColumnNumber(n), 1);
+        return super.visitAssignment(node, p);
+    }
+
+    @Override
+    public Object visitAssert(AssertTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_ASSERT, filename, map.getLineNumber(n), map.getColumnNumber(n), 6);
+        return super.visitAssert(node, p);
+    }
+
+    @Override
+    public Object visitVariable(VariableTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_VARDEF, filename, map.getLineNumber(n), map.getColumnNumber(n), node.toString().length());
+        return super.visitVariable(node, p);
+    }
+
+    @Override
+    public Object visitConditionalExpression(ConditionalExpressionTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_COND, filename, map.getLineNumber(n), map.getColumnNumber(n), 1);
+        return super.visitConditionalExpression(node, p);
+    }
+
+    @Override
+    public Object visitMethodInvocation(MethodInvocationTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_APPLY, filename, map.getLineNumber(n), map.getColumnNumber(n),
+                positions.getEndPosition(ast, node.getMethodSelect()) - n);
+        return super.visitMethodInvocation(node, p);
+    }
+
+    @Override
+    public Object visitAnnotation(AnnotationTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_ANNO, filename, map.getLineNumber(n), map.getColumnNumber(n), 1);
+        return super.visitAnnotation(node, p);
+    }
+
+    @Override
+    public Object visitModule(ModuleTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        long m = positions.getEndPosition(ast, node);
+        parser.add(JavaTokenConstants.J_MODULE_BEGIN, filename, map.getLineNumber(n), map.getColumnNumber(n), 6);
+        Object ret = super.visitModule(node, p);
+        parser.add(JavaTokenConstants.J_MODULE_END, filename, map.getLineNumber(m - 1), map.getColumnNumber(m - 1), 1);
+        return ret;
+    }
+
+    @Override
+    public Object visitRequires(RequiresTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_REQUIRES, filename, map.getLineNumber(n), map.getColumnNumber(n), 8);
+        return super.visitRequires(node, p);
+    }
+
+    @Override
+    public Object visitProvides(ProvidesTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_PROVIDES, filename, map.getLineNumber(n), map.getColumnNumber(n), 8);
+        return super.visitProvides(node, p);
+    }
+
+    @Override
+    public Object visitExports(ExportsTree node, Object p) {
+        long n = positions.getStartPosition(ast, node);
+        parser.add(JavaTokenConstants.J_EXPORTS, filename, map.getLineNumber(n), map.getColumnNumber(n), 7);
+        return super.visitExports(node, p);
+    }
+
+    @Override
+    public Object visitErroneous(ErroneousTree node, Object p) {
+        parser.errorsInc();
+        return super.visitErroneous(node, p);
+    }
+}