Skip to content

Commit

Permalink
Fix regressions introduced by #748
Browse files Browse the repository at this point in the history
* fix(array): Allows array in an array.
* fix(array): Builds dimensions with casts.
* fix(executable): Allows block in executable.
* fix(access): Qualified field access with import static.
* fix(actual): Rewrite actual types with their enclosing class.
  • Loading branch information
monperrus authored Aug 17, 2016
2 parents 74e519d + 4b106a3 commit 16160f9
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1679,7 +1679,10 @@ private void visitCtTypeReference(CtTypeReference<?> ref, boolean withGenerics)
printer.write(ref.getSimpleName());
}
if (withGenerics && !context.ignoreGenerics) {
final boolean old = context.ignoreEnclosingClass;
context.ignoreEnclosingClass = false;
elementPrinterHelper.writeActualTypeArguments(ref);
context.ignoreEnclosingClass = old;
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -940,8 +940,7 @@ public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {

// Create block
if (!methodDeclaration.isAbstract() && (methodDeclaration.modifiers & ClassFileConstants.AccNative) == 0) {
m.setBody(getFactory().Core().createBlock());
context.enter(m.getBody(), methodDeclaration);
context.enter(getFactory().Core().createBlock(), methodDeclaration);
context.exit(methodDeclaration);
}

Expand All @@ -955,8 +954,7 @@ public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope s
context.enter(c, constructorDeclaration);

// Create block
c.setBody(factory.Core().createBlock());
context.enter(c.getBody(), constructorDeclaration);
context.enter(factory.Core().createBlock(), constructorDeclaration);
context.exit(constructorDeclaration);

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ public boolean onAccess(char[][] tokens, int index) {
typeAccess.setPosition(
jdtTreeBuilder.getPositionBuilder().buildPosition(qualifiedNameReference.sourceStart(), (int) (positions[qualifiedNameReference.indexOfFirstFieldBinding - 1] >>> 32) - 2));
} else {
typeAccess.setImplicit(true);
typeAccess.setImplicit(qualifiedNameReference.isImplicitThis());
}

return typeAccess;
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/spoon/support/compiler/jdt/ParentExiter.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
Expand Down Expand Up @@ -256,7 +257,10 @@ public <A extends java.lang.annotation.Annotation> void visitCtAnnotation(CtAnno

@Override
public <T> void visitCtConstructor(CtConstructor<T> e) {
if (child instanceof CtStatement && !(child instanceof CtBlock)) {
if (e.getBody() == null && child instanceof CtBlock) {
e.setBody((CtBlock) child);
return;
} else if (child instanceof CtStatement) {
visitCtBlock(e.getBody());
return;
}
Expand All @@ -265,7 +269,10 @@ public <T> void visitCtConstructor(CtConstructor<T> e) {

@Override
public <T> void visitCtMethod(CtMethod<T> e) {
if (child instanceof CtStatement && !(child instanceof CtBlock)) {
if (e.getBody() == null && child instanceof CtBlock) {
e.setBody((CtBlock) child);
return;
} else if (child instanceof CtStatement) {
visitCtBlock(e.getBody());
return;
} else if (child instanceof CtTypeAccess && hasChildEqualsToType(e)) {
Expand Down Expand Up @@ -612,7 +619,7 @@ public <T> void visitCtNewArray(CtNewArray<T> newArray) {
} else if (child instanceof CtExpression) {
if (isContainedInDimensionExpression()) {
newArray.addDimensionExpression((CtExpression<Integer>) child);
} else if (child instanceof CtNewArray) {
} else if (child instanceof CtNewArray && childJDT instanceof ArrayInitializer && jdtTreeBuilder.getContextBuilder().stack.peek().node instanceof ArrayAllocationExpression) {
newArray.setElements(((CtNewArray) child).getElements());
} else {
newArray.addElement((CtExpression) child);
Expand All @@ -629,7 +636,7 @@ private boolean isContainedInDimensionExpression() {
return false;
}
for (Expression dimension : parent.dimensions) {
if (dimension != null && dimension.equals(childJDT)) {
if (dimension != null && getFinalExpressionFromCast(dimension).equals(childJDT)) {
return true;
}
}
Expand Down Expand Up @@ -662,7 +669,7 @@ private <T> boolean hasChildEqualsToEnclosingInstance(CtConstructorCall<T> ctCon
}
final QualifiedAllocationExpression parent = (QualifiedAllocationExpression) jdtTreeBuilder.getContextBuilder().stack.peek().node;
// Enclosing instance is equals to the jdt child.
return parent.enclosingInstance != null && parent.enclosingInstance.equals(childJDT)
return parent.enclosingInstance != null && getFinalExpressionFromCast(parent.enclosingInstance).equals(childJDT)
// Enclosing instance not yet initialized.
&& !child.equals(ctConstructorCall.getTarget());
}
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/spoon/test/arrays/ArraysTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static spoon.testing.utils.ModelUtils.build;

public class ArraysTest {
Expand Down Expand Up @@ -62,4 +63,17 @@ public void testInitializeWithNewArray() throws Exception {
assertEquals("new Type[list.size()]", local.toString());
}

@Test
public void testCtNewArrayInnerCtNewArray() throws Exception {
final Launcher launcher = new Launcher();
launcher.addInputResource("src/test/java/spoon/test/arrays/testclasses/Foo.java");
launcher.setSourceOutputDirectory("target/foo");
launcher.buildModel();
launcher.prettyprint();
try {
launcher.getModelBuilder().compile();
} catch (Exception e) {
fail(e.getMessage());
}
}
}
17 changes: 17 additions & 0 deletions src/test/java/spoon/test/arrays/testclasses/Foo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package spoon.test.arrays.testclasses;

import java.io.EOFException;

public class Foo {
public byte[] readByteArray(long byteCount) throws EOFException {
byte[] result = new byte[(int) byteCount];
return result;
}
String[] s = new String[] { "--help" };
protected static final int grad4[][] = {
{ 0, 1, 1, 1 }, { 0, 1, 1, -1 }, { 0, 1, -1, 1 }, { 0, 1, -1, -1 }, { 0, -1, 1, 1 }, { 0, -1, 1, -1 }, { 0, -1, -1, 1 }, { 0, -1, -1, -1 }, { 1, 0, 1, 1 }, { 1, 0, 1, -1 },
{ 1, 0, -1, 1 }, { 1, 0, -1, -1 }, { -1, 0, 1, 1 }, { -1, 0, 1, -1 }, { -1, 0, -1, 1 }, { -1, 0, -1, -1 }, { 1, 1, 0, 1 }, { 1, 1, 0, -1 }, { 1, -1, 0, 1 }, { 1, -1, 0, -1 },
{ -1, 1, 0, 1 }, { -1, 1, 0, -1 }, { -1, -1, 0, 1 }, { -1, -1, 0, -1 }, { 1, 1, 1, 0 }, { 1, 1, -1, 0 }, { 1, -1, 1, 0 }, { 1, -1, -1, 0 }, { -1, 1, 1, 0 }, { -1, 1, -1, 0 },
{ -1, -1, 1, 0 }, { -1, -1, -1, 0 }
};
}
11 changes: 11 additions & 0 deletions src/test/java/spoon/test/executable/ExecutableTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

import org.junit.Test;
import spoon.Launcher;
import spoon.reflect.code.CtBlock;
import spoon.reflect.declaration.CtAnonymousExecutable;
import spoon.reflect.declaration.CtType;
import spoon.reflect.visitor.Query;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.executable.testclasses.Pozole;
import spoon.testing.utils.ModelUtils;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class ExecutableTest {
@Test
Expand All @@ -29,4 +34,10 @@ public void testInfoInsideAnonymousExecutable() throws Exception {
assertEquals(0, anonymousExecutable.getThrownTypes().size());
}
}

@Test
public void testBlockInExecutable() throws Exception {
final CtType<Pozole> aPozole = ModelUtils.buildClass(Pozole.class);
assertTrue(aPozole.getMethod("m").getBody().getStatement(1) instanceof CtBlock);
}
}
8 changes: 8 additions & 0 deletions src/test/java/spoon/test/executable/testclasses/Pozole.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@ public void cook() {
public void run() {

}

void m() {
int i;
{
i = 0;
}
int x = 2 * i;
}
}
17 changes: 17 additions & 0 deletions src/test/java/spoon/test/imports/ImportTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import spoon.compiler.SpoonResourceHelper;
import spoon.reflect.code.CtConstructorCall;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLocalVariable;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtThisAccess;
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.declaration.CtClass;
Expand All @@ -25,6 +27,7 @@
import spoon.test.imports.testclasses.NotImportExecutableType;
import spoon.test.imports.testclasses.Pozole;
import spoon.test.imports.testclasses.SubClass;
import spoon.test.imports.testclasses.Tacos;
import spoon.test.imports.testclasses.internal.ChildClass;

import java.util.Arrays;
Expand Down Expand Up @@ -261,6 +264,20 @@ public void testImportOfInvocationOfStaticMethod() throws Exception {
assertEquals("spoon.test.imports.testclasses.internal2.Menudo", imports.toArray()[0].toString());
}

@Test
public void testImportStaticAndFieldAccess() throws Exception {
// contract: Qualified field access and an import static should rewrite in fully qualified mode.
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/imports/testclasses/internal4/");
launcher.addInputResource("./src/test/java/spoon/test/imports/testclasses/Tacos.java");
launcher.buildModel();

final CtType<Object> aTacos = launcher.getFactory().Type().get(Tacos.class);
final CtStatement assignment = aTacos.getMethod("m").getBody().getStatement(0);
assertTrue(assignment instanceof CtLocalVariable);
assertEquals("spoon.test.imports.testclasses.internal4.Constants.CONSTANT.foo", ((CtLocalVariable) assignment).getAssignment().toString());
}

private Factory getFactory(String...inputs) {
final Launcher launcher = new Launcher();
for (String input : inputs) {
Expand Down
9 changes: 9 additions & 0 deletions src/test/java/spoon/test/imports/testclasses/Tacos.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package spoon.test.imports.testclasses;

import static spoon.test.imports.testclasses.internal4.Constants.*;

public class Tacos {
void m() {
int i = CONSTANT.foo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package spoon.test.imports.testclasses.internal4;

public interface Constants {
Foo CONSTANT = new Foo();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package spoon.test.imports.testclasses.internal4;

public class Foo {
public int foo;
}
15 changes: 15 additions & 0 deletions src/test/java/spoon/test/reference/TypeReferenceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
import spoon.compiler.SpoonResource;
import spoon.compiler.SpoonResourceHelper;
import spoon.reflect.code.CtConstructorCall;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtFieldRead;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtNewClass;
import spoon.reflect.code.CtReturn;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtInterface;
Expand All @@ -25,6 +28,7 @@
import spoon.reflect.visitor.filter.ReferenceTypeFilter;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.reference.testclasses.EnumValue;
import spoon.test.reference.testclasses.Panini;
import spoon.testing.utils.ModelUtils;

import java.util.ArrayList;
Expand All @@ -40,6 +44,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static spoon.testing.utils.ModelUtils.buildClass;
import static spoon.testing.utils.ModelUtils.canBeBuilt;
import static spoon.testing.utils.ModelUtils.createFactory;

Expand Down Expand Up @@ -498,6 +503,16 @@ public void testReferenceName() throws Exception {
typeReference.setSimpleName("?");
}

@Test
public void testIgnoreEnclosingClassInActualTypes() throws Exception {
final CtType<Panini> aPanini = buildClass(Panini.class);
final CtStatement ctReturn = aPanini.getMethod("entryIterator").getBody().getStatement(0);
assertTrue(ctReturn instanceof CtReturn);
final CtExpression ctConstructorCall = ((CtReturn) ctReturn).getReturnedExpression();
assertTrue(ctConstructorCall instanceof CtConstructorCall);
assertEquals("spoon.test.reference.testclasses.Panini<K, V>.Itr<java.util.Map.Entry<K, V>>", ctConstructorCall.getType().toString());
}

class A {
class Tacos<K> {
}
Expand Down
34 changes: 34 additions & 0 deletions src/test/java/spoon/test/reference/testclasses/Panini.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package spoon.test.reference.testclasses;

import java.util.Iterator;
import java.util.Map;

public class Panini<K, V> {
Iterator<Map.Entry<K, V>> entryIterator() {
return new Itr<Map.Entry<K, V>>() {
@Override
Map.Entry<K, V> output(K key, V value) {
return null;
}
};
}

private abstract class Itr<T> implements Iterator<T> {
@Override
public T next() {
return null;
}

@Override
public boolean hasNext() {
return false;
}

@Override
public void remove() {

}

abstract T output(K key, V value);
}
}

0 comments on commit 16160f9

Please sign in to comment.