use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class Verifier method addDefaultParameterConstructors.
/**
* Creates a new constructor for each combination of default parameter expressions.
*/
protected void addDefaultParameterConstructors(final ClassNode type) {
List<ConstructorNode> constructors = new ArrayList<>(type.getDeclaredConstructors());
addDefaultParameters(constructors, (arguments, params, method) -> {
// GROOVY-9151: check for references to parameters that have been removed
for (ListIterator<Expression> it = arguments.getExpressions().listIterator(); it.hasNext(); ) {
Expression argument = it.next();
if (argument instanceof CastExpression) {
argument = ((CastExpression) argument).getExpression();
}
if (argument instanceof VariableExpression) {
VariableExpression v = (VariableExpression) argument;
if (v.getAccessedVariable() instanceof Parameter) {
Parameter p = (Parameter) v.getAccessedVariable();
if (p.hasInitialExpression() && !Arrays.asList(params).contains(p) && p.getInitialExpression() instanceof ConstantExpression) {
// replace argument "(Type) param" with "(Type) <param's default>" for simple default value
it.set(castX(method.getParameters()[it.nextIndex() - 1].getType(), p.getInitialExpression()));
}
}
}
}
GroovyCodeVisitor visitor = new CodeVisitorSupport() {
@Override
public void visitVariableExpression(final VariableExpression e) {
if (e.getAccessedVariable() instanceof Parameter) {
Parameter p = (Parameter) e.getAccessedVariable();
if (p.hasInitialExpression() && !Arrays.asList(params).contains(p)) {
String error = String.format("The generated constructor \"%s(%s)\" references parameter '%s' which has been replaced by a default value expression.", type.getNameWithoutPackage(), Arrays.stream(params).map(Parameter::getType).map(ClassNodeUtils::formatTypeName).collect(joining(",")), p.getName());
throw new RuntimeParserException(error, sourceOf(method));
}
}
}
};
visitor.visitArgumentlistExpression(arguments);
// delegate to original constructor using arguments derived from defaults
Statement code = new ExpressionStatement(new ConstructorCallExpression(ClassNode.THIS, arguments));
addConstructor(params, (ConstructorNode) method, code, type);
});
}
use of org.codehaus.groovy.ast.Parameter 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.Parameter in project groovy by apache.
the class VariableScopeVisitor method visitClosureExpression.
@Override
public void visitClosureExpression(final ClosureExpression expression) {
pushState();
expression.setVariableScope(currentScope);
inClosure = !isAnonymous(currentScope.getParent().getClassScope());
if (expression.isParameterSpecified()) {
for (Parameter parameter : expression.getParameters()) {
parameter.setInStaticContext(currentScope.isInStaticContext());
if (parameter.hasInitialExpression()) {
parameter.getInitialExpression().visit(this);
}
declare(parameter, expression);
}
} else if (expression.getParameters() != null) {
Parameter var = new Parameter(ClassHelper.dynamicType(), "it");
var.setInStaticContext(currentScope.isInStaticContext());
currentScope.putDeclaredVariable(var);
}
super.visitClosureExpression(expression);
markClosureSharedVariables();
popState();
}
use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class VariableScopeVisitor method visitForLoop.
@Override
public void visitForLoop(final ForStatement statement) {
pushState();
statement.setVariableScope(currentScope);
Parameter parameter = statement.getVariable();
parameter.setInStaticContext(currentScope.isInStaticContext());
if (parameter != ForStatement.FOR_LOOP_DUMMY)
declare(parameter, statement);
super.visitForLoop(statement);
popState();
}
use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class VariableScopeVisitor method visitConstructorCallExpression.
@Override
public void visitConstructorCallExpression(final ConstructorCallExpression expression) {
boolean oldInSpecialCtorFlag = inSpecialConstructorCall;
inSpecialConstructorCall |= expression.isSpecialCall();
super.visitConstructorCallExpression(expression);
inSpecialConstructorCall = oldInSpecialCtorFlag;
if (!expression.isUsingAnonymousInnerClass())
return;
pushState();
InnerClassNode innerClass = (InnerClassNode) expression.getType();
innerClass.setVariableScope(currentScope);
currentScope.setClassScope(innerClass);
currentScope.setInStaticContext(false);
for (MethodNode method : innerClass.getMethods()) {
// GROOVY-7033
visitAnnotations(method);
Parameter[] parameters = method.getParameters();
// GROOVY-7033
for (Parameter p : parameters) visitAnnotations(p);
// disable implicit "it"
if (parameters.length == 0)
parameters = null;
visitClosureExpression(new ClosureExpression(parameters, method.getCode()));
}
for (FieldNode field : innerClass.getFields()) {
// GROOVY-7033
visitAnnotations(field);
Expression initExpression = field.getInitialExpression();
if (initExpression != null) {
pushState(field.isStatic());
if (initExpression.isSynthetic() && initExpression instanceof VariableExpression && ((VariableExpression) initExpression).getAccessedVariable() instanceof Parameter) {
// GROOVY-6834: accessing a parameter which is not yet seen in scope
popState();
continue;
}
initExpression.visit(this);
popState();
}
}
for (Statement initStatement : innerClass.getObjectInitializerStatements()) {
initStatement.visit(this);
}
markClosureSharedVariables();
popState();
}
Aggregations