use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
the class Verifier method addFieldInitialization.
protected void addFieldInitialization(List list, List staticList, FieldNode fieldNode, boolean isEnumClassNode, List initStmtsAfterEnumValuesInit, Set explicitStaticPropsInEnum) {
Expression expression = fieldNode.getInitialExpression();
if (expression != null) {
final FieldExpression fe = new FieldExpression(fieldNode);
if (fieldNode.getType().equals(ClassHelper.REFERENCE_TYPE) && ((fieldNode.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0)) {
fe.setUseReferenceDirectly(true);
}
ExpressionStatement statement = new ExpressionStatement(new BinaryExpression(fe, Token.newSymbol(Types.EQUAL, fieldNode.getLineNumber(), fieldNode.getColumnNumber()), expression));
if (fieldNode.isStatic()) {
// GROOVY-3311: pre-defined constants added by groovy compiler for numbers/characters should be
// initialized first so that code dependent on it does not see their values as empty
Expression initialValueExpression = fieldNode.getInitialValueExpression();
if (initialValueExpression instanceof ConstantExpression) {
ConstantExpression cexp = (ConstantExpression) initialValueExpression;
cexp = transformToPrimitiveConstantIfPossible(cexp);
if (fieldNode.isFinal() && ClassHelper.isStaticConstantInitializerType(cexp.getType()) && cexp.getType().equals(fieldNode.getType())) {
// GROOVY-5150: primitive type constants will be initialized directly
return;
}
staticList.add(0, statement);
} else {
staticList.add(statement);
}
// to avoid double initialization in case of several constructors
fieldNode.setInitialValueExpression(null);
/*
* If it is a statement for an explicitly declared static field inside an enum, store its
* reference. For enums, they need to be handled differently as such init statements should
* come after the enum values have been initialized inside <clinit> block. GROOVY-3161.
*/
if (isEnumClassNode && explicitStaticPropsInEnum.contains(fieldNode.getName())) {
initStmtsAfterEnumValuesInit.add(statement);
}
} else {
list.add(statement);
}
}
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
the class InnerClassCompletionVisitor method addThisReference.
private void addThisReference(ConstructorNode node) {
if (!shouldHandleImplicitThisForInnerClass(classNode))
return;
Statement code = node.getCode();
// 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 = null;
if (code == null) {
block = new BlockStatement();
} else if (!(code instanceof BlockStatement)) {
block = new BlockStatement();
block.addStatement(code);
} else {
block = (BlockStatement) code;
}
BlockStatement newCode = new BlockStatement();
addFieldInit(thisPara, thisField, newCode);
ConstructorCallExpression cce = getFirstIfSpecialConstructorCall(block);
if (cce == null) {
cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression());
block.getStatements().add(0, new ExpressionStatement(cce));
}
if (shouldImplicitlyPassThisPara(cce)) {
// add thisPara to this(...)
TupleExpression args = (TupleExpression) cce.getArguments();
List<Expression> expressions = args.getExpressions();
VariableExpression ve = new VariableExpression(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.stmt.ExpressionStatement in project groovy by apache.
the class InnerClassCompletionVisitor method getFirstIfSpecialConstructorCall.
private static ConstructorCallExpression getFirstIfSpecialConstructorCall(BlockStatement code) {
if (code == null)
return null;
final List<Statement> statementList = code.getStatements();
if (statementList.isEmpty())
return null;
final Statement statement = statementList.get(0);
if (!(statement instanceof ExpressionStatement))
return null;
Expression expression = ((ExpressionStatement) statement).getExpression();
if (!(expression instanceof ConstructorCallExpression))
return null;
ConstructorCallExpression cce = (ConstructorCallExpression) expression;
if (cce.isSpecialCall())
return cce;
return null;
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
the class InnerClassVisitor method visitConstructorCallExpression.
@Override
public void visitConstructorCallExpression(ConstructorCallExpression call) {
super.visitConstructorCallExpression(call);
if (!call.isUsingAnonymousInnerClass()) {
passThisReference(call);
return;
}
InnerClassNode innerClass = (InnerClassNode) call.getType();
ClassNode outerClass = innerClass.getOuterClass();
ClassNode superClass = innerClass.getSuperClass();
if (superClass instanceof InnerClassNode && !superClass.isInterface() && !(superClass.isStaticClass() || ((superClass.getModifiers() & ACC_STATIC) == ACC_STATIC))) {
insertThis0ToSuperCall(call, innerClass);
}
if (!innerClass.getDeclaredConstructors().isEmpty())
return;
if ((innerClass.getModifiers() & ACC_STATIC) != 0)
return;
VariableScope scope = innerClass.getVariableScope();
if (scope == null)
return;
// expressions = constructor call arguments
List<Expression> expressions = ((TupleExpression) call.getArguments()).getExpressions();
// block = init code for the constructor we produce
BlockStatement block = new BlockStatement();
// parameters = parameters of the constructor
final int additionalParamCount = 1 + scope.getReferencedLocalVariablesCount();
List<Parameter> parameters = new ArrayList<Parameter>(expressions.size() + additionalParamCount);
// superCallArguments = arguments for the super call == the constructor call arguments
List<Expression> superCallArguments = new ArrayList<Expression>(expressions.size());
// first we add a super() call for all expressions given in the
// constructor call expression
int pCount = additionalParamCount;
for (Expression expr : expressions) {
pCount++;
// add one parameter for each expression in the
// constructor call
Parameter param = new Parameter(ClassHelper.OBJECT_TYPE, "p" + pCount);
parameters.add(param);
// add to super call
superCallArguments.add(new VariableExpression(param));
}
// add the super call
ConstructorCallExpression cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression(superCallArguments));
block.addStatement(new ExpressionStatement(cce));
// we need to add "this" to access unknown methods/properties
// this is saved in a field named this$0
pCount = 0;
expressions.add(pCount, VariableExpression.THIS_EXPRESSION);
boolean isStatic = isStaticThis(innerClass, scope);
ClassNode outerClassType = getClassNode(outerClass, isStatic);
if (!isStatic && inClosure)
outerClassType = ClassHelper.CLOSURE_TYPE;
outerClassType = outerClassType.getPlainNodeReference();
Parameter thisParameter = new Parameter(outerClassType, "p" + pCount);
parameters.add(pCount, thisParameter);
thisField = innerClass.addField("this$0", PUBLIC_SYNTHETIC, outerClassType, null);
addFieldInit(thisParameter, thisField, block);
// for each shared variable we add a reference and save it as field
for (Iterator it = scope.getReferencedLocalVariablesIterator(); it.hasNext(); ) {
pCount++;
org.codehaus.groovy.ast.Variable var = (org.codehaus.groovy.ast.Variable) it.next();
VariableExpression ve = new VariableExpression(var);
ve.setClosureSharedVariable(true);
ve.setUseReferenceDirectly(true);
expressions.add(pCount, ve);
ClassNode rawReferenceType = ClassHelper.REFERENCE_TYPE.getPlainNodeReference();
Parameter p = new Parameter(rawReferenceType, "p" + pCount);
parameters.add(pCount, p);
p.setOriginType(var.getOriginType());
final VariableExpression initial = new VariableExpression(p);
initial.setSynthetic(true);
initial.setUseReferenceDirectly(true);
final FieldNode pField = innerClass.addFieldFirst(ve.getName(), PUBLIC_SYNTHETIC, rawReferenceType, initial);
pField.setHolder(true);
pField.setOriginType(ClassHelper.getWrapper(var.getOriginType()));
}
innerClass.addConstructor(ACC_SYNTHETIC, parameters.toArray(new Parameter[parameters.size()]), ClassNode.EMPTY_ARRAY, block);
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
the class InnerClassVisitorHelper method setPropertySetterDispatcher.
protected static void setPropertySetterDispatcher(BlockStatement block, Expression thiz, Parameter[] parameters) {
List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
gStringStrings.add(new ConstantExpression(""));
gStringStrings.add(new ConstantExpression(""));
List<Expression> gStringValues = new ArrayList<Expression>();
gStringValues.add(new VariableExpression(parameters[0]));
block.addStatement(new ExpressionStatement(new BinaryExpression(new PropertyExpression(thiz, new GStringExpression("$name", gStringStrings, gStringValues)), Token.newSymbol(Types.ASSIGN, -1, -1), new VariableExpression(parameters[1]))));
}
Aggregations