use of org.codehaus.groovy.ast.expr.DeclarationExpression in project groovy by apache.
the class AbstractInterruptibleASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
internalError("Expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes));
}
this.source = source;
AnnotationNode node = (AnnotationNode) nodes[0];
AnnotatedNode annotatedNode = (AnnotatedNode) nodes[1];
if (!type().equals(node.getClassNode())) {
internalError("Transformation called from wrong annotation: " + node.getClassNode().getName());
}
setupTransform(node);
// should be limited to the current SourceUnit or propagated to the whole CompilationUnit
final ModuleNode tree = source.getAST();
if (applyToAllClasses) {
// guard every class and method defined in this script
if (tree != null) {
final List<ClassNode> classes = tree.getClasses();
for (ClassNode classNode : classes) {
visitClass(classNode);
}
}
} else if (annotatedNode instanceof ClassNode) {
// only guard this particular class
this.visitClass((ClassNode) annotatedNode);
} else if (!applyToAllMembers && annotatedNode instanceof MethodNode) {
this.visitMethod((MethodNode) annotatedNode);
this.visitClass(annotatedNode.getDeclaringClass());
} else if (!applyToAllMembers && annotatedNode instanceof FieldNode) {
this.visitField((FieldNode) annotatedNode);
this.visitClass(annotatedNode.getDeclaringClass());
} else if (!applyToAllMembers && annotatedNode instanceof DeclarationExpression) {
this.visitDeclarationExpression((DeclarationExpression) annotatedNode);
this.visitClass(annotatedNode.getDeclaringClass());
} else {
// only guard the script class
if (tree != null) {
final List<ClassNode> classes = tree.getClasses();
for (ClassNode classNode : classes) {
if (classNode.isScript()) {
visitClass(classNode);
}
}
}
}
}
use of org.codehaus.groovy.ast.expr.DeclarationExpression in project groovy by apache.
the class BaseScriptASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source);
AnnotatedNode parent = (AnnotatedNode) nodes[1];
AnnotationNode node = (AnnotationNode) nodes[0];
if (!MY_TYPE.equals(node.getClassNode()))
return;
if (parent instanceof DeclarationExpression) {
changeBaseScriptTypeFromDeclaration((DeclarationExpression) parent, node);
} else if (parent instanceof ImportNode || parent instanceof PackageNode) {
changeBaseScriptTypeFromPackageOrImport(source, parent, node);
} else if (parent instanceof ClassNode) {
changeBaseScriptTypeFromClass((ClassNode) parent, node);
}
}
use of org.codehaus.groovy.ast.expr.DeclarationExpression in project groovy by apache.
the class BaseScriptASTTransformation method changeBaseScriptTypeFromDeclaration.
private void changeBaseScriptTypeFromDeclaration(final DeclarationExpression de, final AnnotationNode node) {
if (de.isMultipleAssignmentDeclaration()) {
addError("Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", de);
return;
}
if (!(de.getRightExpression() instanceof EmptyExpression)) {
addError("Annotation " + MY_TYPE_NAME + " not supported with variable assignment.", de);
return;
}
Expression value = node.getMember("value");
if (value != null) {
addError("Annotation " + MY_TYPE_NAME + " cannot have member 'value' if used on a declaration.", value);
return;
}
ClassNode cNode = de.getDeclaringClass();
ClassNode baseScriptType = de.getVariableExpression().getType().getPlainNodeReference();
de.setRightExpression(new VariableExpression("this"));
changeBaseScriptType(de, cNode, baseScriptType);
}
use of org.codehaus.groovy.ast.expr.DeclarationExpression in project groovy-core by groovy.
the class Verifier method addDefaultParameterMethods.
/**
* Creates a new helper method for each combination of default parameter expressions
*/
protected void addDefaultParameterMethods(final ClassNode node) {
List methods = new ArrayList(node.getMethods());
addDefaultParameters(methods, new DefaultArgsAction() {
public void call(ArgumentListExpression arguments, Parameter[] newParams, MethodNode method) {
final BlockStatement code = new BlockStatement();
MethodNode newMethod = new MethodNode(method.getName(), method.getModifiers(), method.getReturnType(), newParams, method.getExceptions(), code);
// GROOVY-5681 and GROOVY-5632
for (Expression argument : arguments.getExpressions()) {
if (argument instanceof CastExpression) {
argument = ((CastExpression) argument).getExpression();
}
if (argument instanceof ConstructorCallExpression) {
ClassNode type = argument.getType();
if (type instanceof InnerClassNode && ((InnerClassNode) type).isAnonymous()) {
type.setEnclosingMethod(newMethod);
}
}
// check whether closure shared variables refer to params with default values (GROOVY-5632)
if (argument instanceof ClosureExpression) {
final List<Parameter> newMethodNodeParameters = Arrays.asList(newParams);
CodeVisitorSupport visitor = new CodeVisitorSupport() {
@Override
public void visitVariableExpression(VariableExpression expression) {
Variable v = expression.getAccessedVariable();
if (!(v instanceof Parameter))
return;
Parameter param = (Parameter) v;
if (param.hasInitialExpression() && code.getVariableScope().getDeclaredVariable(param.getName()) == null && !newMethodNodeParameters.contains(param)) {
VariableExpression localVariable = new VariableExpression(param.getName(), ClassHelper.makeReference());
DeclarationExpression declarationExpression = new DeclarationExpression(localVariable, Token.newSymbol(Types.EQUAL, -1, -1), new ConstructorCallExpression(ClassHelper.makeReference(), param.getInitialExpression()));
code.addStatement(new ExpressionStatement(declarationExpression));
code.getVariableScope().putDeclaredVariable(localVariable);
}
}
};
visitor.visitClosureExpression((ClosureExpression) argument);
}
}
MethodCallExpression expression = new MethodCallExpression(VariableExpression.THIS_EXPRESSION, method.getName(), arguments);
expression.setMethodTarget(method);
expression.setImplicitThis(true);
if (method.isVoidMethod()) {
code.addStatement(new ExpressionStatement(expression));
} else {
code.addStatement(new ReturnStatement(expression));
}
List<AnnotationNode> annotations = method.getAnnotations();
if (annotations != null) {
newMethod.addAnnotations(annotations);
}
MethodNode oldMethod = node.getDeclaredMethod(method.getName(), newParams);
if (oldMethod != null) {
throw new RuntimeParserException("The method with default parameters \"" + method.getTypeDescriptor() + "\" defines a method \"" + newMethod.getTypeDescriptor() + "\" that is already defined.", method);
}
addPropertyMethod(newMethod);
newMethod.setGenericsTypes(method.getGenericsTypes());
}
});
}
use of org.codehaus.groovy.ast.expr.DeclarationExpression in project grails-core by grails.
the class ControllerActionTransformer method wrapMethodBodyWithExceptionHandling.
/**
* This will wrap the method body in a try catch block which does something
* like this:
* <pre>
* try {
* // original method body here
* } catch (Exception $caughtException) {
* Method $method = getExceptionHandlerMethod($caughtException.getClass())
* if($method) {
* return $method.invoke(this, $caughtException)
* } else {
* throw $caughtException
* }
* }
* </pre>
* @param methodNode the method to add the try catch block to
*/
protected void wrapMethodBodyWithExceptionHandling(final ClassNode controllerClassNode, final MethodNode methodNode) {
final BlockStatement catchBlockCode = new BlockStatement();
final String caughtExceptionArgumentName = "$caughtException";
final Expression caughtExceptionVariableExpression = new VariableExpression(caughtExceptionArgumentName);
final Expression caughtExceptionTypeExpression = new PropertyExpression(caughtExceptionVariableExpression, "class");
final Expression thisExpression = new VariableExpression("this");
final MethodCallExpression getExceptionHandlerMethodCall = new MethodCallExpression(thisExpression, "getExceptionHandlerMethodFor", caughtExceptionTypeExpression);
applyDefaultMethodTarget(getExceptionHandlerMethodCall, controllerClassNode);
final ClassNode reflectMethodClassNode = new ClassNode(Method.class);
final String exceptionHandlerMethodVariableName = "$method";
final Expression exceptionHandlerMethodExpression = new VariableExpression(exceptionHandlerMethodVariableName, new ClassNode(Method.class));
final Expression declareExceptionHandlerMethod = new DeclarationExpression(new VariableExpression(exceptionHandlerMethodVariableName, reflectMethodClassNode), Token.newSymbol(Types.EQUALS, 0, 0), getExceptionHandlerMethodCall);
final ArgumentListExpression invokeArguments = new ArgumentListExpression();
invokeArguments.addExpression(thisExpression);
invokeArguments.addExpression(caughtExceptionVariableExpression);
final MethodCallExpression invokeExceptionHandlerMethodExpression = new MethodCallExpression(new VariableExpression(exceptionHandlerMethodVariableName), "invoke", invokeArguments);
applyDefaultMethodTarget(invokeExceptionHandlerMethodExpression, reflectMethodClassNode);
final Statement returnStatement = new ReturnStatement(invokeExceptionHandlerMethodExpression);
final Statement throwCaughtExceptionStatement = new ThrowStatement(caughtExceptionVariableExpression);
final Statement ifExceptionHandlerMethodExistsStatement = new IfStatement(new BooleanExpression(exceptionHandlerMethodExpression), returnStatement, throwCaughtExceptionStatement);
catchBlockCode.addStatement(new ExpressionStatement(declareExceptionHandlerMethod));
catchBlockCode.addStatement(ifExceptionHandlerMethodExistsStatement);
final CatchStatement catchStatement = new CatchStatement(new Parameter(new ClassNode(Exception.class), caughtExceptionArgumentName), catchBlockCode);
final Statement methodBody = methodNode.getCode();
BlockStatement tryBlock = new BlockStatement();
BlockStatement codeToHandleAllowedMethods = getCodeToHandleAllowedMethods(controllerClassNode, methodNode.getName());
tryBlock.addStatement(codeToHandleAllowedMethods);
tryBlock.addStatement(methodBody);
final TryCatchStatement tryCatchStatement = new TryCatchStatement(tryBlock, new EmptyStatement());
tryCatchStatement.addCatch(catchStatement);
final ArgumentListExpression argumentListExpression = new ArgumentListExpression();
argumentListExpression.addExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME));
final PropertyExpression requestPropertyExpression = new PropertyExpression(new VariableExpression("this"), "request");
final Expression removeAttributeMethodCall = new MethodCallExpression(requestPropertyExpression, "removeAttribute", argumentListExpression);
final Expression getAttributeMethodCall = new MethodCallExpression(requestPropertyExpression, "getAttribute", new ArgumentListExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME)));
final VariableExpression attributeValueExpression = new VariableExpression("$allowed_methods_attribute_value", ClassHelper.make(Object.class));
final Expression initializeAttributeValue = new DeclarationExpression(attributeValueExpression, Token.newSymbol(Types.EQUALS, 0, 0), getAttributeMethodCall);
final Expression attributeValueMatchesMethodNameExpression = new BinaryExpression(new ConstantExpression(methodNode.getName()), Token.newSymbol(Types.COMPARE_EQUAL, 0, 0), attributeValueExpression);
final Statement ifAttributeValueMatchesMethodName = new IfStatement(new BooleanExpression(attributeValueMatchesMethodNameExpression), new ExpressionStatement(removeAttributeMethodCall), new EmptyStatement());
final BlockStatement blockToRemoveAttribute = new BlockStatement();
blockToRemoveAttribute.addStatement(new ExpressionStatement(initializeAttributeValue));
blockToRemoveAttribute.addStatement(ifAttributeValueMatchesMethodName);
final TryCatchStatement tryCatchToRemoveAttribute = new TryCatchStatement(blockToRemoveAttribute, new EmptyStatement());
tryCatchToRemoveAttribute.addCatch(new CatchStatement(new Parameter(ClassHelper.make(Exception.class), "$exceptionRemovingAttribute"), new EmptyStatement()));
tryCatchStatement.setFinallyStatement(tryCatchToRemoveAttribute);
methodNode.setCode(tryCatchStatement);
}
Aggregations