spoon.examples.analysis.processing.ReferenceProcessor Maven / Gradle / Ivy
The newest version!
package spoon.examples.analysis.processing;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
import spoon.processing.AbstractProcessor;
import spoon.processing.Environment;
import spoon.processing.FactoryAccessor;
import spoon.processing.Severity;
import spoon.reflect.Factory;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtSimpleType;
import spoon.reflect.reference.CtPackageReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.Query;
import spoon.reflect.visitor.filter.ReferenceTypeFilter;
/**
* Finds circular dependencies between packages and report warnings when found.
*/
public class ReferenceProcessor extends AbstractProcessor {
List> ignoredTypes = new ArrayList>();
@Override
public void init() {
ignoredTypes
.add(getFactory().Type().createReference(Environment.class));
ignoredTypes.add(getFactory().Type().createReference(Factory.class));
ignoredTypes.add(getFactory().Type().createReference(
FactoryAccessor.class));
}
Map> packRefs = new HashMap>();
public void process(CtPackage element) {
CtPackageReference pack = element.getReference();
Set refs = new TreeSet();
for (CtSimpleType> t : element.getTypes()) {
for (CtTypeReference> tref : Query.getReferences(t,
new ReferenceTypeFilter>(
CtTypeReference.class))) {
if (tref.getPackage() != null
&& !tref.getPackage().equals(pack)) {
if (ignoredTypes.contains(tref))
continue;
refs.add(tref.getPackage());
}
}
}
if (refs.size() > 0)
packRefs.put(pack, refs);
// if (getFactory().getEnvironment().isVerbose())
// System.out.println(refs);
}
@Override
public void processingDone() {
// getFactory().getEnvironment().reportMessage(
// "package dependencies: " + packRefs);
// getFactory().getEnvironment().reportMessage(
// "looking for circular package dependencies...");
// looking for circular dependecies
for (CtPackageReference p : packRefs.keySet()) {
Stack path = new Stack();
path.push(p);
scanDependencies(path);
}
}
Set scanned = new TreeSet();
void scanDependencies(Stack path) {
// getFactory().getEnvironment().reportMessage("scanning " + path);
CtPackageReference ref = path.peek();
// return if already scanned
if (scanned.contains(ref))
return;
scanned.add(ref);
Set refs = packRefs.get(ref);
if (refs != null) {
for (CtPackageReference p : refs) {
if (path.contains(p)) {
List circularPath = new ArrayList(
path.subList(path.indexOf(p), path.size()));
circularPath.add(p);
getEnvironment().report(this,
Severity.WARNING,
"circular dependency " + circularPath);
break;
} else {
path.push(p);
scanDependencies(path);
path.pop();
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy