Skip to content

Commit

Permalink
feature(API): add CtTypeMember.getTopLevelType() (#1004)
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky authored and monperrus committed Nov 26, 2016
1 parent 60dd786 commit ddf4db5
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 12 deletions.
6 changes: 6 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtTypeMember.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ public interface CtTypeMember extends CtModifiable {
@DerivedProperty
CtType<?> getDeclaringType();

/**
* Returns the top level type declaring this type if an inner type or type member.
* If this is already a top-level type, then returns itself.
*/
@DerivedProperty
<T> CtType<T> getTopLevelType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package spoon.support.reflect.declaration;

import spoon.reflect.declaration.CtAnonymousExecutable;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtModifiable;
import spoon.reflect.declaration.CtNamedElement;
Expand Down Expand Up @@ -61,11 +60,6 @@ public Set<ModifierKind> getModifiers() {
return modifiers;
}

@Override
public CtClass<?> getDeclaringType() {
return (CtClass<?>) parent;
}

@Override
public ModifierKind getVisibility() {
if (getModifiers().contains(ModifierKind.PUBLIC)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.declaration.CtType;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.support.util.QualifiedNameBasedSortedSet;
Expand All @@ -50,6 +51,14 @@ public CtExecutableImpl() {
super();
}

public CtType<?> getDeclaringType() {
return (CtType<?>) parent;
}

public <T> CtType<T> getTopLevelType() {
return getDeclaringType().getTopLevelType();
}

@Override
@SuppressWarnings("unchecked")
public CtBlock<R> getBody() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public CtType<?> getDeclaringType() {
return (CtType<?>) parent;
}

@Override
public <T> CtType<T> getTopLevelType() {
return getDeclaringType().getTopLevelType();
}

@Override
public CtExpression<T> getDefaultExpression() {
return defaultExpression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtModifiable;
import spoon.reflect.declaration.CtShadowable;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtTypeParameter;
import spoon.reflect.declaration.CtTypedElement;
import spoon.reflect.declaration.ModifierKind;
Expand Down Expand Up @@ -77,11 +76,6 @@ public <C extends CtTypedElement> C setType(CtTypeReference<T> type) {
return (C) this;
}

@Override
public CtType<?> getDeclaringType() {
return (CtType<?>) parent;
}

@Override
public boolean isDefaultMethod() {
return defaultMethod;
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,20 @@ public CtType<?> getDeclaringType() {
}
}

@SuppressWarnings("unchecked")
@Override
public <T> CtType<T> getTopLevelType() {
CtType<?> top = this;

while (true) {
CtType<?> nextTop = top.getDeclaringType();
if (nextTop == null) {
return (CtType<T>) top;
}
top = nextTop;
}
}

@Override
@SuppressWarnings("unchecked")
public <N extends CtType<?>> N getNestedType(final String name) {
Expand Down
46 changes: 46 additions & 0 deletions src/test/java/spoon/test/parent/TopLevelTypeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package spoon.test.parent;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

import spoon.Launcher;
import spoon.compiler.SpoonResourceHelper;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.factory.Factory;

public class TopLevelTypeTest
{
Factory factory;

@Before
public void setup() throws Exception {
Launcher spoon = new Launcher();
spoon.setArgs(new String[] {"--output-type", "nooutput" });
factory = spoon.createFactory();
spoon.createCompiler(
factory,
SpoonResourceHelper
.resources("./src/test/java/spoon/test/parent/Foo.java"))
.build();
}


@Test
public void testTopLevelType() throws Exception {
CtClass<?> foo = factory.Class().get(Foo.class);
assertEquals(foo, foo.getTopLevelType());
CtMethod<?> internalClassMethod = foo.getMethod("internalClass");
assertEquals(foo, internalClassMethod.getDeclaringType());
assertEquals(foo, internalClassMethod.getTopLevelType());
CtClass<?> internalClass = (CtClass<?>)internalClassMethod.getBody().getStatement(0);
assertEquals(foo, internalClassMethod.getDeclaringType());
assertEquals(foo, internalClassMethod.getTopLevelType());
CtMethod<?> mm = internalClass.getMethod("m");
assertEquals(internalClass, mm.getDeclaringType());
assertEquals(foo, mm.getTopLevelType());
}

}

0 comments on commit ddf4db5

Please sign in to comment.