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

spoon.reflect.factory.CodeFactory Maven / Gradle / Ivy

/* 
 * Spoon - http://spoon.gforge.inria.fr/
 * Copyright (C) 2006 INRIA Futurs 
 * 
 * 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.factory;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import spoon.reflect.code.BinaryOperatorKind;
import spoon.reflect.code.CtAssignment;
import spoon.reflect.code.CtBinaryOperator;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtCodeSnippetExpression;
import spoon.reflect.code.CtCodeSnippetStatement;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtFieldAccess;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.code.CtLocalVariable;
import spoon.reflect.code.CtNewArray;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtStatementList;
import spoon.reflect.code.CtThisAccess;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.declaration.CtNamedElement;
import spoon.reflect.declaration.CtVariable;
import spoon.reflect.declaration.ModifierKind;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.reference.CtLocalVariableReference;
import spoon.reflect.reference.CtReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.reference.CtVariableReference;

/**
 * This sub-factory contains utility methods to create code elements. To avoid
 * over-using reflection, consider using {@link spoon.template.Template}.
 */
public class CodeFactory extends SubFactory {

	private static final long serialVersionUID = 1L;

	/**
	 * Creates a {@link spoon.reflect.code.CtCodeElement} sub-factory.
	 */
	public CodeFactory(Factory factory) {
		super(factory);
	}

	/**
	 * Creates a binary operator.
	 * 
	 * @param 
	 *            the type of the expression
	 * @param left
	 *            the left operand
	 * @param right
	 *            the right operand
	 * @param kind
	 *            the operator kind
	 * @return a binary operator expression
	 */
	public  CtBinaryOperator createBinaryOperator(CtExpression left,
			CtExpression right, BinaryOperatorKind kind) {
		CtBinaryOperator op = factory.Core().createBinaryOperator();
		op.setLeftHandOperand(left);
		op.setRightHandOperand(right);
		op.setKind(kind);
		return op;
	}

	/**
	 * Creates a class access expression of the form C.class.
	 * 
	 * @param 
	 *            the actual type of the accessed class if available
	 * @param type
	 *            a type reference to the accessed class
	 * @return the class access expression.
	 */
	public  CtFieldAccess> createClassAccess(CtTypeReference type) {
		CtFieldAccess> ca = factory.Core().createFieldAccess();
		@SuppressWarnings({ "rawtypes", "unchecked" })
		CtTypeReference> classType = (CtTypeReference) factory.Type()
				.createReference(Class.class);

		ca.setType(classType);
		CtFieldReference> field = factory.Core()
				.createFieldReference();
		field.setDeclaringType(type);
		field.setType(classType);
		field.setSimpleName("class");
		ca.setVariable(field);
		return ca;
	}

	/**
	 * Creates an invocation (can be a statement or an expression).
	 * 
	 * @param 
	 *            the return type of the invoked method
	 * @param target
	 *            the target expression
	 * @param executable
	 *            the invoked executable
	 * @param arguments
	 *            the argument list
	 * @return the new invocation
	 */
	public  CtInvocation createInvocation(CtExpression target,
			CtExecutableReference executable, CtExpression... arguments) {
		List> ext = new ArrayList>();
		for (CtExpression arg : arguments) {
			ext.add(arg);
		}
		return createInvocation(target, executable, ext);
	}

	/**
	 * Creates an invocation (can be a statement or an expression).
	 * 
	 * @param 
	 *            the return type of the invoked method
	 * @param target
	 *            the target expression
	 * @param executable
	 *            the invoked executable
	 * @param arguments
	 *            the argument list
	 * @return the new invocation
	 */
	public  CtInvocation createInvocation(CtExpression target,
			CtExecutableReference executable, List> arguments) {
		CtInvocation invocation = factory.Core().createInvocation();
		invocation.setTarget(target);
		invocation.setExecutable(executable);
		invocation.setArguments(arguments);
		return invocation;
	}

	/**
	 * Creates a literal with a given value.
	 * 
	 * @param 
	 *            the type of the literal
	 * @param value
	 *            the value of the litteral
	 * @return a new literal
	 */
	public  CtLiteral createLiteral(T value) {
		CtLiteral l = factory.Core().createLiteral();
		l.setValue(value);
		return l;
	}

	/**
	 * Creates a one-dimension array that must only contain literals.
	 */
	@SuppressWarnings("unchecked")
	public  CtNewArray createLiteralArray(T[] value) {
		if (!value.getClass().isArray())
			throw new RuntimeException("value is not an array");
		if (value.getClass().getComponentType().isArray())
			throw new RuntimeException("can only create one-dimension arrays");
		CtNewArray array = factory.Core().createNewArray();
		array.setType(factory.Type().createArrayReference(
				factory.Type().createReference(
						(Class) value.getClass().getComponentType())));
		for (T e : value) {
			CtLiteral l = factory.Core().createLiteral();
			l.setValue(e);
			array.getElements().add(l);
		}
		return array;
	}

	/**
	 * Creates a local variable declaration.
	 * 
	 * @param 
	 *            the local variable type
	 * @param type
	 *            the reference to the type
	 * @param name
	 *            the name of the variable
	 * @param defaultExpression
	 *            the assigned default expression
	 * @return a new local variable declaration
	 */
	public  CtLocalVariable createLocalVariable(CtTypeReference type,
			String name, CtExpression defaultExpression) {
		CtLocalVariable var = factory.Core().createLocalVariable();
		var.setSimpleName(name);
		var.setType(type);
		var.setDefaultExpression(defaultExpression);
		return var;
	}

