use of spoon.reflect.declaration.CtField in project spoon by INRIA.
the class StringLiteralTest method testSnippetFullClass.
@SuppressWarnings("unused")
@Test
public void testSnippetFullClass() {
Factory factory = createFactory();
CtClass<?> clazz = factory.Code().createCodeSnippetStatement("class StringValueUTF {\n" + " String f0 = \"toto\";\n" + " String f1 = \"\\n\";\n" + " char c1 = '\\n';\n" + " String f2 = \"\\u20ac\";\n" + " char c2 = '\\u20ac';\n" + " String f3 = \"€\";\n" + " char c3 = '€';\n" + " String f4 = \"\\t\";\n" + " char c4 = '\\t';\n" + " String f5 = \" \";\n" + " char c5 = ' ';\n" + " String f6 = \"€\\u20ac\";\n" + "}").compile();
CtField<?> f0 = (CtField<?>) clazz.getFields().toArray()[0];
CtField<?> f1 = (CtField<?>) clazz.getFields().toArray()[1];
CtField<?> c1 = (CtField<?>) clazz.getFields().toArray()[2];
CtField<?> f2 = (CtField<?>) clazz.getFields().toArray()[3];
CtField<?> c2 = (CtField<?>) clazz.getFields().toArray()[4];
CtField<?> f3 = (CtField<?>) clazz.getFields().toArray()[5];
CtField<?> c3 = (CtField<?>) clazz.getFields().toArray()[6];
CtField<?> f4 = (CtField<?>) clazz.getFields().toArray()[7];
CtField<?> c4 = (CtField<?>) clazz.getFields().toArray()[8];
CtField<?> f5 = (CtField<?>) clazz.getFields().toArray()[9];
CtField<?> c5 = (CtField<?>) clazz.getFields().toArray()[10];
CtField<?> f6 = (CtField<?>) clazz.getFields().toArray()[11];
assertEquals("java.lang.String f0 = \"toto\";", f0.toString());
assertEquals("java.lang.String f1 = \"\\n\";", f1.toString());
assertEquals("char c1 = '\\n';", c1.toString());
assertEquals("java.lang.String f2 = \"\\u20ac\";", f2.toString());
assertEquals("char c2 = '\\u20ac';", c2.toString());
assertEquals("java.lang.String f3 = \"€\";", f3.toString());
assertEquals("char c3 = '€';", c3.toString());
assertEquals("java.lang.String f4 = \"\\t\";", f4.toString());
assertEquals("char c4 = '\\t';", c4.toString());
assertEquals("java.lang.String f5 = \" \";", f5.toString());
assertEquals("char c5 = ' ';", c5.toString());
// spoon cannot handle unicode and unicode in the same literal
// assertEquals("java.lang.String f6 = \"€\\u20ac\";", f6.toString());
}
use of spoon.reflect.declaration.CtField 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.declaration.CtField in project spoon by INRIA.
the class FieldReferenceFunction method apply.
@Override
public void apply(CtElement fieldOrScope, CtConsumer<Object> outputConsumer) {
CtElement scope;
CtField<?> field = this.field;
if (field == null) {
if (fieldOrScope instanceof CtField) {
field = (CtField<?>) fieldOrScope;
} else {
throw new SpoonException("The input of FieldReferenceFunction must be a CtField but is " + fieldOrScope.getClass().getSimpleName());
}
scope = field.getFactory().getModel().getUnnamedModule();
} else {
scope = fieldOrScope;
}
scope.filterChildren(new DirectReferenceFilter<CtFieldReference<?>>(field.getReference())).forEach(outputConsumer);
}
use of spoon.reflect.declaration.CtField in project spoon by INRIA.
the class MetamodelTest method testRoleOnField.
@Test
public void testRoleOnField() {
// contract: all non-final fields must be annotated with {@link spoon.reflect.annotations.MetamodelPropertyField}
SpoonAPI implementations = new Launcher();
implementations.addInputResource("src/main/java/spoon/support/reflect");
implementations.buildModel();
Factory factory = implementations.getFactory();
CtTypeReference metamodelPropertyField = factory.Type().get(MetamodelPropertyField.class).getReference();
final List<String> result = new ArrayList();
List<CtField> fieldWithoutAnnotation = (List<CtField>) implementations.getModel().getElements(new TypeFilter<CtField>(CtField.class) {
@Override
public boolean matches(CtField candidate) {
if (candidate.hasModifier(ModifierKind.FINAL) || candidate.hasModifier(ModifierKind.STATIC) || candidate.hasModifier(ModifierKind.TRANSIENT)) {
return false;
}
if (// not a role
"parent".equals(candidate.getSimpleName()) || "metadata".equals(candidate.getSimpleName()) || // cache field
"valueOfMethod".equals(candidate.getSimpleName())) {
return false;
}
CtClass parent = candidate.getParent(CtClass.class);
return parent != null && (parent.isSubtypeOf(candidate.getFactory().createCtTypeReference(CtReference.class)) || parent.isSubtypeOf(candidate.getFactory().createCtTypeReference(CtElement.class)));
}
}).stream().map(x -> {
result.add(x.toString());
return x;
}).filter(f -> f.getAnnotation(metamodelPropertyField) == null).collect(Collectors.toList());
assertTrue(result.contains("@spoon.reflect.annotations.MetamodelPropertyField(role = spoon.reflect.path.CtRole.IS_SHADOW)\nboolean isShadow;"));
assertTrue(result.contains("@spoon.reflect.annotations.MetamodelPropertyField(role = spoon.reflect.path.CtRole.TYPE)\nspoon.reflect.reference.CtTypeReference<T> type;"));
assertTrue(result.size() > 100);
Assert.assertEquals(Collections.emptyList(), fieldWithoutAnnotation);
final CtTypeReference propertySetter = factory.Type().get(PropertySetter.class).getReference();
final CtTypeReference propertyGetter = factory.Type().get(PropertyGetter.class).getReference();
List<CtField> fields = factory.getModel().getElements(new AnnotationFilter<CtField>(MetamodelPropertyField.class));
for (CtField field : fields) {
CtClass parent = field.getParent(CtClass.class);
CtExpression roleExpression = field.getAnnotation(metamodelPropertyField).getValue("role");
List<String> roles = new ArrayList<>();
if (roleExpression instanceof CtFieldRead) {
roles.add(((CtFieldRead) roleExpression).getVariable().getSimpleName());
} else if (roleExpression instanceof CtNewArray) {
List<CtFieldRead> elements = ((CtNewArray) roleExpression).getElements();
for (int i = 0; i < elements.size(); i++) {
CtFieldRead ctFieldRead = elements.get(i);
roles.add(ctFieldRead.getVariable().getSimpleName());
}
}
CtQuery superQuery = parent.map(new SuperInheritanceHierarchyFunction());
List<CtMethod> methods = superQuery.map((CtType type) -> type.getMethodsAnnotatedWith(propertyGetter, propertySetter)).list();
boolean setterFound = false;
boolean getterFound = false;
for (CtMethod method : methods) {
CtAnnotation getterAnnotation = method.getAnnotation(propertyGetter);
CtAnnotation setterAnnotation = method.getAnnotation(propertySetter);
if (getterAnnotation != null) {
getterFound |= roles.contains(((CtFieldRead) getterAnnotation.getValue("role")).getVariable().getSimpleName());
}
if (setterAnnotation != null) {
setterFound |= roles.contains(((CtFieldRead) setterAnnotation.getValue("role")).getVariable().getSimpleName());
}
}
assertTrue(roles + " must have a getter in " + parent.getQualifiedName(), getterFound);
assertTrue(roles + " must have a setter in " + parent.getQualifiedName(), setterFound);
}
}
use of spoon.reflect.declaration.CtField in project spoon by INRIA.
the class NoClasspathTest method testInheritanceInNoClassPathWithClasses.
@Test
public void testInheritanceInNoClassPathWithClasses() throws IOException {
// contract: when using noclasspath in combination with a source classpath
// spoon is able to resolve the inheritance between classes contained in source cp
String sourceInputDirPath = "./src/test/resources/spoon/test/inheritance";
String targetBinPath = "./target/spoon-nocp-bin";
Launcher spoon = new Launcher();
spoon.getEnvironment().setShouldCompile(true);
spoon.addInputResource(sourceInputDirPath);
spoon.setBinaryOutputDirectory(targetBinPath);
spoon.run();
spoon = new Launcher();
spoon.getEnvironment().setNoClasspath(true);
spoon.getEnvironment().setSourceClasspath(new String[] { targetBinPath });
spoon.addInputResource(sourceInputDirPath + "/AnotherClass.java");
spoon.buildModel();
CtType anotherclass = spoon.getFactory().Type().get("org.acme.AnotherClass");
assertEquals(1, anotherclass.getFields().size());
CtField field = (CtField) anotherclass.getFields().get(0);
CtTypeReference myClassReference = spoon.getFactory().Type().createReference("fr.acme.MyClass");
assertEquals(myClassReference, field.getType());
assertNotNull(myClassReference.getActualClass());
CtTypeReference myInterfaceReference = spoon.getFactory().Type().createReference("org.myorganization.MyInterface");
assertTrue(myClassReference.isSubtypeOf(myInterfaceReference));
assertTrue(field.getType().isSubtypeOf(myInterfaceReference));
}
Aggregations