• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

raphw / byte-buddy / #801

27 Oct 2025 09:37AM UTC coverage: 84.715% (-0.4%) from 85.118%
#801

push

raphw
Fix imports.

29586 of 34924 relevant lines covered (84.72%)

0.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.72
/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/FieldLocator.java
1
/*
2
 * Copyright 2014 - Present Rafael Winterhalter
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package net.bytebuddy.dynamic.scaffold;
17

18
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
19
import net.bytebuddy.description.field.FieldDescription;
20
import net.bytebuddy.description.field.FieldList;
21
import net.bytebuddy.description.method.MethodDescription;
22
import net.bytebuddy.description.type.TypeDefinition;
23
import net.bytebuddy.description.type.TypeDescription;
24
import net.bytebuddy.matcher.ElementMatcher;
25

26
import static net.bytebuddy.matcher.ElementMatchers.fieldType;
27
import static net.bytebuddy.matcher.ElementMatchers.isGetter;
28
import static net.bytebuddy.matcher.ElementMatchers.isSetter;
29
import static net.bytebuddy.matcher.ElementMatchers.isVisibleTo;
30
import static net.bytebuddy.matcher.ElementMatchers.named;
31

32
/**
33
 * A field locator offers an interface for locating a field that is declared by a specified type.
34
 */
