Skip to content

Commit

Permalink
Fix: source position when there is a comment character in annotation (#…
Browse files Browse the repository at this point in the history
…3720)

Co-authored-by: Martin Monperrus <martin.monperrus@gnieh.org>
  • Loading branch information
andrewbwogi and monperrus authored Dec 15, 2020
1 parent 1ea39bf commit 8f86cf9
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/main/java/spoon/support/compiler/jdt/PositionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ static int findNextChar(char[] contents, int maxOff, int off, char expectedChar)
static int findNextNonWhitespace(char[] content, int maxOff, int off) {
return findNextNonWhitespace(true, content, maxOff, off);
}

static int findNextNonWhitespace(boolean commentIsWhiteSpace, char[] content, int maxOff, int off) {
maxOff = Math.min(maxOff, content.length - 1);
while (off >= 0 && off <= maxOff) {
Expand All @@ -697,17 +698,24 @@ static int findNextNonWhitespace(boolean commentIsWhiteSpace, char[] content, in
* Note: all kinds of java comments are understood as whitespace too. Then it returns offset of the first character of the comment
*/
static int findNextWhitespace(char[] content, int maxOff, int off) {
boolean inString = false;
maxOff = Math.min(maxOff, content.length - 1);
while (off >= 0 && off <= maxOff) {
char c = content[off];
if (Character.isWhitespace(c) || getEndOfComment(content, maxOff, off) >= 0) {
if (c == '"' && !inString) {
inString = true;
} else if (c == '"' && inString) {
inString = false;
}
if (Character.isWhitespace(c) || (!inString && getEndOfComment(content, maxOff, off) >= 0)) {
//it is whitespace or comment starts there
return off;
}
off++;
}
return -1;
}

/**
* @param minOff the minimal acceptable return value
* @return index of first non whitespace char, searching backward. Can return `off` if it is already a non whitespace.
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/spoon/test/sourcePosition/SourcePositionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,26 @@

import org.junit.Test;

import spoon.Launcher;
import spoon.reflect.CtModel;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.cu.CompilationUnit;
import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtModifiable;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.Filter;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.reflect.CtExtendedModifier;
import spoon.support.reflect.cu.CompilationUnitImpl;
import spoon.support.reflect.cu.position.BodyHolderSourcePositionImpl;
import spoon.support.reflect.cu.position.DeclarationSourcePositionImpl;
import spoon.support.reflect.cu.position.SourcePositionImpl;
import spoon.support.reflect.declaration.CtClassImpl;
import spoon.test.sourcePosition.testclasses.Brambora;
import spoon.testing.utils.ModelUtils;

Expand Down Expand Up @@ -112,4 +118,15 @@ public String getOriginalSourceCode() {
"name = |4;7|4567|\n" +
"body = |8;9|89|", bhsp.getSourceDetails());
}

@Test
public void testSourcePositionWhenCommentInAnnotation() {
// contract: comment characters as element values in annotations should not break position assignment to modifiers
Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/resources/spoon/test/sourcePosition/ClassWithAnnotation.java");
launcher.addInputResource("./src/test/resources/spoon/test/sourcePosition/TestAnnotation.java");
CtModel model = launcher.buildModel();
List<CtClassImpl> list = model.getElements(new TypeFilter<>(CtClassImpl.class));
assertEquals(4,list.get(0).getPosition().getLine());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package spoon.test.sourcePosition

@TestAnnotation("/*")
public class ClassWithAnnotation { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package spoon.test.sourcePosition;

// resource for https://github.com/INRIA/spoon/issues/3606
public @interface TestAnnotation {
String value() default "";
}

0 comments on commit 8f86cf9

Please sign in to comment.