use of org.codehaus.groovy.ast.DynamicVariable in project groovy-core by groovy.
the class LogASTTransformation method visit.
public void visit(ASTNode[] nodes, final SourceUnit source) {
init(nodes, source);
AnnotatedNode targetClass = (AnnotatedNode) nodes[1];
AnnotationNode logAnnotation = (AnnotationNode) nodes[0];
final GroovyClassLoader classLoader = compilationUnit != null ? compilationUnit.getTransformLoader() : source.getClassLoader();
final LoggingStrategy loggingStrategy = createLoggingStrategy(logAnnotation, classLoader);
if (loggingStrategy == null)
return;
final String logFieldName = lookupLogFieldName(logAnnotation);
final String categoryName = lookupCategoryName(logAnnotation);
if (!(targetClass instanceof ClassNode))
throw new GroovyBugError("Class annotation " + logAnnotation.getClassNode().getName() + " annotated no Class, this must not happen.");
final ClassNode classNode = (ClassNode) targetClass;
ClassCodeExpressionTransformer transformer = new ClassCodeExpressionTransformer() {
private FieldNode logNode;
@Override
protected SourceUnit getSourceUnit() {
return source;
}
public Expression transform(Expression exp) {
if (exp == null)
return null;
if (exp instanceof MethodCallExpression) {
return transformMethodCallExpression(exp);
}
return super.transform(exp);
}
@Override
public void visitClass(ClassNode node) {
FieldNode logField = node.getField(logFieldName);
if (logField != null && logField.getOwner().equals(node)) {
addError("Class annotated with Log annotation cannot have log field declared", logField);
} else if (logField != null && !Modifier.isPrivate(logField.getModifiers())) {
addError("Class annotated with Log annotation cannot have log field declared because the field exists in the parent class: " + logField.getOwner().getName(), logField);
} else {
logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName);
}
super.visitClass(node);
}
private Expression transformMethodCallExpression(Expression exp) {
MethodCallExpression mce = (MethodCallExpression) exp;
if (!(mce.getObjectExpression() instanceof VariableExpression)) {
return exp;
}
VariableExpression variableExpression = (VariableExpression) mce.getObjectExpression();
if (!variableExpression.getName().equals(logFieldName) || !(variableExpression.getAccessedVariable() instanceof DynamicVariable)) {
return exp;
}
String methodName = mce.getMethodAsString();
if (methodName == null)
return exp;
if (usesSimpleMethodArgumentsOnly(mce))
return exp;
variableExpression.setAccessedVariable(logNode);
if (!loggingStrategy.isLoggingMethod(methodName))
return exp;
return loggingStrategy.wrapLoggingMethodCall(variableExpression, methodName, exp);
}
private boolean usesSimpleMethodArgumentsOnly(MethodCallExpression mce) {
Expression arguments = mce.getArguments();
if (arguments instanceof TupleExpression) {
TupleExpression tuple = (TupleExpression) arguments;
for (Expression exp : tuple.getExpressions()) {
if (!isSimpleExpression(exp))
return false;
}
return true;
}
return !isSimpleExpression(arguments);
}
private boolean isSimpleExpression(Expression exp) {
if (exp instanceof ConstantExpression)
return true;
if (exp instanceof VariableExpression)
return true;
return false;
}
};
transformer.visitClass(classNode);
// GROOVY-6373: references to 'log' field are normally already FieldNodes by now, so revisit scoping
new VariableScopeVisitor(sourceUnit, true).visitClass(classNode);
}
use of org.codehaus.groovy.ast.DynamicVariable in project groovy by apache.
the class MarkupBuilderCodeTransformer method transform.
@Override
public Expression transform(final Expression exp) {
if (exp instanceof BinaryExpression) {
return transformBinaryExpression((BinaryExpression) exp);
}
if (exp instanceof MethodCallExpression) {
return transformMethodCall((MethodCallExpression) exp);
}
if (exp instanceof ClosureExpression) {
ClosureExpression cl = (ClosureExpression) exp;
cl.getCode().visit(this);
return cl;
}
if (exp instanceof VariableExpression) {
VariableExpression var = (VariableExpression) exp;
if (var.getAccessedVariable() instanceof DynamicVariable) {
MethodCallExpression callGetModel = new MethodCallExpression(new VariableExpression("this"), "getModel", ArgumentListExpression.EMPTY_ARGUMENTS);
callGetModel.setImplicitThis(true);
callGetModel.setSourcePosition(exp);
String varName = var.getName();
if ("model".equals(varName) || "unescaped".equals(varName)) {
return callGetModel;
}
MethodCallExpression mce = new MethodCallExpression(callGetModel, "get", new ArgumentListExpression(new ConstantExpression(varName)));
mce.setSourcePosition(exp);
mce.setImplicitThis(false);
MethodCallExpression yield = new MethodCallExpression(new VariableExpression("this"), "tryEscape", new ArgumentListExpression(mce));
yield.setImplicitThis(true);
yield.setSourcePosition(exp);
yield.putNodeMetaData(TARGET_VARIABLE, varName);
return autoEscape ? yield : mce;
}
}
return super.transform(exp);
}
use of org.codehaus.groovy.ast.DynamicVariable in project groovy by apache.
the class StaticVerifier method addStaticVariableError.
private void addStaticVariableError(VariableExpression ve) {
// propertyExpressions will handle the error a bit differently
if (!inSpecialConstructorCall && (inClosure || !ve.isInStaticContext()))
return;
if (ve.isThisExpression() || ve.isSuperExpression())
return;
Variable v = ve.getAccessedVariable();
if (currentMethod != null && currentMethod.isStatic()) {
FieldNode fieldNode = getDeclaredOrInheritedField(currentMethod.getDeclaringClass(), ve.getName());
if (fieldNode != null && fieldNode.isStatic())
return;
}
if (v != null && !(v instanceof DynamicVariable) && v.isInStaticContext())
return;
addVariableError(ve);
}
use of org.codehaus.groovy.ast.DynamicVariable in project groovy by apache.
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)) {
return createFieldHelperCall(exp, weavedType, propName);
} 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)) {
return createFieldHelperCall(exp, weavedType, propName);
}
}
} 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);
boolean oldInClosure = inClosure;
inClosure = true;
((ClosureExpression) exp).getCode().visit(this);
inClosure = oldInClosure;
// 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.DynamicVariable in project groovy by apache.
the class BinaryExpressionMultiTypeDispatcher method doAssignmentToLocalVariable.
private boolean doAssignmentToLocalVariable(String method, BinaryExpression binExp) {
Expression left = binExp.getLeftExpression();
if (left instanceof VariableExpression) {
VariableExpression ve = (VariableExpression) left;
Variable v = ve.getAccessedVariable();
if (v instanceof DynamicVariable)
return false;
if (v instanceof PropertyExpression)
return false;
/* field and declaration we don't return false */
} else {
return false;
}
evaluateBinaryExpression(method, binExp);
getController().getOperandStack().dup();
getController().getCompileStack().pushLHS(true);
binExp.getLeftExpression().visit(getController().getAcg());
getController().getCompileStack().popLHS();
return true;
}
Aggregations