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);
  }
Example #4
0
 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();
  }
Example #9
0
 /**
  * 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));
 }