@Override
  protected void performInjectionInternal(
      String apiInstanceProperty, SourceUnit source, ClassNode classNode) {
    List<PropertyNode> tags = findTags(classNode);

    PropertyNode namespaceProperty = classNode.getProperty(NAMESPACE_PROPERTY);
    String namespace = GroovyPage.DEFAULT_NAMESPACE;
    if (namespaceProperty != null && namespaceProperty.isStatic()) {
      Expression initialExpression = namespaceProperty.getInitialExpression();
      if (initialExpression instanceof ConstantExpression) {
        namespace = initialExpression.getText();
      }
    }

    addGetTagLibNamespaceMethod(classNode, namespace);

    MethodCallExpression tagLibraryLookupMethodCall =
        new MethodCallExpression(
            new VariableExpression(apiInstanceProperty, ClassHelper.make(TagLibraryApi.class)),
            "getTagLibraryLookup",
            ZERO_ARGS);
    for (PropertyNode tag : tags) {
      String tagName = tag.getName();
      addAttributesAndBodyMethod(classNode, tagLibraryLookupMethodCall, tagName);
      addAttributesAndStringBodyMethod(classNode, tagName);
      addAttributesAndBodyMethod(classNode, tagLibraryLookupMethodCall, tagName, false);
      addAttributesAndBodyMethod(classNode, tagLibraryLookupMethodCall, tagName, true, false);
      addAttributesAndBodyMethod(classNode, tagLibraryLookupMethodCall, tagName, false, false);
    }
  }
 private Statement createConstructorStatement(
     ClassNode cNode,
     PropertyNode pNode,
     List<String> knownImmutableClasses,
     List<String> knownImmutables) {
   FieldNode fNode = pNode.getField();
   final ClassNode fieldType = fNode.getType();
   Statement statement = null;
   if (fieldType.isArray() || isOrImplements(fieldType, CLONEABLE_TYPE)) {
     statement = createConstructorStatementArrayOrCloneable(fNode);
   } else if (isKnownImmutableClass(fieldType, knownImmutableClasses)
       || isKnownImmutable(pNode.getName(), knownImmutables)) {
     statement = createConstructorStatementDefault(fNode);
   } else if (fieldType.isDerivedFrom(DATE_TYPE)) {
     statement = createConstructorStatementDate(fNode);
   } else if (isOrImplements(fieldType, COLLECTION_TYPE)
       || fieldType.isDerivedFrom(COLLECTION_TYPE)
       || isOrImplements(fieldType, MAP_TYPE)
       || fieldType.isDerivedFrom(MAP_TYPE)) {
     statement = createConstructorStatementCollection(fNode);
   } else if (fieldType.isResolved()) {
     addError(
         createErrorMessage(cNode.getName(), fNode.getName(), fieldType.getName(), "compiling"),
         fNode);
     statement = EmptyStatement.INSTANCE;
   } else {
     statement = createConstructorStatementGuarded(cNode, fNode);
   }
   return statement;
 }
 public static List<String> getInstancePropertyNames(ClassNode cNode) {
   List<PropertyNode> pList = BeanUtils.getAllProperties(cNode, false, false, true);
   List<String> result = new ArrayList<String>(pList.size());
   for (PropertyNode pNode : pList) {
     result.add(pNode.getName());
   }
   return result;
 }
Esempio n. 4
0
 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 Set<String> generateDomainProperties(DomainClass domain) {
   Assert.isNotNull(domain, "Domain class should not be null");
   List<PropertyNode> domainPropertiesNodes = domain.getDomainProperties();
   Set<String> properties = new HashSet<String>(domainPropertiesNodes.size() * 2);
   for (PropertyNode property : domainPropertiesNodes) {
     properties.add(capitalize(property.getName()));
   }
   return properties;
 }
 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;
 }
  /**
   * 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;
  }
 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;
 }
  public void visitProperty(PropertyNode node) {
    visitAnnotations(node);
    Statement statement = node.getGetterBlock();
    visitClassCodeContainer(statement);

    statement = node.getSetterBlock();
    visitClassCodeContainer(statement);

    Expression init = node.getInitialExpression();
    if (init != null) init.visit(this);
  }
 private void injectAssociationProperties(ClassNode classNode, List propertiesToAdd) {
   for (Iterator i = propertiesToAdd.iterator(); i.hasNext(); ) {
     PropertyNode pn = (PropertyNode) i.next();
     if (! /*GrailsASTUtils.*/hasProperty(classNode, pn.getName())) {
       // if(LOG.isDebugEnabled()) {
       //    LOG.debug("[GrailsDomainInjector] Adding property [" + pn.getName() + "] to class [" +
       // classNode.getName() + "]");
       // }
       classNode.addProperty(pn);
     }
   }
 }
 /**
  * This method is similar to {@link #propX(Expression, Expression)} but will make sure that if the
  * property being accessed is defined inside the classnode provided as a parameter, then a getter
  * call is generated instead of a field access.
  *
  * @param annotatedNode the class node where the property node is accessed from
  * @param pNode the property being accessed
  * @return a method call expression or a property expression
  */
 public static Expression getterThisX(ClassNode annotatedNode, PropertyNode pNode) {
   ClassNode owner = pNode.getDeclaringClass();
   if (annotatedNode.equals(owner)) {
     String getterName = "get" + MetaClassHelper.capitalize(pNode.getName());
     boolean existingExplicitGetter =
         annotatedNode.getMethod(getterName, Parameter.EMPTY_ARRAY) != null;
     if (ClassHelper.boolean_TYPE.equals(pNode.getOriginType()) && !existingExplicitGetter) {
       getterName = "is" + MetaClassHelper.capitalize(pNode.getName());
     }
     return callThisX(getterName);
   }
   return propX(new VariableExpression("this"), pNode.getName());
 }
 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;
 }
