Last active
December 19, 2015 08:39
-
-
Save OdaShinsuke/5927702 to your computer and use it in GitHub Desktop.
Xtend ActiveAnnotation メソッドの事前条件埋めてみた
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package contracts | |
import java.lang.annotation.ElementType | |
import java.lang.annotation.Target | |
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.declaration.MutableMethodDeclaration | |
import org.eclipse.xtend.lib.macro.declaration.Visibility | |
@Target(ElementType::METHOD) | |
@Active(typeof(PreConditionProcessor)) | |
annotation PreCondition { | |
public String expression | |
} | |
class PreConditionProcessor extends AbstractMethodProcessor { | |
override doTransform(MutableMethodDeclaration annotatedMethod, extension TransformationContext context) { | |
val conditions = annotatedMethod.annotations.filter[annotationTypeDeclaration.qualifiedName == "contracts.PreCondition"]; | |
val asserts = conditions.map[getValue("expression")] | |
val name = annotatedMethod.simpleName | |
val realMethodName = "__" + name | |
annotatedMethod.simpleName = realMethodName | |
annotatedMethod.visibility = Visibility::PRIVATE | |
annotatedMethod.declaringType.addMethod(name) [ | |
docComment = annotatedMethod.docComment | |
returnType = annotatedMethod.returnType | |
for (p : annotatedMethod.parameters) { | |
addParameter(p.simpleName, p.type) | |
} | |
exceptions = annotatedMethod.exceptions | |
body = [''' | |
«FOR a : asserts»assert «a» : "assert error";«ENDFOR» | |
«IF !annotatedMethod.returnType.void»return «ENDIF»«realMethodName»(«FOR p : annotatedMethod.parameters SEPARATOR ', '»«p.simpleName»«ENDFOR»);'''] | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package contracts | |
import org.eclipse.xtend.core.compiler.batch.XtendCompilerTester | |
import org.junit.Test | |
class ReqMethodTest { | |
extension XtendCompilerTester compilerTester = XtendCompilerTester::newXtendCompilerTester(typeof(PreCondition)) | |
@Test def void testReturn() { | |
''' | |
import contracts.PreCondition | |
class MyClass { | |
@PreCondition(expression="myParam == null") | |
def String doStuff(String myParam) throws IllegalArgumentException { | |
return myParam | |
} | |
} | |
'''.assertCompilesTo( | |
''' | |
import contracts.PreCondition; | |
@SuppressWarnings("all") | |
public class MyClass { | |
@PreCondition(expression = "myParam == null") | |
private String __doStuff(final String myParam) throws IllegalArgumentException { | |
return myParam; | |
} | |
public String doStuff(final String myParam) throws IllegalArgumentException { | |
assert myParam == null : "assert error"; | |
return __doStuff(myParam); | |
} | |
} | |
''') | |
} | |
@Test def void testVoid() { | |
''' | |
import contracts.PreCondition | |
class MyClass { | |
@PreCondition(expression="myParam == null") | |
def void doStuff(String myParam) throws IllegalArgumentException { | |
// doSomething | |
} | |
} | |
'''.assertCompilesTo( | |
''' | |
import contracts.PreCondition; | |
@SuppressWarnings("all") | |
public class MyClass { | |
@PreCondition(expression = "myParam == null") | |
private void __doStuff(final String myParam) throws IllegalArgumentException { | |
} | |
public void doStuff(final String myParam) throws IllegalArgumentException { | |
assert myParam == null : "assert error"; | |
__doStuff(myParam); | |
} | |
} | |
''') | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment