diff --git a/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java b/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java index f659ba2b2..1681903a5 100644 --- a/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java +++ b/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import org.junit.jupiter.api.AfterAll; @@ -247,7 +248,7 @@ final List getTokenPositionTestData() { @MethodSource("getAllTestData") @DisplayName("Test that the tokens map to ascending line numbers") final void testMonotoneTokenOrder(TestData data) throws ParsingException, IOException { - List tokens = parseTokens(data); + List tokens = parseTokens(data).stream().filter(it -> !getIgnoredTokensForMonotoneTokenOrder().contains(it.getType())).toList(); for (int i = 0; i < tokens.size() - 2; i++) { Token first = tokens.get(i); @@ -338,4 +339,8 @@ private > C ignoreEmptyTestType(C data) { protected File getTestFileLocation() { return new File(DEFAULT_TEST_CODE_PATH_BASE.toFile(), this.language.getIdentifier()); } + + protected List getIgnoredTokensForMonotoneTokenOrder() { + return Collections.emptyList(); + } } diff --git a/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java b/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java index 9589da81b..503c84fb0 100644 --- a/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java +++ b/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java @@ -136,7 +136,8 @@ public Void visitClass(ClassTree node, Void unused) { } } - long start = positions.getStartPosition(ast, node); + long start = positions.getEndPosition(ast, node.getModifiers()) + 1; + long nameLength = node.getSimpleName().length(); long end = positions.getEndPosition(ast, node) - 1; CodeSemantics semantics = CodeSemantics.createControl(); if (node.getKind() == Tree.Kind.ENUM) { @@ -146,7 +147,9 @@ public Void visitClass(ClassTree node, Void unused) { } else if (node.getKind() == Tree.Kind.RECORD) { addToken(JavaTokenType.J_RECORD_BEGIN, start, 1, semantics); } else if (node.getKind() == Tree.Kind.ANNOTATION_TYPE) { - addToken(JavaTokenType.J_ANNO_T_BEGIN, start, 10, semantics); + // The start position for the is calculated that way, because the @ is the final element in the modifier list for + // annotations + addToken(JavaTokenType.J_ANNO_T_BEGIN, start - 2, (start - 2) + 11 + nameLength, semantics); } else if (node.getKind() == Tree.Kind.CLASS) { addToken(JavaTokenType.J_CLASS_BEGIN, start, 5, semantics); } @@ -508,7 +511,8 @@ public Void visitMethodInvocation(MethodInvocationTree node, Void unused) { @Override public Void visitAnnotation(AnnotationTree node, Void unused) { long start = positions.getStartPosition(ast, node); - addToken(JavaTokenType.J_ANNO, start, 1, new CodeSemantics()); + String annotationName = node.getAnnotationType().toString(); + addToken(JavaTokenType.J_ANNO, start, annotationName.length() + 1, new CodeSemantics()); return super.visitAnnotation(node, null); } diff --git a/languages/java/src/test/java/de/jplag/java/JavaLanguageTest.java b/languages/java/src/test/java/de/jplag/java/JavaLanguageTest.java index a4f89d9bb..8e9320553 100644 --- a/languages/java/src/test/java/de/jplag/java/JavaLanguageTest.java +++ b/languages/java/src/test/java/de/jplag/java/JavaLanguageTest.java @@ -29,6 +29,9 @@ import static de.jplag.java.JavaTokenType.J_TRY_END; import static de.jplag.java.JavaTokenType.J_VARDEF; +import java.util.List; + +import de.jplag.TokenType; import de.jplag.testutils.LanguageModuleTest; import de.jplag.testutils.datacollector.TestDataCollector; import de.jplag.testutils.datacollector.TestSourceIgnoredLinesCollector; @@ -84,4 +87,9 @@ protected void configureIgnoredLines(TestSourceIgnoredLinesCollector collector) collector.ignoreLinesByPrefix("})"); collector.ignoreByCondition(line -> line.contains("else") && !line.contains("if")); } + + @Override + protected List getIgnoredTokensForMonotoneTokenOrder() { + return List.of(JavaTokenType.J_ANNO); + } } diff --git a/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_1.java b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_1.java new file mode 100644 index 000000000..e78c1a3f9 --- /dev/null +++ b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_1.java @@ -0,0 +1,3 @@ +>@SuppressWarnings +$| J_ANNO 17 +>class Anno {} \ No newline at end of file diff --git a/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_2.java b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_2.java new file mode 100644 index 000000000..54f9b612a --- /dev/null +++ b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_2.java @@ -0,0 +1,3 @@ +>@SuppressWarnings("SomeWarning") +$| J_ANNO 17 +>class Anno {} \ No newline at end of file diff --git a/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_3.java b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_3.java new file mode 100644 index 000000000..522a18dae --- /dev/null +++ b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_3.java @@ -0,0 +1,6 @@ +>class Anno { +> @Deprecated +$ | J_ANNO 11 +> public void testFunction() { +> } +>} \ No newline at end of file diff --git a/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_4.java b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_4.java new file mode 100644 index 000000000..92db1e255 --- /dev/null +++ b/languages/java/src/test/resources/de/jplag/java/tokenPositions/Anno_4.java @@ -0,0 +1,7 @@ +>import javax.annotation.processing.Generated; +> +>class Anno { +> public void testMethod(@Generated String param) { +$ | J_ANNO 10 +> } +>} diff --git a/languages/java/src/test/resources/de/jplag/java/tokenPositions/JAnnoTBegin-End_1.java b/languages/java/src/test/resources/de/jplag/java/tokenPositions/JAnnoTBegin-End_1.java new file mode 100644 index 000000000..119972961 --- /dev/null +++ b/languages/java/src/test/resources/de/jplag/java/tokenPositions/JAnnoTBegin-End_1.java @@ -0,0 +1,3 @@ +>public @interface MyAnnotation {} +$ | J_ANNO_T_BEGIN 23 +$ | J_ANNO_T_END 1 \ No newline at end of file diff --git a/languages/java/src/test/resources/de/jplag/java/tokenPositions/JAnnoTBegin-End_2.java b/languages/java/src/test/resources/de/jplag/java/tokenPositions/JAnnoTBegin-End_2.java new file mode 100644 index 000000000..0d0d89d1e --- /dev/null +++ b/languages/java/src/test/resources/de/jplag/java/tokenPositions/JAnnoTBegin-End_2.java @@ -0,0 +1,4 @@ +>public @interface MyAnnotation { +$ | J_ANNO_T_BEGIN 23 +>} +$| J_ANNO_T_END 1