use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleSetter method generateSetterForType.
public boolean generateSetterForType(EclipseNode typeNode, EclipseNode pos, AccessLevel level, boolean checkForTypeLevelSetter) {
if (checkForTypeLevelSetter) {
if (hasAnnotation(Setter.class, typeNode)) {
//The annotation will make it happen, so we can skip it.
return true;
}
}
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration)
typeDecl = (TypeDeclaration) typeNode.get();
int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0;
if (typeDecl == null || notAClass) {
pos.addError("@Setter is only supported on a class or a field.");
return false;
}
for (EclipseNode field : typeNode.down()) {
if (field.getKind() != Kind.FIELD)
continue;
FieldDeclaration fieldDecl = (FieldDeclaration) field.get();
if (!filterField(fieldDecl))
continue;
//Skip final fields.
if ((fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0)
continue;
generateSetterForField(field, pos, level);
}
return true;
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleSynchronized method handle.
@Override
public void handle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.SYNCHRONIZED_FLAG_USAGE, "@Synchronized");
int p1 = source.sourceStart - 1;
int p2 = source.sourceStart - 2;
long pos = (((long) p1) << 32) | p2;
EclipseNode methodNode = annotationNode.up();
if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof MethodDeclaration)) {
annotationNode.addError("@Synchronized is legal only on methods.");
return;
}
MethodDeclaration method = (MethodDeclaration) methodNode.get();
if (method.isAbstract()) {
annotationNode.addError("@Synchronized is legal only on concrete methods.");
return;
}
char[] lockName = createLockField(annotation, annotationNode, method.isStatic(), true);
if (lockName == null)
return;
if (method.statements == null)
return;
Block block = new Block(0);
setGeneratedBy(block, source);
block.statements = method.statements;
// Positions for in-method generated nodes are special
block.sourceEnd = method.bodyEnd;
block.sourceStart = method.bodyStart;
Expression lockVariable;
if (method.isStatic())
lockVariable = new QualifiedNameReference(new char[][] { methodNode.up().getName().toCharArray(), lockName }, new long[] { pos, pos }, p1, p2);
else {
lockVariable = new FieldReference(lockName, pos);
ThisReference thisReference = new ThisReference(p1, p2);
setGeneratedBy(thisReference, source);
((FieldReference) lockVariable).receiver = thisReference;
}
setGeneratedBy(lockVariable, source);
method.statements = new Statement[] { new SynchronizedStatement(lockVariable, block, 0, 0) };
// Positions for in-method generated nodes are special
method.statements[0].sourceEnd = method.bodyEnd;
method.statements[0].sourceStart = method.bodyStart;
setGeneratedBy(method.statements[0], source);
methodNode.rebuild();
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleToString method generateToString.
public void generateToString(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration)
typeDecl = (TypeDeclaration) typeNode.get();
int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0;
if (typeDecl == null || notAClass) {
errorNode.addError("@ToString is only supported on a class or enum.");
}
if (callSuper == null) {
try {
callSuper = ((Boolean) ToString.class.getMethod("callSuper").getDefaultValue()).booleanValue();
} catch (Exception ignore) {
}
}
List<EclipseNode> nodesForToString = new ArrayList<EclipseNode>();
if (includes != null) {
for (EclipseNode child : typeNode.down()) {
if (child.getKind() != Kind.FIELD)
continue;
FieldDeclaration fieldDecl = (FieldDeclaration) child.get();
if (includes.contains(new String(fieldDecl.name)))
nodesForToString.add(child);
}
} else {
for (EclipseNode child : typeNode.down()) {
if (child.getKind() != Kind.FIELD)
continue;
FieldDeclaration fieldDecl = (FieldDeclaration) child.get();
if (!filterField(fieldDecl))
continue;
//Skip excluded fields.
if (excludes != null && excludes.contains(new String(fieldDecl.name)))
continue;
nodesForToString.add(child);
}
}
switch(methodExists("toString", typeNode, 0)) {
case NOT_EXISTS:
MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get(), fieldAccess);
injectMethod(typeNode, toString);
break;
case EXISTS_BY_LOMBOK:
break;
default:
case EXISTS_BY_USER:
if (whineIfExists) {
errorNode.addWarning("Not generating toString(): A method with that name already exists");
}
}
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleToString method createToString.
public static MethodDeclaration createToString(EclipseNode type, Collection<EclipseNode> fields, boolean includeFieldNames, boolean callSuper, ASTNode source, FieldAccess fieldAccess) {
String typeName = getTypeName(type);
char[] suffix = ")".toCharArray();
String infixS = ", ";
char[] infix = infixS.toCharArray();
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
final int PLUS = OperatorIds.PLUS;
char[] prefix;
if (callSuper) {
prefix = (typeName + "(super=").toCharArray();
} else if (fields.isEmpty()) {
prefix = (typeName + "()").toCharArray();
} else if (includeFieldNames) {
prefix = (typeName + "(" + new String(((FieldDeclaration) fields.iterator().next().get()).name) + "=").toCharArray();
} else {
prefix = (typeName + "(").toCharArray();
}
boolean first = true;
Expression current = new StringLiteral(prefix, pS, pE, 0);
setGeneratedBy(current, source);
if (callSuper) {
MessageSend callToSuper = new MessageSend();
callToSuper.sourceStart = pS;
callToSuper.sourceEnd = pE;
setGeneratedBy(callToSuper, source);
callToSuper.receiver = new SuperReference(pS, pE);
setGeneratedBy(callToSuper, source);
callToSuper.selector = "toString".toCharArray();
current = new BinaryExpression(current, callToSuper, PLUS);
setGeneratedBy(current, source);
first = false;
}
for (EclipseNode field : fields) {
TypeReference fieldType = getFieldType(field, fieldAccess);
Expression fieldAccessor = createFieldAccessor(field, fieldAccess, source);
// The distinction between primitive and object will be useful if we ever add a 'hideNulls' option.
boolean fieldBaseTypeIsPrimitive = BUILT_IN_TYPES.contains(new String(fieldType.getLastToken()));
boolean fieldIsPrimitive = fieldType.dimensions() == 0 && fieldBaseTypeIsPrimitive;
boolean fieldIsPrimitiveArray = fieldType.dimensions() == 1 && fieldBaseTypeIsPrimitive;
boolean fieldIsObjectArray = fieldType.dimensions() > 0 && !fieldIsPrimitiveArray;
@SuppressWarnings("unused") boolean fieldIsObject = !fieldIsPrimitive && !fieldIsPrimitiveArray && !fieldIsObjectArray;
Expression ex;
if (fieldIsPrimitiveArray || fieldIsObjectArray) {
MessageSend arrayToString = new MessageSend();
arrayToString.sourceStart = pS;
arrayToString.sourceEnd = pE;
arrayToString.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray());
arrayToString.arguments = new Expression[] { fieldAccessor };
setGeneratedBy(arrayToString.arguments[0], source);
arrayToString.selector = (fieldIsObjectArray ? "deepToString" : "toString").toCharArray();
ex = arrayToString;
} else {
ex = fieldAccessor;
}
setGeneratedBy(ex, source);
if (first) {
current = new BinaryExpression(current, ex, PLUS);
current.sourceStart = pS;
current.sourceEnd = pE;
setGeneratedBy(current, source);
first = false;
continue;
}
StringLiteral fieldNameLiteral;
if (includeFieldNames) {
char[] namePlusEqualsSign = (infixS + field.getName() + "=").toCharArray();
fieldNameLiteral = new StringLiteral(namePlusEqualsSign, pS, pE, 0);
} else {
fieldNameLiteral = new StringLiteral(infix, pS, pE, 0);
}
setGeneratedBy(fieldNameLiteral, source);
current = new BinaryExpression(current, fieldNameLiteral, PLUS);
setGeneratedBy(current, source);
current = new BinaryExpression(current, ex, PLUS);
setGeneratedBy(current, source);
}
if (!first) {
StringLiteral suffixLiteral = new StringLiteral(suffix, pS, pE, 0);
setGeneratedBy(suffixLiteral, source);
current = new BinaryExpression(current, suffixLiteral, PLUS);
setGeneratedBy(current, source);
}
ReturnStatement returnStatement = new ReturnStatement(current, pS, pE);
setGeneratedBy(returnStatement, source);
MethodDeclaration method = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
setGeneratedBy(method, source);
method.modifiers = toEclipseModifier(AccessLevel.PUBLIC);
method.returnType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] { p, p, p });
setGeneratedBy(method.returnType, source);
method.annotations = new Annotation[] { makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source) };
method.arguments = null;
method.selector = "toString".toCharArray();
method.thrownExceptions = null;
method.typeParameters = null;
method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
method.statements = new Statement[] { returnStatement };
return method;
}
use of lombok.eclipse.EclipseNode in project lombok by rzwitserloot.
the class HandleToString method handle.
public void handle(AnnotationValues<ToString> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.TO_STRING_FLAG_USAGE, "@ToString");
ToString ann = annotation.getInstance();
List<String> excludes = Arrays.asList(ann.exclude());
List<String> includes = Arrays.asList(ann.of());
EclipseNode typeNode = annotationNode.up();
Boolean callSuper = ann.callSuper();
if (!annotation.isExplicit("callSuper"))
callSuper = null;
if (!annotation.isExplicit("exclude"))
excludes = null;
if (!annotation.isExplicit("of"))
includes = null;
if (excludes != null && includes != null) {
excludes = null;
annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored.");
}
checkForBogusFieldNames(typeNode, annotation);
Boolean doNotUseGettersConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_DO_NOT_USE_GETTERS);
boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration;
FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER;
Boolean fieldNamesConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES);
boolean includeFieldNames = annotation.isExplicit("includeFieldNames") || fieldNamesConfiguration == null ? ann.includeFieldNames() : fieldNamesConfiguration;
generateToString(typeNode, annotationNode, excludes, includes, includeFieldNames, callSuper, true, fieldAccess);
}
Aggregations