use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.
the class GenericsVisitor method visitField.
public void visitField(FieldNode node) {
ClassNode type = node.getType();
checkGenericsUsage(type, type.redirect());
}
use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.
the class GenericsVisitor method getPrintName.
private String getPrintName(GenericsType gt) {
String ret = gt.getName();
ClassNode[] upperBounds = gt.getUpperBounds();
ClassNode lowerBound = gt.getLowerBound();
if (upperBounds != null) {
ret += " extends ";
for (int i = 0; i < upperBounds.length; i++) {
ret += getPrintName(upperBounds[i]);
if (i + 1 < upperBounds.length)
ret += " & ";
}
} else if (lowerBound != null) {
ret += " super " + getPrintName(lowerBound);
}
return ret;
}
use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.
the class GenericsVisitor method checkGenericsUsage.
private void checkGenericsUsage(ClassNode n, ClassNode cn) {
if (n.isGenericsPlaceHolder())
return;
GenericsType[] nTypes = n.getGenericsTypes();
GenericsType[] cnTypes = cn.getGenericsTypes();
// raw type usage is always allowed
if (nTypes == null)
return;
// parameterize a type by using all of the parameters only
if (cnTypes == null) {
addError("The class " + n.getName() + " refers to the class " + cn.getName() + " and uses " + nTypes.length + " parameters, but the referred class takes no parameters", n);
return;
}
if (nTypes.length != cnTypes.length) {
addError("The class " + n.getName() + " refers to the class " + cn.getName() + " and uses " + nTypes.length + " parameters, but the referred class needs " + cnTypes.length, n);
return;
}
// check bounds
for (int i = 0; i < nTypes.length; i++) {
ClassNode nType = nTypes[i].getType();
ClassNode cnType = cnTypes[i].getType();
if (!nType.isDerivedFrom(cnType)) {
if (cnType.isInterface() && nType.implementsInterface(cnType))
continue;
addError("The type " + nTypes[i].getName() + " is not a valid substitute for the bounded parameter <" + getPrintName(cnTypes[i]) + ">", n);
}
}
}
use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.
the class MopWriter method createMopMethods.
public void createMopMethods() {
ClassNode classNode = controller.getClassNode();
if (classNode.declaresInterface(ClassHelper.GENERATED_CLOSURE_Type)) {
return;
}
Set<MopKey> currentClassSignatures = buildCurrentClassSignatureSet(classNode.getMethods());
visitMopMethodList(classNode.getMethods(), true, Collections.EMPTY_SET);
visitMopMethodList(classNode.getSuperClass().getAllDeclaredMethods(), false, currentClassSignatures);
}
use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.
the class MopWriter method generateMopCalls.
/**
* generates a Meta Object Protocol method, that is used to call a non public
* method, or to make a call to super.
*
* @param mopCalls list of methods a mop call method should be generated for
* @param useThis true if "this" should be used for the naming
*/
protected void generateMopCalls(LinkedList<MethodNode> mopCalls, boolean useThis) {
for (MethodNode method : mopCalls) {
String name = getMopMethodName(method, useThis);
Parameter[] parameters = method.getParameters();
String methodDescriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameters());
MethodVisitor mv = controller.getClassVisitor().visitMethod(ACC_PUBLIC | ACC_SYNTHETIC, name, methodDescriptor, null, null);
controller.setMethodVisitor(mv);
mv.visitVarInsn(ALOAD, 0);
int newRegister = 1;
OperandStack operandStack = controller.getOperandStack();
for (Parameter parameter : parameters) {
ClassNode type = parameter.getType();
operandStack.load(parameter.getType(), newRegister);
// increment to next register, double/long are using two places
newRegister++;
if (type == ClassHelper.double_TYPE || type == ClassHelper.long_TYPE)
newRegister++;
}
operandStack.remove(parameters.length);
ClassNode declaringClass = method.getDeclaringClass();
// JDK 8 support for default methods in interfaces
// this should probably be strenghtened when we support the A.super.foo() syntax
int opcode = declaringClass.isInterface() ? INVOKEINTERFACE : INVOKESPECIAL;
mv.visitMethodInsn(opcode, BytecodeHelper.getClassInternalName(declaringClass), method.getName(), methodDescriptor, opcode == INVOKEINTERFACE);
BytecodeHelper.doReturn(mv, method.getReturnType());
mv.visitMaxs(0, 0);
mv.visitEnd();
controller.getClassNode().addMethod(name, ACC_PUBLIC | ACC_SYNTHETIC, method.getReturnType(), parameters, null, null);
}
}
Aggregations