From 1c323332493148f0aaa936e668e1b0da5d09c8be Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Thu, 11 Nov 2010 01:58:48 +0100 Subject: @Getter(lazy=true) support for javac --- .../javac/handlers/HandleEqualsAndHashCode.java | 34 ++-- src/core/lombok/javac/handlers/HandleGetter.java | 189 +++++++++++++++++++-- src/core/lombok/javac/handlers/HandleSetter.java | 3 +- src/core/lombok/javac/handlers/HandleToString.java | 17 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 35 +++- 5 files changed, 233 insertions(+), 45 deletions(-) (limited to 'src/core/lombok/javac/handlers') diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 60b0f89f..e076b295 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -90,7 +90,9 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler excludes, List includes, - Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) { + Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { boolean notAClass = true; if (typeNode.get() instanceof JCClassDecl) { long flags = ((JCClassDecl)typeNode.get()).mods.flags; @@ -173,7 +175,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler fields, boolean callSuper, boolean useFieldsDirectly) { + private JCMethodDecl createHashCode(JavacNode typeNode, List fields, boolean callSuper, FieldAccess fieldAccess) { TreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.nil()); @@ -247,8 +249,8 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandlernil(), hcMethod, List.of(fieldAccessor))); } else /* objects */ { /* this.fieldName == null ? 0 : this.fieldName.hashCode() */ - JCExpression hcCall = maker.Apply(List.nil(), maker.Select(createFieldAccessor(maker, fieldNode, useFieldsDirectly), typeNode.toName("hashCode")), + JCExpression hcCall = maker.Apply(List.nil(), maker.Select(createFieldAccessor(maker, fieldNode, fieldAccess), typeNode.toName("hashCode")), List.nil()); JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, fieldAccessor, maker.Literal(TypeTags.BOT, null)); intoResult = intoResult.append( @@ -329,7 +331,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler fields, boolean callSuper, boolean useFieldsDirectly, boolean needsCanEqual) { + private JCMethodDecl createEquals(JavacNode typeNode, List fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual) { TreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); @@ -398,9 +400,9 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandlernil(), - maker.Select(createFieldAccessor(maker, fieldNode, useFieldsDirectly), typeNode.toName("equals")), - List.of(createFieldAccessor(maker, fieldNode, useFieldsDirectly, maker.Ident(otherName)))); + maker.Select(createFieldAccessor(maker, fieldNode, fieldAccess), typeNode.toName("equals")), + List.of(createFieldAccessor(maker, fieldNode, fieldAccess, maker.Ident(otherName)))); JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(JCTree.NOT, thisEqualsThat)); statements = statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null)); } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 79e842dc..ab4bcb60 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -24,6 +24,9 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.*; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import lombok.AccessLevel; import lombok.Getter; @@ -33,17 +36,28 @@ import lombok.core.handlers.TransformationsUtil; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; +import com.sun.tools.javac.tree.JCTree.JCIf; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCNewClass; +import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCSynchronized; +import com.sun.tools.javac.tree.JCTree.JCTypeApply; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; @@ -78,7 +92,7 @@ public class HandleGetter implements JavacAnnotationHandler { } for (JavacNode field : typeNode.down()) { - if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, errorNode.get(), level, List.nil()); + if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, errorNode.get(), level, List.nil(), false); } return true; @@ -108,8 +122,9 @@ public class HandleGetter implements JavacAnnotationHandler { * * @param fieldNode The node representing the field you want a getter for. * @param pos The node responsible for generating the getter (the {@code @Data} or {@code @Getter} annotation). + * @param lazy */ - public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, List onMethod) { + public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, List onMethod, boolean lazy) { for (JavacNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { if (Javac.annotationTypeMatches(Getter.class, child)) { @@ -119,7 +134,7 @@ public class HandleGetter implements JavacAnnotationHandler { } } - createGetterForField(level, fieldNode, fieldNode, false, onMethod); + createGetterForField(level, fieldNode, fieldNode, false, onMethod, lazy); } @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -127,38 +142,58 @@ public class HandleGetter implements JavacAnnotationHandler { markAnnotationAsProcessed(annotationNode, Getter.class); deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode node = annotationNode.up(); - AccessLevel level = annotation.getInstance().value(); - if (level == AccessLevel.NONE) return true; + Getter annotationInstance = annotation.getInstance(); + AccessLevel level = annotationInstance.value(); + boolean lazy = annotationInstance.lazy(); + if (level == AccessLevel.NONE) { + if (lazy) { + annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE."); + } + return true; + } if (node == null) return false; List onMethod = getAndRemoveAnnotationParameter(ast, "onMethod"); if (node.getKind() == Kind.FIELD) { - return createGetterForFields(level, fields, annotationNode, true, onMethod); + return createGetterForFields(level, fields, annotationNode, true, onMethod, lazy); } if (node.getKind() == Kind.TYPE) { if (!onMethod.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Getter on a type."); + if (lazy) annotationNode.addError("'lazy' is not supported for @Getter on a type."); return generateGetterForType(node, annotationNode, level, false); } return false; } - private boolean createGetterForFields(AccessLevel level, Collection fieldNodes, JavacNode errorNode, boolean whineIfExists, List onMethod) { + private boolean createGetterForFields(AccessLevel level, Collection fieldNodes, JavacNode errorNode, boolean whineIfExists, List onMethod, boolean lazy) { for (JavacNode fieldNode : fieldNodes) { - createGetterForField(level, fieldNode, errorNode, whineIfExists, onMethod); + createGetterForField(level, fieldNode, errorNode, whineIfExists, onMethod, lazy); } return true; } private boolean createGetterForField(AccessLevel level, - JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists, List onMethod) { + JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists, List onMethod, boolean lazy) { if (fieldNode.getKind() != Kind.FIELD) { errorNode.addError("@Getter is only supported on a class or a field."); return true; } JCVariableDecl fieldDecl = (JCVariableDecl)fieldNode.get(); + + if (lazy) { + if ((fieldDecl.mods.flags & Flags.PRIVATE) == 0 || (fieldDecl.mods.flags & Flags.FINAL) == 0) { + errorNode.addError("'lazy' requires the field to be private and final."); + return true; + } + if (fieldDecl.init == null) { + errorNode.addError("'lazy' requires field initialization."); + return true; + } + } + String methodName = toGetterName(fieldDecl); for (String altName : toAllGetterNames(fieldDecl)) { @@ -181,19 +216,27 @@ public class HandleGetter implements JavacAnnotationHandler { long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), onMethod)); + injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), onMethod, lazy)); return true; } - private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, List onMethod) { + + private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, List onMethod, boolean lazy) { JCVariableDecl fieldNode = (JCVariableDecl) field.get(); - JCExpression fieldRef = createFieldAccessor(treeMaker, field, true); - JCStatement returnStatement = treeMaker.Return(fieldRef); - JCBlock methodBody = treeMaker.Block(0, List.of(returnStatement)); + // Remember the type; lazy will change it; + JCExpression methodType = copyType(treeMaker, fieldNode); + + List statements; + if (lazy) { + statements = createLazyGetterBody(treeMaker, field); + } else { + statements = createSimpleGetterBody(treeMaker, field); + } + + JCBlock methodBody = treeMaker.Block(0, statements); Name methodName = field.toName(toGetterName(fieldNode)); - JCExpression methodType = fieldNode.type != null ? treeMaker.Type(fieldNode.type) : fieldNode.vartype; List methodGenericParams = List.nil(); List parameters = List.nil(); @@ -208,4 +251,120 @@ public class HandleGetter implements JavacAnnotationHandler { return treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue); } + + private List createSimpleGetterBody(TreeMaker treeMaker, JavacNode field) { + return List.of(treeMaker.Return(createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD))); + } + + private static final String AR = "java.util.concurrent.atomic.AtomicReference"; + private static final List NIL_EXPRESSION = List.nil(); + + private static final java.util.Map TYPE_MAP; + static { + Map m = new HashMap(); + m.put(TypeTags.INT, "java.lang.Integer"); + m.put(TypeTags.DOUBLE, "java.lang.Double"); + m.put(TypeTags.FLOAT, "java.lang.Float"); + m.put(TypeTags.SHORT, "java.lang.Short"); + m.put(TypeTags.BYTE, "java.lang.Byte"); + m.put(TypeTags.LONG, "java.lang.Long"); + m.put(TypeTags.BOOLEAN, "java.lang.Boolean"); + m.put(TypeTags.CHAR, "java.lang.Character"); + TYPE_MAP = Collections.unmodifiableMap(m); + } + + private List createLazyGetterBody(TreeMaker maker, JavacNode fieldNode) { + /* + java.util.concurrent.atomic.AtomicReference value = this.fieldName.get(); + if (value == null) { + synchronized (this.fieldName) { + value = this.fieldName.get(); + if (value == null) { + value = new java.util.concurrent.atomic.AtomicReference(new ValueType()); + this.fieldName.set(value); + } + } + } + return value.get(); + */ + + List statements = List.nil(); + + JCVariableDecl field = (JCVariableDecl) fieldNode.get(); + field.type = null; + if (field.vartype instanceof JCPrimitiveTypeTree) { + String boxed = TYPE_MAP.get(((JCPrimitiveTypeTree)field.vartype).typetag); + if (boxed != null) { + field.vartype = chainDotsString(maker, fieldNode, boxed); + } + } + + Name valueName = fieldNode.toName("value"); + + /* java.util.concurrent.atomic.AtomicReference value = this.fieldName.get();*/ { + JCTypeApply valueVarType = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))); + statements = 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) { */ { + List synchronizedStatements = List.nil(); + /* value = this.fieldName.get(); */ { + JCExpressionStatement newAssign = maker.Exec(maker.Assign(maker.Ident(valueName), callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD)))); + synchronizedStatements = synchronizedStatements.append(newAssign); + } + + /* if (value == null) { */ { + List innerIfStatements = List.nil(); + /* value = new java.util.concurrent.atomic.AtomicReference(new ValueType());*/ { + JCTypeApply valueVarType = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))); + JCNewClass newInstance = maker.NewClass(null, NIL_EXPRESSION, valueVarType, List.of(field.init), null); + + JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), newInstance)); + innerIfStatements = innerIfStatements.append(statement); + } + /* this.fieldName.set(value); */ { + JCStatement statement = callSet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Ident(valueName)); + innerIfStatements = innerIfStatements.append(statement); + } + + JCBinary isNull = maker.Binary(JCTree.EQ, maker.Ident(valueName), maker.Literal(TypeTags.BOT, null)); + JCIf ifStatement = maker.If(isNull, maker.Block(0, innerIfStatements), null); + synchronizedStatements = synchronizedStatements.append(ifStatement); + } + + synchronizedStatement = maker.Synchronized(createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Block(0, synchronizedStatements)); + } + + JCBinary isNull = maker.Binary(JCTree.EQ, maker.Ident(valueName), maker.Literal(TypeTags.BOT, null)); + JCIf ifStatement = maker.If(isNull, maker.Block(0, List.of(synchronizedStatement)), null); + statements = statements.append(ifStatement); + } + /* return value.get(); */ + statements = statements.append(maker.Return(callGet(fieldNode, maker.Ident(valueName)))); + + // update the field type and init last + + /* private final java.util.concurrent.atomic.AtomicReference fieldName = new java.util.concurrent.atomic.AtomicReference>(); */ { + field.vartype = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))))); + field.init = maker.NewClass(null, NIL_EXPRESSION, copyType(maker, field), NIL_EXPRESSION, null); + } + + return statements; + } + + private JCMethodInvocation callGet(JavacNode source, JCExpression receiver) { + TreeMaker maker = source.getTreeMaker(); + return maker.Apply(NIL_EXPRESSION, maker.Select(receiver, source.toName("get")), NIL_EXPRESSION); + } + + private JCStatement callSet(JavacNode source, JCExpression receiver, JCExpression value) { + TreeMaker maker = source.getTreeMaker(); + return maker.Exec(maker.Apply(NIL_EXPRESSION, maker.Select(receiver, source.toName("set")), List.of(value))); + } + + private JCExpression copyType(TreeMaker treeMaker, JCVariableDecl fieldNode) { + return fieldNode.type != null ? treeMaker.Type(fieldNode.type) : fieldNode.vartype; + } } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index af6f546d..e6a39577 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -38,6 +38,7 @@ import lombok.core.handlers.TransformationsUtil; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; @@ -197,7 +198,7 @@ public class HandleSetter implements JavacAnnotationHandler { private JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, List onMethod, List onParam) { JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); - JCExpression fieldRef = createFieldAccessor(treeMaker, field, true); + JCExpression fieldRef = createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD); JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(fieldDecl.name)); List statements; diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index e3cb0294..64200904 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -29,6 +29,7 @@ import lombok.core.AST.Kind; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; @@ -88,7 +89,9 @@ public class HandleToString implements JavacAnnotationHandler { annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored."); } - return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, ann.doNotUseGetters()); + FieldAccess fieldAccess = ann.doNotUseGetters() ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; + + return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, fieldAccess); } public void generateToStringForType(JavacNode typeNode, JavacNode errorNode) { @@ -105,11 +108,11 @@ public class HandleToString implements JavacAnnotationHandler { try { includeFieldNames = ((Boolean)ToString.class.getMethod("includeFieldNames").getDefaultValue()).booleanValue(); } catch (Exception ignore) {} - generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, false); + generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, FieldAccess.GETTER); } private boolean generateToString(JavacNode typeNode, JavacNode errorNode, List excludes, List includes, - boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) { + boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { boolean notAClass = true; if (typeNode.get() instanceof JCClassDecl) { long flags = ((JCClassDecl)typeNode.get()).mods.flags; @@ -150,7 +153,7 @@ public class HandleToString implements JavacAnnotationHandler { switch (methodExists("toString", typeNode)) { case NOT_EXISTS: - JCMethodDecl method = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, useFieldsDirectly); + JCMethodDecl method = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, fieldAccess); injectMethod(typeNode, method); return true; case EXISTS_BY_LOMBOK: @@ -165,7 +168,7 @@ public class HandleToString implements JavacAnnotationHandler { } - private JCMethodDecl createToString(JavacNode typeNode, List fields, boolean includeFieldNames, boolean callSuper, boolean useFieldsDirectly) { + private JCMethodDecl createToString(JavacNode typeNode, List fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess) { TreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.nil()); @@ -202,9 +205,9 @@ public class HandleToString implements JavacAnnotationHandler { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); JCExpression expr; - JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, useFieldsDirectly); + JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess); - if (getFieldType(fieldNode, useFieldsDirectly) instanceof JCArrayTypeTree) { + if (getFieldType(fieldNode, fieldAccess) instanceof JCArrayTypeTree) { boolean multiDim = ((JCArrayTypeTree)field.vartype).elemtype instanceof JCArrayTypeTree; boolean primitiveArray = ((JCArrayTypeTree)field.vartype).elemtype instanceof JCPrimitiveTypeTree; boolean useDeepTS = multiDim || !primitiveArray; diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index bf356853..d1884e5c 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -345,13 +345,34 @@ public class JavacHandlerUtil { return null; } + enum FieldAccess { + GETTER, PREFER_FIELD, ALWAYS_FIELD; + } + + static boolean lookForGetter(JavacNode field, FieldAccess fieldAccess) { + if (fieldAccess == FieldAccess.GETTER) return true; + if (fieldAccess == FieldAccess.ALWAYS_FIELD) return false; + + // If @Getter(lazy = true) is used, then using it is mandatory. + for (JavacNode child : field.down()) { + if (child.getKind() != Kind.ANNOTATION) continue; + if (Javac.annotationTypeMatches(Getter.class, child)) { + AnnotationValues ann = Javac.createAnnotation(Getter.class, child); + if (ann.getInstance().lazy()) return true; + } + } + return false; + } + /** * Returns the type of the field, unless a getter exists for this field, in which case the return type of the getter is returned. * * @see #createFieldAccessor(TreeMaker, JavacNode) */ - static JCExpression getFieldType(JavacNode field, boolean useFieldsDirectly) { - GetterMethod getter = useFieldsDirectly ? null : findGetter(field); + static JCExpression getFieldType(JavacNode field, FieldAccess fieldAccess) { + boolean lookForGetter = lookForGetter(field, fieldAccess); + + GetterMethod getter = lookForGetter ? findGetter(field) : null; if (getter == null) { return ((JCVariableDecl)field.get()).vartype; @@ -363,12 +384,14 @@ public class JavacHandlerUtil { /** * Creates an expression that reads the field. Will either be {@code this.field} or {@code this.getField()} depending on whether or not there's a getter. */ - static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, boolean useFieldsDirectly) { - return createFieldAccessor(maker, field, useFieldsDirectly, null); + static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, FieldAccess fieldAccess) { + return createFieldAccessor(maker, field, fieldAccess, null); } - static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, boolean useFieldsDirectly, JCExpression receiver) { - GetterMethod getter = useFieldsDirectly ? null : findGetter(field); + static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, FieldAccess fieldAccess, JCExpression receiver) { + boolean lookForGetter = lookForGetter(field, fieldAccess); + + GetterMethod getter = lookForGetter ? findGetter(field) : null; JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); if (getter == null) { -- cgit