use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method getType.
protected ClassNode getType(ASTNode exp) {
ClassNode cn = exp.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
if (cn != null)
return cn;
if (exp instanceof ClassExpression) {
ClassNode node = CLASS_Type.getPlainNodeReference();
node.setGenericsTypes(new GenericsType[] { new GenericsType(((ClassExpression) exp).getType()) });
return node;
} else if (exp instanceof VariableExpression) {
VariableExpression vexp = (VariableExpression) exp;
if (vexp == VariableExpression.THIS_EXPRESSION)
return makeThis();
if (vexp == VariableExpression.SUPER_EXPRESSION)
return makeSuper();
ClassNode selfTrait = isTraitSelf(vexp);
if (selfTrait != null)
return makeSelf(selfTrait);
final Variable variable = vexp.getAccessedVariable();
if (variable instanceof FieldNode) {
checkOrMarkPrivateAccess(vexp, (FieldNode) variable);
return getType((FieldNode) variable);
}
if (variable != null && variable != vexp && variable instanceof VariableExpression) {
return getType((Expression) variable);
}
if (variable instanceof Parameter) {
Parameter parameter = (Parameter) variable;
ClassNode type = typeCheckingContext.controlStructureVariables.get(parameter);
TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
ClassNode[] closureParamTypes = (ClassNode[]) (enclosingClosure != null ? enclosingClosure.getClosureExpression().getNodeMetaData(StaticTypesMarker.CLOSURE_ARGUMENTS) : null);
if (type == null && enclosingClosure != null && "it".equals(variable.getName()) && closureParamTypes != null) {
final Parameter[] parameters = enclosingClosure.getClosureExpression().getParameters();
if (parameters.length == 0 && getTemporaryTypesForExpression(vexp) == null) {
type = closureParamTypes[0];
}
}
if (type != null) {
storeType((VariableExpression) exp, type);
return type;
}
}
}
if (exp instanceof ListExpression) {
return inferListExpressionType((ListExpression) exp);
} else if (exp instanceof MapExpression) {
return inferMapExpressionType((MapExpression) exp);
}
if (exp instanceof ConstructorCallExpression) {
return ((ConstructorCallExpression) exp).getType();
}
if (exp instanceof MethodNode) {
if ((exp == GET_DELEGATE || exp == GET_OWNER || exp == GET_THISOBJECT) && typeCheckingContext.getEnclosingClosure() != null) {
return typeCheckingContext.getEnclosingClassNode();
}
ClassNode ret = getInferredReturnType(exp);
return ret != null ? ret : ((MethodNode) exp).getReturnType();
}
if (exp instanceof ClosureExpression) {
ClassNode irt = getInferredReturnType(exp);
if (irt != null) {
irt = wrapTypeIfNecessary(irt);
ClassNode result = CLOSURE_TYPE.getPlainNodeReference();
result.setGenericsTypes(new GenericsType[] { new GenericsType(irt) });
return result;
}
}
if (exp instanceof RangeExpression) {
ClassNode plain = ClassHelper.RANGE_TYPE.getPlainNodeReference();
RangeExpression re = (RangeExpression) exp;
ClassNode fromType = getType(re.getFrom());
ClassNode toType = getType(re.getTo());
if (fromType.equals(toType)) {
plain.setGenericsTypes(new GenericsType[] { new GenericsType(wrapTypeIfNecessary(fromType)) });
} else {
plain.setGenericsTypes(new GenericsType[] { new GenericsType(wrapTypeIfNecessary(lowestUpperBound(fromType, toType))) });
}
return plain;
}
if (exp instanceof UnaryPlusExpression) {
return getType(((UnaryPlusExpression) exp).getExpression());
}
if (exp instanceof UnaryMinusExpression) {
return getType(((UnaryMinusExpression) exp).getExpression());
}
if (exp instanceof BitwiseNegationExpression) {
return getType(((BitwiseNegationExpression) exp).getExpression());
}
if (exp instanceof MethodCall) {
MethodNode target = (MethodNode) exp.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
if (target != null) {
return getType(target);
}
}
if (exp instanceof Parameter) {
return ((Parameter) exp).getOriginType();
}
if (exp instanceof FieldNode) {
FieldNode fn = (FieldNode) exp;
return getGenericsResolvedTypeOfFieldOrProperty(fn, fn.getOriginType());
}
if (exp instanceof PropertyNode) {
PropertyNode pn = (PropertyNode) exp;
return getGenericsResolvedTypeOfFieldOrProperty(pn, pn.getOriginType());
}
return exp instanceof VariableExpression ? ((VariableExpression) exp).getOriginType() : ((Expression) exp).getType();
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class MethodCallExpressionTransformer method transformMethodCallExpression.
Expression transformMethodCallExpression(final MethodCallExpression expr) {
Expression trn = tryTransformIsToCompareIdentity(expr);
if (trn != null) {
return trn;
}
ClassNode superCallReceiver = expr.getNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED);
if (superCallReceiver != null) {
return transformMethodCallExpression(transformToMopSuperCall(superCallReceiver, expr));
}
Expression objectExpression = expr.getObjectExpression();
ClassNode type = staticCompilationTransformer.getTypeChooser().resolveType(objectExpression, staticCompilationTransformer.getClassNode());
if (isCallOnClosure(expr)) {
FieldNode field = staticCompilationTransformer.getClassNode().getField(expr.getMethodAsString());
if (field != null) {
VariableExpression vexp = new VariableExpression(field);
MethodCallExpression result = new MethodCallExpression(vexp, "call", staticCompilationTransformer.transform(expr.getArguments()));
result.setImplicitThis(false);
result.setSourcePosition(expr);
result.setSafe(expr.isSafe());
result.setSpreadSafe(expr.isSpreadSafe());
result.setMethodTarget(StaticTypeCheckingVisitor.CLOSURE_CALL_VARGS);
return result;
}
}
if (type != null && type.isArray()) {
String method = expr.getMethodAsString();
ClassNode componentType = type.getComponentType();
if ("getAt".equals(method)) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
List<Expression> argList = ((TupleExpression) arguments).getExpressions();
if (argList.size() == 1) {
Expression indexExpr = argList.get(0);
ClassNode argType = staticCompilationTransformer.getTypeChooser().resolveType(indexExpr, staticCompilationTransformer.getClassNode());
ClassNode indexType = ClassHelper.getWrapper(argType);
if (componentType.isEnum() && ClassHelper.Number_TYPE == indexType) {
// workaround for generated code in enums which use .next() returning a Number
indexType = ClassHelper.Integer_TYPE;
}
if (argType != null && ClassHelper.Integer_TYPE == indexType) {
BinaryExpression binaryExpression = new BinaryExpression(objectExpression, Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()), indexExpr);
binaryExpression.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
return staticCompilationTransformer.transform(binaryExpression);
}
}
}
} else if ("putAt".equals(method)) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
List<Expression> argList = ((TupleExpression) arguments).getExpressions();
if (argList.size() == 2) {
Expression indexExpr = argList.get(0);
Expression objExpr = argList.get(1);
ClassNode argType = staticCompilationTransformer.getTypeChooser().resolveType(indexExpr, staticCompilationTransformer.getClassNode());
if (argType != null && ClassHelper.Integer_TYPE == ClassHelper.getWrapper(argType)) {
BinaryExpression arrayGet = new BinaryExpression(objectExpression, Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()), indexExpr);
arrayGet.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
BinaryExpression assignment = new BinaryExpression(arrayGet, Token.newSymbol("=", objExpr.getLineNumber(), objExpr.getColumnNumber()), objExpr);
return staticCompilationTransformer.transform(assignment);
}
}
}
}
}
return staticCompilationTransformer.superTransform(expr);
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class SynchronizedASTTransformation method determineLock.
private String determineLock(String value, ClassNode cNode, MethodNode mNode) {
boolean isStatic = mNode.isStatic();
if (value != null && value.length() > 0 && !value.equalsIgnoreCase("$lock")) {
if (cNode.getDeclaredField(value) == null) {
addError("Error during " + MY_TYPE_NAME + " processing: lock field with name '" + value + "' not found in class " + cNode.getName(), mNode);
return null;
}
FieldNode field = cNode.getDeclaredField(value);
if (isStatic && !field.isStatic()) {
addError("Error during " + MY_TYPE_NAME + " processing: lock field with name '" + value + "' must be static for static method '" + mNode.getName() + "'", field);
return null;
}
return value;
}
if (isStatic) {
FieldNode field = cNode.getDeclaredField("$LOCK");
if (field == null) {
int visibility = ACC_PRIVATE | ACC_STATIC | ACC_FINAL;
cNode.addField("$LOCK", visibility, ClassHelper.OBJECT_TYPE, zeroLengthObjectArray());
} else if (!field.isStatic()) {
addError("Error during " + MY_TYPE_NAME + " processing: $LOCK field must be static", field);
}
return "$LOCK";
}
FieldNode field = cNode.getDeclaredField("$lock");
if (field == null) {
int visibility = ACC_PRIVATE | ACC_FINAL;
cNode.addField("$lock", visibility, ClassHelper.OBJECT_TYPE, zeroLengthObjectArray());
} else if (field.isStatic()) {
addError("Error during " + MY_TYPE_NAME + " processing: $lock field must not be static", field);
}
return "$lock";
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class TupleConstructorASTTransformation method createConstructor.
public static void createConstructor(ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperFields, boolean includeSuperProperties, boolean callSuper, boolean force, List<String> excludes, List<String> includes, boolean useSetters) {
// no processing if existing constructors found
List<ConstructorNode> constructors = cNode.getDeclaredConstructors();
if (constructors.size() > 1 && !force)
return;
boolean foundEmpty = constructors.size() == 1 && constructors.get(0).getFirstStatement() == null;
if (constructors.size() == 1 && !foundEmpty && !force)
return;
// HACK: JavaStubGenerator could have snuck in a constructor we don't want
if (foundEmpty)
constructors.remove(0);
List<FieldNode> superList = new ArrayList<FieldNode>();
if (includeSuperProperties) {
superList.addAll(getSuperPropertyFields(cNode.getSuperClass()));
}
if (includeSuperFields) {
superList.addAll(getSuperNonPropertyFields(cNode.getSuperClass()));
}
List<FieldNode> list = new ArrayList<FieldNode>();
if (includeProperties) {
list.addAll(getInstancePropertyFields(cNode));
}
if (includeFields) {
list.addAll(getInstanceNonPropertyFields(cNode));
}
final List<Parameter> params = new ArrayList<Parameter>();
final List<Expression> superParams = new ArrayList<Expression>();
final BlockStatement body = new BlockStatement();
for (FieldNode fNode : superList) {
String name = fNode.getName();
if (shouldSkip(name, excludes, includes))
continue;
params.add(createParam(fNode, name));
boolean hasSetter = cNode.getProperty(name) != null && !fNode.isFinal();
if (callSuper) {
superParams.add(varX(name));
} else {
if (useSetters && hasSetter) {
body.addStatement(stmt(callThisX(getSetterName(name), varX(name))));
} else {
body.addStatement(assignS(propX(varX("this"), name), varX(name)));
}
}
}
if (callSuper) {
body.addStatement(stmt(ctorX(ClassNode.SUPER, args(superParams))));
}
for (FieldNode fNode : list) {
String name = fNode.getName();
if (shouldSkip(name, excludes, includes))
continue;
Parameter nextParam = createParam(fNode, name);
params.add(nextParam);
boolean hasSetter = cNode.getProperty(name) != null && !fNode.isFinal();
if (useSetters && hasSetter) {
body.addStatement(stmt(callThisX(getSetterName(name), varX(nextParam))));
} else {
body.addStatement(assignS(propX(varX("this"), name), varX(nextParam)));
}
}
cNode.addConstructor(new ConstructorNode(ACC_PUBLIC, params.toArray(new Parameter[params.size()]), ClassNode.EMPTY_ARRAY, body));
// or if there is only one Map property (for backwards compatibility)
if (params.size() > 0) {
ClassNode firstParam = params.get(0).getType();
if (params.size() > 1 || firstParam.equals(ClassHelper.OBJECT_TYPE)) {
if (firstParam.equals(ClassHelper.MAP_TYPE)) {
addMapConstructors(cNode, true, "The class " + cNode.getName() + " was incorrectly initialized via the map constructor with null.");
} else {
ClassNode candidate = HMAP_TYPE;
while (candidate != null) {
if (candidate.equals(firstParam)) {
addMapConstructors(cNode, true, "The class " + cNode.getName() + " was incorrectly initialized via the map constructor with null.");
break;
}
candidate = candidate.getSuperClass();
}
}
}
}
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class AutoCloneASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source);
AnnotatedNode parent = (AnnotatedNode) nodes[1];
AnnotationNode anno = (AnnotationNode) nodes[0];
if (!MY_TYPE.equals(anno.getClassNode()))
return;
if (parent instanceof ClassNode) {
ClassNode cNode = (ClassNode) parent;
if (!checkNotInterface(cNode, MY_TYPE_NAME))
return;
cNode.addInterface(CLONEABLE_TYPE);
boolean includeFields = memberHasValue(anno, "includeFields", true);
AutoCloneStyle style = getStyle(anno, "style");
List<String> excludes = getMemberList(anno, "excludes");
List<FieldNode> list = getInstancePropertyFields(cNode);
if (includeFields) {
list.addAll(getInstanceNonPropertyFields(cNode));
}
if (style == null)
style = AutoCloneStyle.CLONE;
switch(style) {
case COPY_CONSTRUCTOR:
createCloneCopyConstructor(cNode, list, excludes);
break;
case SERIALIZATION:
createCloneSerialization(cNode);
break;
case CLONE:
createClone(cNode, list, excludes);
break;
case SIMPLE:
createSimpleClone(cNode, list, excludes);
break;
}
}
}
Aggregations