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

org.evosuite.instrumentation.PurityAnalysisClassVisitor Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
 * contributors
 *
 * This file is part of EvoSuite.
 *
 * EvoSuite is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3.0 of the License, or
 * (at your option) any later version.
 *
 * EvoSuite 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 GNU
 * Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with EvoSuite. If not, see .
 */
package org.evosuite.instrumentation;

import java.util.HashMap;

import org.evosuite.assertion.CheapPurityAnalyzer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

/**
 * It launches a PurityAnalysisMethodVisitor on each method.
 * This class only reads the existing bytecode.
 * 
 * @author Juan Galeotti
 */
public class PurityAnalysisClassVisitor extends ClassVisitor {

	private final CheapPurityAnalyzer purityAnalyzer;

	public static class MethodEntry {
		private final String className;
		private final String methodName;
		private final String descriptor;

		public MethodEntry(String className, String methodName,
				String descriptor) {
			this.className = className;
			this.methodName = methodName;
			this.descriptor = descriptor;
		}

		@Override
		public boolean equals(Object o) {
			if (o == null)
				return false;

			if (!o.getClass().equals(MethodEntry.class))
				return false;

			MethodEntry that = (MethodEntry) o;

			return this.className.equals(that.className)
					&& this.methodName.equals(that.methodName)
					&& this.descriptor.equals(that.descriptor);
		}

		@Override
		public int hashCode() {
			return this.className.hashCode() + this.methodName.hashCode()
					+ this.descriptor.hashCode();
		}
	}

	private final String className;
	private final HashMap method_adapters = new HashMap();

	/**
	 * 

* Constructor for StaticInitializationClassAdapter. *

* * @param visitor * a {@link org.objectweb.asm.ClassVisitor} object. * @param className * a {@link java.lang.String} object. */ public PurityAnalysisClassVisitor(ClassVisitor visitor, String className, CheapPurityAnalyzer purityAnalyzer) { super(Opcodes.ASM5, visitor); this.className = className; this.purityAnalyzer = purityAnalyzer; } /** {@inheritDoc} */ @Override public MethodVisitor visitMethod(int methodAccess, String name, String descriptor, String signature, String[] exceptions) { if (visitingInterface == true) { purityAnalyzer.addInterfaceMethod(className.replace('/', '.'), name, descriptor); } else { purityAnalyzer.addMethod(className.replace('/', '.'), name, descriptor); if ((methodAccess & Opcodes.ACC_ABSTRACT) != Opcodes.ACC_ABSTRACT) { purityAnalyzer.addMethodWithBody(className.replace('/', '.'), name, descriptor); } else { // The declaration of this method is abstract. So // there is no method body for this method in this class } } MethodVisitor mv = super.visitMethod(methodAccess, name, descriptor, signature, exceptions); PurityAnalysisMethodVisitor purityAnalysisMethodVisitor = new PurityAnalysisMethodVisitor( className, name, descriptor, mv, purityAnalyzer); MethodEntry methodEntry = new MethodEntry(className, name, descriptor); this.method_adapters.put(methodEntry, purityAnalysisMethodVisitor); return purityAnalysisMethodVisitor; } @Override public void visitEnd() { for (MethodEntry method_entry : this.method_adapters.keySet()) { if (this.method_adapters.get(method_entry).updatesField()) { purityAnalyzer.addUpdatesFieldMethod(method_entry.className, method_entry.methodName, method_entry.descriptor); } } } private boolean visitingInterface = false; @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { if ((access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) { visitingInterface = true; } super.visit(version, access, name, signature, superName, interfaces); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy