private List<PropertyNode> findTags(ClassNode classNode) {
    List<PropertyNode> tags = new ArrayList<PropertyNode>();
    List<PropertyNode> properties = classNode.getProperties();
    List<PropertyNode> potentialAliases = new ArrayList<PropertyNode>();
    for (PropertyNode property : properties) {
      if (property.isPublic()) {
        Expression initialExpression = property.getInitialExpression();
        if (initialExpression instanceof ClosureExpression) {
          ClosureExpression ce = (ClosureExpression) initialExpression;
          Parameter[] parameters = ce.getParameters();

          if (parameters.length <= 2) {
            tags.add(property);
            // force Closure type for DefaultGrailsTagLibClass
            property.setType(CLOSURE_CLASS_NODE);
          }
        } else if (initialExpression instanceof VariableExpression) {
          potentialAliases.add(property);
        }
      }
    }

    for (PropertyNode potentialAlias : potentialAliases) {
      VariableExpression pe = (VariableExpression) potentialAlias.getInitialExpression();

      String propertyName = pe.getName();
      PropertyNode property = classNode.getProperty(propertyName);
      if (property != null && tags.contains(property)) {
        potentialAlias.setType(CLOSURE_CLASS_NODE);
        tags.add(potentialAlias);
      }
    }
    return tags;
  }
 public static List<FieldNode> getInstancePropertyFields(ClassNode cNode) {
   final List<FieldNode> result = new ArrayList<FieldNode>();
   for (PropertyNode pNode : cNode.getProperties()) {
     if (!pNode.isStatic()) {
       result.add(pNode.getField());
     }
   }
   return result;
 }
 public static List<PropertyNode> getAllProperties(ClassNode type) {
   ClassNode node = type;
   List<PropertyNode> result = new ArrayList<PropertyNode>();
   while (node != null) {
     result.addAll(node.getProperties());
     node = node.getSuperClass();
   }
   return result;
 }
 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;
 }
  /**
   * Returns whether a classNode has the specified property or not
   *
   * @param classNode The ClassNode
   * @param propertyName The name of the property
   * @return True if the property exists in the ClassNode
   */
  public static boolean hasProperty(ClassNode classNode, String propertyName) {
    if (classNode == null || propertyName == null || "".equals(propertyName.trim())) return false;

    List properties = classNode.getProperties();
    for (Iterator i = properties.iterator(); i.hasNext(); ) {
      PropertyNode pn = (PropertyNode) i.next();
      if (pn.getName().equals(propertyName)) return true;
    }
    return false;
  }
 public static List<FieldNode> getSuperPropertyFields(ClassNode cNode) {
   final List<FieldNode> result;
   if (cNode == ClassHelper.OBJECT_TYPE) {
     result = new ArrayList<FieldNode>();
   } else {
     result = getSuperPropertyFields(cNode.getSuperClass());
   }
   for (PropertyNode pNode : cNode.getProperties()) {
     if (!pNode.isStatic()) {
       result.add(pNode.getField());
     }
   }
   return result;
 }
 private void visitFieldNode(FieldNode fNode) {
   final ClassNode cNode = fNode.getDeclaringClass();
   final List<PropertyNode> pList = cNode.getProperties();
   PropertyNode foundProp = null;
   for (PropertyNode pNode : pList) {
     if (pNode.getName().equals(fNode.getName())) {
       foundProp = pNode;
       break;
     }
   }
   if (foundProp != null) {
     revertVisibility(fNode);
     pList.remove(foundProp);
   }
 }
  /**
   * If we are in a constructor, that is static compiled, but in a class, that is not, it may happen
   * that init code from object initializers, fields or properties is added into the constructor
   * code. The backend assumes a purely static contructor, so it may fail if it encounters dynamic
   * code here. Thus we make this kind of code fail
   */
  private void checkForConstructorWithCSButClassWithout(MethodNode node) {
    if (!(node instanceof ConstructorNode)) return;
    Object meta = node.getNodeMetaData(STATIC_COMPILE_NODE);
    if (!Boolean.TRUE.equals(meta)) return;
    ClassNode clz = typeCheckingContext.getEnclosingClassNode();
    meta = clz.getNodeMetaData(STATIC_COMPILE_NODE);
    if (Boolean.TRUE.equals(meta)) return;
    if (clz.getObjectInitializerStatements().isEmpty()
        && clz.getFields().isEmpty()
        && clz.getProperties().isEmpty()) {
      return;
    }

    addStaticTypeError(
        "Cannot statically compile constructor implicitly including non static elements from object initializers, properties or fields.",
        node);
  }
