use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class EqualsAndHashCodeASTTransformation method calculateHashStatementsPOJO.
private static Statement calculateHashStatementsPOJO(ClassNode cNode, Expression hash, boolean includeFields, boolean callSuper, List<String> excludes, List<String> includes, boolean allNames, boolean allProperties) {
final Set<String> names = new HashSet<>();
final List<PropertyNode> pList = getAllProperties(names, cNode, true, false, allProperties, false, false, false);
final List<FieldNode> fList = new ArrayList<>();
if (includeFields) {
fList.addAll(getInstanceNonPropertyFields(cNode));
}
final BlockStatement body = new BlockStatement();
final ArgumentListExpression args = new ArgumentListExpression();
for (PropertyNode pNode : pList) {
if (shouldSkipUndefinedAware(pNode.getName(), excludes, includes, allNames))
continue;
args.addExpression(getterThisX(cNode, pNode));
}
for (FieldNode fNode : fList) {
if (shouldSkipUndefinedAware(fNode.getName(), excludes, includes, allNames))
continue;
args.addExpression(varX(fNode));
}
if (callSuper) {
args.addExpression(varX("super"));
}
Expression calcHash = callX(OBJECTS_TYPE, "hash", args);
if (hash != null) {
body.addStatement(assignS(hash, calcHash));
} else {
body.addStatement(returnS(calcHash));
}
return body;
}
use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class EqualsAndHashCodeASTTransformation method calculateHashStatementsDefault.
private static Statement calculateHashStatementsDefault(ClassNode cNode, Expression hash, boolean includeFields, boolean callSuper, List<String> excludes, List<String> includes, boolean allNames, boolean allProperties) {
final Set<String> names = new HashSet<>();
final List<PropertyNode> pList = getAllProperties(names, cNode, true, false, allProperties, false, false, false);
final List<FieldNode> fList = new ArrayList<>();
if (includeFields) {
fList.addAll(getInstanceNonPropertyFields(cNode));
}
final BlockStatement body = new BlockStatement();
// def _result = HashCodeHelper.initHash()
final Expression result = localVarX("_result");
body.addStatement(declS(result, callX(HASHUTIL_TYPE, "initHash")));
for (PropertyNode pNode : pList) {
if (shouldSkipUndefinedAware(pNode.getName(), excludes, includes, allNames))
continue;
// _result = HashCodeHelper.updateHash(_result, getProperty()) // plus self-reference checking
Expression getter = getterThisX(cNode, pNode);
final Expression current = callX(HASHUTIL_TYPE, UPDATE_HASH, args(result, getter));
body.addStatement(ifS(notIdenticalX(getter, varX("this")), assignS(result, current)));
}
for (FieldNode fNode : fList) {
if (shouldSkipUndefinedAware(fNode.getName(), excludes, includes, allNames))
continue;
// _result = HashCodeHelper.updateHash(_result, field) // plus self-reference checking
final Expression fieldExpr = varX(fNode);
final Expression current = callX(HASHUTIL_TYPE, UPDATE_HASH, args(result, fieldExpr));
body.addStatement(ifS(notIdenticalX(fieldExpr, varX("this")), assignS(result, current)));
}
if (callSuper) {
// _result = HashCodeHelper.updateHash(_result, super.hashCode())
final Expression current = callX(HASHUTIL_TYPE, UPDATE_HASH, args(result, callSuperX(HASH_CODE)));
body.addStatement(assignS(result, current));
}
// $hash$code = _result
if (hash != null) {
body.addStatement(assignS(hash, result));
} else {
body.addStatement(returnS(result));
}
return body;
}
use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class JavaStubGenerator method printClassContents.
private void printClassContents(PrintWriter out, ClassNode classNode) {
if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) {
// if it is an anonymous inner class, don't generate the stub code for it.
return;
}
try {
Verifier verifier = new Verifier() {
@Override
public void visitClass(ClassNode node) {
List<Statement> savedStatements = new ArrayList<>(node.getObjectInitializerStatements());
super.visitClass(node);
node.getObjectInitializerStatements().addAll(savedStatements);
for (ClassNode trait : findTraits(node)) {
// GROOVY-9031: replace property type placeholder with resolved type from trait generics
Map<String, ClassNode> generics = trait.isUsingGenerics() ? createGenericsSpec(trait) : null;
for (PropertyNode traitProperty : trait.getProperties()) {
ClassNode traitPropertyType = traitProperty.getType();
traitProperty.setType(correctToGenericsSpecRecurse(generics, traitPropertyType));
super.visitProperty(traitProperty);
traitProperty.setType(traitPropertyType);
}
}
}
@Override
public void visitConstructor(ConstructorNode node) {
Statement stmt = node.getCode();
if (stmt != null) {
stmt.visit(new VerifierCodeVisitor(getClassNode()));
}
}
@Override
public void visitProperty(PropertyNode node) {
// GROOVY-8233 skip static properties for traits since they don't make the interface
if (!node.isStatic() || !Traits.isTrait(node.getDeclaringClass())) {
super.visitProperty(node);
}
}
@Override
public void addCovariantMethods(ClassNode cn) {
}
@Override
protected void addInitialization(ClassNode node) {
}
@Override
protected void addPropertyMethod(MethodNode method) {
doAddMethod(method);
}
@Override
protected void addReturnIfNeeded(MethodNode node) {
}
@Override
protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
return doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
}
@Override
protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
if (code instanceof ExpressionStatement) {
// GROOVY-4508
Statement temp = code;
code = new BlockStatement();
((BlockStatement) code).addStatement(temp);
}
ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
ctrNode.setDeclaringClass(node);
constructors.add(ctrNode);
}
@Override
protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) {
final Parameter[] parameters = method.getParameters();
final Expression[] saved = new Expression[parameters.length];
for (int i = 0; i < parameters.length; i++) {
if (parameters[i].hasInitialExpression())
saved[i] = parameters[i].getInitialExpression();
}
super.addDefaultParameters(action, method);
for (int i = 0; i < parameters.length; i++) {
if (saved[i] != null)
parameters[i].setInitialExpression(saved[i]);
}
}
private MethodNode doAddMethod(MethodNode method) {
String sig = method.getTypeDescriptor();
if (propertyMethodsWithSigs.containsKey(sig))
return method;
propertyMethods.add(method);
propertyMethodsWithSigs.put(sig, method);
return method;
}
@Override
protected void addDefaultConstructor(ClassNode node) {
// not required for stub generation
}
@Override
protected FinalVariableAnalyzer.VariableNotFinalCallback getFinalVariablesCallback() {
return null;
}
};
int origNumConstructors = classNode.getDeclaredConstructors().size();
verifier.visitClass(classNode);
// undo unwanted side-effect of verifier
if (origNumConstructors == 0 && classNode.getDeclaredConstructors().size() == 1) {
classNode.getDeclaredConstructors().clear();
}
boolean isInterface = isInterfaceOrTrait(classNode);
boolean isEnum = classNode.isEnum();
boolean isAnnotationDefinition = classNode.isAnnotationDefinition();
printAnnotations(out, classNode);
printModifiers(out, classNode.getModifiers() & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0) & ~(isEnum ? Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT : 0));
if (isInterface) {
if (isAnnotationDefinition) {
out.print("@");
}
out.print("interface ");
} else if (isEnum) {
out.print("enum ");
} else {
out.print("class ");
}
String className = classNode.getNameWithoutPackage();
if (classNode instanceof InnerClassNode)
className = className.substring(className.lastIndexOf('$') + 1);
out.println(className);
printGenericsBounds(out, classNode, true);
ClassNode superClass = classNode.getUnresolvedSuperClass(false);
if (!isInterface && !isEnum) {
out.print(" extends ");
printType(out, superClass);
}
ClassNode[] interfaces = classNode.getInterfaces();
if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) {
if (isInterface) {
out.println(" extends");
} else {
out.println(" implements");
}
for (int i = 0; i < interfaces.length - 1; ++i) {
out.print(" ");
printType(out, interfaces[i]);
out.print(",");
}
out.print(" ");
printType(out, interfaces[interfaces.length - 1]);
}
out.println(" {");
printFields(out, classNode);
printMethods(out, classNode, isEnum);
for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext(); ) {
// GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in inner ones
propertyMethods.clear();
propertyMethodsWithSigs.clear();
constructors.clear();
printClassContents(out, inner.next());
}
out.println("}");
} finally {
propertyMethods.clear();
propertyMethodsWithSigs.clear();
constructors.clear();
}
}
use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class StaticTypesBinaryExpressionMultiTypeDispatcher method makeSetProperty.
private boolean makeSetProperty(final Expression receiver, final Expression message, final Expression arguments, final boolean safe, final boolean spreadSafe, final boolean implicitThis, final boolean isAttribute) {
ClassNode receiverType = controller.getTypeChooser().resolveType(receiver, controller.getClassNode());
String property = message.getText();
boolean isThisExpression = isThisExpression(receiver);
if (isAttribute || (isThisExpression && receiverType.getDeclaredField(property) != null)) {
ClassNode current = receiverType;
FieldNode fn = null;
while (fn == null && current != null) {
fn = current.getDeclaredField(property);
if (fn == null) {
current = current.getSuperClass();
}
}
if (fn != null && receiverType != current && !fn.isPublic()) {
// check that direct access is allowed
if (!fn.isProtected()) {
return false;
}
if (!Objects.equals(receiverType.getPackageName(), current.getPackageName())) {
return false;
}
if (!fn.isStatic()) {
receiver.visit(controller.getAcg());
}
arguments.visit(controller.getAcg());
OperandStack operandStack = controller.getOperandStack();
operandStack.doGroovyCast(fn.getOriginType());
MethodVisitor mv = controller.getMethodVisitor();
mv.visitFieldInsn(fn.isStatic() ? PUTSTATIC : PUTFIELD, BytecodeHelper.getClassInternalName(fn.getOwner()), property, BytecodeHelper.getTypeDescription(fn.getOriginType()));
operandStack.remove(fn.isStatic() ? 1 : 2);
return true;
}
}
if (!isAttribute) {
String setter = getSetterName(property);
MethodNode setterMethod = receiverType.getSetterMethod(setter, false);
ClassNode declaringClass = setterMethod != null ? setterMethod.getDeclaringClass() : null;
if (isThisExpression && declaringClass != null && declaringClass.equals(controller.getClassNode())) {
// this.x = ... shouldn't use a setter if in the same class
setterMethod = null;
} else if (setterMethod == null) {
PropertyNode propertyNode = receiverType.getProperty(property);
if (propertyNode != null) {
if (!Modifier.isFinal(propertyNode.getModifiers())) {
setterMethod = new MethodNode(setter, ACC_PUBLIC, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(propertyNode.getOriginType(), "value") }, ClassNode.EMPTY_ARRAY, EmptyStatement.INSTANCE);
setterMethod.setDeclaringClass(receiverType);
}
}
}
if (setterMethod != null) {
Expression call = StaticPropertyAccessHelper.transformToSetterCall(receiver, setterMethod, arguments, implicitThis, safe, spreadSafe, // to be replaced with a proper test whether a return value should be used or not
true, message);
call.visit(controller.getAcg());
return true;
}
if (isThisExpression && !controller.isInGeneratedFunction()) {
receiverType = controller.getClassNode();
}
if (makeSetPrivateFieldWithBridgeMethod(receiver, receiverType, property, arguments, safe, spreadSafe, implicitThis)) {
return true;
}
}
return false;
}
use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class GeneralUtils method getAllProperties.
public static List<PropertyNode> getAllProperties(final Set<String> names, final ClassNode origType, final ClassNode cNode, final boolean includeProperties, final boolean includeFields, final boolean includePseudoGetters, final boolean includePseudoSetters, final boolean traverseSuperClasses, final boolean skipReadonly, final boolean reverse, final boolean allNames, final boolean includeStatic) {
List<PropertyNode> result = new ArrayList<>();
if (!(isObjectType(cNode)) && traverseSuperClasses && !reverse) {
result.addAll(getAllProperties(names, origType, cNode.getSuperClass(), includeProperties, includeFields, includePseudoGetters, includePseudoSetters, true, skipReadonly));
}
if (includeProperties) {
for (PropertyNode pNode : cNode.getProperties()) {
if ((!pNode.isStatic() || includeStatic) && !names.contains(pNode.getName())) {
result.add(pNode);
names.add(pNode.getName());
}
}
if (includePseudoGetters || includePseudoSetters) {
BeanUtils.addPseudoProperties(origType, cNode, result, names, includeStatic, includePseudoGetters, includePseudoSetters);
}
}
if (includeFields) {
for (FieldNode fNode : cNode.getFields()) {
if ((fNode.isStatic() && !includeStatic) || fNode.isSynthetic() || cNode.getProperty(fNode.getName()) != null || names.contains(fNode.getName())) {
continue;
}
// internal field
if (fNode.getName().contains("$") && !allNames) {
continue;
}
if (fNode.isPrivate() && !cNode.equals(origType)) {
continue;
}
if (fNode.isFinal() && fNode.getInitialExpression() != null && skipReadonly) {
continue;
}
result.add(new PropertyNode(fNode, fNode.getModifiers(), null, null));
names.add(fNode.getName());
}
}
if (!(isObjectType(cNode)) && traverseSuperClasses && reverse) {
result.addAll(getAllProperties(names, origType, cNode.getSuperClass(), includeProperties, includeFields, includePseudoGetters, includePseudoSetters, true, skipReadonly));
}
return result;
}
Aggregations