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);
}
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.
the class Verifier method visitConstructor.
public void visitConstructor(ConstructorNode node) {
CodeVisitorSupport checkSuper = new CodeVisitorSupport() {
boolean firstMethodCall = true;
String type = null;
public void visitMethodCallExpression(MethodCallExpression call) {
if (!firstMethodCall)
return;
firstMethodCall = false;
String name = call.getMethodAsString();
// the name might be null if the method name is a GString for example
if (name == null)
return;
if (!name.equals("super") && !name.equals("this"))
return;
type = name;
call.getArguments().visit(this);
type = null;
}
public void visitConstructorCallExpression(ConstructorCallExpression call) {
if (!call.isSpecialCall())
return;
type = call.getText();
call.getArguments().visit(this);
type = null;
}
public void visitVariableExpression(VariableExpression expression) {
if (type == null)
return;
String name = expression.getName();
if (!name.equals("this") && !name.equals("super"))
return;
throw new RuntimeParserException("cannot reference " + name + " inside of " + type + "(....) before supertype constructor has been called", expression);
}
};
Statement s = node.getCode();
if (s == null) {
return;
} else {
s.visit(new VerifierCodeVisitor(this));
}
s.visit(checkSuper);
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.
the class Verifier method addCovariantMethods.
protected void addCovariantMethods(ClassNode classNode) {
Map methodsToAdd = new HashMap();
Map genericsSpec = new HashMap();
// unimplemented abstract methods from interfaces
Map abstractMethods = new HashMap();
Map<String, MethodNode> allInterfaceMethods = new HashMap<String, MethodNode>();
ClassNode[] interfaces = classNode.getInterfaces();
for (ClassNode iface : interfaces) {
Map ifaceMethodsMap = iface.getDeclaredMethodsMap();
abstractMethods.putAll(ifaceMethodsMap);
allInterfaceMethods.putAll(ifaceMethodsMap);
}
collectSuperInterfaceMethods(classNode, allInterfaceMethods);
List<MethodNode> declaredMethods = new ArrayList<MethodNode>(classNode.getMethods());
// remove all static, private and package private methods
for (Iterator methodsIterator = declaredMethods.iterator(); methodsIterator.hasNext(); ) {
MethodNode m = (MethodNode) methodsIterator.next();
abstractMethods.remove(m.getTypeDescriptor());
if (m.isStatic() || !(m.isPublic() || m.isProtected())) {
methodsIterator.remove();
}
MethodNode intfMethod = allInterfaceMethods.get(m.getTypeDescriptor());
if (intfMethod != null && ((m.getModifiers() & ACC_SYNTHETIC) == 0) && !m.isPublic() && !m.isStaticConstructor()) {
throw new RuntimeParserException("The method " + m.getName() + " should be public as it implements the corresponding method from interface " + intfMethod.getDeclaringClass(), m);
}
}
addCovariantMethods(classNode, declaredMethods, abstractMethods, methodsToAdd, genericsSpec);
Map<String, MethodNode> declaredMethodsMap = new HashMap<String, MethodNode>();
if (methodsToAdd.size() > 0) {
for (MethodNode mn : declaredMethods) {
declaredMethodsMap.put(mn.getTypeDescriptor(), mn);
}
}
for (Object o : methodsToAdd.entrySet()) {
Map.Entry entry = (Map.Entry) o;
MethodNode method = (MethodNode) entry.getValue();
// we skip bridge methods implemented in current class already
MethodNode mn = declaredMethodsMap.get(entry.getKey());
if (mn != null && mn.getDeclaringClass().equals(classNode))
continue;
addPropertyMethod(method);
}
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.
the class Verifier method checkReturnInObjectInitializer.
private void checkReturnInObjectInitializer(List init) {
CodeVisitorSupport cvs = new CodeVisitorSupport() {
@Override
public void visitClosureExpression(ClosureExpression expression) {
// return is OK in closures in object initializers
}
public void visitReturnStatement(ReturnStatement statement) {
throw new RuntimeParserException("'return' is not allowed in object initializer", statement);
}
};
for (Iterator iterator = init.iterator(); iterator.hasNext(); ) {
Statement stm = (Statement) iterator.next();
stm.visit(cvs);
}
}
use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy-core by groovy.
the class Verifier method getCovariantImplementation.
private MethodNode getCovariantImplementation(final MethodNode oldMethod, final MethodNode overridingMethod, Map genericsSpec) {
// 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)) {
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;
}
Aggregations