use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.
the class HandleBuilder method makePrefixedSetterMethodForBuilder.
private void makePrefixedSetterMethodForBuilder(BuilderJob job, BuilderFieldData bfd, boolean deprecate, String prefix) {
JavacNode fieldNode = bfd.createdFields.get(0);
String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
String setterName = HandlerUtil.buildAccessorName(job.sourceNode, setterPrefix, bfd.name.toString());
Name setterName_ = job.builderType.toName(setterName);
for (JavacNode child : job.builderType.down()) {
if (child.getKind() != Kind.METHOD)
continue;
JCMethodDecl methodDecl = (JCMethodDecl) child.get();
Name existingName = methodDecl.name;
if (existingName.equals(setterName_) && !isTolerate(fieldNode, methodDecl))
return;
}
JavacTreeMaker maker = fieldNode.getTreeMaker();
List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(bfd.originalFieldNode);
JCMethodDecl newMethod = HandleSetter.createSetter(toJavacModifier(job.accessInners), deprecate, fieldNode, maker, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, job.sourceNode, methodAnns, bfd.annotations);
recursiveSetGeneratedBy(newMethod, job.sourceNode);
if (job.sourceNode.up().getKind() == Kind.METHOD) {
copyJavadocFromParam(bfd.originalFieldNode.up(), newMethod, bfd.name.toString());
} else {
copyJavadoc(bfd.originalFieldNode, newMethod, CopyJavadoc.SETTER, true);
}
injectMethod(job.builderType, newMethod);
}
use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.
the class JavacAST method buildLocalVar.
private JavacNode buildLocalVar(JCVariableDecl local, Kind kind) {
if (setAndGetAsHandled(local))
return null;
List<JavacNode> childNodes = new ArrayList<JavacNode>();
for (JCAnnotation annotation : local.mods.annotations) addIfNotNull(childNodes, buildAnnotation(annotation, true));
addIfNotNull(childNodes, buildTypeUse(local.vartype));
addIfNotNull(childNodes, buildExpression(local.init));
return putInMap(new JavacNode(this, local, childNodes, kind));
}
use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.
the class HandleVal method endVisitLocal.
@SuppressWarnings("deprecation")
@Override
public void endVisitLocal(JavacNode localNode, JCVariableDecl local) {
JCTree typeTree = local.vartype;
if (typeTree == null)
return;
String typeTreeToString = typeTree.toString();
JavacNode typeNode = localNode.getNodeFor(typeTree);
if (!(eq(typeTreeToString, "val") || eq(typeTreeToString, "var")))
return;
boolean isVal = typeMatches(val.class, localNode, typeTree);
boolean isVar = typeMatches(var.class, localNode, typeTree);
if (!(isVal || isVar))
return;
if (isVal)
handleFlagUsage(localNode, ConfigurationKeys.VAL_FLAG_USAGE, "val");
if (isVar)
handleFlagUsage(localNode, ConfigurationKeys.VAR_FLAG_USAGE, "var");
JCTree parentRaw = localNode.directUp().get();
if (isVal && parentRaw instanceof JCForLoop) {
localNode.addError("'val' is not allowed in old-style for loops");
return;
}
if (parentRaw instanceof JCForLoop && ((JCForLoop) parentRaw).getInitializer().size() > 1) {
localNode.addError("'var' is not allowed in old-style for loops if there is more than 1 initializer");
return;
}
JCExpression rhsOfEnhancedForLoop = null;
if (local.init == null) {
if (parentRaw instanceof JCEnhancedForLoop) {
JCEnhancedForLoop efl = (JCEnhancedForLoop) parentRaw;
if (efl.var == local)
rhsOfEnhancedForLoop = efl.expr;
}
}
final String annotation = typeTreeToString;
if (rhsOfEnhancedForLoop == null && local.init == null) {
localNode.addError("'" + annotation + "' on a local variable requires an initializer expression");
return;
}
if (local.init instanceof JCNewArray && ((JCNewArray) local.init).elemtype == null) {
localNode.addError("'" + annotation + "' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })");
return;
}
if (localNode.shouldDeleteLombokAnnotations()) {
JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, val.class.getName());
JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, lombok.experimental.var.class.getName());
JavacHandlerUtil.deleteImportFromCompilationUnit(localNode, var.class.getName());
}
if (isVal)
local.mods.flags |= Flags.FINAL;
if (!localNode.shouldDeleteLombokAnnotations()) {
JCAnnotation valAnnotation = recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), typeNode);
local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation);
}
if (localNode.getSourceVersion() >= 10) {
local.vartype = null;
localNode.getAst().setChanged();
return;
}
if (JavacResolution.platformHasTargetTyping()) {
local.vartype = localNode.getAst().getTreeMaker().Ident(localNode.getAst().toName("___Lombok_VAL_Attrib__"));
} else {
local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
}
Type type;
try {
if (rhsOfEnhancedForLoop == null) {
if (local.init.type == null) {
if (isVar && local.init instanceof JCLiteral && ((JCLiteral) local.init).value == null) {
localNode.addError("variable initializer is 'null'");
}
JavacResolution resolver = new JavacResolution(localNode.getContext());
try {
type = ((JCExpression) resolver.resolveMethodMember(localNode).get(local.init)).type;
} catch (RuntimeException e) {
System.err.println("Exception while resolving: " + localNode + "(" + localNode.getFileName() + ")");
throw e;
}
} else {
type = local.init.type;
if (type.isErroneous()) {
try {
JavacResolution resolver = new JavacResolution(localNode.getContext());
local.type = Symtab.instance(localNode.getContext()).unknownType;
type = ((JCExpression) resolver.resolveMethodMember(localNode).get(local.init)).type;
} catch (RuntimeException e) {
System.err.println("Exception while resolving: " + localNode + "(" + localNode.getFileName() + ")");
throw e;
}
}
}
} else {
if (rhsOfEnhancedForLoop.type == null) {
JavacResolution resolver = new JavacResolution(localNode.getContext());
type = ((JCExpression) resolver.resolveMethodMember(localNode.directUp()).get(rhsOfEnhancedForLoop)).type;
} else {
type = rhsOfEnhancedForLoop.type;
}
}
try {
JCExpression replacement;
if (rhsOfEnhancedForLoop != null) {
Type componentType = JavacResolution.ifTypeIsIterableToComponent(type, localNode.getAst());
if (componentType == null)
replacement = JavacResolution.createJavaLangObject(localNode.getAst());
else
replacement = JavacResolution.typeToJCTree(componentType, localNode.getAst(), false);
} else {
replacement = JavacResolution.typeToJCTree(type, localNode.getAst(), false);
}
if (replacement != null) {
local.vartype = replacement;
} else {
local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
}
localNode.getAst().setChanged();
} catch (JavacResolution.TypeNotConvertibleException e) {
localNode.addError("Cannot use '" + annotation + "' here because initializer expression does not have a representable type: " + e.getMessage());
local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
}
} catch (RuntimeException e) {
local.vartype = JavacResolution.createJavaLangObject(localNode.getAst());
throw e;
} finally {
recursiveSetGeneratedBy(local.vartype, typeNode);
}
}
use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.
the class HandleWith method createWith.
public JCMethodDecl createWith(long access, JavacNode field, JavacTreeMaker maker, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam, boolean makeAbstract) {
String withName = toWithName(field);
if (withName == null)
return null;
JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
List<JCAnnotation> copyableAnnotations = findCopyableAnnotations(field);
Name methodName = field.toName(withName);
JCExpression returnType = cloneSelfType(field);
JCBlock methodBody = null;
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(copyableAnnotations);
JCExpression pType = cloneType(maker, fieldDecl.vartype, source);
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, pType, null);
if (!makeAbstract) {
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
JCExpression selfType = cloneSelfType(field);
if (selfType == null)
return null;
ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
for (JavacNode child : field.up().down()) {
if (child.getKind() != Kind.FIELD)
continue;
JCVariableDecl childDecl = (JCVariableDecl) child.get();
// Skip fields that start with $
if (childDecl.name.toString().startsWith("$"))
continue;
long fieldFlags = childDecl.mods.flags;
// Skip static fields.
if ((fieldFlags & Flags.STATIC) != 0)
continue;
// Skip initialized final fields.
if (((fieldFlags & Flags.FINAL) != 0) && childDecl.init != null)
continue;
if (child.get() == field.get()) {
args.append(maker.Ident(fieldDecl.name));
} else {
args.append(createFieldAccessor(maker, child, FieldAccess.ALWAYS_FIELD));
}
}
JCNewClass newClass = maker.NewClass(null, List.<JCExpression>nil(), selfType, args.toList(), null);
JCExpression identityCheck = maker.Binary(CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name));
JCConditional conditional = maker.Conditional(identityCheck, maker.Ident(field.toName("this")), newClass);
JCReturn returnStatement = maker.Return(conditional);
if (!hasNonNullAnnotations(field)) {
statements.append(returnStatement);
} else {
JCStatement nullCheck = generateNullCheck(maker, field, source);
if (nullCheck != null)
statements.append(nullCheck);
statements.append(returnStatement);
}
methodBody = maker.Block(0, statements.toList());
}
List<JCTypeParameter> methodGenericParams = List.nil();
List<JCVariableDecl> parameters = List.of(param);
List<JCExpression> throwsClauses = List.nil();
JCExpression annotationMethodDefaultValue = null;
List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod);
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(source);
if (checkerFramework.generateSideEffectFree())
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
if (isFieldDeprecated(field))
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
if (makeAbstract)
access |= Flags.ABSTRACT;
AnnotationValues<Accessors> accessors = JavacHandlerUtil.getAccessorsForField(field);
boolean makeFinal = shouldMakeFinal(field, accessors);
if (makeFinal)
access |= Flags.FINAL;
JCMethodDecl decl = recursiveSetGeneratedBy(maker.MethodDef(maker.Modifiers(access, annsOnMethod), methodName, returnType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source);
copyJavadoc(field, decl, CopyJavadoc.WITH);
return decl;
}
use of com.sun.tools.javac.tree.JCTree.JCAnnotation in project lombok by rzwitserloot.
the class JavacHandlerUtil method findAnnotationsInList.
/**
* Searches the given field node for annotations that are in the given list, and returns those.
*/
private static List<JCAnnotation> findAnnotationsInList(JavacNode node, java.util.List<String> annotationsToFind) {
JCAnnotation anno = null;
String annoName = null;
for (JavacNode child : node.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (anno != null) {
annoName = "";
break;
}
JCAnnotation annotation = (JCAnnotation) child.get();
annoName = annotation.annotationType.toString();
anno = annotation;
}
}
if (annoName == null)
return List.nil();
if (!annoName.isEmpty()) {
for (String bn : annotationsToFind) if (typeMatches(bn, node, anno.annotationType))
return List.of(anno);
}
ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
for (JavacNode child : node.down()) {
if (child.getKind() == Kind.ANNOTATION) {
JCAnnotation annotation = (JCAnnotation) child.get();
boolean match = false;
if (!match)
for (String bn : annotationsToFind) if (typeMatches(bn, node, annotation.annotationType)) {
result.append(annotation);
break;
}
}
}
return result.toList();
}
Aggregations