Skip to content

Commit

Permalink
Ignore differences in empty statements when parsing ajava files and s…
Browse files Browse the repository at this point in the history
…ource files together
  • Loading branch information
kelloggm authored May 13, 2024
1 parent e8a30ea commit 63cc1a2
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.DoWhileLoopTree;
import com.sun.source.tree.EmptyStatementTree;
import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.ForLoopTree;
Expand Down Expand Up @@ -399,4 +400,14 @@ public Void visitYield17(Tree tree, Void p) {
// So skip yields.
return null;
}

@Override
public Void visitEmptyStatement(EmptyStatementTree tree, Void p) {
// JavaParser doesn't seem to include completely-empty classes.
// See https://github.com/typetools/checker-framework/issues/6570
// for a discussion of our motivation for excluding empty statements.
// Also, empty statements don't have semantics, so it's okay if there
// are arbitraily-many extra empty statements in one of the inputs.
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,25 @@ public Void visitCompilationUnit(CompilationUnitTree javacTree, Node javaParserN
CompilationUnit node = castNode(CompilationUnit.class, javaParserNode, javacTree);
processCompilationUnit(javacTree, node);
visitOptional(javacTree.getPackage(), node.getPackageDeclaration());

// This is the fix for https://github.com/typetools/checker-framework/issues/6570.
// If the input java file contains semicolons between classes, then
// the javac tree will contain "type declarations" for those semicolons
// (for some reason? a javac bug?) but an ajava file will not (JavaParser
// appears to strip them out? frankly, we're not sure why). This code works
// around the problem by filtering any "type declarations" that contain only
// a single semicolon from the javacTypeDecls list before passing the list
// to the rest of the visitor.
List<? extends Tree> javacTypeDecls = javacTree.getTypeDecls();
List<Tree> javacTypeDeclsWithoutSemicolons = new ArrayList<>();
for (Tree javacTypeDecl : javacTypeDecls) {
if (javacTypeDecl.getKind() != Tree.Kind.EMPTY_STATEMENT) {
javacTypeDeclsWithoutSemicolons.add(javacTypeDecl);
}
}

visitLists(javacTree.getImports(), node.getImports());
visitLists(javacTree.getTypeDecls(), node.getTypes());
visitLists(javacTypeDeclsWithoutSemicolons, node.getTypes());
return null;
}

Expand Down
6 changes: 6 additions & 0 deletions framework/tests/all-systems/EndsWithSemicolon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// test case for https://github.com/typetools/checker-framework/issues/6570

// A class is technically permitted to end with a semicolon (though it doesn't do
// anything).
public class EndsWithSemicolon {}
;

0 comments on commit 63cc1a2

Please sign in to comment.