public void call(SourceUnit source) throws CompilationFailedException {
          List<ClassNode> classes = source.ast.getClasses();
          for (ClassNode node : classes) {
            CompileUnit cu = node.getCompileUnit();
            for (Iterator iter = cu.iterateClassNodeToCompile(); iter.hasNext(); ) {
              String name = (String) iter.next();
              SourceUnit su = ast.getScriptSourceLocation(name);
              List<ClassNode> classesInSourceUnit = su.ast.getClasses();
              StringBuilder message = new StringBuilder();
              message
                  .append("Compilation incomplete: expected to find the class ")
                  .append(name)
                  .append(" in ")
                  .append(su.getName());
              if (classesInSourceUnit.isEmpty()) {
                message.append(", but the file seems not to contain any classes");
              } else {
                message.append(", but the file contains the classes: ");
                boolean first = true;
                for (ClassNode cn : classesInSourceUnit) {
                  if (!first) {
                    message.append(", ");
                  } else {
                    first = false;
                  }
                  message.append(cn.getName());
                }
              }

              getErrorCollector()
                  .addErrorAndContinue(new SimpleMessage(message.toString(), CompilationUnit.this));
              iter.remove();
            }
          }
        }
 public void removeField(String oldName) {
   ClassNode r = redirect();
   if (r.fieldIndex == null) r.fieldIndex = new HashMap<String, FieldNode>();
   final Map<String, FieldNode> index = r.fieldIndex;
   r.fields.remove(index.get(oldName));
   index.remove(oldName);
 }
  public Map<String, MethodNode> getDeclaredMethodsMap() {
    // Start off with the methods from the superclass.
    ClassNode parent = getSuperClass();
    Map<String, MethodNode> result = null;
    if (parent != null) {
      result = parent.getDeclaredMethodsMap();
    } else {
      result = new HashMap<String, MethodNode>();
    }

    // add in unimplemented abstract methods from the interfaces
    for (ClassNode iface : getInterfaces()) {
      Map<String, MethodNode> ifaceMethodsMap = iface.getDeclaredMethodsMap();
      for (String methSig : ifaceMethodsMap.keySet()) {
        if (!result.containsKey(methSig)) {
          MethodNode methNode = ifaceMethodsMap.get(methSig);
          result.put(methSig, methNode);
        }
      }
    }

    // And add in the methods implemented in this class.
    for (MethodNode method : getMethods()) {
      String sig = method.getTypeDescriptor();
      result.put(sig, method);
    }
    return result;
  }
  private Expression transformInlineConstants(Expression exp) {
    if (exp instanceof PropertyExpression) {
      PropertyExpression pe = (PropertyExpression) exp;
      if (pe.getObjectExpression() instanceof ClassExpression) {
        ClassExpression ce = (ClassExpression) pe.getObjectExpression();
        ClassNode type = ce.getType();
        if (type.isEnum()) return exp;
        Expression constant = findConstant(type.getField(pe.getPropertyAsString()));
        // GRECLIPSE edit
        // if (constant != null) return constant;
        if (constant != null) {
          String name = pe.getText().replace('$', '.');
          Object alias = pe.getNodeMetaData("static.import.alias");
          if (alias != null && !alias.equals(pe.getPropertyAsString())) {
            name += " as " + alias;
          }
          // store the qualified name to facilitate organizing static imports
          constant.setNodeMetaData("static.import", name);

          return constant;
        }
        // GRECLIPSE end
      }
    } else if (exp instanceof ListExpression) {
      ListExpression le = (ListExpression) exp;
      ListExpression result = new ListExpression();
      for (Expression e : le.getExpressions()) {
        result.addExpression(transformInlineConstants(e));
      }
      return result;
    }

    return exp;
  }
  private void assertMembersNamesAreUnique() {
    Map<String, FieldNode> allDslCollectionFieldNodesOfHierarchy = new HashMap<String, FieldNode>();

    for (ClassNode level : ASTHelper.getHierarchyOfDSLObjectAncestors(annotatedClass)) {
      for (FieldNode field : level.getFields()) {
        if (!ASTHelper.isListOrMap(field.getType())) continue;

        String memberName = getElementNameForCollectionField(field);

        FieldNode conflictingField = allDslCollectionFieldNodesOfHierarchy.get(memberName);

        if (conflictingField != null) {
          addCompileError(
              String.format(
                  "Member name %s is used more than once: %s:%s and %s:%s",
                  memberName,
                  field.getOwner().getName(),
                  field.getName(),
                  conflictingField.getOwner().getName(),
                  conflictingField.getName()),
              field);
          return;
        }

        allDslCollectionFieldNodesOfHierarchy.put(memberName, field);
      }
    }
  }
  private void getAllInterfaces(Set<ClassNode> res) {
    if (isInterface()) res.add(this);

    for (ClassNode anInterface : getInterfaces()) {
      res.add(anInterface);
      anInterface.getAllInterfaces(res);
    }
  }
 public void addProperty(PropertyNode node) {
   node.setDeclaringClass(redirect());
   FieldNode field = node.getField();
   addField(field);
   final ClassNode r = redirect();
   if (r.properties == null) r.properties = new ArrayList<PropertyNode>();
   r.properties.add(node);
 }
 private Expression findStaticField(ClassNode staticImportType, String fieldName) {
   if (staticImportType.isPrimaryClassNode() || staticImportType.isResolved()) {
     FieldNode field = staticImportType.getField(fieldName);
     if (field != null && field.isStatic())
       return new PropertyExpression(new ClassExpression(staticImportType), fieldName);
   }
   return null;
 }
 private Expression findStaticMethod(
     ClassNode staticImportType, String methodName, Expression args) {
   if (staticImportType.isPrimaryClassNode() || staticImportType.isResolved()) {
     if (staticImportType.hasPossibleStaticMethod(methodName, args)) {
       return new StaticMethodCallExpression(staticImportType, methodName, args);
     }
   }
   return null;
 }
  public void preprocessClassNode(ClassNode node) {
    super.preprocessClassNode(node);

    classes.add(node);

    getChartData(node.getFeatures().size())[FEATURES_PER_CLASS]++;
    getChartData(node.getInboundDependencies().size())[INBOUNDS_PER_CLASS]++;
    getChartData(node.getOutboundDependencies().size())[OUTBOUNDS_PER_CLASS]++;
  }
 /** @return the ClassNode of the super class of this type */
 public ClassNode getSuperClass() {
   if (!lazyInitDone && !isResolved()) {
     throw new GroovyBugError(
         "ClassNode#getSuperClass for " + getName() + " called before class resolving");
   }
   ClassNode sn = redirect().getUnresolvedSuperClass();
   if (sn != null) sn = sn.redirect();
   return sn;
 }
 /**
  * This methods creates a list of all methods with this name of the current class and of all super
  * classes
  *
  * @return the methods list
  * @see #getDeclaredMethods(String)
  */
 public List<MethodNode> getMethods(String name) {
   List<MethodNode> answer = new ArrayList<MethodNode>();
   ClassNode node = this;
   while (node != null) {
     answer.addAll(node.getDeclaredMethods(name));
     node = node.getSuperClass();
   }
   return answer;
 }
 /**
  * Finds a field matching the given name in this class or a parent class.
  *
  * @param name the name of the field of interest
  * @return the method matching the given name and parameters or null
  */
 public FieldNode getField(String name) {
   ClassNode node = this;
   while (node != null) {
     FieldNode fn = node.getDeclaredField(name);
     if (fn != null) return fn;
     node = node.getSuperClass();
   }
   return null;
 }
 public void addMethod(MethodNode node) {
   node.setDeclaringClass(this);
   ClassNode base = redirect();
   if (base.methodsList.isEmpty()) {
     base.methodsList = new ArrayList<MethodNode>();
   }
   base.methodsList.add(node);
   base.methods.put(node.getName(), node);
 }
  public void visitInboundClassNode(ClassNode node) {
    if (!getCoverage().contains(node)) {
      getSelectedNodes().add(node);

      Node copy = getFactory().createClass(node.getName(), node.isConfirmed());
      getCopiedNodes().add(copy);
      copy.addDependency(currentNode);
    }
  }
 public void addFieldFirst(FieldNode node) {
   final ClassNode r = redirect();
   node.setDeclaringClass(r);
   node.setOwner(r);
   if (r.fields == null) r.fields = new LinkedList<FieldNode>();
   if (r.fieldIndex == null) r.fieldIndex = new HashMap<String, FieldNode>();
   r.fields.addFirst(node);
   r.fieldIndex.put(node.getName(), node);
 }
  /**
   * A loop driver for applying operations to all primary ClassNodes in our AST. Automatically skips
   * units that have already been processed through the current phase.
   */
  public void applyToPrimaryClassNodes(PrimaryClassNodeOperation body)
      throws CompilationFailedException {
    // GRECLIPSE: start
    /*old{
    Iterator classNodes = getPrimaryClassNodes(body.needSortedInput()).iterator();
    }*/
    // newcode
    List primaryClassNodes = getPrimaryClassNodes(body.needSortedInput());
    Iterator classNodes = primaryClassNodes.iterator();
    // end
    while (classNodes.hasNext()) {
      SourceUnit context = null;
      try {
        ClassNode classNode = (ClassNode) classNodes.next();
        context = classNode.getModule().getContext();
        // GRECLIPSE get to the bottom of this - why are operations running multiple times that
        // should only run once?
        if (context == null
            || context.phase < phase
            || (context.phase == phase && !context.phaseComplete)) {

          int offset = 1;
          Iterator<InnerClassNode> iterator = classNode.getInnerClasses();
          while (iterator.hasNext()) {
            iterator.next();
            offset++;
          }
          body.call(context, new GeneratorContext(this.ast, offset), classNode);
        }
      } catch (CompilationFailedException e) {
        // fall through, getErrorReporter().failIfErrors() will trigger
      } catch (NullPointerException npe) {
        throw npe;
      } catch (GroovyBugError e) {
        changeBugText(e, context);
        throw e;
      } catch (Exception e) {
        // check the exception for a nested compilation exception
        ErrorCollector nestedCollector = null;
        for (Throwable next = e.getCause(); next != e && next != null; next = next.getCause()) {
          if (!(next instanceof MultipleCompilationErrorsException)) continue;
          MultipleCompilationErrorsException mcee = (MultipleCompilationErrorsException) next;
          nestedCollector = mcee.collector;
          break;
        }

        if (nestedCollector != null) {
          getErrorCollector().addCollectorContents(nestedCollector);
        } else {
          getErrorCollector().addError(new ExceptionMessage(e, configuration.getDebug(), this));
        }
      }
    }

    getErrorCollector().failIfErrors();
  }
 /**
  * @param classNode the class node for the interface
  * @return true if this class or any base class implements the given interface
  */
 public boolean implementsInterface(ClassNode classNode) {
   ClassNode node = redirect();
   do {
     if (node.declaresInterface(classNode)) {
       return true;
     }
     node = node.getSuperClass();
   } while (node != null);
   return false;
 }
 public ClassNode getPlainNodeReference() {
   if (ClassHelper.isPrimitiveType(this)) return this;
   ClassNode n = new ClassNode(name, modifiers, superClass, null, null);
   n.isPrimaryNode = false;
   n.setRedirect(redirect());
   if (isArray()) {
     n.componentType = redirect().getComponentType();
   }
   return n;
 }
 private boolean hasStaticProperty(ClassNode staticImportType, String propName) {
   ClassNode classNode = staticImportType;
   while (classNode != null) {
     for (PropertyNode pn : classNode.getProperties()) {
       if (pn.getName().equals(propName) && pn.isStatic()) return true;
     }
     classNode = classNode.getSuperClass();
   }
   return false;
 }
 /**
  * @param classNode the class node for the interface
  * @return true if this class declares that it implements the given interface or if one of its
  *     interfaces extends directly or indirectly the interface
  *     <p>NOTE: Doesn't consider an interface to implement itself. I think this is intended to be
  *     called on ClassNodes representing classes, not interfaces.
  */
 public boolean declaresInterface(ClassNode classNode) {
   ClassNode[] interfaces = redirect().getInterfaces();
   for (ClassNode cn : interfaces) {
     if (cn.equals(classNode)) return true;
   }
   for (ClassNode cn : interfaces) {
     if (cn.declaresInterface(classNode)) return true;
   }
   return false;
 }
  /**
   * Returns the concrete class this classnode relates to. However, this method is inherently unsafe
   * as it may return null depending on the compile phase you are using. AST transformations should
   * never use this method directly, but rather obtain a new class node using {@link
   * #getPlainNodeReference()}.
   *
   * @return the class this classnode relates to. May return null.
   */
  public Class getTypeClass() {
    if (clazz != null) return clazz;
    if (redirect != null) return redirect.getTypeClass();

    ClassNode component = redirect().componentType;
    if (component != null && component.isResolved()) {
      return Array.newInstance(component.getTypeClass(), 0).getClass();
    }
    throw new GroovyBugError(
        "ClassNode#getTypeClass for " + getName() + " is called before the type class is set ");
  }
 private void createKeyConstructor() {
   annotatedClass.addConstructor(
       ACC_PUBLIC,
       params(param(STRING_TYPE, "key")),
       NO_EXCEPTIONS,
       block(
           ASTHelper.isDSLObject(annotatedClass.getSuperClass())
               ? ctorSuperS(args("key"))
               : ctorSuperS(),
           assignS(propX(varX("this"), keyField.getName()), varX("key"))));
 }
 /**
  * Parse a string, assuming that it is of the type expected by a given NamedParameter.
  *
  * <p>This method does not deal with sets; if the NamedParameter is set valued, then the provided
  * string should correspond to a single member of the set. It is up to the caller to call parse
  * once for each value that should be parsed as a member of the set.
  *
  * @return a non-null reference to the parsed value.
  */
 @Override
 @SuppressWarnings("unchecked")
 public <T> T parse(final NamedParameterNode<T> np, final String value) throws ParseException {
   final ClassNode<T> iface;
   try {
     iface = (ClassNode<T>) getNode(np.getFullArgName());
   } catch (final NameResolutionException e) {
     throw new IllegalStateException(
         "Could not parse validated named parameter argument type.  NamedParameter is "
             + np.getFullName()
             + " argument type is "
             + np.getFullArgName());
   }
   Class<?> clazz;
   String fullName;
   try {
     clazz = classForName(iface.getFullName());
     fullName = null;
   } catch (final ClassNotFoundException e) {
     clazz = null;
     fullName = iface.getFullName();
   }
   try {
     if (clazz != null) {
       return (T) parameterParser.parse(clazz, value);
     } else {
       return parameterParser.parse(fullName, value);
     }
   } catch (final UnsupportedOperationException e) {
     try {
       final Node impl = getNode(value);
       if (impl instanceof ClassNode && isImplementation(iface, (ClassNode<?>) impl)) {
         return (T) impl;
       }
       throw new ParseException(
           "Name<"
               + iface.getFullName()
               + "> "
               + np.getFullName()
               + " cannot take non-subclass "
               + impl.getFullName(),
           e);
     } catch (final NameResolutionException e2) {
       throw new ParseException(
           "Name<"
               + iface.getFullName()
               + "> "
               + np.getFullName()
               + " cannot take non-class "
               + value,
           e);
     }
   }
 }
 /**
  * Sets this instance as proxy for the given ClassNode.
  *
  * @param cn the class to redirect to. If set to null the redirect will be removed
  */
 public void setRedirect(ClassNode cn) {
   if (isPrimaryNode)
     throw new GroovyBugError(
         "tried to set a redirect for a primary ClassNode ("
             + getName()
             + "->"
             + cn.getName()
             + ").");
   if (cn != null) cn = cn.redirect();
   if (cn == this) return;
   redirect = cn;
 }
 public MethodNode getSetterMethod(String setterName, boolean voidOnly) {
   for (MethodNode method : getDeclaredMethods(setterName)) {
     if (setterName.equals(method.getName())
         && (!voidOnly || ClassHelper.VOID_TYPE == method.getReturnType())
         && method.getParameters().length == 1) {
       return method;
     }
   }
   ClassNode parent = getSuperClass();
   if (parent != null) return parent.getSetterMethod(setterName, voidOnly);
   return null;
 }
 public MethodNode getGetterMethod(String getterName) {
   for (MethodNode method : getDeclaredMethods(getterName)) {
     if (getterName.equals(method.getName())
         && ClassHelper.VOID_TYPE != method.getReturnType()
         && method.getParameters().length == 0) {
       return method;
     }
   }
   ClassNode parent = getSuperClass();
   if (parent != null) return parent.getGetterMethod(getterName);
   return null;
 }
  protected byte[] transformClass(byte[] bytes, String clssname) {
    InputStream is = getClass().getResourceAsStream("/" + clssname.replace('.', '/') + ".class");

    ClassReader orig = null;
    try {
      ClassReader crRepl = new ClassReader(is);
      ClassNode cnRepl = new ClassNode(Opcodes.ASM4);
      crRepl.accept(cnRepl, ClassReader.SKIP_FRAMES);

      ClassReader crOrig = new ClassReader(bytes);
      ClassNode cnOrig = new ClassNode(Opcodes.ASM4);
      crOrig.accept(cnOrig, ClassReader.SKIP_FRAMES);

      for (Object ofnRepl : cnRepl.fields) {
        FieldNode fnRepl = (FieldNode) ofnRepl;

        if (hasReplaceAnnotation(fnRepl.visibleAnnotations)) {
          FieldNode fnOrig = findField(cnOrig.fields, fnRepl);
          if (fnOrig != null) {
            cnOrig.fields.remove(fnOrig);
            cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl));
          }
        } else if (hasAddAnnotation(fnRepl.visibleAnnotations)) {
          cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl));
        }
      }

      for (Object omnRepl : cnRepl.methods) {
        MethodNode mnRepl = (MethodNode) omnRepl;

        if (hasReplaceAnnotation(mnRepl.visibleAnnotations)) {
          MethodNode mnOrig = findMethod(cnOrig.methods, mnRepl);
          if (mnOrig != null) {
            cnOrig.methods.remove(mnOrig);
            cnOrig.methods.add(cnOrig.methods.size(), scrubMethod(cnOrig, cnRepl, mnRepl));
          }
        } else if (hasAddAnnotation(mnRepl.visibleAnnotations)) {
          cnOrig.methods.add(cnOrig.methods.size() + 1, scrubMethod(cnOrig, cnRepl, mnRepl));
        }
      }

      ClassWriter cwNew = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
      cnOrig.accept(cwNew);
      return cwNew.toByteArray();
    } catch (IOException e) {
      e.printStackTrace(); // To change body of catch statement use File | Settings | File
      // Templates.
    }

    return bytes;
  }
 /**
  * @param type the ClassNode of interest
  * @return true if this node is derived from the given ClassNode
  */
 public boolean isDerivedFrom(ClassNode type) {
   if (this.equals(ClassHelper.VOID_TYPE)) {
     return type.equals(ClassHelper.VOID_TYPE);
   }
   if (type.equals(ClassHelper.OBJECT_TYPE)) return true;
   ClassNode node = this;
   while (node != null) {
     if (type.equals(node)) {
       return true;
     }
     node = node.getSuperClass();
   }
   return false;
 }
  @Override
  public void visitConstructorCallExpression(final ConstructorCallExpression call) {
    super.visitConstructorCallExpression(call);

    MethodNode target = (MethodNode) call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
    if (target == null && call.getLineNumber() > 0) {
      addError("Target constructor for constructor call expression hasn't been set", call);
    } else {
      if (target == null) {
        // try to find a target
        ArgumentListExpression argumentListExpression =
            InvocationWriter.makeArgumentList(call.getArguments());
        List<Expression> expressions = argumentListExpression.getExpressions();
        ClassNode[] args = new ClassNode[expressions.size()];
        for (int i = 0; i < args.length; i++) {
          args[i] = typeChooser.resolveType(expressions.get(i), classNode);
        }
        MethodNode constructor =
            findMethodOrFail(
                call, call.isSuperCall() ? classNode.getSuperClass() : classNode, "<init>", args);
        call.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, constructor);
        target = constructor;
      }
    }
    if (target != null) {
      memorizeInitialExpressions(target);
    }
  }