From 4db4efe9f454c8f9587cf5edea210226ab237f0d Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Mon, 18 Apr 2016 12:42:11 +0200 Subject: [PATCH] adds support for incremental model (#584) --- src/main/java/spoon/reflect/CtModel.java | 18 +++++++- src/main/java/spoon/reflect/CtModelImpl.java | 20 ++++++++- .../reflect/declaration/CtPackageImpl.java | 41 ++++++++++++++++--- .../java/spoon/test/factory/FactoryTest.java | 35 ++++++++++++++++ .../spoon/test/factory/testclasses2/Baz.java | 4 ++ 5 files changed, 110 insertions(+), 8 deletions(-) create mode 100644 src/test/java/spoon/test/factory/testclasses2/Baz.java diff --git a/src/main/java/spoon/reflect/CtModel.java b/src/main/java/spoon/reflect/CtModel.java index 756f0a3f86a..1376c0805ed 100644 --- a/src/main/java/spoon/reflect/CtModel.java +++ b/src/main/java/spoon/reflect/CtModel.java @@ -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; @@ -21,6 +37,6 @@ public interface CtModel { Collection getAllPackages(); /** process this model with the given processor */ - void processWith(Processor abstractProcessor); + void processWith(Processor processor); } diff --git a/src/main/java/spoon/reflect/CtModelImpl.java b/src/main/java/spoon/reflect/CtModelImpl.java index 6c50c228dd0..2da062b8308 100644 --- a/src/main/java/spoon/reflect/CtModelImpl.java +++ b/src/main/java/spoon/reflect/CtModelImpl.java @@ -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; @@ -78,12 +94,12 @@ public Collection> getAllTypes() { @Override public Collection getAllPackages() { - return Collections.unmodifiableCollection(rootPackage.getElements(new TypeFilter<>(CtPackage.class))); + return Collections.unmodifiableCollection(rootPackage.getElements(new TypeFilter(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()); diff --git a/src/main/java/spoon/support/reflect/declaration/CtPackageImpl.java b/src/main/java/spoon/support/reflect/declaration/CtPackageImpl.java index eb93638a914..fc49cdb4f99 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtPackageImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtPackageImpl.java @@ -16,15 +16,15 @@ */ 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.reference.CtPackageReference; import spoon.reflect.visitor.CtVisitor; -import java.util.Set; -import java.util.TreeSet; - /** * The implementation for {@link spoon.reflect.declaration.CtPackage}. * @@ -33,7 +33,7 @@ public class CtPackageImpl extends CtNamedElementImpl implements CtPackage { private static final long serialVersionUID = 1L; - private Set packs = new TreeSet(); + protected Set packs = new TreeSet(); private Set> types = new TreeSet>(); @@ -48,11 +48,42 @@ public void accept(CtVisitor v) { @Override public 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); diff --git a/src/test/java/spoon/test/factory/FactoryTest.java b/src/test/java/spoon/test/factory/FactoryTest.java index 0bce360c4a2..47e47ce4683 100644 --- a/src/test/java/spoon/test/factory/FactoryTest.java +++ b/src/test/java/spoon/test/factory/FactoryTest.java @@ -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() { + @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()); + } + } diff --git a/src/test/java/spoon/test/factory/testclasses2/Baz.java b/src/test/java/spoon/test/factory/testclasses2/Baz.java new file mode 100644 index 00000000000..00f4d3a2312 --- /dev/null +++ b/src/test/java/spoon/test/factory/testclasses2/Baz.java @@ -0,0 +1,4 @@ +package spoon.test.factory.testclasses2; + +public class Baz { +}