Esempio n. 13
0
  public PropertyNode addProperty(
      String name,
      int modifiers,
      ClassNode type,
      Expression initialValueExpression,
      Statement getterBlock,
      Statement setterBlock) {
    for (PropertyNode pn : getProperties()) {
      if (pn.getName().equals(name)) {
        if (pn.getInitialExpression() == null && initialValueExpression != null)
          pn.getField().setInitialValueExpression(initialValueExpression);

        if (pn.getGetterBlock() == null && getterBlock != null) pn.setGetterBlock(getterBlock);

        if (pn.getSetterBlock() == null && setterBlock != null) pn.setSetterBlock(setterBlock);

        return pn;
      }
    }
    PropertyNode node =
        new PropertyNode(
            name, modifiers, type, redirect(), initialValueExpression, getterBlock, setterBlock);
    addProperty(node);
    return node;
  }
 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);
   }
 }
 private String getRefDescriptor(ASTNode ref) {
   if (ref instanceof FieldNode) {
     FieldNode f = (FieldNode) ref;
     return "the field " + f.getName() + " ";
   } else if (ref instanceof PropertyNode) {
     PropertyNode p = (PropertyNode) ref;
     return "the property " + p.getName() + " ";
   } else if (ref instanceof ConstructorNode) {
     return "the constructor " + ref.getText() + " ";
   } else if (ref instanceof MethodNode) {
     return "the method " + ref.getText() + " ";
   } else if (ref instanceof ClassNode) {
     return "the super class " + ref + " ";
   }
   return "<unknown with class " + ref.getClass() + "> ";
 }
