use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy by apache.
the class Verifier method getCovariantImplementation.
private MethodNode getCovariantImplementation(final MethodNode oldMethod, final MethodNode overridingMethod, Map genericsSpec, boolean ignoreError) {
// method name
if (!oldMethod.getName().equals(overridingMethod.getName()))
return null;
if ((overridingMethod.getModifiers() & ACC_BRIDGE) != 0)
return null;
if (oldMethod.isPrivate())
return null;
// parameters
boolean normalEqualParameters = equalParametersNormal(overridingMethod, oldMethod);
boolean genericEqualParameters = equalParametersWithGenerics(overridingMethod, oldMethod, genericsSpec);
if (!normalEqualParameters && !genericEqualParameters)
return null;
//correct to method level generics for the overriding method
genericsSpec = GenericsUtils.addMethodGenerics(overridingMethod, genericsSpec);
// return type
ClassNode mr = overridingMethod.getReturnType();
ClassNode omr = oldMethod.getReturnType();
boolean equalReturnType = mr.equals(omr);
ClassNode testmr = correctToGenericsSpec(genericsSpec, omr);
if (!isAssignable(mr, testmr)) {
if (ignoreError)
return null;
throw new RuntimeParserException("The return type of " + overridingMethod.getTypeDescriptor() + " in " + overridingMethod.getDeclaringClass().getName() + " is incompatible with " + testmr.getName() + " in " + oldMethod.getDeclaringClass().getName(), overridingMethod);
}
if (equalReturnType && normalEqualParameters)
return null;
if ((oldMethod.getModifiers() & ACC_FINAL) != 0) {
throw new RuntimeParserException("Cannot override final method " + oldMethod.getTypeDescriptor() + " in " + oldMethod.getDeclaringClass().getName(), overridingMethod);
}
if (oldMethod.isStatic() != overridingMethod.isStatic()) {
throw new RuntimeParserException("Cannot override method " + oldMethod.getTypeDescriptor() + " in " + oldMethod.getDeclaringClass().getName() + " with disparate static modifier", overridingMethod);
}
if (!equalReturnType) {
boolean oldM = ClassHelper.isPrimitiveType(oldMethod.getReturnType());
boolean newM = ClassHelper.isPrimitiveType(overridingMethod.getReturnType());
if (oldM || newM) {
String message = "";
if (oldM && newM) {
message = " with old and new method having different primitive return types";
} else if (newM) {
message = " with new method having a primitive return type and old method not";
} else /* oldM */
{
message = " with old method having a primitive return type and new method not";
}
throw new RuntimeParserException("Cannot override method " + oldMethod.getTypeDescriptor() + " in " + oldMethod.getDeclaringClass().getName() + message, overridingMethod);
}
}
// if we reach this point we have at least one parameter or return type, that
// is different in its specified form. That means we have to create a bridge method!
MethodNode newMethod = new MethodNode(oldMethod.getName(), overridingMethod.getModifiers() | ACC_SYNTHETIC | ACC_BRIDGE, oldMethod.getReturnType().getPlainNodeReference(), cleanParameters(oldMethod.getParameters()), oldMethod.getExceptions(), null);
List instructions = new ArrayList(1);
instructions.add(new BytecodeInstruction() {
public void visit(MethodVisitor mv) {
mv.visitVarInsn(ALOAD, 0);
Parameter[] para = oldMethod.getParameters();
Parameter[] goal = overridingMethod.getParameters();
int doubleSlotOffset = 0;
for (int i = 0; i < para.length; i++) {
ClassNode type = para[i].getType();
BytecodeHelper.load(mv, type, i + 1 + doubleSlotOffset);
if (type.redirect() == ClassHelper.double_TYPE || type.redirect() == ClassHelper.long_TYPE) {
doubleSlotOffset++;
}
if (!type.equals(goal[i].getType())) {
BytecodeHelper.doCast(mv, goal[i].getType());
}
}
mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(classNode), overridingMethod.getName(), BytecodeHelper.getMethodDescriptor(overridingMethod.getReturnType(), overridingMethod.getParameters()), false);
BytecodeHelper.doReturn(mv, oldMethod.getReturnType());
}
});
newMethod.setCode(new BytecodeSequence(instructions));
return newMethod;
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.
the class Verifier method visitMethod.
public void visitMethod(MethodNode node) {
// GROOVY-3712 - if it's an MOP method, it's an error as they aren't supposed to exist before ACG is invoked
if (MopWriter.isMopMethod(node.getName())) {
throw new RuntimeParserException("Found unexpected MOP methods in the class node for " + classNode.getName() + "(" + node.getName() + ")", classNode);
}
this.methodNode = node;
adjustTypesIfStaticMainMethod(node);
addReturnIfNeeded(node);
Statement statement;
statement = node.getCode();
if (statement != null)
statement.visit(new VerifierCodeVisitor(this));
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.
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());
}
});
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.
the class VerifierCodeVisitorTest method assertInvalidName.
protected void assertInvalidName(String name) {
try {
VerifierCodeVisitor.assertValidIdentifier(name, "variable name", new ASTNode());
fail("Should have thrown exception due to invalid name: " + name);
} catch (RuntimeParserException e) {
System.out.println("Caught invalid exception: " + e);
}
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy by apache.
the class VerifierCodeVisitorTest method assertInvalidName.
protected void assertInvalidName(String name) {
try {
VerifierCodeVisitor.assertValidIdentifier(name, "variable name", new ASTNode());
fail("Should have thrown exception due to invalid name: " + name);
} catch (RuntimeParserException e) {
System.out.println("Caught invalid exception: " + e);
}
}
Aggregations