@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; }
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; }
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() + "> "; }
/** * 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); }
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); }