use of org.codehaus.groovy.ast.MethodNode in project groovy-core by groovy.
the class BindableASTTransformation method wrapSetterMethod.
/*
* Wrap an existing setter.
*/
private void wrapSetterMethod(ClassNode classNode, String propertyName) {
String getterName = "get" + MetaClassHelper.capitalize(propertyName);
MethodNode setter = classNode.getSetterMethod("set" + MetaClassHelper.capitalize(propertyName));
if (setter != null) {
// Get the existing code block
Statement code = setter.getCode();
Expression oldValue = varX("$oldValue");
Expression newValue = varX("$newValue");
BlockStatement block = new BlockStatement();
// create a local variable to hold the old value from the getter
block.addStatement(declS(oldValue, callThisX(getterName)));
// call the existing block, which will presumably set the value properly
block.addStatement(code);
// get the new value to emit in the event
block.addStatement(declS(newValue, callThisX(getterName)));
// add the firePropertyChange method call
block.addStatement(stmt(callThisX("firePropertyChange", args(constX(propertyName), oldValue, newValue))));
// replace the existing code block with our new one
setter.setCode(block);
}
}
use of org.codehaus.groovy.ast.MethodNode in project grails-core by grails.
the class TestMixinTransformation method weaveMixinIntoClass.
protected void weaveMixinIntoClass(final ClassNode classNode, final ClassNode mixinClassNode, final Junit3TestFixtureMethodHandler junit3MethodHandler, ClassNode applicationClassNode) {
if (mixinClassNode.getName().equals(IntegrationTestMixin.class.getName())) {
new IntegrationTestMixinTransformation().weaveIntegrationTestMixin(classNode, applicationClassNode);
return;
}
final String fieldName = '$' + GrailsNameUtils.getPropertyName(mixinClassNode.getName());
boolean implementsTestRuntimeAwareMixin = GrailsASTUtils.findInterface(mixinClassNode, ClassHelper.make(TestRuntimeAwareMixin.class)) != null;
FieldNode mixinFieldNode;
if (!implementsTestRuntimeAwareMixin) {
mixinFieldNode = addLegacyMixinFieldIfNonExistent(classNode, mixinClassNode, fieldName);
} else {
mixinFieldNode = addTestRuntimeAwareMixinFieldIfNonExistent(classNode, mixinClassNode, fieldName);
}
// already woven
if (mixinFieldNode == null)
return;
FieldExpression fieldReference = new FieldExpression(mixinFieldNode);
ClassNode currentMixinClassNode = mixinClassNode;
while (!currentMixinClassNode.getName().equals(GrailsASTUtils.OBJECT_CLASS)) {
final List<MethodNode> mixinMethods = currentMixinClassNode.getMethods();
for (MethodNode mixinMethod : mixinMethods) {
if (!isCandidateMethod(mixinMethod) || hasDeclaredMethod(classNode, mixinMethod)) {
continue;
}
MethodNode methodNode;
if (mixinMethod.isStatic()) {
methodNode = GrailsASTUtils.addDelegateStaticMethod(classNode, mixinMethod);
} else {
methodNode = GrailsASTUtils.addDelegateInstanceMethod(classNode, fieldReference, mixinMethod, false);
}
if (methodNode != null) {
methodNode.addAnnotation(MIXIN_METHOD_ANNOTATION);
GrailsASTUtils.addCompileStaticAnnotation(methodNode);
}
if (junit3MethodHandler != null) {
junit3MethodHandler.handle(mixinMethod, methodNode);
}
}
currentMixinClassNode = currentMixinClassNode.getSuperClass();
if (junit3MethodHandler != null) {
junit3MethodHandler.mixinSuperClassChanged();
}
}
}
use of org.codehaus.groovy.ast.MethodNode in project grails-core by grails.
the class DefaultASTValidateableHelper method getPropertiesToEnsureConstraintsFor.
/**
* Retrieves a Map describing all of the properties which need to be constrained for the class
* represented by classNode. The keys in the Map will be property names and the values are the
* type of the corresponding property.
*
* @param classNode the class to inspect
* @return a Map describing all of the properties which need to be constrained
*/
protected Map<String, ClassNode> getPropertiesToEnsureConstraintsFor(final ClassNode classNode) {
final Map<String, ClassNode> fieldsToConstrain = new HashMap<String, ClassNode>();
final List<FieldNode> allFields = classNode.getFields();
for (final FieldNode field : allFields) {
if (!field.isStatic()) {
final PropertyNode property = classNode.getProperty(field.getName());
if (property != null) {
fieldsToConstrain.put(field.getName(), field.getType());
}
}
}
final Map<String, MethodNode> declaredMethodsMap = classNode.getDeclaredMethodsMap();
for (Entry<String, MethodNode> methodEntry : declaredMethodsMap.entrySet()) {
final MethodNode value = methodEntry.getValue();
if (!value.isStatic() && value.isPublic() && classNode.equals(value.getDeclaringClass()) && value.getLineNumber() > 0) {
Parameter[] parameters = value.getParameters();
if (parameters == null || parameters.length == 0) {
final String methodName = value.getName();
if (methodName.startsWith("get")) {
final ClassNode returnType = value.getReturnType();
final String restOfMethodName = methodName.substring(3);
final String propertyName = GrailsNameUtils.getPropertyName(restOfMethodName);
fieldsToConstrain.put(propertyName, returnType);
}
}
}
}
final ClassNode superClass = classNode.getSuperClass();
if (!superClass.equals(new ClassNode(Object.class))) {
fieldsToConstrain.putAll(getPropertiesToEnsureConstraintsFor(superClass));
}
return fieldsToConstrain;
}
use of org.codehaus.groovy.ast.MethodNode in project grails-core by grails.
the class DefaultASTValidateableHelper method addValidateMethod.
protected void addValidateMethod(final ClassNode classNode) {
String fieldsToValidateParameterName = "$fieldsToValidate";
final MethodNode listArgValidateMethod = classNode.getMethod(VALIDATE_METHOD_NAME, new Parameter[] { new Parameter(new ClassNode(List.class), fieldsToValidateParameterName) });
if (listArgValidateMethod == null) {
final BlockStatement validateMethodCode = new BlockStatement();
final ArgumentListExpression validateInstanceArguments = new ArgumentListExpression();
validateInstanceArguments.addExpression(new VariableExpression("this"));
validateInstanceArguments.addExpression(new VariableExpression(fieldsToValidateParameterName, ClassHelper.LIST_TYPE));
final ClassNode validationSupportClassNode = ClassHelper.make(ValidationSupport.class);
final StaticMethodCallExpression invokeValidateInstanceExpression = new StaticMethodCallExpression(validationSupportClassNode, "validateInstance", validateInstanceArguments);
validateMethodCode.addStatement(new ExpressionStatement(invokeValidateInstanceExpression));
final Parameter fieldsToValidateParameter = new Parameter(new ClassNode(List.class), fieldsToValidateParameterName);
classNode.addMethod(new MethodNode(VALIDATE_METHOD_NAME, Modifier.PUBLIC, ClassHelper.boolean_TYPE, new Parameter[] { fieldsToValidateParameter }, EMPTY_CLASS_ARRAY, validateMethodCode));
}
final MethodNode noArgValidateMethod = classNode.getMethod(VALIDATE_METHOD_NAME, ZERO_PARAMETERS);
if (noArgValidateMethod == null) {
final BlockStatement validateMethodCode = new BlockStatement();
final ArgumentListExpression validateInstanceArguments = new ArgumentListExpression();
validateInstanceArguments.addExpression(new CastExpression(new ClassNode(List.class), new ConstantExpression(null)));
final Expression callListArgValidateMethod = new MethodCallExpression(new VariableExpression("this"), VALIDATE_METHOD_NAME, validateInstanceArguments);
validateMethodCode.addStatement(new ReturnStatement(callListArgValidateMethod));
classNode.addMethod(new MethodNode(VALIDATE_METHOD_NAME, Modifier.PUBLIC, ClassHelper.boolean_TYPE, ZERO_PARAMETERS, EMPTY_CLASS_ARRAY, validateMethodCode));
}
}
use of org.codehaus.groovy.ast.MethodNode in project grails-core by grails.
the class DefaultASTValidateableHelper method addGetConstraintsMethod.
protected void addGetConstraintsMethod(final ClassNode classNode, boolean defaultNullable) {
final String getConstraintsMethodName = "getConstraints";
MethodNode getConstraintsMethod = classNode.getMethod(getConstraintsMethodName, ZERO_PARAMETERS);
if (getConstraintsMethod == null || !getConstraintsMethod.getDeclaringClass().equals(classNode)) {
final BooleanExpression isConstraintsPropertyNull = new BooleanExpression(new BinaryExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME), Token.newSymbol(Types.COMPARE_EQUAL, 0, 0), new ConstantExpression(null)));
final BlockStatement ifConstraintsPropertyIsNullBlockStatement = new BlockStatement();
final ArgumentListExpression getConstrainedPropertiesForClassArguments = new ArgumentListExpression();
getConstrainedPropertiesForClassArguments.addExpression(new VariableExpression("this"));
getConstrainedPropertiesForClassArguments.addExpression(new ConstantExpression(defaultNullable));
final Expression getConstraintsMethodCall = new StaticMethodCallExpression(ClassHelper.make(ValidationSupport.class), "getConstrainedPropertiesForClass", getConstrainedPropertiesForClassArguments);
final Expression initializeConstraintsFieldExpression = new BinaryExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME), Token.newSymbol(Types.EQUALS, 0, 0), getConstraintsMethodCall);
final Statement ifConstraintsPropertyIsNullStatement = new IfStatement(isConstraintsPropertyNull, ifConstraintsPropertyIsNullBlockStatement, new ExpressionStatement(new EmptyExpression()));
ifConstraintsPropertyIsNullBlockStatement.addStatement(new ExpressionStatement(initializeConstraintsFieldExpression));
if (!defaultNullable) {
final Map<String, ClassNode> propertiesToConstrain = getPropertiesToEnsureConstraintsFor(classNode);
for (final Map.Entry<String, ClassNode> entry : propertiesToConstrain.entrySet()) {
final String propertyName = entry.getKey();
final ClassNode propertyType = entry.getValue();
final String cpName = "$" + propertyName + "$constrainedProperty";
final ArgumentListExpression constrainedPropertyConstructorArgumentList = new ArgumentListExpression();
constrainedPropertyConstructorArgumentList.addExpression(new ClassExpression(classNode));
constrainedPropertyConstructorArgumentList.addExpression(new ConstantExpression(propertyName));
constrainedPropertyConstructorArgumentList.addExpression(new ClassExpression(propertyType));
final ConstructorCallExpression constrainedPropertyCtorCallExpression = new ConstructorCallExpression(new ClassNode(ConstrainedProperty.class), constrainedPropertyConstructorArgumentList);
final Expression declareConstrainedPropertyExpression = new DeclarationExpression(new VariableExpression(cpName, ClassHelper.OBJECT_TYPE), Token.newSymbol(Types.EQUALS, 0, 0), constrainedPropertyCtorCallExpression);
final ArgumentListExpression applyConstraintMethodArgumentList = new ArgumentListExpression();
applyConstraintMethodArgumentList.addExpression(new ConstantExpression(ConstrainedProperty.NULLABLE_CONSTRAINT));
applyConstraintMethodArgumentList.addExpression(new ConstantExpression(defaultNullable));
final Expression applyNullableConstraintMethodCallExpression = new MethodCallExpression(new VariableExpression(cpName), "applyConstraint", applyConstraintMethodArgumentList);
final ArgumentListExpression putMethodArgumentList = new ArgumentListExpression();
putMethodArgumentList.addExpression(new ConstantExpression(propertyName));
putMethodArgumentList.addExpression(new VariableExpression(cpName));
final MethodCallExpression addToConstraintsMapExpression = new MethodCallExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME), "put", putMethodArgumentList);
final BlockStatement addNullableConstraintBlock = new BlockStatement();
addNullableConstraintBlock.addStatement(new ExpressionStatement(declareConstrainedPropertyExpression));
addNullableConstraintBlock.addStatement(new ExpressionStatement(applyNullableConstraintMethodCallExpression));
addNullableConstraintBlock.addStatement(new ExpressionStatement(addToConstraintsMapExpression));
final Expression constraintsMapContainsKeyExpression = new MethodCallExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME, ClassHelper.make(Map.class)), "containsKey", new ArgumentListExpression(new ConstantExpression(propertyName)));
final BooleanExpression ifPropertyIsAlreadyConstrainedExpression = new BooleanExpression(constraintsMapContainsKeyExpression);
final Statement ifPropertyIsAlreadyConstrainedStatement = new IfStatement(ifPropertyIsAlreadyConstrainedExpression, new ExpressionStatement(new EmptyExpression()), addNullableConstraintBlock);
ifConstraintsPropertyIsNullBlockStatement.addStatement(ifPropertyIsAlreadyConstrainedStatement);
}
}
final BlockStatement methodBlockStatement = new BlockStatement();
methodBlockStatement.addStatement(ifConstraintsPropertyIsNullStatement);
final Statement returnStatement = new ReturnStatement(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME));
methodBlockStatement.addStatement(returnStatement);
final MethodNode methodNode = new MethodNode(getConstraintsMethodName, Modifier.STATIC | Modifier.PUBLIC, new ClassNode(Map.class), ZERO_PARAMETERS, null, methodBlockStatement);
if (classNode.redirect() == null) {
classNode.addMethod(methodNode);
} else {
classNode.redirect().addMethod(methodNode);
}
}
}
Aggregations