/** * Returns the top-level statements in the specified method or constructor. * If no such statements are found, an empty * list is returned. * * @param node a MethodNode representing a method or constructor * @return the top-level statements in the specified method or constructor */ public List<Statement> getStatements(MethodNode node) { return getStatements((BlockStatement)node.getCode()); }
/** * Returns a list of statements of the given method. Modifications to the returned list * will affect the method's statements. * * @param method a method (node) * @return a list of statements of the given method */ @SuppressWarnings("unchecked") public static List<Statement> getStatements(MethodNode method) { Statement code = method.getCode(); if (!(code instanceof BlockStatement)) { // null or single statement BlockStatement block = new BlockStatement(); if (code != null) block.addStatement(code); method.setCode(block); } return ((BlockStatement)method.getCode()).getStatements(); }
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); }
protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { visitAnnotations(node); visitClassCodeContainer(node.getCode()); for (Parameter param : node.getParameters()) { visitAnnotations(param); } }
private boolean checkIfMandatoryAnnotationValuesPassed(AnnotationNode node) { boolean ok = true; Map attributes = node.getMembers(); ClassNode classNode = node.getClassNode(); for (MethodNode mn : classNode.getMethods()) { String methodName = mn.getName(); // if the annotation attribute has a default, getCode() returns a ReturnStatement with the default value if (mn.getCode() == null && !attributes.containsKey(methodName)) { addError("No explicit/default value found for annotation attribute '" + methodName + "'", node); ok = false; } } return ok; }
private static void visit(Closure closure, CodeVisitorSupport visitor) { if (closure != null) { ClassNode classNode = closure.getMetaClass().getClassNode(); if (classNode == null) { throw new GroovyRuntimeException( "DataSet unable to evaluate expression. AST not available for closure: " + closure.getMetaClass().getTheClass().getName() + ". Is the source code on the classpath?"); } List methods = classNode.getDeclaredMethods("doCall"); if (!methods.isEmpty()) { MethodNode method = (MethodNode) methods.get(0); if (method != null) { Statement statement = method.getCode(); if (statement != null) { statement.visit(visitor); } } } } }
private void transformRunMethod(final ClassNode classNode, final SourceUnit source) { MethodNode runMethod = classNode.getDeclaredMethod("run", Parameter.EMPTY_ARRAY); Statement code = runMethod.getCode(); MarkupBuilderCodeTransformer transformer = new MarkupBuilderCodeTransformer(source, classNode, config.isAutoEscape()); code.visit(transformer); }
private void visitAnnotationDefault(MethodNode node, MethodVisitor mv) { if (!node.hasAnnotationDefault()) return; Expression exp = ((ReturnStatement) node.getCode()).getExpression(); AnnotationVisitor av = mv.visitAnnotationDefault(); visitAnnotationDefaultExpression(av,node.getReturnType(),exp); }
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); }
protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { visitAnnotations(node); analyseMethodHead(node); Statement code = node.getCode(); visitClassCodeContainer(code); }
@Override protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { this.currentMethod = node; visitAnnotations(node); visitClassCodeContainer(node.getCode()); // GROOVY-5681: initial expressions should be visited too! for (Parameter param : node.getParameters()) { if (param.hasInitialExpression()) { param.getInitialExpression().visit(this); } visitAnnotations(param); } this.currentMethod = null; }
public void visitMethod(MethodNode node) { //GROOVY-3712 - if it's an MOP method, it's an error as they aren't supposed to exist before ACG is invoked if (MopWriter.isMopMethod(node.getName())) { throw new RuntimeParserException("Found unexpected MOP methods in the class node for " + classNode.getName() + "(" + node.getName() + ")", classNode); } this.methodNode = node; adjustTypesIfStaticMainMethod(node); addReturnIfNeeded(node); Statement statement; statement = node.getCode(); if (statement != null) statement.visit(new VerifierCodeVisitor(this)); }
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(); }
public static MethodNode correctToGenericsSpec(Map<String, ClassNode> genericsSpec, MethodNode mn) { ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, mn.getReturnType()); Parameter[] origParameters = mn.getParameters(); Parameter[] newParameters = new Parameter[origParameters.length]; for (int i = 0; i < origParameters.length; i++) { Parameter origParameter = origParameters[i]; newParameters[i] = new Parameter(correctToGenericsSpecRecurse(genericsSpec, origParameter.getType()), origParameter.getName(), origParameter.getInitialExpression()); } return new MethodNode(mn.getName(), mn.getModifiers(), correctedType, newParameters, mn.getExceptions(), mn.getCode()); }
private static MethodNode buildDelegatingMethod(final MethodNode annotatedMethod, final ClassNode ownerClassNode) { Statement code = annotatedMethod.getCode(); int access = ACC_PROTECTED; if (annotatedMethod.isStatic()) { access = ACC_PRIVATE | ACC_STATIC; } MethodNode method = new MethodNode( buildUniqueName(ownerClassNode, METHOD_LABEL, annotatedMethod), access, annotatedMethod.getReturnType(), cloneParams(annotatedMethod.getParameters()), annotatedMethod.getExceptions(), code ); method.addAnnotations(filterAnnotations(annotatedMethod.getAnnotations())); return method; }
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; String value = getMemberStringValue(node, "value"); if (parent instanceof MethodNode) { MethodNode mNode = (MethodNode) parent; if (mNode.isAbstract()) { addError("Error during " + MY_TYPE_NAME + " processing: annotation not allowed on abstract method '" + mNode.getName() + "'", mNode); return; } ClassNode cNode = mNode.getDeclaringClass(); String lockExpr = determineLock(value, cNode, mNode); if (lockExpr == null) return; Statement origCode = mNode.getCode(); Statement newCode = new SynchronizedStatement(varX(lockExpr), origCode); mNode.setCode(newCode); } }
private MethodNode copyMethod(MethodNode method, String newName) { // can't hurt to set return type to void MethodNode newMethod = new MethodNode(newName, method.getModifiers(), ClassHelper.VOID_TYPE, method.getParameters(), method.getExceptions(), method.getCode()); newMethod.addAnnotations(method.getAnnotations()); newMethod.setSynthetic(method.isSynthetic()); newMethod.setDeclaringClass(method.getDeclaringClass()); newMethod.setSourcePosition(method); newMethod.setVariableScope(method.getVariableScope()); newMethod.setGenericsTypes(method.getGenericsTypes()); newMethod.setAnnotationDefault(method.hasAnnotationDefault()); return newMethod; }
public void checkCircularReference(ClassNode searchClass, ClassNode attrType, Expression startExp) { if (!isValidAnnotationClass(attrType)) return; if (!(startExp instanceof AnnotationConstantExpression)) { addError("Found '" + startExp.getText() + "' when expecting an Annotation Constant", startExp); return; } AnnotationConstantExpression ace = (AnnotationConstantExpression) startExp; AnnotationNode annotationNode = (AnnotationNode) ace.getValue(); if (annotationNode.getClassNode().equals(searchClass)) { addError("Circular reference discovered in " + searchClass.getName(), startExp); return; } ClassNode cn = annotationNode.getClassNode(); for (MethodNode method : cn.getMethods()) { if (method.getReturnType().equals(searchClass)) { addError("Circular reference discovered in " + cn.getName(), startExp); } ReturnStatement code = (ReturnStatement) method.getCode(); if (code == null) continue; checkCircularReference(searchClass, method.getReturnType(), code.getExpression()); } }
private static 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); } }
private MethodNode processMethod(ClassNode traitClass, ClassNode traitHelperClass, MethodNode methodNode, ClassNode fieldHelper, Collection<String> knownFields) { Parameter[] initialParams = methodNode.getParameters(); Parameter[] newParams = new Parameter[initialParams.length + 1]; newParams[0] = createSelfParameter(traitClass, methodNode.isStatic()); System.arraycopy(initialParams, 0, newParams, 1, initialParams.length); final int mod = methodNode.isPrivate() ? ACC_PRIVATE : ACC_PUBLIC | (methodNode.isFinal() ? ACC_FINAL : 0); MethodNode mNode = new MethodNode( methodNode.getName(), mod | ACC_STATIC, methodNode.getReturnType(), newParams, methodNode.getExceptions(), processBody(new VariableExpression(newParams[0]), methodNode.getCode(), traitClass, traitHelperClass, fieldHelper, knownFields) ); mNode.setSourcePosition(methodNode); mNode.addAnnotations(filterAnnotations(methodNode.getAnnotations())); mNode.setGenericsTypes(methodNode.getGenericsTypes()); if (methodNode.isAbstract()) { mNode.setModifiers(ACC_PUBLIC | ACC_ABSTRACT); } else { methodNode.addAnnotation(new AnnotationNode(Traits.IMPLEMENTED_CLASSNODE)); } methodNode.setCode(null); if (!methodNode.isPrivate() && !methodNode.isStatic()) { methodNode.setModifiers(ACC_PUBLIC | ACC_ABSTRACT); } return mNode; }