use of org.codehaus.groovy.syntax.RuntimeParserException in project groovy by apache.
the class Verifier method addCovariantMethods.
protected void addCovariantMethods(ClassNode classNode) {
Map methodsToAdd = new HashMap();
Map genericsSpec = new HashMap();
// unimplemented abstract methods from interfaces
Map<String, MethodNode> abstractMethods = ClassNodeUtils.getDeclaredMethodMapsFromInterfaces(classNode);
Map<String, MethodNode> allInterfaceMethods = new HashMap<String, MethodNode>(abstractMethods);
ClassNodeUtils.addDeclaredMethodMapsFromSuperInterfaces(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.isEmpty()) {
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 by apache.
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 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);
}
});
}
Aggregations