use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class TraitReceiverTransformer method transform.
@Override
public Expression transform(final Expression exp) {
ClassNode weavedType = weaved.getOriginType();
if (exp instanceof BinaryExpression) {
return transformBinaryExpression((BinaryExpression) exp, weavedType);
} else if (exp instanceof StaticMethodCallExpression) {
StaticMethodCallExpression call = (StaticMethodCallExpression) exp;
ClassNode ownerType = call.getOwnerType();
if (traitClass.equals(ownerType)) {
MethodCallExpression result = new MethodCallExpression(new VariableExpression(weaved), call.getMethod(), transform(call.getArguments()));
result.setSafe(false);
result.setImplicitThis(false);
result.setSpreadSafe(false);
result.setSourcePosition(call);
return result;
}
} else if (exp instanceof MethodCallExpression) {
MethodCallExpression call = (MethodCallExpression) exp;
Expression obj = call.getObjectExpression();
if (call.isImplicitThis() || "this".equals(obj.getText())) {
return transformMethodCallOnThis(call);
} else if ("super".equals(obj.getText())) {
return transformSuperMethodCall(call);
}
} else if (exp instanceof FieldExpression) {
return transformFieldExpression((FieldExpression) exp);
} else if (exp instanceof VariableExpression) {
VariableExpression vexp = (VariableExpression) exp;
Variable accessedVariable = vexp.getAccessedVariable();
if (accessedVariable instanceof FieldNode) {
FieldNode fn = (FieldNode) accessedVariable;
Expression receiver = createFieldHelperReceiver();
MethodCallExpression mce;
boolean isStatic = fn.isStatic();
if (isStatic) {
receiver = createStaticReceiver(receiver);
}
mce = new MethodCallExpression(receiver, Traits.helperGetterName(fn), ArgumentListExpression.EMPTY_ARGUMENTS);
mce.setSourcePosition(exp);
mce.setImplicitThis(false);
markDynamicCall(mce, fn, isStatic);
return mce;
} else if (accessedVariable instanceof PropertyNode) {
String propName = accessedVariable.getName();
if (knownFields.contains(propName)) {
return createFieldHelperCall(exp, weavedType, propName);
} else {
return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
}
} else if (accessedVariable instanceof DynamicVariable) {
return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
}
if (vexp.isThisExpression()) {
VariableExpression res = new VariableExpression(weaved);
res.setSourcePosition(exp);
return res;
}
if (vexp.isSuperExpression()) {
throwSuperError(vexp);
}
} else if (exp instanceof PropertyExpression) {
PropertyExpression pexp = (PropertyExpression) exp;
Expression object = pexp.getObjectExpression();
if (pexp.isImplicitThis() || "this".equals(object.getText())) {
String propName = pexp.getPropertyAsString();
if (knownFields.contains(propName)) {
return createFieldHelperCall(exp, weavedType, propName);
}
}
} else if (exp instanceof ClosureExpression) {
MethodCallExpression mce = new MethodCallExpression(exp, "rehydrate", new ArgumentListExpression(new VariableExpression(weaved), new VariableExpression(weaved), new VariableExpression(weaved)));
mce.setImplicitThis(false);
mce.setSourcePosition(exp);
boolean oldInClosure = inClosure;
inClosure = true;
((ClosureExpression) exp).getCode().visit(this);
inClosure = oldInClosure;
// The rewrite we do is causing some troubles with type checking, which will
// not be able to perform closure parameter type inference
// so we store the replacement, which will be done *after* type checking.
exp.putNodeMetaData(TraitASTTransformation.POST_TYPECHECKING_REPLACEMENT, mce);
return exp;
}
// todo: unary expressions (field++, field+=, ...)
return super.transform(exp);
}
use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class DelegateASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source);
AnnotatedNode parent = (AnnotatedNode) nodes[1];
AnnotationNode node = (AnnotationNode) nodes[0];
DelegateDescription delegate = null;
if (parent instanceof FieldNode) {
FieldNode fieldNode = (FieldNode) parent;
delegate = new DelegateDescription();
delegate.delegate = fieldNode;
delegate.annotation = node;
delegate.name = fieldNode.getName();
delegate.type = fieldNode.getType();
delegate.owner = fieldNode.getOwner();
delegate.getOp = varX(fieldNode);
delegate.origin = "field";
} else if (parent instanceof MethodNode) {
MethodNode methodNode = (MethodNode) parent;
delegate = new DelegateDescription();
delegate.delegate = methodNode;
delegate.annotation = node;
delegate.name = methodNode.getName();
delegate.type = methodNode.getReturnType();
delegate.owner = methodNode.getDeclaringClass();
delegate.getOp = callThisX(delegate.name);
delegate.origin = "method";
if (methodNode.getParameters().length > 0) {
addError("You can only delegate to methods that take no parameters, but " + delegate.name + " takes " + methodNode.getParameters().length + " parameters.", parent);
return;
}
}
if (delegate != null) {
if (delegate.type.equals(ClassHelper.OBJECT_TYPE) || delegate.type.equals(GROOVYOBJECT_TYPE)) {
addError(MY_TYPE_NAME + " " + delegate.origin + " '" + delegate.name + "' has an inappropriate type: " + delegate.type.getName() + ". Please add an explicit type but not java.lang.Object or groovy.lang.GroovyObject.", parent);
return;
}
if (delegate.type.equals(delegate.owner)) {
addError(MY_TYPE_NAME + " " + delegate.origin + " '" + delegate.name + "' has an inappropriate type: " + delegate.type.getName() + ". Delegation to own type not supported. Please use a different type.", parent);
return;
}
final List<MethodNode> delegateMethods = getAllMethods(delegate.type);
for (ClassNode next : delegate.type.getAllInterfaces()) {
delegateMethods.addAll(getAllMethods(next));
}
final boolean skipInterfaces = memberHasValue(node, MEMBER_INTERFACES, false);
final boolean includeDeprecated = memberHasValue(node, MEMBER_DEPRECATED, true) || (delegate.type.isInterface() && !skipInterfaces);
final boolean allNames = memberHasValue(node, MEMBER_ALL_NAMES, true);
delegate.excludes = getMemberStringList(node, MEMBER_EXCLUDES);
delegate.includes = getMemberStringList(node, MEMBER_INCLUDES);
delegate.excludeTypes = getMemberClassList(node, MEMBER_EXCLUDE_TYPES);
delegate.includeTypes = getMemberClassList(node, MEMBER_INCLUDE_TYPES);
checkIncludeExcludeUndefinedAware(node, delegate.excludes, delegate.includes, delegate.excludeTypes, delegate.includeTypes, MY_TYPE_NAME);
final List<MethodNode> ownerMethods = getAllMethods(delegate.owner);
for (MethodNode mn : delegateMethods) {
addDelegateMethod(delegate, ownerMethods, mn, includeDeprecated, allNames);
}
for (PropertyNode prop : getAllProperties(delegate.type)) {
if (prop.isStatic() || !prop.isPublic())
continue;
String name = prop.getName();
addGetterIfNeeded(delegate, prop, name, allNames);
addSetterIfNeeded(delegate, prop, name, allNames);
}
if (skipInterfaces)
return;
final Set<ClassNode> allInterfaces = getInterfacesAndSuperInterfaces(delegate.type);
final Set<ClassNode> ownerIfaces = delegate.owner.getAllInterfaces();
Map<String, ClassNode> genericsSpec = createGenericsSpec(delegate.owner);
genericsSpec = createGenericsSpec(delegate.type, genericsSpec);
for (ClassNode iface : allInterfaces) {
if (Modifier.isPublic(iface.getModifiers()) && !ownerIfaces.contains(iface)) {
final ClassNode[] ifaces = delegate.owner.getInterfaces();
final ClassNode[] newIfaces = new ClassNode[ifaces.length + 1];
for (int i = 0; i < ifaces.length; i++) {
newIfaces[i] = correctToGenericsSpecRecurse(genericsSpec, ifaces[i]);
}
newIfaces[ifaces.length] = correctToGenericsSpecRecurse(genericsSpec, iface);
delegate.owner.setInterfaces(newIfaces);
}
}
}
}
use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class EqualsAndHashCodeASTTransformation method calculateHashStatements.
private static Statement calculateHashStatements(ClassNode cNode, Expression hash, boolean includeFields, boolean callSuper, List<String> excludes, List<String> includes, boolean allNames) {
final List<PropertyNode> pList = getInstanceProperties(cNode);
final List<FieldNode> fList = new ArrayList<FieldNode>();
if (includeFields) {
fList.addAll(getInstanceNonPropertyFields(cNode));
}
final BlockStatement body = new BlockStatement();
// def _result = HashCodeHelper.initHash()
final Expression result = varX("_result");
body.addStatement(declS(result, callX(HASHUTIL_TYPE, "initHash")));
for (PropertyNode pNode : pList) {
if (shouldSkip(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, "updateHash", args(result, getter));
body.addStatement(ifS(notX(sameX(getter, varX("this"))), assignS(result, current)));
}
for (FieldNode fNode : fList) {
if (shouldSkip(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, "updateHash", args(result, fieldExpr));
body.addStatement(ifS(notX(sameX(fieldExpr, varX("this"))), assignS(result, current)));
}
if (callSuper) {
// _result = HashCodeHelper.updateHash(_result, super.hashCode())
final Expression current = callX(HASHUTIL_TYPE, "updateHash", args(result, callSuperX("hashCode")));
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 LazyASTTransformation method visitField.
static void visitField(ErrorCollecting xform, AnnotationNode node, FieldNode fieldNode) {
final Expression soft = node.getMember("soft");
final Expression init = getInitExpr(xform, fieldNode);
String backingFieldName = "$" + fieldNode.getName();
fieldNode.rename(backingFieldName);
fieldNode.setModifiers(ACC_PRIVATE | (fieldNode.getModifiers() & (~(ACC_PUBLIC | ACC_PROTECTED))));
PropertyNode pNode = fieldNode.getDeclaringClass().getProperty(backingFieldName);
if (pNode != null) {
fieldNode.getDeclaringClass().getProperties().remove(pNode);
}
if (soft instanceof ConstantExpression && ((ConstantExpression) soft).getValue().equals(true)) {
createSoft(fieldNode, init);
} else {
create(fieldNode, init);
// @Lazy not meaningful with primitive so convert to wrapper if needed
if (ClassHelper.isPrimitiveType(fieldNode.getType())) {
fieldNode.setType(ClassHelper.getWrapper(fieldNode.getType()));
}
}
}
use of org.codehaus.groovy.ast.PropertyNode in project groovy by apache.
the class PackageScopeASTTransformation method visitClassNode.
private void visitClassNode(ClassNode cNode, List<PackageScopeTarget> value) {
String cName = cNode.getName();
if (cNode.isInterface() && value.size() != 1 && value.get(0) != PackageScopeTarget.CLASS) {
addError("Error processing interface '" + cName + "'. " + MY_TYPE_NAME + " not allowed for interfaces except when targeting Class level.", cNode);
}
if (value.contains(groovy.transform.PackageScopeTarget.CLASS)) {
if (cNode.isSyntheticPublic())
revertVisibility(cNode);
else
addError("Can't use " + MY_TYPE_NAME + " for class '" + cNode.getName() + "' which has explicit visibility.", cNode);
}
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(groovy.transform.PackageScopeTarget.CONSTRUCTORS)) {
final List<ConstructorNode> cList = cNode.getDeclaredConstructors();
for (MethodNode mNode : cList) {
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);
}
}
}
}
Aggregations