	/**
	 * Creates a local variable reference that points to an existing local
	 * variable (strong referencing).
	 */
	public  CtLocalVariableReference createLocalVariableReference(
			CtLocalVariable localVariable) {
		CtLocalVariableReference ref = factory.Core()
				.createLocalVariableReference();
		ref.setType(localVariable.getType());
		ref.setSimpleName(localVariable.getSimpleName());
		ref.setDeclaration(localVariable);
		return ref;
	}

	/**
	 * Creates a local variable reference with its name an type (weak
	 * referencing).
	 */
	public  CtLocalVariableReference createLocalVariableReference(
			CtTypeReference type, String name) {
		CtLocalVariableReference ref = factory.Core()
				.createLocalVariableReference();
		ref.setType(type);
		ref.setSimpleName(name);
		return ref;
	}

	/**
	 * Creates a new statement list from an existing block.
	 */
	public  CtStatementList createStatementList(CtBlock block) {
		CtStatementList l = factory.Core().createStatementList();
		for (CtStatement s : block.getStatements()) {
			l.addStatement(factory.Core().clone(s));
		}
		return l;
	}

	/**
	 * Creates an access to a this variable (of the form
	 * type.this).
	 * 
	 * @param 
	 *            the actual type of this
	 * @param type
	 *            the reference to the type that holds the this
	 *            variable
	 * @return a type.this expression
	 */
	public  CtThisAccess createThisAccess(CtTypeReference type) {
		CtThisAccess fa = factory.Core().createThisAccess();
		fa.setType(type);
		return fa;
	}

	/**
	 * Creates a variable access.
	 */
	public  CtVariableAccess createVariableAccess(
			CtVariableReference variable, boolean isStatic) {
		CtVariableAccess va;
		if (variable instanceof CtFieldReference) {
			va = factory.Core().createFieldAccess();
			// creates a this target for non-static fields to avoid name
			// conflicts...
			if (!isStatic) {
				((CtFieldAccess) va)
						.setTarget(createThisAccess(((CtFieldReference) variable)
								.getDeclaringType()));
			}
		} else {
			va = factory.Core().createVariableAccess();
		}
		va.setVariable(variable);
		va.setType(variable.getType());
		return va;
	}

	/**
	 * Creates a list of variable accesses.
	 * 
	 * @param variables
	 *            the variables to be accessed
	 */
	public List> createVariableAccesses(
			List> variables) {
		List> result = new ArrayList>();
		for (CtVariable v : variables) {
			result.add(createVariableAccess(v.getReference(), v.getModifiers()
					.contains(ModifierKind.STATIC)));
		}
		return result;
	}

	/**
	 * Creates a variable assignment (can be an expression or a statement).
	 * 
	 * @param 
	 *            the type of the assigned variable
	 * @param variable
	 *            a reference to the assigned variable
	 * @param isStatic
	 *            tells if the assigned variable is static or not
	 * @param expression
	 *            the assigned expression
	 * @return a variable assignment
	 */
	public  CtAssignment createVariableAssignment(
			CtVariableReference variable, boolean isStatic,
			CtExpression expression) {
		CtAssignment va = factory.Core().createAssignment();
		va.setAssignment(expression);
		CtVariableAccess vaccess = createVariableAccess(variable, isStatic);
		va.setAssigned(vaccess);
		return va;
	}

	/**
	 * Creates a list of statements that contains the assignments of a set of
	 * variables.
	 * 
	 * @param variables
	 *            the variables to be assigned
	 * @param expressions
	 *            the assigned expressions
	 * @return a list of variable assignments
	 */
	public  CtStatementList createVariableAssignments(
			List> variables,
			List> expressions) {
		CtStatementList result = factory.Core().createStatementList();
		for (int i = 0; i < variables.size(); i++) {
			result.addStatement(createVariableAssignment(
					variables.get(i).getReference(),
					variables.get(i).getModifiers()
							.contains(ModifierKind.STATIC), expressions.get(i)));
		}
		return result;
	}

	/**
	 * Gets a list of references from a list of elements.
	 * 
	 * @param 
	 *            the expected reference type
	 * @param 
	 *            the element type
	 * @param elements
	 *            the element list
	 * @return the corresponding list of references
	 */
	@SuppressWarnings("unchecked")
	public  List getReferences(
			List elements) {
		List refs = new ArrayList();
		for (E e : elements) {
			refs.add((R) e.getReference());
		}
		return refs;
	}

	/**
	 * Creates a modifier set.
	 * 
	 * @param modifiers
	 *            to put in set
	 * @return Set of given modifiers
	 */
	public Set modifiers(ModifierKind... modifiers) {
		Set ret = new TreeSet();
		for (ModifierKind m : modifiers)
			ret.add(m);
		return ret;
	}

	/**
	 * Creates a Code Snippet expression.
	 * 
	 * @param 
	 *            The type of the expression represented by the CodeSnippet
	 * @param expression
	 *            The string that contains the expression.
	 * @return a new CtCodeSnippetExpression.
	 */
	public  CtCodeSnippetExpression createCodeSnippetExpression(
			String expression) {
		CtCodeSnippetExpression e = factory.Core()
				.createCodeSnippetExpression();
		e.setValue(expression);
		return e;
	}

	/**
	 * Creates a Code Snippet statement.
	 * 
	 * @param statement
	 *            The String containing the statement.
	 * @return a new CtCodeSnippetStatement
	 */
	public CtCodeSnippetStatement createCodeSnippetStatement(String statement) {
		CtCodeSnippetStatement e = factory.Core().createCodeSnippetStatement();
		e.setValue(statement);
		return e;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy