use of org.codehaus.groovy.ast.expr.CastExpression in project groovy-core by groovy.
the class CastExpressionOptimizer method transformCastExpression.
public Expression transformCastExpression(final CastExpression cast) {
if (cast.isCoerce()) {
Expression expression = cast.getExpression();
ClassNode exprInferredType = transformer.getTypeChooser().resolveType(expression, transformer.getClassNode());
ClassNode castType = cast.getType();
if (castType.isArray() && expression instanceof ListExpression) {
ArrayExpression arrayExpression = new ArrayExpression(castType.getComponentType(), ((ListExpression) expression).getExpressions());
arrayExpression.setSourcePosition(cast);
return transformer.transform(arrayExpression);
}
if (isOptimizable(exprInferredType, castType)) {
// coerce is not needed
CastExpression trn = new CastExpression(castType, transformer.transform(expression));
trn.setSourcePosition(cast);
trn.copyNodeMetaData(cast);
return trn;
}
} else if (ClassHelper.char_TYPE.equals(cast.getType())) {
Expression expression = cast.getExpression();
if (expression instanceof ConstantExpression) {
ConstantExpression ce = (ConstantExpression) expression;
if (ClassHelper.STRING_TYPE.equals(ce.getType())) {
String val = (String) ce.getValue();
if (val != null && val.length() == 1) {
ConstantExpression result = new ConstantExpression(val.charAt(0), true);
result.setSourcePosition(cast);
return result;
}
}
}
}
return transformer.superTransform(cast);
}
use of org.codehaus.groovy.ast.expr.CastExpression in project groovy-core by groovy.
the class EqualsAndHashCodeASTTransformation method createEquals.
public static void createEquals(ClassNode cNode, boolean includeFields, boolean callSuper, boolean useCanEqual, List<String> excludes, List<String> includes) {
if (useCanEqual)
createCanEqual(cNode);
// make a public method if none exists otherwise try a private method with leading underscore
boolean hasExistingEquals = hasDeclaredMethod(cNode, "equals", 1);
if (hasExistingEquals && hasDeclaredMethod(cNode, "_equals", 1))
return;
final BlockStatement body = new BlockStatement();
VariableExpression other = varX("other");
// some short circuit cases for efficiency
body.addStatement(ifS(equalsNullX(other), returnS(constX(Boolean.FALSE, true))));
body.addStatement(ifS(sameX(varX("this"), other), returnS(constX(Boolean.TRUE, true))));
if (useCanEqual) {
body.addStatement(ifS(notX(isInstanceOfX(other, GenericsUtils.nonGeneric(cNode))), returnS(constX(Boolean.FALSE, true))));
} else {
body.addStatement(ifS(notX(hasClassX(other, GenericsUtils.nonGeneric(cNode))), returnS(constX(Boolean.FALSE, true))));
}
VariableExpression otherTyped = varX("otherTyped", GenericsUtils.nonGeneric(cNode));
CastExpression castExpression = new CastExpression(GenericsUtils.nonGeneric(cNode), other);
castExpression.setStrict(true);
body.addStatement(declS(otherTyped, castExpression));
if (useCanEqual) {
body.addStatement(ifS(notX(callX(otherTyped, "canEqual", varX("this"))), returnS(constX(Boolean.FALSE, true))));
}
List<PropertyNode> pList = getInstanceProperties(cNode);
for (PropertyNode pNode : pList) {
if (shouldSkip(pNode.getName(), excludes, includes))
continue;
boolean canBeSelf = StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(pNode.getOriginType(), cNode);
if (!canBeSelf) {
body.addStatement(ifS(notX(hasEqualPropertyX(pNode, otherTyped)), returnS(constX(Boolean.FALSE, true))));
} else {
body.addStatement(ifS(notX(hasSamePropertyX(pNode, otherTyped)), ifElseS(differentSelfRecursivePropertyX(pNode, otherTyped), returnS(constX(Boolean.FALSE, true)), ifS(notX(bothSelfRecursivePropertyX(pNode, otherTyped)), ifS(notX(hasEqualPropertyX(pNode, otherTyped)), returnS(constX(Boolean.FALSE, true)))))));
}
}
List<FieldNode> fList = new ArrayList<FieldNode>();
if (includeFields) {
fList.addAll(getInstanceNonPropertyFields(cNode));
}
for (FieldNode fNode : fList) {
if (shouldSkip(fNode.getName(), excludes, includes))
continue;
body.addStatement(ifS(notX(hasSameFieldX(fNode, otherTyped)), ifElseS(differentSelfRecursiveFieldX(fNode, otherTyped), returnS(constX(Boolean.FALSE, true)), ifS(notX(bothSelfRecursiveFieldX(fNode, otherTyped)), ifS(notX(hasEqualFieldX(fNode, otherTyped)), returnS(constX(Boolean.FALSE, true)))))));
}
if (callSuper) {
body.addStatement(ifS(notX(isTrueX(callSuperX("equals", other))), returnS(constX(Boolean.FALSE, true))));
}
// default
body.addStatement(returnS(constX(Boolean.TRUE, true)));
cNode.addMethod(new MethodNode(hasExistingEquals ? "_equals" : "equals", hasExistingEquals ? ACC_PRIVATE : ACC_PUBLIC, ClassHelper.boolean_TYPE, params(param(OBJECT_TYPE, other.getName())), ClassNode.EMPTY_ARRAY, body));
}
use of org.codehaus.groovy.ast.expr.CastExpression in project groovy-core by groovy.
the class TraitComposer method createSuperFallback.
private static Statement createSuperFallback(MethodNode forwarderMethod, ClassNode returnType) {
ArgumentListExpression args = new ArgumentListExpression();
Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
args.addExpression(new VariableExpression(forwarderMethodParameter));
}
BinaryExpression instanceOfExpr = new BinaryExpression(new VariableExpression("this"), Token.newSymbol(Types.KEYWORD_INSTANCEOF, -1, -1), new ClassExpression(Traits.GENERATED_PROXY_CLASSNODE));
MethodCallExpression superCall = new MethodCallExpression(new VariableExpression("super"), forwarderMethod.getName(), args);
superCall.setImplicitThis(false);
CastExpression proxyReceiver = new CastExpression(Traits.GENERATED_PROXY_CLASSNODE, new VariableExpression("this"));
MethodCallExpression getProxy = new MethodCallExpression(proxyReceiver, "getProxyTarget", ArgumentListExpression.EMPTY_ARGUMENTS);
getProxy.setImplicitThis(true);
StaticMethodCallExpression proxyCall = new StaticMethodCallExpression(ClassHelper.make(InvokerHelper.class), "invokeMethod", new ArgumentListExpression(getProxy, new ConstantExpression(forwarderMethod.getName()), new ArrayExpression(ClassHelper.OBJECT_TYPE, args.getExpressions())));
IfStatement stmt = new IfStatement(new BooleanExpression(instanceOfExpr), new ExpressionStatement(new CastExpression(returnType, proxyCall)), new ExpressionStatement(superCall));
return stmt;
}
use of org.codehaus.groovy.ast.expr.CastExpression in project groovy by apache.
the class Verifier method addDefaultParameterMethods.
/**
* Creates a new helper method for each combination of default parameter expressions
*/
protected void addDefaultParameterMethods(final ClassNode node) {
List methods = new ArrayList(node.getMethods());
addDefaultParameters(methods, new DefaultArgsAction() {
public void call(ArgumentListExpression arguments, Parameter[] newParams, MethodNode method) {
final BlockStatement code = new BlockStatement();
MethodNode newMethod = new MethodNode(method.getName(), method.getModifiers(), method.getReturnType(), newParams, method.getExceptions(), code);
// GROOVY-5681 and GROOVY-5632
for (Expression argument : arguments.getExpressions()) {
if (argument instanceof CastExpression) {
argument = ((CastExpression) argument).getExpression();
}
if (argument instanceof ConstructorCallExpression) {
ClassNode type = argument.getType();
if (type instanceof InnerClassNode && ((InnerClassNode) type).isAnonymous()) {
type.setEnclosingMethod(newMethod);
}
}
// check whether closure shared variables refer to params with default values (GROOVY-5632)
if (argument instanceof ClosureExpression) {
final List<Parameter> newMethodNodeParameters = Arrays.asList(newParams);
CodeVisitorSupport visitor = new CodeVisitorSupport() {
@Override
public void visitVariableExpression(VariableExpression expression) {
Variable v = expression.getAccessedVariable();
if (!(v instanceof Parameter))
return;
Parameter param = (Parameter) v;
if (param.hasInitialExpression() && code.getVariableScope().getDeclaredVariable(param.getName()) == null && !newMethodNodeParameters.contains(param)) {
VariableExpression localVariable = new VariableExpression(param.getName(), ClassHelper.makeReference());
DeclarationExpression declarationExpression = new DeclarationExpression(localVariable, Token.newSymbol(Types.EQUAL, -1, -1), new ConstructorCallExpression(ClassHelper.makeReference(), param.getInitialExpression()));
code.addStatement(new ExpressionStatement(declarationExpression));
code.getVariableScope().putDeclaredVariable(localVariable);
}
}
};
visitor.visitClosureExpression((ClosureExpression) argument);
}
}
MethodCallExpression expression = new MethodCallExpression(VariableExpression.THIS_EXPRESSION, method.getName(), arguments);
expression.setMethodTarget(method);
expression.setImplicitThis(true);
if (method.isVoidMethod()) {
code.addStatement(new ExpressionStatement(expression));
} else {
code.addStatement(new ReturnStatement(expression));
}
List<AnnotationNode> annotations = method.getAnnotations();
if (annotations != null) {
newMethod.addAnnotations(annotations);
}
MethodNode oldMethod = node.getDeclaredMethod(method.getName(), newParams);
if (oldMethod != null) {
throw new RuntimeParserException("The method with default parameters \"" + method.getTypeDescriptor() + "\" defines a method \"" + newMethod.getTypeDescriptor() + "\" that is already defined.", method);
}
addPropertyMethod(newMethod);
newMethod.setGenericsTypes(method.getGenericsTypes());
newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, true);
}
});
}
use of org.codehaus.groovy.ast.expr.CastExpression in project groovy by apache.
the class TraitASTTransformation method processField.
private void processField(final FieldNode field, final MethodNode initializer, final MethodNode staticInitializer, final ClassNode fieldHelper, final ClassNode helper, final ClassNode trait, final Set<String> knownFields) {
if (field.isProtected()) {
unit.addError(new SyntaxException("Cannot have protected field in a trait (" + trait.getName() + "#" + field.getName() + ")", field.getLineNumber(), field.getColumnNumber()));
return;
}
Expression initialExpression = field.getInitialExpression();
MethodNode selectedMethod = field.isStatic() ? staticInitializer : initializer;
if (initialExpression != null) {
if (field.isFinal()) {
String baseName = field.isStatic() ? Traits.STATIC_INIT_METHOD : Traits.INIT_METHOD;
MethodNode fieldInitializer = new MethodNode(baseName + Traits.remappedFieldName(trait, field.getName()), ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC, field.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(initialExpression));
helper.addMethod(fieldInitializer);
}
VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]);
ExpressionStatement initCode = new ExpressionStatement(initialExpression);
processBody(thisObject, initCode, trait, helper, fieldHelper, knownFields);
BlockStatement code = (BlockStatement) selectedMethod.getCode();
MethodCallExpression mce;
if (field.isStatic()) {
mce = new MethodCallExpression(new ClassExpression(INVOKERHELPER_CLASSNODE), "invokeStaticMethod", new ArgumentListExpression(thisObject, new ConstantExpression(Traits.helperSetterName(field)), initCode.getExpression()));
} else {
mce = new MethodCallExpression(new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject), Traits.helperSetterName(field), new CastExpression(field.getOriginType(), initCode.getExpression()));
}
mce.setImplicitThis(false);
mce.setSourcePosition(initialExpression);
code.addStatement(new ExpressionStatement(mce));
}
// define setter/getter helper methods (setter added even for final fields for legacy compatibility)
fieldHelper.addMethod(Traits.helperSetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), new Parameter[] { new Parameter(field.getOriginType(), "val") }, ClassNode.EMPTY_ARRAY, null);
fieldHelper.addMethod(Traits.helperGetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
// dummy fields are only used to carry annotations if instance field
// and to differentiate from static fields otherwise
int mods = field.getModifiers() & Traits.FIELD_PREFIX_MASK;
String dummyFieldName = String.format("$0x%04x", mods) + Traits.remappedFieldName(field.getOwner(), field.getName());
FieldNode dummyField = new FieldNode(dummyFieldName, ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, field.getOriginType(), fieldHelper, field.isFinal() ? initialExpression : null);
// copy annotations from field to dummy field
List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
List<AnnotationNode> notCopied = new LinkedList<AnnotationNode>();
GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
dummyField.addAnnotations(copied);
fieldHelper.addField(dummyField);
// retain legacy field (will be given lower precedence than above)
dummyFieldName = (field.isStatic() ? Traits.STATIC_FIELD_PREFIX : Traits.FIELD_PREFIX) + (field.isPublic() ? Traits.PUBLIC_FIELD_PREFIX : Traits.PRIVATE_FIELD_PREFIX) + Traits.remappedFieldName(field.getOwner(), field.getName());
dummyField = new FieldNode(dummyFieldName, ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, field.getOriginType(), fieldHelper, null);
// copy annotations from field to legacy dummy field
copied = new LinkedList<AnnotationNode>();
notCopied = new LinkedList<AnnotationNode>();
GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
dummyField.addAnnotations(copied);
fieldHelper.addField(dummyField);
}
Aggregations