Skip to content

Commit

Permalink
fix: source position of expressions and type casts
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky committed Jun 27, 2018
1 parent d9d6e3f commit 7dfeb7c
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 7 deletions.
11 changes: 9 additions & 2 deletions src/main/java/spoon/support/compiler/jdt/ContextBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ public class ContextBuilder {

Deque<String> annotationValueName = new ArrayDeque<>();

List<CtTypeReference<?>> casts = new ArrayList<>(CASTS_CONTAINER_DEFAULT_CAPACITY);
public static class CastInfo {
int nrOfBrackets;
CtTypeReference<?> typeRef;
}

List<CastInfo> casts = new ArrayList<>(CASTS_CONTAINER_DEFAULT_CAPACITY);

CompilationUnitDeclaration compilationunitdeclaration;

Expand All @@ -72,6 +77,8 @@ public class ContextBuilder {

boolean isBuildLambda = false;

boolean isBuildTypeCast = false;

boolean ignoreComputeImports = false;

/**
Expand Down Expand Up @@ -99,7 +106,7 @@ void enter(CtElement e, ASTNode node) {

if (current instanceof CtExpression) {
while (!casts.isEmpty()) {
((CtExpression<?>) current).addTypeCast(casts.remove(0));
((CtExpression<?>) current).addTypeCast(casts.remove(0).typeRef);
}
}
if (current instanceof CtStatement && !this.label.isEmpty()) {
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
import spoon.reflect.reference.CtReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.reference.CtUnboundVariableReference;
import spoon.support.compiler.jdt.ContextBuilder.CastInfo;
import spoon.support.reflect.CtExtendedModifier;

import java.util.HashSet;
Expand Down Expand Up @@ -935,7 +936,10 @@ public boolean visit(BreakStatement breakStatement, BlockScope scope) {

@Override
public boolean visit(CastExpression castExpression, BlockScope scope) {
context.casts.add(this.references.buildTypeReference(castExpression.type, scope));
CastInfo ci = new CastInfo();
ci.nrOfBrackets = ((castExpression.bits >>> 21) & 0xF);
ci.typeRef = this.references.buildTypeReference(castExpression.type, scope, true);
context.casts.add(ci);
castExpression.expression.traverse(this, scope);
return false;
}
Expand Down
65 changes: 64 additions & 1 deletion src/main/java/spoon/support/compiler/jdt/PositionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import spoon.SpoonException;
import spoon.reflect.code.CtCatchVariable;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtStatementList;
import spoon.reflect.cu.CompilationUnit;
import spoon.reflect.cu.SourcePosition;
Expand All @@ -42,9 +43,12 @@
import spoon.reflect.declaration.CtModifiable;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.factory.CoreFactory;
import spoon.reflect.reference.CtTypeReference;
import spoon.support.compiler.jdt.ContextBuilder.CastInfo;
import spoon.support.reflect.CtExtendedModifier;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import static spoon.support.compiler.jdt.JDTTreeBuilderQuery.getModifiers;
Expand Down Expand Up @@ -73,7 +77,6 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) {
int[] lineSeparatorPositions = cr.lineSeparatorPositions;
char[] contents = cr.compilationUnit.getContents();


int sourceStart = node.sourceStart;
int sourceEnd = node.sourceEnd;
if ((node instanceof Annotation)) {
Expand All @@ -90,6 +93,55 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) {
if (statementEnd > 0) {
sourceEnd = statementEnd;
}

if (this.jdtTreeBuilder.getContextBuilder().isBuildTypeCast && e instanceof CtTypeReference) {
//the type cast reference must be enclosed with brackets
int declarationSourceStart = sourceStart;
int declarationSourceEnd = sourceEnd;
declarationSourceStart = findPrevNonWhitespace(contents, 0, declarationSourceStart - 1);
if (contents[declarationSourceStart] != '(') {
throw new SpoonException("Unexpected character \'" + contents[declarationSourceStart] + "\' at start of cast expression on offset: " + declarationSourceStart);
}
declarationSourceEnd = findNextNonWhitespace(contents, contents.length, declarationSourceEnd + 1);
if (contents[declarationSourceEnd] != ')') {
throw new SpoonException("Unexpected character \'" + contents[declarationSourceStart] + "\' at end of cast expression on offset: " + declarationSourceEnd);
}
return cf.createCompoundSourcePosition(cu,
sourceStart, sourceEnd,
declarationSourceStart, declarationSourceEnd,
lineSeparatorPositions);
}

List<CastInfo> casts = this.jdtTreeBuilder.getContextBuilder().casts;

if (casts.size() > 0 && e instanceof CtExpression) {
int declarationSourceStart = sourceStart;
int declarationSourceEnd = sourceEnd;
SourcePosition pos = casts.get(0).typeRef.getPosition();
if (pos.isValidPosition()) {
declarationSourceStart = pos.getSourceStart();
int nrOfBrackets = getNrOfFirstCastExpressionBrackets();
while (nrOfBrackets > 0) {
declarationSourceStart = findPrevNonWhitespace(contents, 0, declarationSourceStart - 1);
if (contents[declarationSourceStart] != '(') {
throw new SpoonException("Unexpected character \'" + contents[declarationSourceStart] + "\' at start of expression on offset: " + declarationSourceStart);
}
nrOfBrackets--;
}
nrOfBrackets = getNrOfCastExpressionBrackets();
while (nrOfBrackets > 0) {
declarationSourceEnd = findNextNonWhitespace(contents, contents.length, declarationSourceEnd + 1);
if (contents[declarationSourceEnd] != ')') {
throw new SpoonException("Unexpected character \'" + contents[declarationSourceStart] + "\' at end of expression on offset: " + declarationSourceEnd);
}
nrOfBrackets--;
}
}
return cf.createCompoundSourcePosition(cu,
sourceStart, sourceEnd,
declarationSourceStart, declarationSourceEnd,
lineSeparatorPositions);
}
}

if (node instanceof TypeParameter) {
Expand Down Expand Up @@ -285,6 +337,17 @@ SourcePosition buildPositionCtElement(CtElement e, ASTNode node) {
return cf.createSourcePosition(cu, sourceStart, sourceEnd, lineSeparatorPositions);
}

private int getNrOfFirstCastExpressionBrackets() {
return this.jdtTreeBuilder.getContextBuilder().casts.get(0).nrOfBrackets;
}

private int getNrOfCastExpressionBrackets() {
int nr = 0;
for (CastInfo castInfo : this.jdtTreeBuilder.getContextBuilder().casts) {
nr += castInfo.nrOfBrackets;
}
return nr;
}

private void setModifiersPosition(CtModifiable e, int start, int end) {
CoreFactory cf = this.jdtTreeBuilder.getFactory().Core();
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,14 @@ private CtTypeReference<?> getBoundedTypeReference(TypeBinding binding) {
* @return a type reference.
*/
<T> CtTypeReference<T> buildTypeReference(TypeReference type, Scope scope) {
return buildTypeReference(type, scope, false);
}
<T> CtTypeReference<T> buildTypeReference(TypeReference type, Scope scope, boolean isTypeCast) {
if (type == null) {
return null;
}
CtTypeReference<T> typeReference = this.<T>getTypeReference(type.resolvedType, type);
return buildTypeReferenceInternal(typeReference, type, scope);
return buildTypeReferenceInternal(typeReference, type, scope, isTypeCast);
}

/**
Expand Down Expand Up @@ -173,11 +176,11 @@ private CtTypeParameterReference buildTypeParameterReference(TypeReference type,
if (type == null) {
return null;
}
return (CtTypeParameterReference) this.buildTypeReferenceInternal(this.getTypeParameterReference(type.resolvedType, type), type, scope);
return (CtTypeParameterReference) this.buildTypeReferenceInternal(this.getTypeParameterReference(type.resolvedType, type), type, scope, false);
}


private <T> CtTypeReference<T> buildTypeReferenceInternal(CtTypeReference<T> typeReference, TypeReference type, Scope scope) {
private <T> CtTypeReference<T> buildTypeReferenceInternal(CtTypeReference<T> typeReference, TypeReference type, Scope scope, boolean isTypeCast) {
if (type == null) {
return null;
}
Expand All @@ -187,7 +190,9 @@ private <T> CtTypeReference<T> buildTypeReferenceInternal(CtTypeReference<T> typ
if (currentReference == null) {
break;
}
this.jdtTreeBuilder.getContextBuilder().isBuildTypeCast = isTypeCast;
this.jdtTreeBuilder.getContextBuilder().enter(currentReference, type);
this.jdtTreeBuilder.getContextBuilder().isBuildTypeCast = false;
if (type.annotations != null && type.annotations.length - 1 <= position && type.annotations[position] != null && type.annotations[position].length > 0) {
for (Annotation annotation : type.annotations[position]) {
if (scope instanceof ClassScope) {
Expand Down

0 comments on commit 7dfeb7c

Please sign in to comment.