35
public interface FieldLocator {
36

37
    /**
38
     * Locates a field with the given name and throws an exception if no such type exists.
39
     *
40
     * @param name The name of the field to locate.
41
     * @return A resolution for a field lookup.
42
     */
43
    Resolution locate(String name);
44

45
    /**
46
     * Locates a field with the given name and type and throws an exception if no such type exists.
47
     *
48
     * @param name The name of the field to locate.
49
     * @param type The type fo the field to locate.
50
     * @return A resolution for a field lookup.
51
     */
52
    Resolution locate(String name, TypeDescription type);
53

54
    /**
55
     * A resolution for a field lookup.
56
     */
57
    interface Resolution {
58

59
        /**
60
         * Returns {@code true} if a field was located.
61
         *
62
         * @return {@code true} if a field was located.
63
         */
64
        boolean isResolved();
65

66
        /**
67
         * Returns the field description if a field was located. This method must only be called if
68
         * this resolution was actually resolved.
69
         *
70
         * @return The located field.
71
         */
72
        FieldDescription getField();
73

74
        /**
75
         * An illegal resolution.
76
         */
77
        enum Illegal implements Resolution {
1✔
78

79
            /**
80
             * The singleton instance.
81
             */
82
            INSTANCE;
1✔
83

84
            /**
85
             * {@inheritDoc}
86
             */
87
            public boolean isResolved() {
88
                return false;
1✔
89
            }
90

91
            /**
92
             * {@inheritDoc}
93
             */
94
            public FieldDescription getField() {
95
                throw new IllegalStateException("Could not locate field");
1✔
96
            }
97
        }
98

99
        /**
100
         * A simple implementation for a field resolution.
101
         */
102
        @HashCodeAndEqualsPlugin.Enhance
103
        class Simple implements Resolution {
104

105
            /**
106
             * A description of the located field.
107
             */
108
            private final FieldDescription fieldDescription;
109

110
            /**
111
             * Creates a new simple resolution for a field.
112
             *
113
             * @param fieldDescription A description of the located field.
114
             */
115
            protected Simple(FieldDescription fieldDescription) {
1✔
116
                this.fieldDescription = fieldDescription;
1✔
117
            }
1✔
118

119
            /**
120
             * Resolves a field locator for a potential accessor method. If the provided method is not a bean accessor,
121
             * an illegal resolution is returned.
122
             *
123
             * @param fieldLocator      The field locator to use.
124
             * @param methodDescription The method description that is the potential accessor.
125
             * @return A resolution for a field locator.
126
             */
127
            public static FieldLocator.Resolution ofBeanAccessor(FieldLocator fieldLocator, MethodDescription methodDescription) {
128
                String name;
129
                if (isSetter().matches(methodDescription)) {
1✔
130
                    name = methodDescription.getInternalName().substring(3);
1✔
131
                } else if (isGetter().matches(methodDescription)) {
1✔
132
                    name = methodDescription.getInternalName().substring(methodDescription.getInternalName().startsWith("is") ? 2 : 3);
1✔
133
                } else {
134
                    return FieldLocator.Resolution.Illegal.INSTANCE;
×
135
                }
136
                Resolution resolution = fieldLocator.locate(Character.toLowerCase(name.charAt(0)) + name.substring(1));
1✔
137
                return resolution.isResolved()
1✔
138
                        ? resolution
139
                        : fieldLocator.locate(Character.toUpperCase(name.charAt(0)) + name.substring(1));
×
140
            }
141

142
            /**
143
             * {@inheritDoc}
144
             */
145
            public boolean isResolved() {
146
                return true;
1✔
147
            }
148

149
            /**
150
             * {@inheritDoc}
151
             */
152
            public FieldDescription getField() {
153
                return fieldDescription;
1✔
154
            }
155
        }
156
    }
157

158
    /**
159
     * A factory for creating a {@link FieldLocator}.
160
     */
161
    interface Factory {
162

163
        /**
164
         * Creates a field locator for a given type.
165
         *
166
         * @param typeDescription The type for which to create a field locator.
167
         * @return A suitable field locator.
168
         */
169
        FieldLocator make(TypeDescription typeDescription);
170
    }
171

172
    /**
173
     * A field locator that never discovers a field.
174
     */
175
    enum NoOp implements FieldLocator, Factory {
1✔
176

177
        /**
178
         * The singleton instance.
179
         */
180
        INSTANCE;
1✔
181

182
        /**
183
         * {@inheritDoc}
184
         */
185
        public FieldLocator make(TypeDescription typeDescription) {
186
            return this;
1✔
187
        }
188

189
        /**
190
         * {@inheritDoc}
191
         */
192
        public Resolution locate(String name) {
193
            return Resolution.Illegal.INSTANCE;
1✔
194
        }
195

196
        /**
197
         * {@inheritDoc}
198
         */
199
        public Resolution locate(String name, TypeDescription type) {
200
            return Resolution.Illegal.INSTANCE;
1✔
201
        }
202
    }
203

204
    /**
205
     * An abstract base implementation of a field locator.
206
     */
207
    @HashCodeAndEqualsPlugin.Enhance
208
    abstract class AbstractBase implements FieldLocator {
209

210
        /**
211
         * The type accessing the field.
212
         */
213
        protected final TypeDescription accessingType;
214

215
        /**
216
         * Creates a new field locator.
217
         *
218
         * @param accessingType The type accessing the field.
219
         */
220
        protected AbstractBase(TypeDescription accessingType) {
1✔
221
            this.accessingType = accessingType;
1✔
222
        }
1✔
223

224
        /**
225
         * {@inheritDoc}
226
         */
227
        public Resolution locate(String name) {
228
            FieldList<?> candidates = locate(named(name).and(isVisibleTo(accessingType)));
1✔
229
            return candidates.size() == 1
1✔
230
                    ? new Resolution.Simple(candidates.getOnly())
1✔
231
                    : Resolution.Illegal.INSTANCE;
232
        }
233

234
        /**
235
         * {@inheritDoc}
236
         */
237
        public Resolution locate(String name, TypeDescription type) {
238
            FieldList<?> candidates = locate(named(name).and(fieldType(type)).and(isVisibleTo(accessingType)));
1✔
239
            return candidates.size() == 1
1✔
240
                    ? new Resolution.Simple(candidates.getOnly())
1✔
241
                    : Resolution.Illegal.INSTANCE;
242
        }
243

244
        /**
245
         * Locates fields that match the given matcher.
246
         *
247
         * @param matcher The matcher that identifies fields of interest.
248
         * @return A list of fields that match the specified matcher.
249
         */
250
        protected abstract FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher);
251
    }
252

253
    /**
254
     * A field locator that only looks up fields that are declared by a specific type.
255
     */
256
    @HashCodeAndEqualsPlugin.Enhance
257
    class ForExactType extends AbstractBase {
258

259
        /**
260
         * The type for which to look up fields.
261
         */
262
        private final TypeDescription typeDescription;
263

264
        /**
265
         * Creates a new field locator for locating fields from a declared type.
266
         *
267
         * @param typeDescription The type for which to look up fields that is also providing the accessing type.
268
         */
269
        public ForExactType(TypeDescription typeDescription) {
270
            this(typeDescription, typeDescription);
1✔
271
        }
1✔
272

273
        /**
274
         * Creates a new field locator for locating fields from a declared type.
275
         *
276
         * @param typeDescription The type for which to look up fields.
277
         * @param accessingType   The accessing type.
278
         */
279
        public ForExactType(TypeDescription typeDescription, TypeDescription accessingType) {
280
            super(accessingType);
1✔
281
            this.typeDescription = typeDescription;
1✔
282
        }
1✔
283

284
        @Override
285
        protected FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher) {
286
            return typeDescription.getDeclaredFields().filter(matcher);
1✔
287
        }
