use of org.codehaus.groovy.ast.ConstructorNode in project groovy-core by groovy.
the class ImmutableASTTransformation method createNoArgConstructor.
private void createNoArgConstructor(ClassNode cNode) {
Statement body = stmt(ctorX(ClassNode.THIS, args(new MapExpression())));
doAddConstructor(cNode, new ConstructorNode(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body));
}
use of org.codehaus.groovy.ast.ConstructorNode in project groovy-core by groovy.
the class DefaultStrategy method createBuildMethodForMethod.
private MethodNode createBuildMethodForMethod(AnnotationNode anno, ClassNode buildee, MethodNode mNode, Parameter[] params) {
String buildMethodName = getMemberStringValue(anno, "buildMethodName", "build");
final BlockStatement body = new BlockStatement();
ClassNode returnType;
if (mNode instanceof ConstructorNode) {
returnType = newClass(buildee);
body.addStatement(returnS(ctorX(newClass(mNode.getDeclaringClass()), args(params))));
} else {
body.addStatement(returnS(callX(newClass(mNode.getDeclaringClass()), mNode.getName(), args(params))));
returnType = newClass(mNode.getReturnType());
}
return new MethodNode(buildMethodName, ACC_PUBLIC, returnType, NO_PARAMS, NO_EXCEPTIONS, body);
}
use of org.codehaus.groovy.ast.ConstructorNode in project groovy by apache.
the class TemplateASTTransformer method createConstructor.
private void createConstructor(final ClassNode classNode) {
Parameter[] params = new Parameter[] { new Parameter(MarkupTemplateEngine.MARKUPTEMPLATEENGINE_CLASSNODE, "engine"), new Parameter(ClassHelper.MAP_TYPE.getPlainNodeReference(), "model"), new Parameter(ClassHelper.MAP_TYPE.getPlainNodeReference(), "modelTypes"), new Parameter(TEMPLATECONFIG_CLASSNODE, "tplConfig") };
List<Expression> vars = new LinkedList<Expression>();
for (Parameter param : params) {
vars.add(new VariableExpression(param));
}
ExpressionStatement body = new ExpressionStatement(new ConstructorCallExpression(ClassNode.SUPER, new ArgumentListExpression(vars)));
ConstructorNode ctor = new ConstructorNode(Opcodes.ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, body);
classNode.addConstructor(ctor);
}
use of org.codehaus.groovy.ast.ConstructorNode in project groovy by apache.
the class AsmClassGenerator method visitStdMethod.
private void visitStdMethod(MethodNode node, boolean isConstructor, Parameter[] parameters, Statement code) {
MethodVisitor mv = controller.getMethodVisitor();
final ClassNode superClass = controller.getClassNode().getSuperClass();
if (isConstructor && (code == null || !((ConstructorNode) node).firstStatementIsSpecialConstructorCall())) {
boolean hasCallToSuper = false;
if (code != null && controller.getClassNode() instanceof InnerClassNode) {
// so we must ensure not to add it twice (see GROOVY-4471)
if (code instanceof BlockStatement) {
for (Statement statement : ((BlockStatement) code).getStatements()) {
if (statement instanceof ExpressionStatement) {
final Expression expression = ((ExpressionStatement) statement).getExpression();
if (expression instanceof ConstructorCallExpression) {
ConstructorCallExpression call = (ConstructorCallExpression) expression;
if (call.isSuperCall()) {
hasCallToSuper = true;
break;
}
}
}
}
}
}
if (!hasCallToSuper) {
// invokes the super class constructor
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(superClass), "<init>", "()V", false);
}
}
controller.getCompileStack().init(node.getVariableScope(), parameters);
controller.getCallSiteWriter().makeSiteEntry();
// handle body
super.visitConstructorOrMethod(node, isConstructor);
controller.getCompileStack().clear();
if (node.isVoidMethod()) {
mv.visitInsn(RETURN);
} else {
// we make a dummy return for label ranges that reach here
ClassNode type = node.getReturnType().redirect();
if (ClassHelper.isPrimitiveType(type)) {
mv.visitLdcInsn(0);
controller.getOperandStack().push(ClassHelper.int_TYPE);
controller.getOperandStack().doGroovyCast(type);
BytecodeHelper.doReturn(mv, type);
controller.getOperandStack().remove(1);
} else {
mv.visitInsn(ACONST_NULL);
BytecodeHelper.doReturn(mv, type);
}
}
}
use of org.codehaus.groovy.ast.ConstructorNode in project groovy by apache.
the class AsmClassGenerator method visitAttributeOrProperty.
private void visitAttributeOrProperty(PropertyExpression expression, MethodCallerMultiAdapter adapter) {
MethodVisitor mv = controller.getMethodVisitor();
Expression objectExpression = expression.getObjectExpression();
ClassNode classNode = controller.getClassNode();
if (isThisOrSuper(objectExpression)) {
// let's use the field expression if it's available
String name = expression.getPropertyAsString();
if (name != null) {
FieldNode field = null;
boolean privateSuperField = false;
if (isSuperExpression(objectExpression)) {
field = classNode.getSuperClass().getDeclaredField(name);
if (field != null && ((field.getModifiers() & ACC_PRIVATE) != 0)) {
privateSuperField = true;
}
} else {
if (controller.isNotExplicitThisInClosure(expression.isImplicitThis())) {
field = classNode.getDeclaredField(name);
if (field == null && classNode instanceof InnerClassNode) {
ClassNode outer = classNode.getOuterClass();
FieldNode outerClassField;
while (outer != null) {
outerClassField = outer.getDeclaredField(name);
if (outerClassField != null && outerClassField.isStatic() && outerClassField.isFinal()) {
if (outer != classNode.getOuterClass() && Modifier.isPrivate(outerClassField.getModifiers())) {
throw new GroovyBugError("Trying to access private constant field [" + outerClassField.getDeclaringClass() + "#" + outerClassField.getName() + "] from inner class");
}
PropertyExpression pexp = new PropertyExpression(new ClassExpression(outer), expression.getProperty());
pexp.visit(controller.getAcg());
return;
}
outer = outer.getSuperClass();
}
}
if (field == null && expression instanceof AttributeExpression && isThisExpression(objectExpression) && controller.isStaticContext()) {
// GROOVY-6183
ClassNode current = classNode.getSuperClass();
while (field == null && current != null) {
field = current.getDeclaredField(name);
current = current.getSuperClass();
}
if (field != null && (field.isProtected() || field.isPublic())) {
visitFieldExpression(new FieldExpression(field));
return;
}
}
}
}
if (field != null && !privateSuperField) {
//GROOVY-4497: don't visit super field if it is private
visitFieldExpression(new FieldExpression(field));
return;
}
if (isSuperExpression(objectExpression)) {
String prefix;
if (controller.getCompileStack().isLHS()) {
throw new GroovyBugError("Unexpected super property set for:" + expression.getText());
} else {
prefix = "get";
}
String propName = prefix + MetaClassHelper.capitalize(name);
visitMethodCallExpression(new MethodCallExpression(objectExpression, propName, MethodCallExpression.NO_ARGUMENTS));
return;
}
}
}
final String propName = expression.getPropertyAsString();
//TODO: add support for super here too
if (expression.getObjectExpression() instanceof ClassExpression && propName != null && propName.equals("this")) {
// we have something like A.B.this, and need to make it
// into this.this$0.this$0, where this.this$0 returns
// A.B and this.this$0.this$0 return A.
ClassNode type = objectExpression.getType();
ClassNode iterType = classNode;
if (controller.getCompileStack().isInSpecialConstructorCall() && classNode instanceof InnerClassNode) {
boolean staticInnerClass = classNode.isStaticClass();
// Outer.this in a special constructor call
if (classNode.getOuterClass().equals(type)) {
ConstructorNode ctor = controller.getConstructorNode();
Expression receiver = !staticInnerClass ? new VariableExpression(ctor.getParameters()[0]) : new ClassExpression(type);
receiver.setSourcePosition(expression);
receiver.visit(this);
return;
}
}
mv.visitVarInsn(ALOAD, 0);
while (!iterType.equals(type)) {
String ownerName = BytecodeHelper.getClassInternalName(iterType);
if (iterType.getOuterClass() == null)
break;
FieldNode thisField = iterType.getField("this$0");
iterType = iterType.getOuterClass();
if (thisField == null) {
// closure within inner class
mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(ClassHelper.CLOSURE_TYPE), "getThisObject", "()Ljava/lang/Object;", false);
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(iterType));
} else {
ClassNode thisFieldType = thisField.getType();
if (ClassHelper.CLOSURE_TYPE.equals(thisFieldType)) {
mv.visitFieldInsn(GETFIELD, ownerName, "this$0", BytecodeHelper.getTypeDescription(ClassHelper.CLOSURE_TYPE));
mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(ClassHelper.CLOSURE_TYPE), "getThisObject", "()Ljava/lang/Object;", false);
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(iterType));
} else {
String typeName = BytecodeHelper.getTypeDescription(iterType);
mv.visitFieldInsn(GETFIELD, ownerName, "this$0", typeName);
}
}
}
controller.getOperandStack().push(type);
return;
}
if (adapter == getProperty && !expression.isSpreadSafe() && propName != null) {
controller.getCallSiteWriter().makeGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());
} else if (adapter == getGroovyObjectProperty && !expression.isSpreadSafe() && propName != null) {
controller.getCallSiteWriter().makeGroovyObjectGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());
} else {
// todo: for improved modularity and extensibility, this should be moved into a writer
if (controller.getCompileStack().isLHS())
controller.getOperandStack().box();
controller.getInvocationWriter().makeCall(expression, // receiver
objectExpression, // messageName
new CastExpression(ClassHelper.STRING_TYPE, expression.getProperty()), MethodCallExpression.NO_ARGUMENTS, adapter, expression.isSafe(), expression.isSpreadSafe(), expression.isImplicitThis());
}
}
Aggregations