use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class InnerClassCompletionVisitor method addThisReference.
private void addThisReference(ConstructorNode node) {
if (!shouldHandleImplicitThisForInnerClass(classNode))
return;
// add "this$0" field init
// add this parameter to node
Parameter[] params = node.getParameters();
Parameter[] newParams = new Parameter[params.length + 1];
System.arraycopy(params, 0, newParams, 1, params.length);
String name = getUniqueName(params, node);
Parameter thisPara = new Parameter(classNode.getOuterClass().getPlainNodeReference(), name);
newParams[0] = thisPara;
node.setParameters(newParams);
BlockStatement block = getCodeAsBlock(node);
BlockStatement newCode = block();
addFieldInit(thisPara, thisField, newCode);
ConstructorCallExpression cce = getFirstIfSpecialConstructorCall(block);
if (cce == null) {
cce = ctorSuperX(new TupleExpression());
block.getStatements().add(0, stmt(cce));
}
if (shouldImplicitlyPassThisPara(cce)) {
// add thisPara to this(...)
TupleExpression args = (TupleExpression) cce.getArguments();
List<Expression> expressions = args.getExpressions();
VariableExpression ve = varX(thisPara.getName());
ve.setAccessedVariable(thisPara);
expressions.add(0, ve);
}
if (cce.isSuperCall()) {
// we have a call to super here, so we need to add
// our code after that
block.getStatements().add(1, newCode);
}
node.setCode(block);
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class InnerClassCompletionVisitor method visitConstructor.
@Override
public void visitConstructor(final ConstructorNode node) {
addThisReference(node);
super.visitConstructor(node);
// an anonymous inner class may use a private constructor (via a bridge) if its super class is also an outer class
if (((InnerClassNode) classNode).isAnonymous() && classNode.getOuterClasses().contains(classNode.getSuperClass())) {
ConstructorNode superCtor = classNode.getSuperClass().getDeclaredConstructor(node.getParameters());
if (superCtor != null && superCtor.isPrivate()) {
ClassNode superClass = classNode.getUnresolvedSuperClass();
// GROOVY-5728
makeBridgeConstructor(superClass, node.getParameters());
ConstructorCallExpression superCtorCall = getFirstIfSpecialConstructorCall(node.getCode());
((TupleExpression) superCtorCall.getArguments()).addExpression(castX(superClass, nullX()));
}
}
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class VariableScopeVisitor method visitDeclarationExpression.
@Override
public void visitDeclarationExpression(final DeclarationExpression expression) {
visitAnnotations(expression);
// visit right side first to prevent the use of a variable before its declaration
expression.getRightExpression().visit(this);
if (expression.isMultipleAssignmentDeclaration()) {
TupleExpression list = expression.getTupleExpression();
for (Expression listExpression : list.getExpressions()) {
declare((VariableExpression) listExpression);
}
} else {
declare(expression.getVariableExpression());
}
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class ClosureWriter method addGeneratedClosureConstructorCall.
public boolean addGeneratedClosureConstructorCall(final ConstructorCallExpression call) {
ClassNode classNode = controller.getClassNode();
if (!classNode.declaresInterface(ClassHelper.GENERATED_CLOSURE_Type))
return false;
AsmClassGenerator acg = controller.getAcg();
OperandStack operandStack = controller.getOperandStack();
MethodVisitor mv = controller.getMethodVisitor();
mv.visitVarInsn(ALOAD, 0);
ClassNode callNode = classNode.getSuperClass();
TupleExpression arguments = (TupleExpression) call.getArguments();
if (arguments.getExpressions().size() != 2)
throw new GroovyBugError("expected 2 arguments for closure constructor super call, but got" + arguments.getExpressions().size());
arguments.getExpression(0).visit(acg);
operandStack.box();
arguments.getExpression(1).visit(acg);
operandStack.box();
// TODO: replace with normal String, p not needed
Parameter p = param(ClassHelper.OBJECT_TYPE, "_p");
String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, new Parameter[] { p, p });
mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
operandStack.remove(2);
return true;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class ClassNodeUtils method hasPossibleStaticMethod.
/**
* Returns true if the given method has a possibly matching static method with the given name and arguments.
* Handles default arguments and optionally spread expressions.
*
* @param cNode the ClassNode of interest
* @param name the name of the method of interest
* @param arguments the arguments to match against
* @param trySpread whether to try to account for SpreadExpressions within the arguments
* @return true if a matching method was found
*/
public static boolean hasPossibleStaticMethod(final ClassNode cNode, final String name, final Expression arguments, final boolean trySpread) {
int count = 0;
boolean foundSpread = false;
if (arguments instanceof TupleExpression) {
TupleExpression tuple = (TupleExpression) arguments;
for (Expression arg : tuple.getExpressions()) {
if (arg instanceof SpreadExpression) {
foundSpread = true;
} else {
count++;
}
}
} else if (arguments instanceof MapExpression) {
count = 1;
}
for (MethodNode method : cNode.getMethods(name)) {
if (method.isStatic()) {
Parameter[] parameters = method.getParameters();
// do fuzzy match for spread case: count will be number of non-spread args
if (trySpread && foundSpread && parameters.length >= count)
return true;
if (parameters.length == count)
return true;
// handle varargs case
if (parameters.length > 0 && parameters[parameters.length - 1].getType().isArray()) {
if (count >= parameters.length - 1)
return true;
// fuzzy match any spread to a varargs
if (trySpread && foundSpread)
return true;
}
// handle parameters with default values
int nonDefaultParameters = 0;
for (Parameter parameter : parameters) {
if (!parameter.hasInitialExpression()) {
nonDefaultParameters++;
}
}
if (count < parameters.length && nonDefaultParameters <= count) {
return true;
}
// TODO handle spread with nonDefaultParams?
}
}
return false;
}
Aggregations