288

289
        /**
290
         * A factory for creating a {@link ForExactType}.
291
         */
292
        @HashCodeAndEqualsPlugin.Enhance
293
        public static class Factory implements FieldLocator.Factory {
294

295
            /**
296
             * The type for which to locate a field.
297
             */
298
            private final TypeDescription typeDescription;
299

300
            /**
301
             * Creates a new factory for a field locator that locates a field for an exact type.
302
             *
303
             * @param typeDescription The type for which to locate a field.
304
             */
305
            public Factory(TypeDescription typeDescription) {
1✔
306
                this.typeDescription = typeDescription;
1✔
307
            }
1✔
308

309
            /**
310
             * {@inheritDoc}
311
             */
312
            public FieldLocator make(TypeDescription typeDescription) {
313
                return new ForExactType(this.typeDescription, typeDescription);
1✔
314
            }
315
        }
316
    }
317

318
    /**
319
     * A field locator that looks up fields that are declared within a class's class hierarchy.
320
     */
321
    @HashCodeAndEqualsPlugin.Enhance
322
    class ForClassHierarchy extends AbstractBase {
323

324
        /**
325
         * The type for which to look up a field within its class hierarchy.
326
         */
327
        private final TypeDescription typeDescription;
328

329
        /**
330
         * Creates a field locator that looks up fields that are declared within a class's class hierarchy.
331
         *
332
         * @param typeDescription The type for which to look up a field within its class hierarchy which is also the accessing type.
333
         */
334
        public ForClassHierarchy(TypeDescription typeDescription) {
335
            this(typeDescription, typeDescription);
1✔
336
        }
1✔
337

338
        /**
339
         * Creates a field locator that looks up fields that are declared within a class's class hierarchy.
340
         *
341
         * @param typeDescription The type for which to look up a field within its class hierarchy.
342
         * @param accessingType   The accessing type.
343
         */
344
        public ForClassHierarchy(TypeDescription typeDescription, TypeDescription accessingType) {
345
            super(accessingType);
1✔
346
            this.typeDescription = typeDescription;
1✔
347
        }
1✔
348

349
        @Override
350
        protected FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher) {
351
            for (TypeDefinition typeDefinition : typeDescription) {
1✔
352
                FieldList<?> candidates = typeDefinition.getDeclaredFields().filter(matcher);
1✔
353
                if (!candidates.isEmpty()) {
1✔
354
                    return candidates;
1✔
355
                }
356
            }
1✔
357
            return new FieldList.Empty<FieldDescription>();
1✔
358
        }
359

360
        /**
361
         * A factory for creating a {@link ForClassHierarchy}.
362
         */
363
        public enum Factory implements FieldLocator.Factory {
1✔
364

365
            /**
366
             * The singleton instance.
367
             */
368
            INSTANCE;
1✔
369

370
            /**
371
             * {@inheritDoc}
372
             */
373
            public FieldLocator make(TypeDescription typeDescription) {
374
                return new ForClassHierarchy(typeDescription);
1✔
375
            }
376
        }
377
    }
378

379
    /**
380
     * A field locator that only locates fields in the top-level type.
381
     */
382
    class ForTopLevelType extends AbstractBase {
383

384
        /**
385
         * Creates a new type locator for a top-level type.
386
         *
387
         * @param typeDescription The type to access.
388
         */
389
        protected ForTopLevelType(TypeDescription typeDescription) {
390
            super(typeDescription);
1✔
391
        }
1✔
392

393
        @Override
394
        protected FieldList<?> locate(ElementMatcher<? super FieldDescription> matcher) {
395
            return accessingType.getDeclaredFields().filter(matcher);
1✔
396
        }
397

398
        /**
399
         * A factory for locating a field in a top-level type.
400
         */
401
        public enum Factory implements FieldLocator.Factory {
1✔
402

403
            /**
404
             * The singleton instance.
405
             */
406
            INSTANCE;
1✔
407

408
            /**
409
             * {@inheritDoc}
410
             */
411
            public FieldLocator make(TypeDescription typeDescription) {
412
                return new ForTopLevelType(typeDescription);
1✔
413
            }
414
        }
415
    }
416
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc