Skip to content
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

feat(field): Adds field at the top of a type. #537

Merged
merged 1 commit into from
Feb 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/main/java/spoon/reflect/declaration/CtType.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,16 @@ public interface CtType<T> extends CtNamedElement, CtTypeInformation, CtTypeMemb
boolean isTopLevel();

/**
* add a Field
* Adds a field at the top of the type (before static block).
* Note that the position of these field will be negative to be written at the top of the type.
*
* @param field
* @return <tt>true</tt> if the field is added.
*/
<F, C extends CtType<T>> C addFieldAtTop(CtField<F> field);

/**
* add a field at the end of the field list.
*
* @param field
* @return <tt>true</tt> if this element changed as a result of the call
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package spoon.support.reflect.declaration;

import spoon.reflect.cu.CompilationUnit;
import spoon.reflect.declaration.CtAnnotation;
import spoon.reflect.declaration.CtAnnotationType;
import spoon.reflect.declaration.CtClass;
Expand Down Expand Up @@ -75,6 +76,22 @@ public CtTypeImpl() {
super();
}

@Override
public <F, C extends CtType<T>> C addFieldAtTop(CtField<F> field) {
if (!this.fields.contains(field)) {
field.setParent(this);
CompilationUnit compilationUnit = null;
if (getPosition() != null) {
compilationUnit = getPosition().getCompilationUnit();
}
field.setPosition(getFactory().Core().createSourcePosition(compilationUnit, -1, -1, -1, new int[0]));
this.fields.add(field);
}

// field already exists
return (C) this;
}

@Override
public <F, C extends CtType<T>> C addField(CtField<F> field) {
if (!this.fields.contains(field)) {
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/spoon/test/field/FieldTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,21 @@

import org.junit.Test;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.ModifierKind;
import spoon.reflect.factory.Factory;
import spoon.support.reflect.cu.CtLineElementComparator;
import spoon.support.util.SortedList;
import spoon.test.field.testclasses.AddFieldAtTop;

import java.io.File;
import java.util.HashSet;

import static org.junit.Assert.assertEquals;
import static spoon.testing.Assert.assertThat;
import static spoon.testing.utils.ModelUtils.build;
import static spoon.testing.utils.ModelUtils.buildClass;
import static spoon.testing.utils.ModelUtils.createFactory;

public class FieldTest {
Expand Down Expand Up @@ -53,6 +61,30 @@ public void testAddAFieldInAClassAtAPositionGiven() throws Exception {
assertEquals(second, fieldClass.getFields().get(2));
}

@Test
public void testAddFieldsAtTop() throws Exception {
// contract: When we use CtType#addFieldAtTop, field added should be printed at the top of the type.
final CtClass<AddFieldAtTop> aClass = (CtClass<AddFieldAtTop>) buildClass(AddFieldAtTop.class);

assertEquals(1, aClass.getFields().size());

final CtField<String> generated = aClass.getFactory().Field().create(null, new HashSet<>(), aClass.getFactory().Type().STRING, "generated");
aClass.addFieldAtTop(generated);
final CtField<String> generated2 = aClass.getFactory().Field().create(null, new HashSet<>(), aClass.getFactory().Type().STRING, "generated2");
aClass.addFieldAtTop(generated2);

assertEquals(3, aClass.getFields().size());
// For now, DefaultJavaPrettyPrinter sorts elements according to their position.
final SortedList<CtElement> sorted = new SortedList<CtElement>(new CtLineElementComparator());
sorted.addAll(aClass.getFields());
sorted.addAll(aClass.getAnonymousExecutables());
assertEquals(generated, sorted.get(0));
assertEquals(generated2, sorted.get(1));
assertEquals(aClass.getAnonymousExecutables().get(0), sorted.get(2));

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add assert that they are before a static block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert is already there at the next line.

assertThat(aClass).isEqualTo(build(new File("./src/test/resources/expected/AddFieldAtTop.java")).Type().get("AddFieldAtTop"));
}

private CtField<Integer> createField(Factory factory, HashSet<ModifierKind> modifiers, String name) {
final CtField<Integer> first = factory.Core().createField();
first.setModifiers(modifiers);
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/spoon/test/field/testclasses/AddFieldAtTop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package spoon.test.field.testclasses;

public class AddFieldAtTop {

static {
}

int i;

void m() {
}
}
13 changes: 13 additions & 0 deletions src/test/resources/expected/AddFieldAtTop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
public class AddFieldAtTop {
java.lang.String generated;

java.lang.String generated2;

static {
}

int i;

void m() {
}
}