use of com.sun.tools.javac.tree.JCTree.JCVariableDecl in project lombok by rzwitserloot.
the class HandleEqualsAndHashCode method createCanEqual.
public JCMethodDecl createCanEqual(JavacNode typeNode, JCTree source, List<JCAnnotation> onParam) {
/* protected boolean canEqual(final java.lang.Object other) {
* return other instanceof Outer.Inner.MyType;
* }
*/
JavacTreeMaker maker = typeNode.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.PROTECTED, List.<JCAnnotation>nil());
JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
Name canEqualName = typeNode.toName("canEqual");
JCExpression objectType = genJavaLangTypeRef(typeNode, "Object");
Name otherName = typeNode.toName("other");
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(flags, onParam), otherName, objectType, null));
JCBlock body = maker.Block(0, List.<JCStatement>of(maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false)))));
return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
use of com.sun.tools.javac.tree.JCTree.JCVariableDecl in project lombok by rzwitserloot.
the class HandleFieldDefaults method setFieldDefaultsForField.
public void setFieldDefaultsForField(JavacNode fieldNode, AccessLevel level, boolean makeFinal) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
if (level != null && level != AccessLevel.NONE) {
if ((field.mods.flags & (Flags.PUBLIC | Flags.PRIVATE | Flags.PROTECTED)) == 0) {
if (!hasAnnotationAndDeleteIfNeccessary(PackagePrivate.class, fieldNode)) {
if ((field.mods.flags & Flags.STATIC) == 0) {
field.mods.flags |= toJavacModifier(level);
}
}
}
}
if (makeFinal && (field.mods.flags & Flags.FINAL) == 0) {
if (!hasAnnotationAndDeleteIfNeccessary(NonFinal.class, fieldNode)) {
if ((field.mods.flags & Flags.STATIC) == 0) {
field.mods.flags |= Flags.FINAL;
}
}
}
fieldNode.rebuild();
}
use of com.sun.tools.javac.tree.JCTree.JCVariableDecl in project lombok by rzwitserloot.
the class HandleGetter method createLazyGetterBody.
public List<JCStatement> createLazyGetterBody(JavacTreeMaker maker, JavacNode fieldNode, JCTree source) {
/*
java.lang.Object value = this.fieldName.get();
if (value == null) {
synchronized (this.fieldName) {
value = this.fieldName.get();
if (value == null) {
final RawValueType actualValue = INITIALIZER_EXPRESSION;
[IF PRIMITIVE]
value = actualValue;
[ELSE]
value = actualValue == null ? this.fieldName : actualValue;
[END IF]
this.fieldName.set(value);
}
}
}
[IF PRIMITIVE]
return (BoxedValueType) value;
[ELSE]
return (BoxedValueType) (value == this.fieldName ? null : value);
[END IF]
*/
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
JCExpression copyOfRawFieldType = copyType(maker, field);
JCExpression copyOfBoxedFieldType = null;
field.type = null;
boolean isPrimitive = false;
if (field.vartype instanceof JCPrimitiveTypeTree) {
String boxed = TYPE_MAP.get(typeTag(field.vartype));
if (boxed != null) {
isPrimitive = true;
field.vartype = genJavaLangTypeRef(fieldNode, boxed);
copyOfBoxedFieldType = genJavaLangTypeRef(fieldNode, boxed);
}
}
if (copyOfBoxedFieldType == null)
copyOfBoxedFieldType = copyType(maker, field);
Name valueName = fieldNode.toName("value");
Name actualValueName = fieldNode.toName("actualValue");
/* java.lang.Object value = this.fieldName.get();*/
{
JCExpression valueVarType = genJavaLangTypeRef(fieldNode, "Object");
statements.append(maker.VarDef(maker.Modifiers(0), valueName, valueVarType, callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD))));
}
/* if (value == null) { */
{
JCSynchronized synchronizedStatement;
/* synchronized (this.fieldName) { */
{
ListBuffer<JCStatement> synchronizedStatements = new ListBuffer<JCStatement>();
/* value = this.fieldName.get(); */
{
JCExpressionStatement newAssign = maker.Exec(maker.Assign(maker.Ident(valueName), callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD))));
synchronizedStatements.append(newAssign);
}
/* if (value == null) { */
{
ListBuffer<JCStatement> innerIfStatements = new ListBuffer<JCStatement>();
/* final RawValueType actualValue = INITIALIZER_EXPRESSION; */
{
innerIfStatements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), actualValueName, copyOfRawFieldType, field.init));
}
/* [IF primitive] value = actualValue; */
{
if (isPrimitive) {
JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), maker.Ident(actualValueName)));
innerIfStatements.append(statement);
}
}
/* [ELSE] value = actualValue == null ? this.fieldName : actualValue; */
{
if (!isPrimitive) {
JCExpression actualValueIsNull = maker.Binary(CTC_EQUAL, maker.Ident(actualValueName), maker.Literal(CTC_BOT, null));
JCExpression thisDotFieldName = createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD);
JCExpression ternary = maker.Conditional(actualValueIsNull, thisDotFieldName, maker.Ident(actualValueName));
JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), ternary));
innerIfStatements.append(statement);
}
}
/* this.fieldName.set(value); */
{
JCStatement statement = callSet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Ident(valueName));
innerIfStatements.append(statement);
}
JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null));
JCIf ifStatement = maker.If(isNull, maker.Block(0, innerIfStatements.toList()), null);
synchronizedStatements.append(ifStatement);
}
synchronizedStatement = maker.Synchronized(createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Block(0, synchronizedStatements.toList()));
}
JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null));
JCIf ifStatement = maker.If(isNull, maker.Block(0, List.<JCStatement>of(synchronizedStatement)), null);
statements.append(ifStatement);
}
/* [IF PRIMITIVE] return (BoxedValueType) value; */
{
if (isPrimitive) {
statements.append(maker.Return(maker.TypeCast(copyOfBoxedFieldType, maker.Ident(valueName))));
}
}
/* [ELSE] return (BoxedValueType) (value == this.fieldName ? null : value); */
{
if (!isPrimitive) {
JCExpression valueEqualsSelf = maker.Binary(CTC_EQUAL, maker.Ident(valueName), createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD));
JCExpression ternary = maker.Conditional(valueEqualsSelf, maker.Literal(CTC_BOT, null), maker.Ident(valueName));
JCExpression typeCast = maker.TypeCast(copyOfBoxedFieldType, maker.Parens(ternary));
statements.append(maker.Return(typeCast));
}
}
// update the field type and init last
/* private final java.util.concurrent.atomic.AtomicReference<Object> fieldName = new java.util.concurrent.atomic.AtomicReference<Object>(); */
{
field.vartype = recursiveSetGeneratedBy(maker.TypeApply(chainDotsString(fieldNode, AR), List.<JCExpression>of(genJavaLangTypeRef(fieldNode, "Object"))), source, fieldNode.getContext());
field.init = recursiveSetGeneratedBy(maker.NewClass(null, NIL_EXPRESSION, copyType(maker, field), NIL_EXPRESSION, null), source, fieldNode.getContext());
}
return statements.toList();
}
use of com.sun.tools.javac.tree.JCTree.JCVariableDecl in project lombok by rzwitserloot.
the class HandleGetter method createGetter.
public JCMethodDecl createGetter(long access, JavacNode field, JavacTreeMaker treeMaker, JCTree source, boolean lazy, List<JCAnnotation> onMethod) {
JCVariableDecl fieldNode = (JCVariableDecl) field.get();
// Remember the type; lazy will change it
JCExpression methodType = copyType(treeMaker, fieldNode);
// Generate the methodName; lazy will change the field type
Name methodName = field.toName(toGetterName(field));
List<JCStatement> statements;
JCTree toClearOfMarkers = null;
if (lazy && !inNetbeansEditor(field)) {
toClearOfMarkers = fieldNode.init;
statements = createLazyGetterBody(treeMaker, field, source);
} else {
statements = createSimpleGetterBody(treeMaker, field);
}
JCBlock methodBody = treeMaker.Block(0, statements);
List<JCTypeParameter> methodGenericParams = List.nil();
List<JCVariableDecl> parameters = List.nil();
List<JCExpression> throwsClauses = List.nil();
JCExpression annotationMethodDefaultValue = null;
List<JCAnnotation> nonNulls = findAnnotations(field, NON_NULL_PATTERN);
List<JCAnnotation> nullables = findAnnotations(field, NULLABLE_PATTERN);
List<JCAnnotation> delegates = findDelegatesAndRemoveFromField(field);
List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables);
if (isFieldDeprecated(field)) {
annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
}
JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source, field.getContext());
if (toClearOfMarkers != null)
recursiveSetGeneratedBy(toClearOfMarkers, null, null);
decl.mods.annotations = decl.mods.annotations.appendList(delegates);
copyJavadoc(field, decl, CopyJavadoc.GETTER);
return decl;
}
use of com.sun.tools.javac.tree.JCTree.JCVariableDecl in project lombok by rzwitserloot.
the class HandleHelper method handle.
@Override
public void handle(AnnotationValues<Helper> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper");
deleteAnnotationIfNeccessary(annotationNode, Helper.class);
JavacNode annotatedType = annotationNode.up();
JavacNode containingBlock = annotatedType == null ? null : annotatedType.directUp();
List<JCStatement> origStatements = getStatementsFromJcNode(containingBlock == null ? null : containingBlock.get());
if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) {
annotationNode.addError("@Helper is legal only on method-local classes.");
return;
}
JCClassDecl annotatedType_ = (JCClassDecl) annotatedType.get();
Iterator<JCStatement> it = origStatements.iterator();
while (it.hasNext()) {
if (it.next() == annotatedType_) {
break;
}
}
java.util.List<String> knownMethodNames = new ArrayList<String>();
for (JavacNode ch : annotatedType.down()) {
if (ch.getKind() != Kind.METHOD)
continue;
String n = ch.getName();
if (n == null || n.isEmpty() || n.charAt(0) == '<')
continue;
knownMethodNames.add(n);
}
Collections.sort(knownMethodNames);
final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
final Name helperName = annotationNode.toName("$" + annotatedType_.name);
final boolean[] helperUsed = new boolean[1];
final JavacTreeMaker maker = annotationNode.getTreeMaker();
TreeVisitor<Void, Void> visitor = new TreeScanner<Void, Void>() {
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
JCMethodInvocation jcmi = (JCMethodInvocation) node;
apply(jcmi);
return super.visitMethodInvocation(node, p);
}
private void apply(JCMethodInvocation jcmi) {
if (!(jcmi.meth instanceof JCIdent))
return;
JCIdent jci = (JCIdent) jcmi.meth;
if (Arrays.binarySearch(knownMethodNames_, jci.name.toString()) < 0)
return;
jcmi.meth = maker.Select(maker.Ident(helperName), jci.name);
helperUsed[0] = true;
}
};
while (it.hasNext()) {
JCStatement stat = it.next();
stat.accept(visitor, null);
}
if (!helperUsed[0]) {
annotationNode.addWarning("No methods of this helper class are ever used.");
return;
}
ListBuffer<JCStatement> newStatements = new ListBuffer<JCStatement>();
boolean mark = false;
for (JCStatement stat : origStatements) {
newStatements.append(stat);
if (mark || stat != annotatedType_)
continue;
mark = true;
JCExpression init = maker.NewClass(null, List.<JCExpression>nil(), maker.Ident(annotatedType_.name), List.<JCExpression>nil(), null);
JCExpression varType = maker.Ident(annotatedType_.name);
JCVariableDecl decl = maker.VarDef(maker.Modifiers(Flags.FINAL), helperName, varType, init);
newStatements.append(decl);
}
setStatementsOfJcNode(containingBlock.get(), newStatements.toList());
}
Aggregations