All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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