use of spoon.reflect.factory.CoreFactory in project spoon by INRIA.
the class FactoryTest method testFactoryOverriding.
@Test
public void testFactoryOverriding() throws Exception {
@SuppressWarnings("serial")
class MyCtMethod<T> extends CtMethodImpl<T> {
}
;
@SuppressWarnings("serial") final CoreFactory specialCoreFactory = new DefaultCoreFactory() {
@Override
public <T> CtMethod<T> createMethod() {
MyCtMethod<T> m = new MyCtMethod<T>();
m.setFactory(getMainFactory());
return m;
}
};
Launcher launcher = new Launcher() {
@Override
public Factory createFactory() {
return new FactoryImpl(specialCoreFactory, new StandardEnvironment());
}
};
CtClass<?> type = build("spoon.test.testclasses", "SampleClass", launcher.getFactory());
CtMethod<?> m = type.getMethodsByName("method3").get(0);
assertTrue(m instanceof MyCtMethod);
}
use of spoon.reflect.factory.CoreFactory in project spoon by INRIA.
the class ConstructorFactoryTest method testCreate.
@Test
public void testCreate() throws Exception {
CtClass<?> type = build("spoon.test.testclasses", "SampleClass");
Factory factory = type.getFactory();
ConstructorFactory ctorf = factory.Constructor();
CoreFactory coref = factory.Core();
Set<ModifierKind> mods = new HashSet<ModifierKind>();
mods.add(ModifierKind.PUBLIC);
List<CtParameter<?>> params = new ArrayList<CtParameter<?>>();
CtParameter<?> param = coref.createParameter();
CtTypeReference<?> tref = factory.Type().createReference(String.class);
param.setType((CtTypeReference) tref);
param.setSimpleName("str");
params.add(param);
Set<CtTypeReference<? extends Throwable>> thrownTypes = new HashSet<CtTypeReference<? extends Throwable>>();
ctorf.create(type, mods, params, thrownTypes);
CtConstructor<?> c = type.getConstructor(tref);
Assert.assertEquals(1, c.getParameters().size());
Assert.assertEquals("str", c.getParameters().get(0).getSimpleName());
}
use of spoon.reflect.factory.CoreFactory in project spoon by INRIA.
the class ContextBuilder method getVariableDeclaration.
@SuppressWarnings("unchecked")
private <T, U extends CtVariable<T>> U getVariableDeclaration(final String name, final Class<U> clazz) {
final CoreFactory coreFactory = jdtTreeBuilder.getFactory().Core();
final TypeFactory typeFactory = jdtTreeBuilder.getFactory().Type();
final ClassFactory classFactory = jdtTreeBuilder.getFactory().Class();
final InterfaceFactory interfaceFactory = jdtTreeBuilder.getFactory().Interface();
final FieldFactory fieldFactory = jdtTreeBuilder.getFactory().Field();
final ReferenceBuilder referenceBuilder = jdtTreeBuilder.getReferencesBuilder();
final Environment environment = jdtTreeBuilder.getFactory().getEnvironment();
// there is some extra work to do if we are looking for CtFields (and subclasses)
final boolean lookingForFields = clazz == null || coreFactory.createField().getClass().isAssignableFrom(clazz);
// try to find the variable on stack beginning with the most recent element
for (final ASTPair astPair : stack) {
// the variable may have been declared directly by one of these elements
final ScopeRespectingVariableScanner<U> scanner = new ScopeRespectingVariableScanner(name, clazz);
astPair.element.accept(scanner);
if (scanner.getResult() != null) {
return scanner.getResult();
}
// the variable may have been declared in a super class/interface
if (lookingForFields && astPair.node instanceof TypeDeclaration) {
final TypeDeclaration nodeDeclaration = (TypeDeclaration) astPair.node;
final Deque<ReferenceBinding> referenceBindings = new ArrayDeque<>();
// add super class if any
if (nodeDeclaration.superclass != null && nodeDeclaration.superclass.resolvedType instanceof ReferenceBinding) {
referenceBindings.push((ReferenceBinding) nodeDeclaration.superclass.resolvedType);
}
// add interfaces if any
if (nodeDeclaration.superInterfaces != null) {
for (final TypeReference tr : nodeDeclaration.superInterfaces) {
if (tr.resolvedType instanceof ReferenceBinding) {
referenceBindings.push((ReferenceBinding) tr.resolvedType);
}
}
}
while (!referenceBindings.isEmpty()) {
final ReferenceBinding referenceBinding = referenceBindings.pop();
for (final FieldBinding fieldBinding : referenceBinding.fields()) {
if (name.equals(new String(fieldBinding.readableName()))) {
final String qualifiedNameOfParent = new String(referenceBinding.readableName());
final CtType parentOfField = referenceBinding.isClass() ? classFactory.create(qualifiedNameOfParent) : interfaceFactory.create(qualifiedNameOfParent);
U field = (U) fieldFactory.create(parentOfField, EnumSet.noneOf(ModifierKind.class), referenceBuilder.getTypeReference(fieldBinding.type), name);
return field.setExtendedModifiers(JDTTreeBuilderQuery.getModifiers(fieldBinding.modifiers, true, false));
}
}
// add super class if any
final ReferenceBinding superclass = referenceBinding.superclass();
if (superclass != null) {
referenceBindings.push(superclass);
}
// add interfaces if any
final ReferenceBinding[] interfaces = referenceBinding.superInterfaces();
if (interfaces != null) {
for (ReferenceBinding rb : interfaces) {
referenceBindings.push(rb);
}
}
}
}
}
// the variable may have been imported statically from another class/interface
if (lookingForFields) {
final CtReference potentialReferenceToField = referenceBuilder.getDeclaringReferenceFromImports(name.toCharArray());
if (potentialReferenceToField != null && potentialReferenceToField instanceof CtTypeReference) {
final CtTypeReference typeReference = (CtTypeReference) potentialReferenceToField;
try {
final Class classOfType = typeReference.getActualClass();
if (classOfType != null) {
final CtType declaringTypeOfField = typeReference.isInterface() ? interfaceFactory.get(classOfType) : classFactory.get(classOfType);
final CtField field = declaringTypeOfField.getField(name);
if (field != null) {
return (U) field;
}
}
} catch (final SpoonClassNotFoundException scnfe) {
// field that has been imported statically from another class (or interface).
if (environment.getNoClasspath()) {
// assume a constant value according to JLS.
if (name.toUpperCase().equals(name)) {
final CtType parentOfField = classFactory.create(typeReference.getQualifiedName());
// it is the best thing we can do
final CtField field = coreFactory.createField();
field.setParent(parentOfField);
field.setSimpleName(name);
// it is the best thing we can do
field.setType(typeFactory.nullType());
return (U) field;
}
}
}
}
}
return null;
}
use of spoon.reflect.factory.CoreFactory in project spoon by INRIA.
the class CompilationTest method compileTest.
@Test
public void compileTest() throws Exception {
// contract: the modified version of classes is the one that is compiled to binary code
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/resources/noclasspath/Simple.java");
File outputBinDirectory = new File("./target/class-simple");
if (!outputBinDirectory.exists()) {
outputBinDirectory.mkdirs();
}
launcher.setBinaryOutputDirectory(outputBinDirectory);
launcher.getEnvironment().setShouldCompile(true);
launcher.buildModel();
Factory factory = launcher.getFactory();
CoreFactory core = factory.Core();
CodeFactory code = factory.Code();
CtClass simple = factory.Class().get("Simple");
CtMethod method = core.createMethod();
method.addModifier(ModifierKind.PUBLIC);
method.setType(factory.Type().integerPrimitiveType());
method.setSimpleName("m");
CtBlock block = core.createBlock();
CtReturn aReturn = core.createReturn();
CtBinaryOperator binaryOperator = code.createBinaryOperator(code.createLiteral(10), code.createLiteral(32), BinaryOperatorKind.PLUS);
aReturn.setReturnedExpression(binaryOperator);
// return 10 + 32;
block.addStatement(aReturn);
method.setBody(block);
simple.addMethod(method);
launcher.getModelBuilder().compile();
final URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { outputBinDirectory.toURL() });
Class<?> aClass = urlClassLoader.loadClass("Simple");
Method m = aClass.getMethod("m");
Assert.assertEquals(42, m.invoke(aClass.newInstance()));
}
use of spoon.reflect.factory.CoreFactory in project spoon by INRIA.
the class JDTTreeBuilderHelper method createVariableAccessNoClasspath.
/**
* Analyzes if {@code singleNameReference} points to a {@link CtVariable} visible in current
* scope and, if existent, returns its corresponding {@link CtVariableAccess}. Returns
* {@code null} if {@code singleNameReference} could not be resolved as variable access. Since
* we are in noclasspath mode this function may also returns {@code null} if
* {@code singleNameReference} points to a variable declared by an unknown class.
*
* @param singleNameReference
* The potential variable access.
* @return A {@link CtVariableAccess} if {@code singleNameReference} points to a variable
* visible in current scope, {@code null} otherwise.
*/
<T> CtVariableAccess<T> createVariableAccessNoClasspath(SingleNameReference singleNameReference) {
final TypeFactory typeFactory = jdtTreeBuilder.getFactory().Type();
final CoreFactory coreFactory = jdtTreeBuilder.getFactory().Core();
final ExecutableFactory executableFactory = jdtTreeBuilder.getFactory().Executable();
final ContextBuilder contextBuilder = jdtTreeBuilder.getContextBuilder();
final ReferenceBuilder referenceBuilder = jdtTreeBuilder.getReferencesBuilder();
final PositionBuilder positionBuilder = jdtTreeBuilder.getPositionBuilder();
final String name = CharOperation.charToString(singleNameReference.token);
final CtVariable<T> variable = contextBuilder.getVariableDeclaration(name);
if (variable == null) {
return null;
}
final CtVariableReference<T> variableReference;
final CtVariableAccess<T> variableAccess;
if (variable instanceof CtParameter) {
// create variable of concrete type to avoid type casting while calling methods
final CtParameterReference<T> parameterReference = coreFactory.createParameterReference();
if (variable.getParent() instanceof CtLambda) {
// nothing
} else {
// Unfortunately, we can not use `variable.getReference()` here as some parent
// references (in terms of Java objects) have not been set up yet. Thus, we need to
// create the required parameter reference by our own.
// Since the given parameter has not been declared in a lambda expression it must
// have been declared by a method/constructor.
final CtExecutable executable = (CtExecutable) variable.getParent();
// create list of executable's parameter types
final List<CtTypeReference<?>> parameterTypesOfExecutable = new ArrayList<>();
@SuppressWarnings("unchecked") final List<CtParameter<?>> parametersOfExecutable = executable.getParameters();
for (CtParameter<?> parameter : parametersOfExecutable) {
parameterTypesOfExecutable.add(parameter.getType() != null ? parameter.getType().clone() : // it's the best match :(
typeFactory.OBJECT.clone());
}
// find executable's corresponding jdt element
AbstractMethodDeclaration executableJDT = null;
for (final ASTPair astPair : contextBuilder.stack) {
if (astPair.element == executable) {
executableJDT = (AbstractMethodDeclaration) astPair.node;
}
}
assert executableJDT != null;
// create a reference to executable's declaring class
final CtTypeReference declaringReferenceOfExecutable = // available
executableJDT.binding == null ? coreFactory.createTypeReference() : referenceBuilder.getTypeReference(executableJDT.binding.declaringClass);
// If executable is a constructor, `executable.getType()` returns null since the
// parent is not available yet. Fortunately, however, the return type of a
// constructor is its declaring class which, in our case, is already available with
// declaringReferenceOfExecutable.
CtTypeReference executableTypeReference = executable instanceof CtConstructor ? // indirectly sets the parent of `rt` and, thus, may break the AST!
declaringReferenceOfExecutable.clone() : executable.getType().clone();
}
variableReference = parameterReference;
variableAccess = isLhsAssignment(contextBuilder, singleNameReference) ? coreFactory.<T>createVariableWrite() : coreFactory.<T>createVariableRead();
} else if (variable instanceof CtField) {
variableReference = variable.getReference();
variableAccess = isLhsAssignment(contextBuilder, singleNameReference) ? coreFactory.<T>createFieldWrite() : coreFactory.<T>createFieldRead();
} else {
// CtLocalVariable, CtCatchVariable, ...
variableReference = variable.getReference();
variableAccess = isLhsAssignment(contextBuilder, singleNameReference) ? coreFactory.<T>createVariableWrite() : coreFactory.<T>createVariableRead();
}
variableReference.setSimpleName(name);
variableReference.setPosition(positionBuilder.buildPosition(singleNameReference.sourceStart(), singleNameReference.sourceEnd()));
variableAccess.setVariable(variableReference);
return variableAccess;
}
Aggregations