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);
      }
    }
  }
 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);
 }
  /**
   * This method is used to add "bridge" methods for private methods of an inner/outer class, so
   * that the outer class is capable of calling them. It does basically the same job as access$000
   * like methods in Java.
   *
   * @param node an inner/outer class node for which to generate bridge methods
   */
  @SuppressWarnings("unchecked")
  private void addPrivateBridgeMethods(final ClassNode node) {
    Set<ASTNode> accessedMethods =
        (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS);
    if (accessedMethods == null) return;
    List<MethodNode> methods = new ArrayList<MethodNode>(node.getAllDeclaredMethods());
    Map<MethodNode, MethodNode> privateBridgeMethods =
        (Map<MethodNode, MethodNode>) node.getNodeMetaData(PRIVATE_BRIDGE_METHODS);
    if (privateBridgeMethods != null) {
      // private bridge methods already added
      return;
    }
    privateBridgeMethods = new HashMap<MethodNode, MethodNode>();
    int i = -1;
    final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
    for (MethodNode method : methods) {
      if (accessedMethods.contains(method)) {
        i++;
        Parameter[] methodParameters = method.getParameters();
        Parameter[] newParams = new Parameter[methodParameters.length + 1];
        System.arraycopy(methodParameters, 0, newParams, 1, methodParameters.length);
        newParams[0] = new Parameter(node.getPlainNodeReference(), "$that");
        Expression arguments;
        if (method.getParameters() == null || method.getParameters().length == 0) {
          arguments = ArgumentListExpression.EMPTY_ARGUMENTS;
        } else {
          List<Expression> args = new LinkedList<Expression>();
          for (Parameter parameter : methodParameters) {
            args.add(new VariableExpression(parameter));
          }
          arguments = new ArgumentListExpression(args);
        }
        Expression receiver =
            method.isStatic() ? new ClassExpression(node) : new VariableExpression(newParams[0]);
        MethodCallExpression mce = new MethodCallExpression(receiver, method.getName(), arguments);
        mce.setMethodTarget(method);

        ExpressionStatement returnStatement = new ExpressionStatement(mce);
        MethodNode bridge =
            node.addMethod(
                "access$" + i,
                access,
                method.getReturnType(),
                newParams,
                method.getExceptions(),
                returnStatement);
        privateBridgeMethods.put(method, bridge);
        bridge.addAnnotation(new AnnotationNode(COMPILESTATIC_CLASSNODE));
      }
    }
    if (!privateBridgeMethods.isEmpty()) {
      node.setNodeMetaData(PRIVATE_BRIDGE_METHODS, privateBridgeMethods);
    }
  }
 public Expression transform(Expression exp) {
   if (exp == null) return null;
   if (exp.getClass() == VariableExpression.class) {
     return transformVariableExpression((VariableExpression) exp);
   }
   if (exp.getClass() == BinaryExpression.class) {
     return transformBinaryExpression((BinaryExpression) exp);
   }
   if (exp.getClass() == PropertyExpression.class) {
     return transformPropertyExpression((PropertyExpression) exp);
   }
   if (exp.getClass() == MethodCallExpression.class) {
     return transformMethodCallExpression((MethodCallExpression) exp);
   }
   if (exp.getClass() == ClosureExpression.class) {
     return transformClosureExpression((ClosureExpression) exp);
   }
   if (exp.getClass() == ConstructorCallExpression.class) {
     return transformConstructorCallExpression((ConstructorCallExpression) exp);
   }
   if (exp.getClass() == ArgumentListExpression.class) {
     Expression result = exp.transformExpression(this);
     if (inPropertyExpression) {
       foundArgs = result;
     }
     return result;
   }
   if (exp instanceof ConstantExpression) {
     Expression result = exp.transformExpression(this);
     if (inPropertyExpression) {
       foundConstant = result;
     }
     if (inAnnotation && exp instanceof AnnotationConstantExpression) {
       ConstantExpression ce = (ConstantExpression) result;
       if (ce.getValue() instanceof AnnotationNode) {
         // replicate a little bit of AnnotationVisitor here
         // because we can't wait until later to do this
         AnnotationNode an = (AnnotationNode) ce.getValue();
         Map<String, Expression> attributes = an.getMembers();
         for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
           Expression attrExpr = transform(entry.getValue());
           entry.setValue(attrExpr);
         }
       }
     }
     return result;
   }
   return exp.transformExpression(this);
 }
  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 transformMapEntryExpression(
     MapEntryExpression me, ClassNode constructorCallType) {
   Expression key = me.getKeyExpression();
   Expression value = me.getValueExpression();
   ModuleNode module = currentClass.getModule();
   if (module != null && key instanceof ConstantExpression) {
     Map<String, ImportNode> importNodes = module.getStaticImports();
     if (importNodes.containsKey(key.getText())) {
       ImportNode importNode = importNodes.get(key.getText());
       if (importNode.getType().equals(constructorCallType)) {
         String newKey = importNode.getFieldName();
         return new MapEntryExpression(
             new ConstantExpression(newKey), value.transformExpression(this));
       }
     }
   }
   return me;
 }
  private Expression findStaticFieldOrPropAccessorImportFromModule(String name) {
    ModuleNode module = currentClass.getModule();
    if (module == null) return null;
    Map<String, ImportNode> importNodes = module.getStaticImports();
    Expression expression;
    String accessorName = getAccessorName(name);
    // look for one of these:
    //   import static MyClass.setProp [as setOtherProp]
    //   import static MyClass.getProp [as getOtherProp]
    // when resolving prop reference
    if (importNodes.containsKey(accessorName)) {
      ImportNode importNode = importNodes.get(accessorName);
      expression =
          findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
      expression =
          findStaticPropertyAccessor(
              importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
      if (expression != null) return expression;
    }
    if (accessorName.startsWith("get")) {
      accessorName = "is" + accessorName.substring(3);
      if (importNodes.containsKey(accessorName)) {
        ImportNode importNode = importNodes.get(accessorName);
        expression =
            findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
        if (expression != null) return expression;
        expression =
            findStaticPropertyAccessor(
                importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
        if (expression != null) return expression;
      }
    }

    // look for one of these:
    //   import static MyClass.prop [as otherProp]
    // when resolving prop or field reference
    if (importNodes.containsKey(name)) {
      ImportNode importNode = importNodes.get(name);
      expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
      expression = findStaticField(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
    }
    // look for one of these:
    //   import static MyClass.*
    // when resolving prop or field reference
    for (ImportNode importNode : module.getStaticStarImports().values()) {
      ClassNode node = importNode.getType();
      expression = findStaticPropertyAccessor(node, name);
      if (expression != null) return expression;
      expression = findStaticField(node, name);
      if (expression != null) return expression;
    }
    return null;
  }
 @SuppressWarnings("unchecked")
 private boolean makeGetPrivateFieldWithBridgeMethod(
     final Expression receiver,
     final ClassNode receiverType,
     final String fieldName,
     final boolean safe,
     final boolean implicitThis) {
   FieldNode field = receiverType.getField(fieldName);
   ClassNode classNode = controller.getClassNode();
   if (field != null
       && Modifier.isPrivate(field.getModifiers())
       && (StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(receiverType, classNode)
           || StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(classNode, receiverType))
       && !receiverType.equals(classNode)) {
     Map<String, MethodNode> accessors =
         (Map<String, MethodNode>)
             receiverType
                 .redirect()
                 .getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_FIELDS_ACCESSORS);
     if (accessors != null) {
       MethodNode methodNode = accessors.get(fieldName);
       if (methodNode != null) {
         MethodCallExpression mce =
             new MethodCallExpression(
                 receiver,
                 methodNode.getName(),
                 new ArgumentListExpression(
                     field.isStatic() ? new ConstantExpression(null) : receiver));
         mce.setMethodTarget(methodNode);
         mce.setSafe(safe);
         mce.setImplicitThis(implicitThis);
         mce.visit(controller.getAcg());
         return true;
       }
     }
   }
   return false;
 }
  /** Adds special accessors for private constants so that inner classes can retrieve them. */
  @SuppressWarnings("unchecked")
  private void addPrivateFieldsAccessors(ClassNode node) {
    Set<ASTNode> accessedFields =
        (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
    if (accessedFields == null) return;
    Map<String, MethodNode> privateConstantAccessors =
        (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_ACCESSORS);
    if (privateConstantAccessors != null) {
      // already added
      return;
    }
    int acc = -1;
    privateConstantAccessors = new HashMap<String, MethodNode>();
    final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
    for (FieldNode fieldNode : node.getFields()) {
      if (accessedFields.contains(fieldNode)) {

        acc++;
        Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
        Expression receiver =
            fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
        Statement stmt =
            new ExpressionStatement(new PropertyExpression(receiver, fieldNode.getName()));
        MethodNode accessor =
            node.addMethod(
                "pfaccess$" + acc,
                access,
                fieldNode.getOriginType(),
                new Parameter[] {param},
                ClassNode.EMPTY_ARRAY,
                stmt);
        privateConstantAccessors.put(fieldNode.getName(), accessor);
      }
    }
    node.setNodeMetaData(PRIVATE_FIELDS_ACCESSORS, privateConstantAccessors);
  }
 private Expression findStaticMethodImportFromModule(Expression method, Expression args) {
   ModuleNode module = currentClass.getModule();
   if (module == null || !(method instanceof ConstantExpression)) return null;
   Map<String, ImportNode> importNodes = module.getStaticImports();
   ConstantExpression ce = (ConstantExpression) method;
   Expression expression;
   Object value = ce.getValue();
   // skip non-Strings, e.g. Integer
   if (!(value instanceof String)) return null;
   final String name = (String) value;
   // look for one of these:
   //   import static SomeClass.method [as otherName]
   // when resolving methodCall() or getProp() or setProp()
   if (importNodes.containsKey(name)) {
     ImportNode importNode = importNodes.get(name);
     expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
     if (expression != null) return expression;
     expression =
         findStaticPropertyAccessorGivenArgs(
             importNode.getType(), getPropNameForAccessor(importNode.getFieldName()), args);
     if (expression != null) {
       return new StaticMethodCallExpression(
           importNode.getType(), importNode.getFieldName(), args);
     }
   }
   // look for one of these:
   //   import static SomeClass.someProp [as otherName]
   // when resolving getProp() or setProp()
   if (validPropName(name)) {
     String propName = getPropNameForAccessor(name);
     if (importNodes.containsKey(propName)) {
       ImportNode importNode = importNodes.get(propName);
       expression =
           findStaticMethod(
               importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args);
       if (expression != null) return expression;
       expression =
           findStaticPropertyAccessorGivenArgs(
               importNode.getType(), importNode.getFieldName(), args);
       if (expression != null) {
         return new StaticMethodCallExpression(
             importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args);
       }
     }
   }
   Map<String, ImportNode> starImports = module.getStaticStarImports();
   ClassNode starImportType;
   if (currentClass.isEnum() && starImports.containsKey(currentClass.getName())) {
     ImportNode importNode = starImports.get(currentClass.getName());
     starImportType = importNode == null ? null : importNode.getType();
     expression = findStaticMethod(starImportType, name, args);
     if (expression != null) return expression;
   } else {
     for (ImportNode importNode : starImports.values()) {
       starImportType = importNode == null ? null : importNode.getType();
       expression = findStaticMethod(starImportType, name, args);
       if (expression != null) return expression;
       expression =
           findStaticPropertyAccessorGivenArgs(starImportType, getPropNameForAccessor(name), args);
       if (expression != null) {
         return new StaticMethodCallExpression(starImportType, name, args);
       }
     }
   }
   return null;
 }
  private Expression findStaticFieldOrPropAccessorImportFromModule(String name) {
    ModuleNode module = currentClass.getModule();
    if (module == null) return null;
    Map<String, ImportNode> importNodes = module.getStaticImports();
    Expression expression = null;
    String accessorName = getAccessorName(name);
    // look for one of these:
    //   import static MyClass.setProp [as setOtherProp]
    //   import static MyClass.getProp [as getOtherProp]
    // when resolving prop reference
    if (importNodes.containsKey(accessorName)) {
      ImportNode importNode = importNodes.get(accessorName);
      expression =
          findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
      if (expression != null) return expression;
      expression =
          findStaticPropertyAccessor(
              importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
      if (expression != null) return expression;
    }
    if (accessorName.startsWith("get")) {
      accessorName = "is" + accessorName.substring(3);
      if (importNodes.containsKey(accessorName)) {
        ImportNode importNode = importNodes.get(accessorName);
        expression =
            findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName());
        if (expression != null) return expression;
        expression =
            findStaticPropertyAccessor(
                importNode.getType(), getPropNameForAccessor(importNode.getFieldName()));
        if (expression != null) return expression;
      }
    }

    // look for one of these:
    //   import static MyClass.prop [as otherProp]
    // when resolving prop or field reference
    if (importNodes.containsKey(name)) {
      ImportNode importNode = importNodes.get(name);
      // GRECLIPSE add
      try {
        if (!isReconcile) {
          // GRECLIPSE end
          expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName());
          if (expression != null) return expression;
          // GRECLIPSE add
        }
        // end
        expression = findStaticField(importNode.getType(), importNode.getFieldName());
        if (expression != null) return expression;
        // GRECLIPSE add
      } finally {
        // store the identifier to facilitate organizing static imports
        if (expression != null) expression.setNodeMetaData("static.import.alias", name);
      }
      // GRECLIPSE end
    }
    // look for one of these:
    //   import static MyClass.*
    // when resolving prop or field reference
    for (ImportNode importNode : module.getStaticStarImports().values()) {
      ClassNode node = importNode.getType();
      expression = findStaticPropertyAccessor(node, name);
      if (expression != null) return expression;
      expression = findStaticField(node, name);
      if (expression != null) return expression;
    }
    return null;
  }
  /**
   * Finds a field matching the given name in this class.
   *
   * @param name the name of the field of interest
   * @return the method matching the given name and parameters or null
   */
  public FieldNode getDeclaredField(String name) {
    if (redirect != null) return redirect().getDeclaredField(name);

    lazyClassInit();
    return fieldIndex == null ? null : fieldIndex.get(name);
  }
 public void renameField(String oldName, String newName) {
   ClassNode r = redirect();
   if (r.fieldIndex == null) r.fieldIndex = new HashMap<String, FieldNode>();
   final Map<String, FieldNode> index = r.fieldIndex;
   index.put(newName, index.remove(oldName));
 }