Exemple #9
0
  /**
   * Returns whether a classNode has the specified property or not
   *
   * @param classNode The ClassNode
   * @param propertyName The name of the property
   * @return True if the property exists in the ClassNode
   */
  public static boolean hasProperty(ClassNode classNode, String propertyName) {
    if (classNode == null || StringUtils.isBlank(propertyName)) {
      return false;
    }

    final MethodNode method =
        classNode.getMethod(GrailsNameUtils.getGetterName(propertyName), Parameter.EMPTY_ARRAY);
    if (method != null) return true;

    for (PropertyNode pn : classNode.getProperties()) {
      if (pn.getName().equals(propertyName) && !pn.isPrivate()) {
        return true;
      }
    }

    return false;
  }
 private void visitClassNode(ClassNode cNode, List<PackageScopeTarget> value) {
   String cName = cNode.getName();
   if (cNode.isInterface() && value.size() != 1 && value.get(0) != PackageScopeTarget.CLASS) {
     throw new RuntimeException(
         "Error processing interface '"
             + cName
             + "'. "
             + MY_TYPE_NAME
             + " not allowed for interfaces except when targeting Class level.");
   }
   if (value.contains(groovy.transform.PackageScopeTarget.CLASS)) {
     if (cNode.isSyntheticPublic()) revertVisibility(cNode);
     else
       throw new RuntimeException(
           "Can't use "
               + MY_TYPE_NAME
               + " for class '"
               + cNode.getName()
               + "' which has explicit visibility.");
   }
   if (value.contains(groovy.transform.PackageScopeTarget.METHODS)) {
     final List<MethodNode> mList = cNode.getMethods();
     for (MethodNode mNode : mList) {
       if (mNode.isSyntheticPublic()) revertVisibility(mNode);
     }
   }
   if (value.contains(PackageScopeTarget.FIELDS)) {
     final List<PropertyNode> pList = cNode.getProperties();
     List<PropertyNode> foundProps = new ArrayList<PropertyNode>();
     List<String> foundNames = new ArrayList<String>();
     for (PropertyNode pNode : pList) {
       foundProps.add(pNode);
       foundNames.add(pNode.getName());
     }
     for (PropertyNode pNode : foundProps) {
       pList.remove(pNode);
     }
     final List<FieldNode> fList = cNode.getFields();
     for (FieldNode fNode : fList) {
       if (foundNames.contains(fNode.getName())) {
         revertVisibility(fNode);
       }
     }
   }
 }
  private void injectAssociations(ClassNode classNode) {

    List properties = classNode.getProperties();
    List propertiesToAdd = new ArrayList();
    for (Iterator p = properties.iterator(); p.hasNext(); ) {
      PropertyNode pn = (PropertyNode) p.next();
      final boolean isHasManyProperty =
          pn.getName().equals(/*GrailsDomainClassProperty.*/ RELATES_TO_MANY)
              || pn.getName().equals(/*GrailsDomainClassProperty.*/ HAS_MANY);
      if (isHasManyProperty) {
        Expression e = pn.getInitialExpression();
        propertiesToAdd.addAll(createPropertiesForHasManyExpression(e, classNode));
      }
      final boolean isBelongsTo = pn.getName().equals(/*GrailsDomainClassProperty.*/ BELONGS_TO);
      if (isBelongsTo) {
        Expression e = pn.getInitialExpression();
        propertiesToAdd.addAll(createPropertiesForBelongsToExpression(e, classNode));
      }
    }
    injectAssociationProperties(classNode, propertiesToAdd);
  }
  public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    AnnotationNode node = (AnnotationNode) nodes[0];
    // temporarily have weaker check which allows for old Deprecated Annotation
    //        if (!MY_TYPE.equals(node.getClassNode())) return;
    if (!node.getClassNode().getName().endsWith(".Immutable")) return;
    List<PropertyNode> newProperties = new ArrayList<PropertyNode>();

    if (parent instanceof ClassNode) {
      final List<String> knownImmutableClasses = getKnownImmutableClasses(node);
      final List<String> knownImmutables = getKnownImmutables(node);

      ClassNode cNode = (ClassNode) parent;
      String cName = cNode.getName();
      checkNotInterface(cNode, MY_TYPE_NAME);
      makeClassFinal(cNode);

      final List<PropertyNode> pList = getInstanceProperties(cNode);
      for (PropertyNode pNode : pList) {
        adjustPropertyForImmutability(pNode, newProperties);
      }
      for (PropertyNode pNode : newProperties) {
        cNode.getProperties().remove(pNode);
        addProperty(cNode, pNode);
      }
      final List<FieldNode> fList = cNode.getFields();
      for (FieldNode fNode : fList) {
        ensureNotPublic(cName, fNode);
      }
      createConstructors(cNode, knownImmutableClasses, knownImmutables);
      if (!hasAnnotation(cNode, EqualsAndHashCodeASTTransformation.MY_TYPE)) {
        createHashCode(cNode, true, false, false, null, null);
        createEquals(cNode, false, false, false, null, null);
      }
      if (!hasAnnotation(cNode, ToStringASTTransformation.MY_TYPE)) {
        createToString(cNode, false, false, null, null, false, true);
      }
    }
  }
 private void checkDuplicateProperties(PropertyNode node) {
   ClassNode cn = node.getDeclaringClass();
   String name = node.getName();
   String getterName = "get" + MetaClassHelper.capitalize(name);
   if (Character.isUpperCase(name.charAt(0))) {
     for (PropertyNode propNode : cn.getProperties()) {
       String otherName = propNode.getField().getName();
       String otherGetterName = "get" + MetaClassHelper.capitalize(otherName);
       if (node != propNode && getterName.equals(otherGetterName)) {
         String msg =
             "The field "
                 + name
                 + " and "
                 + otherName
                 + " on the class "
                 + cn.getName()
                 + " will result in duplicate JavaBean properties, which is not allowed";
         addError(msg, node);
       }
     }
   }
 }
  private Variable findClassMember(ClassNode cn, String name) {
    if (cn == null) return null;
    if (cn.isScript()) {
      return new DynamicVariable(name, false);
    }

    for (FieldNode fn : cn.getFields()) {
      if (fn.getName().equals(name)) return fn;
    }

    for (MethodNode mn : cn.getMethods()) {
      String pName = getPropertyName(mn);
      // GRECLIPSE: start
      // must set the declaringClass
      /*old{
      if (pName != null && pName.equals(name))
          return new PropertyNode(pName, mn.getModifiers(), getPropertyType(mn), cn, null, null, null);
          */
      // newcode
      if (pName != null && pName.equals(name)) {
        PropertyNode property =
            new PropertyNode(pName, mn.getModifiers(), getPropertyType(mn), cn, null, null, null);
        property.setDeclaringClass(cn);
        property.getField().setDeclaringClass(cn);
        return property;
      }
      // GRECLIPSE: end
    }

    for (PropertyNode pn : cn.getProperties()) {
      if (pn.getName().equals(name)) return pn;
    }

    Variable ret = findClassMember(cn.getSuperClass(), name);
    if (ret != null) return ret;
    return findClassMember(cn.getOuterClass(), name);
  }