-
-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Review: feat(position): add the position of the modifier in the ast #1959
Changes from 11 commits
b669990
9f78689
6b4e368
c64acf7
342c870
0b743a6
9acf736
cc00222
4f5cdb4
0e8c755
fcf983b
e9030a5
712689f
a852c54
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,18 +23,26 @@ | |
import org.eclipse.jdt.internal.compiler.ast.Annotation; | ||
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration; | ||
import org.eclipse.jdt.internal.compiler.ast.Expression; | ||
import org.eclipse.jdt.internal.compiler.ast.Initializer; | ||
import org.eclipse.jdt.internal.compiler.ast.Javadoc; | ||
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; | ||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; | ||
import org.eclipse.jdt.internal.compiler.ast.TypeParameter; | ||
import org.eclipse.jdt.internal.compiler.ast.TypeReference; | ||
import spoon.SpoonException; | ||
import spoon.reflect.code.CtCatchVariable; | ||
import spoon.reflect.code.CtStatementList; | ||
import spoon.reflect.cu.CompilationUnit; | ||
import spoon.reflect.cu.SourcePosition; | ||
import spoon.reflect.declaration.CtElement; | ||
import spoon.reflect.declaration.CtPackage; | ||
import spoon.reflect.declaration.CtModifiable; | ||
import spoon.reflect.factory.CoreFactory; | ||
import spoon.support.reflect.CtExtendedModifier; | ||
|
||
import java.util.Arrays; | ||
import java.util.Iterator; | ||
import java.util.Set; | ||
|
||
import static spoon.support.compiler.jdt.JDTTreeBuilderQuery.getModifiers; | ||
|
||
|
@@ -94,18 +102,14 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) { | |
int declarationSourceStart = variableDeclaration.declarationSourceStart; | ||
int declarationSourceEnd = variableDeclaration.declarationSourceEnd; | ||
|
||
Annotation[] annotations = variableDeclaration.annotations; | ||
if (annotations != null && annotations.length > 0) { | ||
if (annotations[0].sourceStart() == sourceStart) { | ||
modifiersSourceStart = annotations[annotations.length - 1].sourceEnd() + 2; | ||
} | ||
} | ||
if (modifiersSourceStart == 0) { | ||
if (modifiersSourceStart <= 0) { | ||
modifiersSourceStart = declarationSourceStart; | ||
} | ||
int modifiersSourceEnd; | ||
if (variableDeclaration.type != null) { | ||
modifiersSourceEnd = variableDeclaration.type.sourceStart() - 2; | ||
} else if (variableDeclaration instanceof Initializer) { | ||
modifiersSourceEnd = ((Initializer) variableDeclaration).block.sourceStart; | ||
} else { | ||
// variable that has no type such as TypeParameter | ||
modifiersSourceEnd = declarationSourceStart - 1; | ||
|
@@ -114,6 +118,8 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) { | |
// when no modifier | ||
if (modifiersSourceStart > modifiersSourceEnd) { | ||
modifiersSourceEnd = modifiersSourceStart - 1; | ||
} else if (e instanceof CtModifiable) { | ||
setModifiersPosition((CtModifiable) e, modifiersSourceStart, modifiersSourceEnd); | ||
} | ||
|
||
return cf.createDeclarationSourcePosition(cu, | ||
|
@@ -133,19 +139,16 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) { | |
int bodyStart = typeDeclaration.bodyStart; | ||
int bodyEnd = typeDeclaration.bodyEnd; | ||
|
||
Annotation[] annotations = typeDeclaration.annotations; | ||
if (annotations != null && annotations.length > 0) { | ||
if (annotations[0].sourceStart() == declarationSourceStart) { | ||
modifiersSourceStart = findNextNonWhitespace(contents, declarationSourceEnd, annotations[annotations.length - 1].declarationSourceEnd + 1); | ||
} | ||
} | ||
if (modifiersSourceStart == 0) { | ||
if (modifiersSourceStart <= 0) { | ||
modifiersSourceStart = declarationSourceStart; | ||
} | ||
//look for start of first keyword before the type keyword e.g. "class". `sourceStart` points at first char of type name | ||
int modifiersSourceEnd = findPrevNonWhitespace(contents, modifiersSourceStart - 1, | ||
findPrevWhitespace(contents, modifiersSourceStart - 1, | ||
findPrevNonWhitespace(contents, modifiersSourceStart - 1, sourceStart - 1))); | ||
if (e instanceof CtModifiable) { | ||
setModifiersPosition((CtModifiable) e, modifiersSourceStart, bodyStart); | ||
} | ||
if (modifiersSourceEnd < modifiersSourceStart) { | ||
//there is no modifier | ||
modifiersSourceEnd = modifiersSourceStart - 1; | ||
|
@@ -172,7 +175,7 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) { | |
int declarationSourceEnd = methodDeclaration.declarationSourceEnd; | ||
int modifiersSourceStart = methodDeclaration.modifiersSourceStart; | ||
|
||
if (modifiersSourceStart == 0) { | ||
if (modifiersSourceStart <= 0) { | ||
modifiersSourceStart = declarationSourceStart; | ||
} | ||
|
||
|
@@ -186,15 +189,13 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) { | |
if (javadoc != null && javadoc.sourceEnd() > declarationSourceStart) { | ||
modifiersSourceStart = javadoc.sourceEnd() + 1; | ||
} | ||
Annotation[] annotations = methodDeclaration.annotations; | ||
if (annotations != null && annotations.length > 0) { | ||
if (annotations[0].sourceStart() == declarationSourceStart) { | ||
modifiersSourceStart = annotations[annotations.length - 1].sourceEnd() + 2; | ||
} | ||
} | ||
|
||
int modifiersSourceEnd = sourceStart - 1; | ||
|
||
if (e instanceof CtModifiable) { | ||
setModifiersPosition((CtModifiable) e, modifiersSourceStart, declarationSourceEnd); | ||
} | ||
|
||
if (methodDeclaration instanceof MethodDeclaration && ((MethodDeclaration) methodDeclaration).returnType != null) { | ||
modifiersSourceEnd = ((MethodDeclaration) methodDeclaration).returnType.sourceStart() - 2; | ||
} | ||
|
@@ -234,13 +235,51 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) { | |
bodyStart, bodyEnd, | ||
lineSeparatorPositions); | ||
} | ||
} else if (e instanceof CtCatchVariable) { | ||
Iterator<ASTPair> iterator = this.jdtTreeBuilder.getContextBuilder().stack.iterator(); | ||
iterator.next(); | ||
ASTPair next = iterator.next(); | ||
buildPositionCtElement(e, next.node); | ||
sourceEnd = getSourceEndOfTypeReference(contents, (TypeReference) node, sourceEnd); | ||
return cf.createSourcePosition(cu, sourceStart, sourceEnd, lineSeparatorPositions); | ||
} else if (node instanceof TypeReference) { | ||
sourceEnd = getSourceEndOfTypeReference(contents, (TypeReference) node, sourceEnd); | ||
} | ||
|
||
if (e instanceof CtModifiable) { | ||
setModifiersPosition((CtModifiable) e, sourceStart, sourceEnd); | ||
} | ||
return cf.createSourcePosition(cu, sourceStart, sourceEnd, lineSeparatorPositions); | ||
} | ||
|
||
|
||
private void setModifiersPosition(CtModifiable e, int start, int end) { | ||
CoreFactory cf = this.jdtTreeBuilder.getFactory().Core(); | ||
CompilationUnit cu = this.jdtTreeBuilder.getFactory().CompilationUnit().getOrCreate(new String(this.jdtTreeBuilder.getContextBuilder().compilationunitdeclaration.getFileName())); | ||
CompilationResult cr = this.jdtTreeBuilder.getContextBuilder().compilationunitdeclaration.compilationResult; | ||
char[] contents = cr.compilationUnit.getContents(); | ||
|
||
Set<CtExtendedModifier> modifiers = e.getExtendedModifiers(); | ||
if (start < 0 || end + 1 > contents.length) { | ||
System.out.println(e); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it really wanted? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, debug point that I forget to remove |
||
} | ||
String modifierContent = String.valueOf(Arrays.copyOfRange(contents, start, end + 1)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess there is faster |
||
for (CtExtendedModifier modifier: modifiers) { | ||
if (modifier.isImplicit()) { | ||
modifier.setPosition(SourcePosition.NOPOSITION); | ||
continue; | ||
} | ||
int index = modifierContent.indexOf(modifier.getKind().toString()); | ||
if (index == -1) { | ||
throw new SpoonException("Explicit modifier not found"); | ||
} | ||
int indexStart = index + start; | ||
int indexEnd = indexStart + modifier.getKind().toString().length() - 1; | ||
|
||
modifier.setPosition(cf.createSourcePosition(cu, indexStart, indexEnd, cr.lineSeparatorPositions)); | ||
} | ||
} | ||
|
||
private int getSourceEndOfTypeReference(char[] contents, TypeReference node, int sourceEnd) { | ||
//e.g. SomeType<String,T> | ||
TypeReference[][] typeArgs = ((TypeReference) node).getTypeArguments(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
*/ | ||
package spoon.support.reflect; | ||
|
||
import spoon.reflect.cu.SourcePosition; | ||
import spoon.reflect.declaration.ModifierKind; | ||
|
||
import java.io.Serializable; | ||
|
@@ -27,6 +28,7 @@ | |
public class CtExtendedModifier implements Serializable { | ||
private boolean implicit; | ||
private ModifierKind kind; | ||
private SourcePosition position; | ||
|
||
public CtExtendedModifier(ModifierKind kind) { | ||
this.kind = kind; | ||
|
@@ -53,6 +55,17 @@ public void setKind(ModifierKind kind) { | |
this.kind = kind; | ||
} | ||
|
||
public SourcePosition getPosition() { | ||
if (position == null) { | ||
return SourcePosition.NOPOSITION; | ||
} | ||
return position; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
public void setPosition(SourcePosition position) { | ||
this.position = position; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not read whole code yet, so may be it is correct, but usage of
bodyStart
here seems to be wrong.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, the searched string is little bit longer then necessary, but I cannot imagine code where it would cause problem, so it is OK for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are here in a TypeDeclaration the bodyStart is the first position that I'm sure will contain the modifier.
I'm pretty sure that the way to perform modifiersSourceEnd in this case does not support annotation and thus can be incorrect in some clases