Skip to content

Commit

Permalink
fix(access): qualified fieldaccess in noclasspath mode (#762)
Browse files Browse the repository at this point in the history
  • Loading branch information
danglotb authored and GerardPaligot committed Jul 25, 2016
1 parent b6a9471 commit 92d7d51
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
22 changes: 22 additions & 0 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.code.CtWhile;
import spoon.reflect.code.UnaryOperatorKind;
import spoon.reflect.cu.CompilationUnit;
import spoon.reflect.declaration.CtAnnotatedElementType;
import spoon.reflect.declaration.CtAnnotation;
import spoon.reflect.declaration.CtAnonymousExecutable;
Expand Down Expand Up @@ -2102,6 +2103,27 @@ public boolean onAccess(char[][] tokens, int index) {
va = other;
i++;
}
} else if (qualifiedNameReference.tokens.length > 1) {
sourceStart = (int) (positions[0] >>> 32);
for (int i = 1; i < qualifiedNameReference.tokens.length; i++) {
char[] token = qualifiedNameReference.tokens[i];
CtFieldAccess<Object> other;
if (qualifiedNameReference.tokens.length == i + 1 && context.stack.peek().element instanceof CtAssignment) {
other = factory.Core().createFieldWrite();
} else {
other = factory.Core().createFieldRead();
}
CtFieldReference fieldReference = factory.Core().createFieldReference();
fieldReference.setSimpleName(new String(token));
other.setVariable(fieldReference);
other.setTarget(va);
//set source position of va;
CompilationUnit cu = factory.CompilationUnit().create(new String(context.compilationunitdeclaration.getFileName()));
sourceEnd = (int) (positions[i]);
final int[] lineSeparatorPositions = context.compilationunitdeclaration.compilationResult.lineSeparatorPositions;
va.setPosition(factory.Core().createSourcePosition(cu, sourceStart, sourceStart, sourceEnd, lineSeparatorPositions));
va = other;
}
}
va.setPosition(this.position.buildPosition(qualifiedNameReference.sourceStart(), qualifiedNameReference.sourceEnd()));
context.enter(va, qualifiedNameReference);
Expand Down
35 changes: 31 additions & 4 deletions src/test/java/spoon/test/fieldaccesses/FieldAccessTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.visitor.CtScanner;
import spoon.reflect.visitor.DefaultJavaPrettyPrinter;
import spoon.reflect.visitor.Query;
import spoon.reflect.visitor.filter.NameFilter;
Expand Down Expand Up @@ -139,14 +140,14 @@ public void testBUG20160112() throws Exception {
CtType<?> type = build("spoon.test.fieldaccesses", "BUG20160112");
assertEquals("BUG20160112", type.getSimpleName());
CtOperatorAssignment<?, ?> ass = type.getElements(
new TypeFilter<CtOperatorAssignment<?,?>>(CtOperatorAssignment.class)).get(0);
new TypeFilter<CtOperatorAssignment<?, ?>>(CtOperatorAssignment.class)).get(0);
assertNotNull("z+=a.us", ass);
CtExpression<?> righthand = ass.getAssignment();
assertTrue("a.us should be CtFieldRead", righthand instanceof CtFieldRead);
}

@Test
public void testTargetedAccessPosition() throws Exception{
public void testTargetedAccessPosition() throws Exception {
CtType<?> type = build("spoon.test.fieldaccesses", "TargetedAccessPosition");
List<CtFieldAccess<?>> vars = type.getElements(
new TypeFilter<CtFieldAccess<?>>(CtFieldAccess.class));
Expand All @@ -162,8 +163,8 @@ public void testTargetedAccessPosition() throws Exception{
assertEquals(3, vars.get(0).getTarget().getPosition().getSourceEnd() - vars.get(0).getTarget().getPosition().getSourceStart());

// 0 is length(t)-1
assertEquals(0, ((CtFieldAccess<?>)vars.get(0).getTarget()).getTarget().getPosition().getSourceEnd() -
((CtFieldAccess<?>)vars.get(0).getTarget()).getTarget().getPosition().getSourceStart());
assertEquals(0, ((CtFieldAccess<?>) vars.get(0).getTarget()).getTarget().getPosition().getSourceEnd() -
((CtFieldAccess<?>) vars.get(0).getTarget()).getTarget().getPosition().getSourceStart());
}

@Test
Expand Down Expand Up @@ -351,4 +352,30 @@ public void testFieldAccessWithoutAnyImport() throws Exception {
assertEquals(0, printer.computeImports(aType).size());
assertEquals("spoon.test.fieldaccesses.testclasses.Mole.Delicious delicious", aType.getMethodsByName("m").get(0).getParameters().get(0).toString());
}

@Test
public void testFieldAccessOnUnknownType() throws Exception {
final Launcher launcher = new Launcher();

launcher.addInputResource("./src/test/resources/noclasspath/FieldAccessRes.java");

launcher.getEnvironment().setNoClasspath(true);

launcher.buildModel();

class CounterScanner extends CtScanner {
private int visited = 0;
@Override
public <T> void visitCtFieldWrite(CtFieldWrite<T> fieldWrite) {
visited++;
assertEquals("array", ((CtVariableWrite) fieldWrite.getTarget()).getVariable().getSimpleName());
assertEquals("length", fieldWrite.getVariable().getSimpleName());
}
}

CounterScanner scanner = new CounterScanner();
launcher.getFactory().Class().get("FieldAccessRes").accept(scanner);

assertEquals(1, scanner.visited);
}
}
8 changes: 8 additions & 0 deletions src/test/resources/noclasspath/FieldAccessRes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
public class FieldAccessRes {

void method() {
A [] array = new A[10];
array.length = 5;
}

}

0 comments on commit 92d7d51

Please sign in to comment.