3838 *
3939 * @author Stephane Nicoll
4040 * @author Phillip Webb
41+ * @author Moritz Halbritter
4142 */
4243class TypeElementMembers {
4344
4445 private static final String OBJECT_CLASS_NAME = Object .class .getName ();
4546
47+ private static final String RECORD_CLASS_NAME = "java.lang.Record" ;
48+
4649 private final MetadataGenerationEnvironment env ;
4750
4851 private final TypeElement targetType ;
4952
53+ private final boolean isRecord ;
54+
5055 private final Map <String , VariableElement > fields = new LinkedHashMap <>();
5156
5257 private final Map <String , List <ExecutableElement >> publicGetters = new LinkedHashMap <>();
@@ -56,18 +61,20 @@ class TypeElementMembers {
5661 TypeElementMembers (MetadataGenerationEnvironment env , TypeElement targetType ) {
5762 this .env = env ;
5863 this .targetType = targetType ;
64+ this .isRecord = RECORD_CLASS_NAME .equals (targetType .getSuperclass ().toString ());
5965 process (targetType );
6066 }
6167
6268 private void process (TypeElement element ) {
63- for (ExecutableElement method : ElementFilter .methodsIn (element .getEnclosedElements ())) {
64- processMethod (method );
65- }
6669 for (VariableElement field : ElementFilter .fieldsIn (element .getEnclosedElements ())) {
6770 processField (field );
6871 }
72+ for (ExecutableElement method : ElementFilter .methodsIn (element .getEnclosedElements ())) {
73+ processMethod (method );
74+ }
6975 Element superType = this .env .getTypeUtils ().asElement (element .getSuperclass ());
70- if (superType instanceof TypeElement && !OBJECT_CLASS_NAME .equals (superType .toString ())) {
76+ if (superType instanceof TypeElement && !OBJECT_CLASS_NAME .equals (superType .toString ())
77+ && !RECORD_CLASS_NAME .equals (superType .toString ())) {
7178 process ((TypeElement ) superType );
7279 }
7380 }
@@ -122,12 +129,22 @@ private ExecutableElement getMatchingAccessor(List<ExecutableElement> candidates
122129 }
123130
124131 private boolean isGetter (ExecutableElement method ) {
132+ boolean hasParameters = !method .getParameters ().isEmpty ();
133+ boolean returnsVoid = TypeKind .VOID == method .getReturnType ().getKind ();
134+ if (hasParameters || returnsVoid ) {
135+ return false ;
136+ }
125137 String name = method .getSimpleName ().toString ();
126- return ((name .startsWith ("get" ) && name .length () > 3 ) || (name .startsWith ("is" ) && name .length () > 2 ))
127- && method .getParameters ().isEmpty () && (TypeKind .VOID != method .getReturnType ().getKind ());
138+ if (this .isRecord && this .fields .containsKey (name )) {
139+ return true ;
140+ }
141+ return (name .startsWith ("get" ) && name .length () > 3 ) || (name .startsWith ("is" ) && name .length () > 2 );
128142 }
129143
130144 private boolean isSetter (ExecutableElement method ) {
145+ if (this .isRecord ) {
146+ return false ;
147+ }
131148 final String name = method .getSimpleName ().toString ();
132149 return (name .startsWith ("set" ) && name .length () > 3 && method .getParameters ().size () == 1
133150 && isSetterReturnType (method ));
@@ -151,16 +168,29 @@ private boolean isSetterReturnType(ExecutableElement method) {
151168 }
152169
153170 private String getAccessorName (String methodName ) {
154- String name = methodName .startsWith ("is" ) ? methodName .substring (2 ) : methodName .substring (3 );
171+ if (this .isRecord ) {
172+ return methodName ;
173+ }
174+ String name ;
175+ if (methodName .startsWith ("is" )) {
176+ name = methodName .substring (2 );
177+ }
178+ else if (methodName .startsWith ("get" )) {
179+ name = methodName .substring (3 );
180+ }
181+ else if (methodName .startsWith ("set" )) {
182+ name = methodName .substring (3 );
183+ }
184+ else {
185+ throw new AssertionError ("methodName must start with 'is', 'get' or 'set', was '" + methodName + "'" );
186+ }
155187 name = Character .toLowerCase (name .charAt (0 )) + name .substring (1 );
156188 return name ;
157189 }
158190
159191 private void processField (VariableElement field ) {
160192 String name = field .getSimpleName ().toString ();
161- if (!this .fields .containsKey (name )) {
162- this .fields .put (name , field );
163- }
193+ this .fields .putIfAbsent (name , field );
164194 }
165195
166196 Map <String , VariableElement > getFields () {
0 commit comments