diff options
Diffstat (limited to 'tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework')
5 files changed, 356 insertions, 0 deletions
diff --git a/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/Cached.xtend b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/Cached.xtend new file mode 100644 index 00000000000..145a1365a45 --- /dev/null +++ b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/Cached.xtend @@ -0,0 +1,108 @@ +/***************************************************************************** + * Copyright (c) 2015 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.tests.framework.xtend.annotations + +import java.lang.annotation.Target +import java.util.Map +import org.eclipse.xtend.lib.macro.AbstractMethodProcessor +import org.eclipse.xtend.lib.macro.Active +import org.eclipse.xtend.lib.macro.TransformationContext +import org.eclipse.xtend.lib.macro.ValidationContext +import org.eclipse.xtend.lib.macro.declaration.MethodDeclaration +import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration +import org.eclipse.xtend.lib.macro.declaration.Visibility +import org.eclipse.xtend.lib.macro.declaration.TypeReference + +/** + * An active annotation for cached methods. A cached method's value is computed at most once + * for any given set of actual parameters. + */ +@Target(METHOD) +@Active(CachedProcessor) +annotation Cached {} + +class CachedProcessor extends AbstractMethodProcessor { + + override doValidate(MethodDeclaration method, extension ValidationContext context) { + if (method.returnType.inferred) { + method.addError('Method result of inferred type cannot be cached') + } else if (method.returnType.primitiveIfWrapper.isVoid) { + method.addError('Void method result cannot be cached') + } + } + + override doTransform(MutableMethodDeclaration method, extension TransformationContext context) { + // Create the once-method + method.declaringType.addMethod('_once_' + method.simpleName) [ + visibility = Visibility.PRIVATE + returnType = method.returnType + method.typeParameters.forEach[tp | + addTypeParameter(tp.simpleName, tp.upperBounds) + ] + method.parameters.forEach[p | + addParameter(p.simpleName, p.type) + ] + body = method.body + primarySourceElement = method + ] + + val listType = newWildcardTypeReference.list + val collectionLiteralsType = CollectionLiterals.findTypeGlobally.newTypeReference + + // Ensure the existence of the cached-null token + val cachedNull = method.declaringType.findDeclaredField('_CACHED_NULL_') ?: + method.declaringType.addField('_CACHED_NULL_') [ + visibility = Visibility.PRIVATE + static = true + final = true + type = object + initializer = ['''new «object»()'''] + ] + + // And of the cache + val cache = method.declaringType.addField('_cache_' + method.simpleName + '_' + method.parameters.map[type.type.simpleName].join('_')) [ + visibility = Visibility.PRIVATE + final = true + type = Map.findTypeGlobally.newTypeReference(listType, object) + initializer = ['''«collectionLiteralsType.name».newHashMap()'''] + ] + + // Create a new body for the cached method. + method.body = [''' + final «listType» key = «collectionLiteralsType.name».newArrayList(«FOR p : method.parameters SEPARATOR ', '»«p.simpleName»«ENDFOR»); + «object» result; + + synchronized («cache.simpleName») { + result = «cache.simpleName».get(key); + if (result == null) { + result = _once_«method.simpleName»(«FOR p : method.parameters SEPARATOR ', '»«p.simpleName»«ENDFOR»); + if (result == null) { + result = «cachedNull.simpleName»; + } + «cache.simpleName».put(key, result); + } + } + + return (result == «cachedNull.simpleName») ? null : («method.returnType.nonClashingName(context)») result; + '''] + } + + // Prefer qualified names for classes whose simple name clashes with a type in the java.lang package + private def nonClashingName(TypeReference typeRef, extension TransformationContext context) { + val base = typeRef.simpleName + val simpleName = if (typeRef.actualTypeArguments.empty) base else base.substring(0, base.indexOf('<')) + + if (('java.lang.' + simpleName).findTypeGlobally == null) base else typeRef.name + } +} diff --git a/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/FrameworkConfig.xtend b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/FrameworkConfig.xtend new file mode 100644 index 00000000000..5fa989fe6bd --- /dev/null +++ b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/FrameworkConfig.xtend @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (c) 2015 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.tests.framework.xtend.annotations + +import java.lang.annotation.Target +import org.eclipse.xtend.lib.macro.AbstractFieldProcessor +import org.eclipse.xtend.lib.macro.Active +import org.eclipse.xtend.lib.macro.TransformationContext +import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration +import com.google.inject.Inject +import com.google.inject.name.Named + +/** + * An active annotation for framework configuration parameters. Annotate a field with this + * to mark it as optionally injected by Guice with the field name as the named injection binding. + * That is, the result of annotating a field as + * <pre> + * {@literal @FrameworkConfig val Iterable<String> myConfigParameter} + * </pre> + * is the same as annotating the field with + * <pre> + * {@literal @Inject(optional=true)} + * {@literal @Named('myConfigParameter')} + * {@literal val Iterable<String> myConfigParameter} + * </pre> + */ +@Target(FIELD) +@Active(FrameworkConfigProcessor) +annotation FrameworkConfig {} + +class FrameworkConfigProcessor extends AbstractFieldProcessor { + + override doTransform(MutableFieldDeclaration field, extension TransformationContext context) { + field.addAnnotation(Inject.newAnnotationReference[ + setBooleanValue('optional', true) + ]) + field.addAnnotation(Named.newAnnotationReference[ + setStringValue('value', field.simpleName) + ]) + } + +}
\ No newline at end of file diff --git a/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/LiteralConstants.xtend b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/LiteralConstants.xtend new file mode 100644 index 00000000000..c402b020d1e --- /dev/null +++ b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/LiteralConstants.xtend @@ -0,0 +1,89 @@ +/***************************************************************************** + * Copyright (c) 2015 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.tests.framework.xtend.annotations + +import java.lang.annotation.Target +import org.eclipse.xtend.lib.annotations.Data +import org.eclipse.xtend.lib.macro.AbstractFieldProcessor +import org.eclipse.xtend.lib.macro.Active +import org.eclipse.xtend.lib.macro.TransformationContext +import org.eclipse.xtend.lib.macro.ValidationContext +import org.eclipse.xtend.lib.macro.declaration.EnumerationTypeDeclaration +import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration +import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration +import org.eclipse.xtend.lib.macro.declaration.Visibility + +/** + * An active annotation for fields of enumeration type that generates camel-case-named constants for each literal of + * the enumeration type. + */ +@Target(FIELD) +@Active(LiteralConstantsProcessor) +annotation LiteralConstants { + /** Whether to generate static constants (default is true). */ + boolean isStatic = true +} + +class LiteralConstantsProcessor extends AbstractFieldProcessor { + + override doValidate(FieldDeclaration field, extension ValidationContext context) { + if (field.type.inferred) { + field.addError('Cannot generate enumeration literal constants for inferred field type') + } else if (!Enum.findTypeGlobally.isAssignableFrom(field.type.type)) { + field.addError('Field is not of enumeration type') + } + } + + override doTransform(MutableFieldDeclaration field, extension TransformationContext context) { + val enumType = field.type.type + val isStatic = field.findAnnotation(LiteralConstants.findTypeGlobally).getBooleanValue('isStatic') + + switch (enumType) { + EnumerationTypeDeclaration : { + for (next : enumType.enumConstants) { + field.declaringType.addField(next.literalName) [ + visibility = Visibility.PUBLIC + static = isStatic + final = true + type = field.type + initializer = '''«field.type.simpleName».«next.constantName»''' + + primarySourceElement = field + ] + } + } + + default: field.addError('Cannot resolve field\'s enumeration type declaration') + } + } + + def enumConstants(EnumerationTypeDeclaration enumType) { + enumType.declaredValues.map[ new EnumConstants(simpleName.toCamelCase, simpleName) ] + } + + def toCamelCase(String name) { + val parts = name.toLowerCase.split('_') + parts.get(0) + parts.subList(1, parts.size).map[toFirstUpper].join + } + + // + // Nested types + // + + @Data + private static class EnumConstants { + String literalName + String constantName + } +} diff --git a/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/TestContextRule.xtend b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/TestContextRule.xtend new file mode 100644 index 00000000000..9a3ca386b07 --- /dev/null +++ b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/TestContextRule.xtend @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (c) 2015 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.tests.framework.xtend.annotations + +import java.lang.annotation.Target +import org.eclipse.xtend.lib.macro.AbstractFieldProcessor +import org.eclipse.xtend.lib.macro.Active +import org.eclipse.xtend.lib.macro.TransformationContext +import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration +import org.eclipse.xtext.xbase.lib.Procedures.Procedure1 +import org.eclipse.xtend.lib.macro.declaration.Visibility + +/** + * An active annotation for test-context class rules. Such rules are blocks that + * define a {@link TestContextBuilder} as the only input (the implicit <b>{@code it}</b> variable). + * The field declaration may omit the type. It may be declared as either {@code var} or {@code val} + * but it will be generated as a {@code val}. + */ +@Target(FIELD) +@Active(TestContextRuleProcessor) +annotation TestContextRule {} + +class TestContextRuleProcessor extends AbstractFieldProcessor { + + override doTransform(MutableFieldDeclaration field, extension TransformationContext context) { + field.type = findTypeGlobally(Procedure1).newTypeReference( + findTypeGlobally("org.eclipse.papyrus.tests.framework.gmfgenuml2utp.TransformationUtilities.TestContextBuilder").newTypeReference.newWildcardTypeReferenceWithLowerBound + ) + field.final = true + field.visibility = Visibility.PRIVATE + + field.declaringType.addMethod('get' + field.simpleName.toFirstUpper) [ + field.markAsRead + returnType = field.type + body = [''' + return «field.simpleName»; + '''] + primarySourceElement = field + ] + } + +}
\ No newline at end of file diff --git a/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/TestPackageRule.xtend b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/TestPackageRule.xtend new file mode 100644 index 00000000000..d159c2a5f13 --- /dev/null +++ b/tests/framework/org.eclipse.papyrus.tests.framework.annotations/src/org/eclipse/papyrus/tests/framework/xtend/annotations/TestPackageRule.xtend @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (c) 2015 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.tests.framework.xtend.annotations + +import java.lang.annotation.Target +import org.eclipse.xtend.lib.macro.AbstractFieldProcessor +import org.eclipse.xtend.lib.macro.Active +import org.eclipse.xtend.lib.macro.TransformationContext +import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration +import org.eclipse.xtext.xbase.lib.Procedures.Procedure1 +import org.eclipse.xtend.lib.macro.declaration.Visibility + +/** + * An active annotation for test-package rules. Such rules are blocks that + * define a {@link TestPackageBuilder} as the only input (the implicit <b>{@code it}</b> variable). + * The field declaration may omit the type. It may be declared as either {@code var} or {@code val} + * but it will be generated as a {@code val}. + */ +@Target(FIELD) +@Active(TestPackageRuleProcessor) +annotation TestPackageRule {} + +class TestPackageRuleProcessor extends AbstractFieldProcessor { + + override doTransform(MutableFieldDeclaration field, extension TransformationContext context) { + field.type = findTypeGlobally(Procedure1).newTypeReference( + findTypeGlobally("org.eclipse.papyrus.tests.framework.gmfgenuml2utp.TransformationUtilities.TestPackageBuilder").newTypeReference.newWildcardTypeReferenceWithLowerBound + ) + field.final = true + field.visibility = Visibility.PRIVATE + + field.declaringType.addMethod('get' + field.simpleName.toFirstUpper) [ + field.markAsRead + returnType = field.type + body = [''' + return «field.simpleName»; + '''] + primarySourceElement = field + ] + } + +}
\ No newline at end of file |