Skip to content

Commit

Permalink
adds support for incremental model (#584)
Browse files Browse the repository at this point in the history
  • Loading branch information
monperrus committed Apr 18, 2016
1 parent 4f40102 commit 66c945c
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 12 deletions.
18 changes: 17 additions & 1 deletion src/main/java/spoon/reflect/CtModel.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* Copyright (C) 2006-2015 INRIA and contributors
* Spoon - http://spoon.gforge.inria.fr/
*
* This software is governed by the CeCILL-C License under French law and
* abiding by the rules of distribution of free software. You can use, modify
* and/or redistribute the software under the terms of the CeCILL-C license as
* circulated by CEA, CNRS and INRIA at http://www.cecill.info.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
package spoon.reflect;

import java.util.Collection;
Expand All @@ -21,6 +37,6 @@ public interface CtModel {
Collection<CtPackage> getAllPackages();

/** process this model with the given processor */
void processWith(Processor<?> abstractProcessor);
void processWith(Processor<?> processor);

}
20 changes: 18 additions & 2 deletions src/main/java/spoon/reflect/CtModelImpl.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* Copyright (C) 2006-2015 INRIA and contributors
* Spoon - http://spoon.gforge.inria.fr/
*
* This software is governed by the CeCILL-C License under French law and
* abiding by the rules of distribution of free software. You can use, modify
* and/or redistribute the software under the terms of the CeCILL-C license as
* circulated by CEA, CNRS and INRIA at http://www.cecill.info.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
package spoon.reflect;

import java.util.Collection;
Expand Down Expand Up @@ -78,12 +94,12 @@ public Collection<CtType<?>> getAllTypes() {

@Override
public Collection<CtPackage> getAllPackages() {
return Collections.unmodifiableCollection(rootPackage.getElements(new TypeFilter<>(CtPackage.class)));
return Collections.unmodifiableCollection(rootPackage.getElements(new TypeFilter<CtPackage>(CtPackage.class)));
}


@Override
public void processWith(Processor<?> abstractProcessor) {
public void processWith(Processor<?> processor) {
// processing (consume all the processors)
ProcessingManager processing = new QueueProcessingManager(rootPackage.getFactory());
processing.process(getRootPackage());
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/spoon/reflect/declaration/CtPackage.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public interface CtPackage extends CtNamedElement {
String TOP_LEVEL_PACKAGE_NAME = "unnamed package";

/**
* Gets the declaring package of the current one.
* Gets the declaring package of the current one. Returns null if the package is not yet in another one.
*/
CtPackage getDeclaringPackage();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public abstract class CtNamedElementImpl extends CtElementImpl implements CtName

private static final long serialVersionUID = 1L;

String simpleName;
String simpleName = "";

@Override
public CtReference getReference() {
Expand Down
48 changes: 42 additions & 6 deletions src/main/java/spoon/support/reflect/declaration/CtPackageImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
*/
package spoon.support.reflect.declaration;

import java.util.Set;
import java.util.TreeSet;

import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.ParentNotInitializedException;
import spoon.reflect.reference.CtPackageReference;
import spoon.reflect.visitor.CtVisitor;

import java.util.Set;
import java.util.TreeSet;

/**
* The implementation for {@link spoon.reflect.declaration.CtPackage}.
*
Expand All @@ -33,7 +34,7 @@
public class CtPackageImpl extends CtNamedElementImpl implements CtPackage {
private static final long serialVersionUID = 1L;

private Set<CtPackage> packs = new TreeSet<CtPackage>();
protected Set<CtPackage> packs = new TreeSet<CtPackage>();

private Set<CtType<?>> types = new TreeSet<CtType<?>>();

Expand All @@ -48,19 +49,54 @@ public void accept(CtVisitor v) {

@Override
public <T extends CtPackage> T addPackage(CtPackage pack) {
// they are the same
if (this.getQualifiedName().equals(pack.getQualifiedName())) {
addAllTypes(pack, this);
addAllPackages(pack, this);
return (T) this;
}

// it already exists
for (CtPackage p1 : packs) {
if (p1.getQualifiedName().equals(pack.getQualifiedName())) {
addAllTypes(pack, p1);
addAllPackages(pack, p1);
return (T) this;
}
}

this.packs.add(pack);
pack.setParent(this);
packs.add(pack);

return (T) this;
}

/** add all types of "from" in "to" */
private void addAllTypes(CtPackage from, CtPackage to) {
for (CtType t : from.getTypes()) {
to.addType(t);
}
}

/** add all packages of "from" in "to" */
private void addAllPackages(CtPackage from, CtPackage to) {
for (CtPackage p : from.getPackages()) {
to.addPackage(p);
}
}

@Override
public boolean removePackage(CtPackage pack) {
return packs.remove(pack);
}

@Override
public CtPackage getDeclaringPackage() {
return getParent(CtPackage.class);
try {
return getParent(CtPackage.class);
} catch (ParentNotInitializedException e) {
return null;
}
}

@Override
Expand Down
35 changes: 35 additions & 0 deletions src/test/java/spoon/test/factory/FactoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,39 @@ public void testCtModel() throws Exception {
// [, spoon, spoon.test, spoon.test.factory, spoon.test.factory.testclasses]
assertEquals(5, model.getAllPackages().size());
}

@Test
public void testIncrementalModel() throws Exception {

// Feed some inputResources to a spoon compiler
SpoonAPI spoon = new Launcher();
spoon.addInputResource("src/test/java/spoon/test/factory/testclasses");

// Build model
spoon.buildModel();

// Do something with that model..
CtModel model = spoon.getModel();
model.processWith(new AbstractProcessor<CtMethod>() {
@Override
public void process(CtMethod element) {
element.setDefaultMethod(false);
}
});

// Feed some new inputResources
SpoonAPI spoon2 = new Launcher();
spoon2.addInputResource("src/test/java/spoon/test/factory/testclasses2");

// Build models of newly added classes/packages
spoon2.buildModel();

// attach them to the existing model.
model.getRootPackage().addPackage(spoon2.getModel().getRootPackage());

// checking the results
assertEquals(6, model.getAllPackages().size());
assertEquals(3, model.getAllTypes().size());
}

}
4 changes: 4 additions & 0 deletions src/test/java/spoon/test/factory/testclasses2/Baz.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package spoon.test.factory.testclasses2;

public class Baz {
}
11 changes: 10 additions & 1 deletion src/test/java/spoon/test/parent/ParentContractTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mockito;

import spoon.SpoonException;
import spoon.reflect.code.CtCatchVariable;
import spoon.reflect.code.CtConstructorCall;
import spoon.reflect.code.CtInvocation;
Expand All @@ -20,6 +22,7 @@
import spoon.reflect.reference.CtReference;
import spoon.reflect.visitor.CtVisitable;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -130,7 +133,13 @@ public void testContract() throws Throwable {
// we check that setParent has been called
verify(mockedArgument).setParent((CtElement) receiver);
} catch (AssertionError e) {
Assert.fail("call setParent contract failed for "+setter.toString()+" "+e.toString());
Assert.fail("call setParent contract failed for "+setter.toString()+" "+e.toString());
} catch (InvocationTargetException e) {
if (e.getCause() instanceof RuntimeException) {
throw e.getCause();
} else {
throw new SpoonException(e.getCause());
}
}
}
}
Expand Down

0 comments on commit 66c945c

Please sign in to comment.