private void visitConstructorOrMethod(MethodNode node, int methodTarget) { visitAnnotations(node, methodTarget); for (int i = 0; i < node.getParameters().length; i++) { Parameter parameter = node.getParameters()[i]; visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET); } if (this.currentClass.isAnnotationDefinition() && !node.isStaticConstructor()) { ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration()); AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector); visitor.setReportClass(currentClass); visitor.checkReturnType(node.getReturnType(), node); if (node.getParameters().length > 0) { addError("Annotation members may not have parameters.", node.getParameters()[0]); } if (node.getExceptions().length > 0) { addError("Annotation members may not have a throws clause.", node.getExceptions()[0]); } ReturnStatement code = (ReturnStatement) node.getCode(); if (code != null) { visitor.visitExpression(node.getName(), code.getExpression(), node.getReturnType()); visitor.checkCircularReference(currentClass, node.getReturnType(), code.getExpression()); } this.source.getErrorCollector().addCollectorContents(errorCollector); } }
public void visitConstructorCallExpression(ConstructorCallExpression call) { isSpecialConstructorCall = call.isSpecialCall(); super.visitConstructorCallExpression(call); isSpecialConstructorCall = false; if (!call.isUsingAnonymousInnerClass()) return; pushState(); InnerClassNode innerClass = (InnerClassNode) call.getType(); innerClass.setVariableScope(currentScope); for (MethodNode method : innerClass.getMethods()) { Parameter[] parameters = method.getParameters(); if (parameters.length == 0) parameters = null; // null means no implicit "it" ClosureExpression cl = new ClosureExpression(parameters, method.getCode()); visitClosureExpression(cl); } for (FieldNode field : innerClass.getFields()) { final Expression expression = field.getInitialExpression(); if (expression != null) { expression.visit(this); } } for (Statement statement : innerClass.getObjectInitializerStatements()) { statement.visit(this); } markClosureSharedVariables(); popState(); }
public void visit(ASTNode[] nodes, SourceUnit source) { if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) { throw new RuntimeException( "Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes)); } AnnotationNode annotationNode = (AnnotationNode) nodes[0]; ASTNode node = nodes[1]; if (!(node instanceof MethodNode)) { addError("@NotYetImplemented must only be applied on test methods!", node); return; } MethodNode methodNode = (MethodNode) node; ArrayList<Statement> statements = new ArrayList<Statement>(); Statement statement = methodNode.getCode(); if (statement instanceof BlockStatement) { statements.addAll(((BlockStatement) statement).getStatements()); } if (statements.size() == 0) return; BlockStatement rewrittenMethodCode = new BlockStatement(); rewrittenMethodCode.addStatement( tryCatchAssertionFailedError(annotationNode, methodNode, statements)); rewrittenMethodCode.addStatement(throwAssertionFailedError(annotationNode)); methodNode.setCode(rewrittenMethodCode); }
public static void visitScriptCode(SourceUnit source, GroovyCodeVisitor transformer) { source.getAST().getStatementBlock().visit(transformer); for (Object method : source.getAST().getMethods()) { MethodNode methodNode = (MethodNode) method; methodNode.getCode().visit(transformer); } }
private Statement getMethodBody(MethodNode methodNode) { Statement code = methodNode.getCode(); if (!(code instanceof BlockStatement)) { BlockStatement body = new BlockStatement(); body.addStatement(code); code = body; } return code; }
// no rename so delete and add private static void renameMethod(ClassNode buildee, MethodNode mNode, String newName) { buildee.addMethod( newName, mNode.getModifiers(), mNode.getReturnType(), mNode.getParameters(), mNode.getExceptions(), mNode.getCode()); buildee.removeMethod(mNode); }
private void changeBaseScriptType( final AnnotatedNode parent, final ClassNode cNode, final ClassNode baseScriptType) { if (!cNode.isScriptBody()) { addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent); return; } if (!baseScriptType.isScript()) { addError( "Declared type " + baseScriptType + " does not extend groovy.lang.Script class!", parent); return; } cNode.setSuperClass(baseScriptType); // Method in base script that will contain the script body code. MethodNode runScriptMethod = ClassHelper.findSAM(baseScriptType); // If they want to use a name other than than "run", then make the change. if (isCustomScriptBodyMethod(runScriptMethod)) { MethodNode defaultMethod = cNode.getDeclaredMethod("run", Parameter.EMPTY_ARRAY); // GROOVY-6706: Sometimes an NPE is thrown here. // The reason is that our transform is getting called more than once sometimes. if (defaultMethod != null) { cNode.removeMethod(defaultMethod); MethodNode methodNode = new MethodNode( runScriptMethod.getName(), runScriptMethod.getModifiers() & ~ACC_ABSTRACT, runScriptMethod.getReturnType(), runScriptMethod.getParameters(), runScriptMethod.getExceptions(), defaultMethod.getCode()); // The AST node metadata has the flag that indicates that this method is a script body. // It may also be carrying data for other AST transforms. methodNode.copyNodeMetaData(defaultMethod); cNode.addMethod(methodNode); } } // If the new script base class does not have a contextual constructor (g.l.Binding), then we // won't either. // We have to do things this way (and rely on just default constructors) because the logic that // generates // the constructors for our script class have already run. if (cNode.getSuperClass().getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS) == null) { ConstructorNode orphanedConstructor = cNode.getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS); cNode.removeConstructor(orphanedConstructor); } }
protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { pushState(node.isStatic()); inConstructor = isConstructor; node.setVariableScope(currentScope); visitAnnotations(node); // GROOVY-2156 Parameter[] parameters = node.getParameters(); for (Parameter parameter : parameters) { visitAnnotations(parameter); } declare(node.getParameters(), node); visitClassCodeContainer(node.getCode()); popState(); }
/** * Wraps a method body in try / catch logic that catches any errors and logs an error, but does * not rethrow! * * @param methodNode The method node */ public static void wrapMethodBodyInTryCatchDebugStatements(MethodNode methodNode) { BlockStatement code = (BlockStatement) methodNode.getCode(); BlockStatement newCode = new BlockStatement(); TryCatchStatement tryCatchStatement = new TryCatchStatement(code, new BlockStatement()); newCode.addStatement(tryCatchStatement); methodNode.setCode(newCode); BlockStatement catchBlock = new BlockStatement(); ArgumentListExpression logArguments = new ArgumentListExpression(); logArguments.addExpression( new BinaryExpression( new ConstantExpression("Error initializing class: "), Token.newSymbol(Types.PLUS, 0, 0), new VariableExpression("e"))); logArguments.addExpression(new VariableExpression("e")); catchBlock.addStatement( new ExpressionStatement( new MethodCallExpression(new VariableExpression("log"), "error", logArguments))); tryCatchStatement.addCatch( new CatchStatement(new Parameter(new ClassNode(Throwable.class), "e"), catchBlock)); }