3737import java .lang .reflect .Method ;
3838import java .lang .reflect .Modifier ;
3939import java .util .ArrayList ;
40+ import java .util .Arrays ;
41+ import java .util .HashMap ;
42+ import java .util .LinkedHashMap ;
4043import java .util .List ;
44+ import java .util .Map ;
4145
4246import org .bridj .ann .Alignment ;
4347import org .bridj .ann .Array ;
4448import org .bridj .ann .Bits ;
4549import org .bridj .ann .Field ;
4650import org .bridj .ann .Union ;
4751
52+ import com .fasterxml .classmate .AnnotationConfiguration ;
53+ import com .fasterxml .classmate .AnnotationInclusion ;
54+ import com .fasterxml .classmate .Filter ;
55+ import com .fasterxml .classmate .MemberResolver ;
56+ import com .fasterxml .classmate .ResolvedType ;
57+ import com .fasterxml .classmate .ResolvedTypeWithMembers ;
58+ import com .fasterxml .classmate .TypeResolver ;
59+ import com .fasterxml .classmate .members .RawField ;
60+ import com .fasterxml .classmate .members .RawMethod ;
61+ import com .fasterxml .classmate .members .ResolvedField ;
62+ import com .fasterxml .classmate .members .ResolvedMember ;
63+ import com .fasterxml .classmate .members .ResolvedMethod ;
64+
4865class StructFieldDeclaration {
4966
5067 final StructFieldDescription desc = new StructFieldDescription ();
@@ -58,6 +75,7 @@ public String toString() {
5875 return desc .name + " (index = " + index + (unionWith < 0 ? "" : ", unionWith = " + unionWith ) + ", desc = " + desc + ")" ;
5976 }
6077
78+ @ Deprecated
6179 protected static boolean acceptFieldGetter (Member member , boolean getter ) {
6280 if ((member instanceof Method ) && ((Method ) member ).getParameterTypes ().length != (getter ? 0 : 1 )) {
6381 return false ;
@@ -71,16 +89,30 @@ protected static boolean acceptFieldGetter(Member member, boolean getter) {
7189
7290 return !Modifier .isStatic (modifiers );
7391 }
92+
93+ protected static boolean acceptFieldGetter (ResolvedMember <?> member , boolean getter ) {
94+ if ((member instanceof ResolvedMethod ) && ((ResolvedMethod ) member ).getRawMember ().getParameterTypes ().length != (getter ? 0 : 1 )) {
95+ return false ;
96+ }
97+
98+ if (member .get (Field .class ) == null ) {
99+ return false ;
100+ }
101+
102+ return !member .isStatic ();
103+ }
74104
75105 /**
76106 * Creates a list of structure fields
77107 */
108+ @ Deprecated
78109 protected static List <StructFieldDeclaration > listFields (Class <?> structClass ) {
79110 List <StructFieldDeclaration > list = new ArrayList <StructFieldDeclaration >();
80111 for (Method method : structClass .getMethods ()) {
81112 if (acceptFieldGetter (method , true )) {
82113 StructFieldDeclaration io = fromGetter (method );
83114 try {
115+ // this only works when the names are equal, does not support setXXX methods.
84116 Method setter = structClass .getMethod (method .getName (), io .valueClass );
85117 if (acceptFieldGetter (setter , false )) {
86118 io .setter = setter ;
@@ -110,7 +142,81 @@ protected static List<StructFieldDeclaration> listFields(Class<?> structClass) {
110142
111143 return list ;
112144 }
145+
146+ protected static List <StructFieldDeclaration > listFields2 (Class <?> structClass ) {
147+ List <StructFieldDeclaration > list = new ArrayList <StructFieldDeclaration >();
148+ ResolvedTypeWithMembers resolvedStruct = resolveType (structClass );
149+ for (ResolvedMethod method : resolvedStruct .getMemberMethods ()) {
150+ if (acceptFieldGetter (method , true )) {
151+ StructFieldDeclaration io = fromGetter (method );
152+ try {
153+ // this only works when the names are equal, does not support setXXX methods.
154+ ResolvedMethod setter = getMethod ( resolvedStruct .getMemberMethods (), method .getName (), io .valueClass );
155+ if (acceptFieldGetter (setter , false )) {
156+ io .setter = setter .getRawMember ();
157+ }
158+ } catch (Exception ex ) {
159+ //assert BridJ.info("No setter for getter " + method);
160+ }
161+ if (io != null ) {
162+ list .add (io );
163+ }
164+ }
165+ }
113166
167+ int nFieldFields = 0 ;
168+ for ( ResolvedField field : resolvedStruct .getMemberFields ()) {
169+ if (acceptFieldGetter (field , true )) {
170+ StructFieldDeclaration io = StructFieldDeclaration .fromField (field );
171+ if (io != null ) {
172+ list .add (io );
173+ nFieldFields ++;
174+ }
175+ }
176+ }
177+ if (nFieldFields > 0 && BridJ .warnStructFields ) {
178+ BridJ .warning ("Struct " + structClass .getName () + " has " + nFieldFields + " struct fields implemented as Java fields, which won't give the best performance and might require counter-intuitive calls to BridJ.readFromNative / .writeToNative. Please consider using JNAerator to generate your struct instead, or use BRIDJ_WARN_STRUCT_FIELDS=0 or -Dbridj.warnStructFields=false to mute this warning." );
179+ }
180+
181+ return list ;
182+ }
183+
184+ public static ResolvedMethod getMethod ( ResolvedMethod [] methods , String name , Class <?>... params ) {
185+ METHODS : for ( ResolvedMethod method : methods ) {
186+ if ( !name .equals (method .getName ()) ) continue METHODS ;
187+ if ( params .length != method .getArgumentCount ()) continue METHODS ;
188+ for ( int i = 0 ; i < params .length ; i ++ ) {
189+ if ( !method .getArgumentType (i ).isInstanceOf (params [i ])) continue METHODS ;
190+ }
191+ return method ;
192+ }
193+ return null ;
194+ }
195+
196+ protected static String nameForMember ( ResolvedMember <?> member ) {
197+ String name = member .getName ();
198+ if (name .matches ("get[A-Z].*" )) {
199+ return Character .toLowerCase (name .charAt (3 )) + name .substring (4 );
200+ } else if ( name .matches ("set[A-Z].*" )) {
201+ return Character .toLowerCase (name .charAt (3 )) + name .substring (4 );
202+ } else {
203+ return name ;
204+ }
205+ }
206+
207+ protected static ResolvedTypeWithMembers resolveType ( Class <?> structClass ) {
208+ TypeResolver resolver = new TypeResolver ();
209+ ResolvedType classType = resolver .resolve (structClass );
210+ MemberResolver mr = new MemberResolver (resolver );
211+ mr .setMethodFilter (method ->
212+ method .getRawMember ().getParameterTypes ().length < 2 &&
213+ !method .isStatic ());
214+ mr .setFieldFilter (field ->!field .isStatic ());
215+ AnnotationConfiguration annConfig = new AnnotationConfiguration .StdConfiguration (AnnotationInclusion .INCLUDE_BUT_DONT_INHERIT );
216+ return mr .resolve (classType , annConfig , null );
217+ }
218+
219+ @ Deprecated
114220 protected static StructFieldDeclaration fromField (java .lang .reflect .Field getter ) {
115221 StructFieldDeclaration field = fromMember ((Member ) getter );
116222 field .desc .field = getter ;
@@ -119,6 +225,15 @@ protected static StructFieldDeclaration fromField(java.lang.reflect.Field getter
119225 return field ;
120226 }
121227
228+ protected static StructFieldDeclaration fromField (ResolvedField getter ) {
229+ StructFieldDeclaration field = fromMember ((ResolvedField ) getter );
230+ field .desc .field = getter .getRawMember ();
231+ field .desc .valueType = getter .getType ();
232+ field .valueClass = getter .getType ().getErasedType ();
233+ return field ;
234+ }
235+
236+ @ Deprecated
122237 protected static StructFieldDeclaration fromGetter (Method getter ) {
123238 StructFieldDeclaration field = fromMember ((Member ) getter );
124239 field .desc .getter = getter ;
@@ -127,6 +242,15 @@ protected static StructFieldDeclaration fromGetter(Method getter) {
127242 return field ;
128243 }
129244
245+ protected static StructFieldDeclaration fromGetter (ResolvedMethod getter ) {
246+ StructFieldDeclaration field = fromMember ((ResolvedMember ) getter );
247+ field .desc .getter = getter .getRawMember ();
248+ field .desc .valueType = getter .getReturnType ();
249+ field .valueClass = getter .getReturnType ().getErasedType ();
250+ return field ;
251+ }
252+
253+ @ Deprecated
130254 private static StructFieldDeclaration fromMember (Member member ) {
131255 StructFieldDeclaration field = new StructFieldDeclaration ();
132256 field .declaringClass = member .getDeclaringClass ();
@@ -170,4 +294,47 @@ private static StructFieldDeclaration fromMember(Member member) {
170294 field .desc .isSizeT = isAnnotationPresent (org .bridj .ann .Ptr .class , getter );
171295 return field ;
172296 }
297+
298+ private static StructFieldDeclaration fromMember (ResolvedMember <?> member ) {
299+ StructFieldDeclaration field = new StructFieldDeclaration ();
300+ field .declaringClass = member .getRawMember ().getDeclaringClass ();
301+
302+ String name = member .getName ();
303+ if (name .matches ("get[A-Z].*" )) {
304+ name = Character .toLowerCase (name .charAt (3 )) + name .substring (4 );
305+ }
306+
307+ field .desc .name = name ;
308+
309+ Field fil = member .get (Field .class );
310+ Bits bits = member .get (Bits .class );
311+ Alignment alignment = member .get (Alignment .class );
312+ Array arr = member .get (Array .class );
313+ if (fil != null ) {
314+ field .index = fil .value ();
315+ //field.byteOffset = fil.offset();
316+ field .unionWith = fil .unionWith ();
317+ }
318+ if (field .unionWith < 0 && field .declaringClass .getAnnotation (Union .class ) != null ) {
319+ field .unionWith = 0 ;
320+ }
321+
322+ if (bits != null ) {
323+ field .desc .bitLength = bits .value ();
324+ }
325+ if (alignment != null ) {
326+ field .desc .alignment = alignment .value ();
327+ }
328+ if (arr != null ) {
329+ long length = 1 ;
330+ for (long dim : arr .value ()) {
331+ length *= dim ;
332+ }
333+ field .desc .arrayLength = length ;
334+ field .desc .isArray = true ;
335+ }
336+ field .desc .isCLong = member .get (org .bridj .ann .CLong .class ) != null ;
337+ field .desc .isSizeT = member .get (org .bridj .ann .Ptr .class ) != null ;
338+ return field ;
339+ }
173340}
0 commit comments