Esempio n. 16
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 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;
  }
 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 createConstructorOrdered(ClassNode cNode, List<PropertyNode> list) {
   final MapExpression argMap = new MapExpression();
   final Parameter[] orderedParams = new Parameter[list.size()];
   int index = 0;
   for (PropertyNode pNode : list) {
     Parameter param = new Parameter(pNode.getField().getType(), pNode.getField().getName());
     orderedParams[index++] = param;
     argMap.addMapEntryExpression(
         new ConstantExpression(pNode.getName()), new VariableExpression(pNode.getName()));
   }
   final BlockStatement orderedBody = new BlockStatement();
   orderedBody.addStatement(
       new ExpressionStatement(
           new ConstructorCallExpression(
               ClassNode.THIS,
               new ArgumentListExpression(new CastExpression(HASHMAP_TYPE, argMap)))));
   doAddConstructor(
       cNode, new ConstructorNode(ACC_PUBLIC, orderedParams, ClassNode.EMPTY_ARRAY, orderedBody));
 }
 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);
  }
 private void addProperty(ClassNode cNode, PropertyNode pNode) {
   final FieldNode fn = pNode.getField();
   cNode.getFields().remove(fn);
   cNode.addProperty(
       pNode.getName(),
       pNode.getModifiers() | ACC_FINAL,
       pNode.getType(),
       pNode.getInitialExpression(),
       pNode.getGetterBlock(),
       pNode.getSetterBlock());
   final FieldNode newfn = cNode.getField(fn.getName());
   cNode.getFields().remove(newfn);
   cNode.addField(fn);
 }
  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 visitProperty(PropertyNode node) {
   pushState(node.isStatic());
   super.visitProperty(node);
   popState();
 }
  private boolean makeGetPropertyWithGetter(
      final Expression receiver,
      final ClassNode receiverType,
      final String methodName,
      final boolean safe,
      final boolean implicitThis) {
    // does a getter exists ?
    String getterName = "get" + MetaClassHelper.capitalize(methodName);
    MethodNode getterNode = receiverType.getGetterMethod(getterName);
    if (getterNode == null) {
      getterName = "is" + MetaClassHelper.capitalize(methodName);
      getterNode = receiverType.getGetterMethod(getterName);
    }
    if (getterNode != null
        && receiver instanceof ClassExpression
        && !CLASS_Type.equals(receiverType)
        && !getterNode.isStatic()) {
      return false;
    }

    // GROOVY-5561: if two files are compiled in the same source unit
    // and that one references the other, the getters for properties have not been
    // generated by the compiler yet (generated by the Verifier)
    PropertyNode propertyNode = receiverType.getProperty(methodName);
    if (propertyNode != null) {
      // it is possible to use a getter
      String prefix = "get";
      if (boolean_TYPE.equals(propertyNode.getOriginType())) {
        prefix = "is";
      }
      getterName = prefix + MetaClassHelper.capitalize(methodName);
      getterNode =
          new MethodNode(
              getterName,
              ACC_PUBLIC,
              propertyNode.getOriginType(),
              Parameter.EMPTY_ARRAY,
              ClassNode.EMPTY_ARRAY,
              EmptyStatement.INSTANCE);
      getterNode.setDeclaringClass(receiverType);
      if (propertyNode.isStatic()) getterNode.setModifiers(ACC_PUBLIC + ACC_STATIC);
    }
    if (getterNode != null) {
      MethodCallExpression call =
          new MethodCallExpression(receiver, getterName, ArgumentListExpression.EMPTY_ARGUMENTS);
      call.setSourcePosition(receiver);
      call.setMethodTarget(getterNode);
      call.setImplicitThis(implicitThis);
      call.setSafe(safe);
      call.visit(controller.getAcg());
      return true;
    }

    if (receiverType instanceof InnerClassNode && !receiverType.isStaticClass()) {
      if (makeGetPropertyWithGetter(
          receiver, receiverType.getOuterClass(), methodName, safe, implicitThis)) {
        return true;
      }
    }

    // go upper level
    ClassNode superClass = receiverType.getSuperClass();
    if (superClass != null) {
      return makeGetPropertyWithGetter(receiver, superClass, methodName, safe, implicitThis);
    }
    return false;
  }
 private void adjustPropertyForImmutability(PropertyNode pNode, List<PropertyNode> newNodes) {
   final FieldNode fNode = pNode.getField();
   fNode.setModifiers((pNode.getModifiers() & (~ACC_PUBLIC)) | ACC_FINAL | ACC_PRIVATE);
   adjustPropertyNode(pNode, createGetterBody(fNode));
   newNodes.add(pNode);
 }
Esempio n. 27
0
 public PropertyNode getProperty(String name) {
   for (PropertyNode pn : getProperties()) {
     if (pn.getName().equals(name)) return pn;
   }
   return null;
 }
  private AnalysisResult scan(GroovyParserResult result) {
    AnalysisResult analysisResult = new AnalysisResult();

    ASTNode root = ASTUtils.getRoot(result);

    if (root == null) {
      return analysisResult;
    }

    structure = new ArrayList<ASTElement>();
    fields = new HashMap<ASTClass, Set<FieldNode>>();
    methods = new ArrayList<ASTMethod>();
    properties = new HashMap<ASTClass, Set<PropertyNode>>();

    AstPath path = new AstPath();
    path.descend(root);
    // TODO: I should pass in a "default" context here to stash methods etc. outside of modules and
    // classes
    scan(result, root, path, null, null, null);
    path.ascend();

    // Process fields
    Map<String, FieldNode> names = new HashMap<String, FieldNode>();

    for (ASTClass clz : fields.keySet()) {
      Set<FieldNode> assignments = fields.get(clz);

      // Find unique variables
      if (assignments != null) {
        for (FieldNode assignment : assignments) {
          names.put(assignment.getName(), assignment);
        }

        // Add unique fields
        for (FieldNode field : names.values()) {
          ASTField co = new ASTField(result, field);
          // co.setIn(AstUtilities.getClassOrModuleName(clz));
          co.setIn(clz.getFqn());

          // Make sure I don't already have an entry for this field as an
          // attr_accessor or writer
          String fieldName = field.getName();

          boolean found = false;

          Set<PropertyNode> nodes = properties.get(clz);
          if (nodes != null) {
            for (PropertyNode node : nodes) {
              if (fieldName.equals(node.getName())) {
                found = true;
                break;
              }
            }
          }

          if (found) {
            co.setProperty(true);
          }
          clz.addChild(co);
        }

        names.clear();
      }
    }

    analysisResult.setElements(structure);

    return analysisResult;
  }
 private void adjustPropertyNode(PropertyNode pNode, Statement getterBody) {
   pNode.setSetterBlock(null);
   pNode.setGetterBlock(getterBody);
 }
 public void visitProperty(PropertyNode node) {
   checkDuplicateProperties(node);
   checkGenericsUsage(node, node.getType());
   super.visitProperty(node);
 }