use of org.codehaus.groovy.ast.expr.FieldExpression in project groovy-core by groovy.
the class TraitReceiverTransformer method transform.
@Override
public Expression transform(final Expression exp) {
ClassNode weavedType = weaved.getOriginType();
if (exp instanceof BinaryExpression) {
return transformBinaryExpression((BinaryExpression) exp, weavedType);
} else if (exp instanceof StaticMethodCallExpression) {
StaticMethodCallExpression call = (StaticMethodCallExpression) exp;
ClassNode ownerType = call.getOwnerType();
if (traitClass.equals(ownerType)) {
MethodCallExpression result = new MethodCallExpression(new VariableExpression(weaved), call.getMethod(), transform(call.getArguments()));
result.setSafe(false);
result.setImplicitThis(false);
result.setSpreadSafe(false);
result.setSourcePosition(call);
return result;
}
} else if (exp instanceof MethodCallExpression) {
MethodCallExpression call = (MethodCallExpression) exp;
Expression obj = call.getObjectExpression();
if (call.isImplicitThis() || "this".equals(obj.getText())) {
return transformMethodCallOnThis(call);
} else if ("super".equals(obj.getText())) {
return transformSuperMethodCall(call);
}
} else if (exp instanceof FieldExpression) {
return transformFieldExpression((FieldExpression) exp);
} else if (exp instanceof VariableExpression) {
VariableExpression vexp = (VariableExpression) exp;
Variable accessedVariable = vexp.getAccessedVariable();
if (accessedVariable instanceof FieldNode) {
FieldNode fn = (FieldNode) accessedVariable;
Expression receiver = createFieldHelperReceiver();
MethodCallExpression mce;
boolean isStatic = fn.isStatic();
if (isStatic) {
receiver = createStaticReceiver(receiver);
}
mce = new MethodCallExpression(receiver, Traits.helperGetterName(fn), ArgumentListExpression.EMPTY_ARGUMENTS);
mce.setSourcePosition(exp);
mce.setImplicitThis(false);
markDynamicCall(mce, fn, isStatic);
return mce;
} else if (accessedVariable instanceof PropertyNode) {
String propName = accessedVariable.getName();
if (knownFields.contains(propName)) {
String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
MethodCallExpression mce = new MethodCallExpression(createFieldHelperReceiver(), method, ArgumentListExpression.EMPTY_ARGUMENTS);
mce.setSourcePosition(exp);
mce.setImplicitThis(false);
return mce;
} else {
return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
}
} else if (accessedVariable instanceof DynamicVariable) {
return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
}
if (vexp.isThisExpression()) {
VariableExpression res = new VariableExpression(weaved);
res.setSourcePosition(exp);
return res;
}
if (vexp.isSuperExpression()) {
throwSuperError(vexp);
}
} else if (exp instanceof PropertyExpression) {
PropertyExpression pexp = (PropertyExpression) exp;
Expression object = pexp.getObjectExpression();
if (pexp.isImplicitThis() || "this".equals(object.getText())) {
String propName = pexp.getPropertyAsString();
if (knownFields.contains(propName)) {
String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
MethodCallExpression mce = new MethodCallExpression(createFieldHelperReceiver(), method, ArgumentListExpression.EMPTY_ARGUMENTS);
mce.setSourcePosition(exp);
mce.setImplicitThis(false);
return mce;
}
}
} else if (exp instanceof ClosureExpression) {
MethodCallExpression mce = new MethodCallExpression(exp, "rehydrate", new ArgumentListExpression(new VariableExpression(weaved), new VariableExpression(weaved), new VariableExpression(weaved)));
mce.setImplicitThis(false);
mce.setSourcePosition(exp);
((ClosureExpression) exp).getCode().visit(this);
// The rewrite we do is causing some troubles with type checking, which will
// not be able to perform closure parameter type inference
// so we store the replacement, which will be done *after* type checking.
exp.putNodeMetaData(TraitASTTransformation.POST_TYPECHECKING_REPLACEMENT, mce);
return exp;
}
// todo: unary expressions (field++, field+=, ...)
return super.transform(exp);
}
use of org.codehaus.groovy.ast.expr.FieldExpression in project groovy by apache.
the class Verifier method addFieldInitialization.
// TODO: add generics to collections
protected void addFieldInitialization(final List list, final List staticList, final FieldNode fieldNode, final boolean isEnumClassNode, final List initStmtsAfterEnumValuesInit, final Set explicitStaticPropsInEnum) {
Expression expression = fieldNode.getInitialExpression();
if (expression != null) {
final FieldExpression fe = fieldX(fieldNode);
if (fieldNode.getType().equals(ClassHelper.REFERENCE_TYPE) && ((fieldNode.getModifiers() & ACC_SYNTHETIC) != 0)) {
fe.setUseReferenceDirectly(true);
}
Statement statement = stmt(binX(fe, Token.newSymbol(Types.ASSIGN, 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();
Expression transformed = transformInlineConstants(initialValueExpression, fieldNode.getType());
if (transformed instanceof ConstantExpression) {
ConstantExpression cexp = (ConstantExpression) transformed;
cexp = transformToPrimitiveConstantIfPossible(cexp);
if (fieldNode.isFinal() && ClassHelper.isStaticConstantInitializerType(cexp.getType()) && cexp.getType().equals(fieldNode.getType())) {
fieldNode.setInitialValueExpression(transformed);
// 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.expr.FieldExpression in project groovy by apache.
the class BinaryExpressionHelper method execMethodAndStoreForSubscriptOperator.
private void execMethodAndStoreForSubscriptOperator(final int op, String method, final Expression expression, final VariableSlotLoader usesSubscript, final Expression orig) {
writePostOrPrefixMethod(op, method, expression, orig);
// we need special code for arrays to store the result (like for a[1]++)
if (usesSubscript != null) {
BinaryExpression be = (BinaryExpression) expression;
CompileStack compileStack = controller.getCompileStack();
OperandStack operandStack = controller.getOperandStack();
ClassNode methodResultType = operandStack.getTopOperand();
int resultIdx = compileStack.defineTemporaryVariable("postfix_" + method, methodResultType, true);
BytecodeExpression methodResultLoader = new VariableSlotLoader(methodResultType, resultIdx, operandStack);
// execute the assignment, this will leave the right side (here the method call result) on the stack
assignToArray(be, be.getLeftExpression(), usesSubscript, methodResultLoader, be.isSafe());
compileStack.removeVar(resultIdx);
} else if (expression instanceof VariableExpression || expression instanceof PropertyExpression || expression instanceof FieldExpression) {
// here we handle a++ and a.b++
controller.getOperandStack().dup();
controller.getCompileStack().pushLHS(true);
expression.visit(controller.getAcg());
controller.getCompileStack().popLHS();
}
// other cases don't need storing, so nothing to be done for them
}
use of org.codehaus.groovy.ast.expr.FieldExpression in project groovy by apache.
the class ClosureWriter method loadReference.
public static void loadReference(final String name, final WriterController controller) {
CompileStack compileStack = controller.getCompileStack();
MethodVisitor mv = controller.getMethodVisitor();
ClassNode classNode = controller.getClassNode();
AsmClassGenerator acg = controller.getAcg();
// an already declared variable.
if (!compileStack.containsVariable(name) && compileStack.getScope().isReferencedClassVariable(name)) {
acg.visitFieldExpression(new FieldExpression(classNode.getDeclaredField(name)));
} else {
BytecodeVariable v = compileStack.getVariable(name, !classNodeUsesReferences(controller.getClassNode()));
if (v == null) {
// variable is not on stack because we are
// inside a nested Closure and this variable
// was not used before
// then load it from the Closure field
FieldNode field = classNode.getDeclaredField(name);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, controller.getInternalClassName(), name, BytecodeHelper.getTypeDescription(field.getType()));
} else {
mv.visitVarInsn(ALOAD, v.getIndex());
}
controller.getOperandStack().push(ClassHelper.REFERENCE_TYPE);
}
}
use of org.codehaus.groovy.ast.expr.FieldExpression in project groovy by apache.
the class StaticTypeCheckingVisitor method visitField.
@Override
public void visitField(final FieldNode node) {
boolean osc = typeCheckingContext.isInStaticContext;
try {
typeCheckingContext.isInStaticContext = node.isInStaticContext();
currentField = node;
visitAnnotations(node);
visitInitialExpression(node.getInitialExpression(), new FieldExpression(node), node);
} finally {
currentField = null;
typeCheckingContext.isInStaticContext = osc;
}
}
Aggregations