use of org.codehaus.groovy.ast.Variable in project groovy-core by groovy.
the class FinalVariableAnalyzer method visitBlockStatement.
@Override
public void visitBlockStatement(final BlockStatement block) {
Set<VariableExpression> old = declaredFinalVariables;
declaredFinalVariables = new HashSet<VariableExpression>();
super.visitBlockStatement(block);
if (callback != null) {
Map<Variable, VariableState> state = getState();
for (VariableExpression declaredFinalVariable : declaredFinalVariables) {
VariableState variableState = state.get(declaredFinalVariable.getAccessedVariable());
if (variableState == null || variableState != VariableState.is_final) {
callback.variableNotAlwaysInitialized(declaredFinalVariable);
}
}
}
declaredFinalVariables = old;
}
use of org.codehaus.groovy.ast.Variable in project groovy-core by groovy.
the class FinalVariableAnalyzer method visitBinaryExpression.
@Override
public void visitBinaryExpression(final BinaryExpression expression) {
boolean assignment = StaticTypeCheckingSupport.isAssignment(expression.getOperation().getType());
boolean isDeclaration = expression instanceof DeclarationExpression;
Expression leftExpression = expression.getLeftExpression();
Expression rightExpression = expression.getRightExpression();
if (isDeclaration && leftExpression instanceof VariableExpression) {
VariableExpression var = (VariableExpression) leftExpression;
if (Modifier.isFinal(var.getModifiers())) {
declaredFinalVariables.add(var);
}
}
leftExpression.visit(this);
inAssignment = assignment;
rightExpression.visit(this);
inAssignment = false;
if (assignment) {
if (leftExpression instanceof Variable) {
boolean uninitialized = isDeclaration && rightExpression == EmptyExpression.INSTANCE;
recordAssignment((Variable) leftExpression, isDeclaration, uninitialized, false, expression);
}
}
}
use of org.codehaus.groovy.ast.Variable in project groovy-core by groovy.
the class FinalVariableAnalyzer method visitIfElse.
@Override
public void visitIfElse(final IfStatement ifElse) {
visitStatement(ifElse);
ifElse.getBooleanExpression().visit(this);
Map<Variable, VariableState> ifState = pushState();
ifElse.getIfBlock().visit(this);
popState();
Statement elseBlock = ifElse.getElseBlock();
Map<Variable, VariableState> elseState = pushState();
if (elseBlock instanceof EmptyStatement) {
// dispatching to EmptyStatement will not call back visitor,
// must call our visitEmptyStatement explicitly
visitEmptyStatement((EmptyStatement) elseBlock);
} else {
elseBlock.visit(this);
}
popState();
// merge if/else branches
Map<Variable, VariableState> curState = getState();
Set<Variable> allVars = new HashSet<Variable>();
allVars.addAll(curState.keySet());
allVars.addAll(ifState.keySet());
allVars.addAll(elseState.keySet());
for (Variable var : allVars) {
VariableState beforeValue = curState.get(var);
VariableState ifValue = ifState.get(var);
VariableState elseValue = elseState.get(var);
// merge if and else values
VariableState mergedIfElse;
mergedIfElse = ifValue != null && elseValue != null && ifValue.isFinal && elseValue.isFinal ? VariableState.is_final : VariableState.is_var;
if (beforeValue == null) {
curState.put(var, mergedIfElse);
} else {
if (beforeValue == VariableState.is_uninitialized) {
curState.put(var, mergedIfElse);
} else if (ifValue != null || elseValue != null) {
curState.put(var, VariableState.is_var);
}
}
}
}
use of org.codehaus.groovy.ast.Variable 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.Variable 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);
}
Aggregations