• 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

97.56
/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/inline/MethodRebaseResolver.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.inline;
17

18
import net.bytebuddy.ClassFileVersion;
19
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
20
import net.bytebuddy.description.annotation.AnnotationList;
21
import net.bytebuddy.description.annotation.AnnotationValue;
22
import net.bytebuddy.description.method.MethodDescription;
23
import net.bytebuddy.description.method.ParameterDescription;
24
import net.bytebuddy.description.method.ParameterList;
25
import net.bytebuddy.description.type.TypeDescription;
26
import net.bytebuddy.description.type.TypeList;
27
import net.bytebuddy.dynamic.DynamicType;
28
import net.bytebuddy.implementation.MethodAccessorFactory;
29
import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
30
import net.bytebuddy.implementation.auxiliary.TrivialType;
31
import net.bytebuddy.utility.CompoundList;
32
import net.bytebuddy.utility.nullability.AlwaysNull;
33
import org.objectweb.asm.Opcodes;
34

35
import javax.annotation.Nonnull;
36
import java.util.Collections;
37
import java.util.HashMap;
38
import java.util.List;
39
import java.util.Map;
40
import java.util.Set;
41

42
/**
43
 * A method rebase resolver is responsible for mapping methods of an instrumented type to an alternative signature.
44
 * This way a method can exist in two versions within a class:
45
 * <ol>
46
 * <li>The rebased method which represents the original implementation as it is present in a class file.</li>
47
 * <li>An overridden method which implements user code which is still able to invoke the original, rebased method.</li>
48
 * </ol>
49
 */
50
public interface MethodRebaseResolver {
51

52
    /**
53
     * Checks if a method is eligible for rebasing and resolves this possibly rebased method.
54
     *
55
     * @param methodDescription A description of the method to resolve.
56
     * @return A resolution for the given method.
57
     */
58
    Resolution resolve(MethodDescription.InDefinedShape methodDescription);
59

60
    /**
61
     * Returns a (potentially empty) list of auxiliary types that are required by this method rebase resolver.
62
     *
63
     * @return A list of auxiliary types that are required by this method rebase resolver.
64
     */
65
    List<DynamicType> getAuxiliaryTypes();
66

67
    /**
68
     * Returns a map of all rebasable methods' signature tokens to their resolution.
69
     *
70
     * @return A map of all rebasable methods' signature tokens to their resolution.
71
     */
72
    Map<MethodDescription.SignatureToken, Resolution> asTokenMap();
73

74
    /**
75
     * A method rebase resolver that preserves any method in its original form.
76
     */
77
    enum Disabled implements MethodRebaseResolver {
1✔
78

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

84
        /**
85
         * {@inheritDoc}
86
         */
87
        public Resolution resolve(MethodDescription.InDefinedShape methodDescription) {
88
            return new Resolution.Preserved(methodDescription);
1✔
89
        }
90

91
        /**
92
         * {@inheritDoc}
93
         */
94
        public List<DynamicType> getAuxiliaryTypes() {
95
            return Collections.emptyList();
1✔
96
        }
97

98
        /**
99
         * {@inheritDoc}
100
         */
101
        public Map<MethodDescription.SignatureToken, Resolution> asTokenMap() {
102
            return Collections.emptyMap();
1✔
103
        }
104

105
    }
106

107
    /**
108
     * A resolution for a method that was checked by a {@link MethodRebaseResolver}.
109
     */
110
    interface Resolution {
111

112
        /**
113
         * Checks if this resolution represents a rebased method.
114
         *
115
         * @return {@code true} if this resolution requires to rebase a method.
116
         */
117
        boolean isRebased();
118

119
        /**
120
         * Returns the resolved method if this resolution represents a rebased method or the original method.
121
         *
122
         * @return The resolved method if this resolution represents a rebased method or the original method.
123
         */
124
        MethodDescription.InDefinedShape getResolvedMethod();
125

126
        /**
127
         * A rebased method might require additional arguments in order to create a distinct signature.
128
         *
129
         * @return A list of parameters that were appended to the rebased method or constructor.
130
         */
131
        TypeList getAppendedParameters();
132

133
        /**
134
         * A {@link MethodRebaseResolver.Resolution} of a non-rebased method.
135
         */
136
        @HashCodeAndEqualsPlugin.Enhance
137
        class Preserved implements Resolution {
138

139
            /**
140
             * The preserved method.
141
             */
142
            private final MethodDescription.InDefinedShape methodDescription;
143

144
            /**
145
             * Creates a new {@link MethodRebaseResolver.Resolution} for
146
             * a non-rebased method.
147
             *
148
             * @param methodDescription The preserved method.
149
             */
150
            public Preserved(MethodDescription.InDefinedShape methodDescription) {
1✔
151
                this.methodDescription = methodDescription;
1✔
152
            }
1✔
153

154
            /**
155
             * {@inheritDoc}
156
             */
157
            public boolean isRebased() {
158
                return false;
1✔
159
            }
160

161
            /**
162
             * {@inheritDoc}
163
             */
164
            public MethodDescription.InDefinedShape getResolvedMethod() {
165
                return methodDescription;
1✔
166
            }
167

168
            /**
169
             * {@inheritDoc}
170
             */
171
            public TypeList getAppendedParameters() {
172
                throw new IllegalStateException("Cannot process additional parameters for non-rebased method: " + methodDescription);
1✔
173
            }
174
        }
175

176
        /**
177
         * A {@link MethodRebaseResolver.Resolution} of a rebased method.
178
         */
179
        @HashCodeAndEqualsPlugin.Enhance
180
        class ForRebasedMethod implements Resolution {
181

182
            /**
183
             * The rebased method.
184
             */
185
            private final MethodDescription.InDefinedShape methodDescription;
186

187
            /**
188
             * Creates a resolution for a rebased method.
189
             *
190
             * @param methodDescription The rebased method.
191
             */
192
            protected ForRebasedMethod(MethodDescription.InDefinedShape methodDescription) {
1✔
193
                this.methodDescription = methodDescription;
1✔
194
            }
1✔
195

196
            /**
197
             * Resolves a rebasement for the provided method.
198
             *
199
             * @param instrumentedType      The instrumented type.
200
             * @param methodDescription     The method to be rebased.
201
             * @param methodNameTransformer The transformer to use for renaming the method.
202
             * @return A resolution for rebasing the provided method.
203
             */
204
            public static Resolution of(TypeDescription instrumentedType,
205
                                        MethodDescription.InDefinedShape methodDescription,
206
                                        MethodNameTransformer methodNameTransformer) {
207
                return new ForRebasedMethod(new RebasedMethod(instrumentedType, methodDescription, methodNameTransformer));
1✔
208
            }
209

210
            /**
211
             * {@inheritDoc}
212
             */
213
            public boolean isRebased() {
214
                return true;
1✔
215
            }
216

217
            /**
218
             * {@inheritDoc}
219
             */
220
            public MethodDescription.InDefinedShape getResolvedMethod() {
221
                return methodDescription;
1✔
222
            }
223

224
            /**
225
             * {@inheritDoc}
226
             */
227
            public TypeList getAppendedParameters() {
228
                return new TypeList.Empty();
1✔
229
            }
230

231
            /**
232
             * A description of a rebased method.
233
             */
234
            protected static class RebasedMethod extends MethodDescription.InDefinedShape.AbstractBase {
235

236
                /**
237
                 * The instrumented type.
238
                 */
239
                private final TypeDescription instrumentedType;
240

241
                /**
242
                 * The method that is being rebased.
243
                 */
244
                private final InDefinedShape methodDescription;
245

246
                /**
247
                 * The transformer to use for renaming the method.
248
                 */
249
                private final MethodNameTransformer methodNameTransformer;
250

251
                /**
252
                 * Creates a new rebased method.
253
                 *
254
                 * @param instrumentedType      The instrumented type.
255
                 * @param methodDescription     The method that is being rebased.
256
                 * @param methodNameTransformer The transformer to use for renaming the method.
257
                 */
258
                protected RebasedMethod(TypeDescription instrumentedType, InDefinedShape methodDescription, MethodNameTransformer methodNameTransformer) {
1✔
259
                    this.instrumentedType = instrumentedType;
1✔
260
                    this.methodDescription = methodDescription;
1✔
261
                    this.methodNameTransformer = methodNameTransformer;
1✔
262
                }
1✔
263

264
                /**
265
                 * {@inheritDoc}
266
                 */
267
                public TypeDescription.Generic getReturnType() {
268
                    return methodDescription.getReturnType().asRawType();
1✔
269
                }
270

271
                /**
272
                 * {@inheritDoc}
273
                 */
274
                public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
275
                    return new ParameterList.Explicit.ForTypes(this, methodDescription.getParameters().asTypeList().asRawTypes());
1✔
276
                }
277

278
                /**
279
                 * {@inheritDoc}
280
                 */
281
                public TypeList.Generic getExceptionTypes() {
282
                    return methodDescription.getExceptionTypes().asRawTypes();
1✔
283
                }
284

285
                /**
286
                 * {@inheritDoc}
287
                 */
288
                @AlwaysNull
289
                public AnnotationValue<?, ?> getDefaultValue() {
290
                    return AnnotationValue.UNDEFINED;
×
291
                }
292

293
                /**
294
                 * {@inheritDoc}
295
                 */
296
                public TypeList.Generic getTypeVariables() {
297
                    return new TypeList.Generic.Empty();
1✔
298
                }
299

300
                /**
301
                 * {@inheritDoc}
302
                 */
303
                public AnnotationList getDeclaredAnnotations() {
304
                    return new AnnotationList.Empty();
1✔
305
                }
306

307
                /**
308
                 * {@inheritDoc}
309
                 */
310
                @Nonnull
311
                public TypeDescription getDeclaringType() {
312
                    return methodDescription.getDeclaringType();
1✔
313
                }
314

315
                /**
316
                 * {@inheritDoc}
317
                 */
318
                public int getModifiers() {
319
                    return Opcodes.ACC_SYNTHETIC
1✔
320
                            | (methodDescription.isStatic() ? Opcodes.ACC_STATIC : EMPTY_MASK)
1✔
321
                            | (methodDescription.isNative() ? Opcodes.ACC_NATIVE | Opcodes.ACC_FINAL : EMPTY_MASK)
1✔
322
                            | (instrumentedType.isInterface() && !methodDescription.isNative() ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE);
1✔
323
                }
324

325
                /**
326
                 * {@inheritDoc}
327
                 */
328
                public String getInternalName() {
329
                    return methodNameTransformer.transform(methodDescription);
1✔
330
                }
331
            }
332
        }
333

334
        /**
335
         * A {@link MethodRebaseResolver.Resolution} of a rebased constructor.
336
         */
337
        @HashCodeAndEqualsPlugin.Enhance
338
        class ForRebasedConstructor implements Resolution {
339

340
            /**
341
             * The rebased constructor.
342
             */
343
            private final MethodDescription.InDefinedShape methodDescription;
344

345
            /**
346
             * The placeholder type that is prepended to the constructor signature.
347
             */
348
            private final TypeDescription placeholderType;
349

350
            /**
351
             * Creates a new resolution for a rebased constructor.
352
             *
353
             * @param methodDescription The rebased constructor.
354
             * @param placeholderType   The placeholder type that is prepended to the constructor signature.
355
             */
356
            protected ForRebasedConstructor(MethodDescription.InDefinedShape methodDescription, TypeDescription placeholderType) {
1✔
357
                this.methodDescription = methodDescription;
1✔
358
                this.placeholderType = placeholderType;
1✔
359
            }
1✔
360

361
            /**
362
             * Resolves a constructor rebasement.
363
             *
364
             * @param methodDescription The constructor to rebase.
365
             * @param placeholderType   The placeholder type to use to distinguish the constructor's signature.
366
             * @return A resolution of the provided constructor.
367
             */
368
            public static Resolution of(MethodDescription.InDefinedShape methodDescription, TypeDescription placeholderType) {
369
                return new ForRebasedConstructor(new RebasedConstructor(methodDescription, placeholderType), placeholderType);
1✔
370
            }
371

372
            /**
373
             * {@inheritDoc}
374
             */
375
            public boolean isRebased() {
376
                return true;
1✔
377
            }
378

379
            /**
380
             * {@inheritDoc}
381
             */
382
            public MethodDescription.InDefinedShape getResolvedMethod() {
383
                return methodDescription;
1✔
384
            }
385

386
            /**
387
             * {@inheritDoc}
388
             */
389
            public TypeList getAppendedParameters() {
390
                return new TypeList.Explicit(placeholderType);
1✔
391
            }
392

393
            /**
394
             * An description of a rebased constructor.
395
             */
396
            protected static class RebasedConstructor extends MethodDescription.InDefinedShape.AbstractBase {
397

398
                /**
399
                 * The constructor that is rebased.
400
                 */
401
                private final InDefinedShape methodDescription;
402

403
                /**
404
                 * The placeholder type that is used to distinguish the constructor's signature.
405
                 */
406
                private final TypeDescription placeholderType;
407

408
                /**
409
                 * Creates a new rebased constructor.
410
                 *
411
                 * @param methodDescription The constructor that is rebased.
412
                 * @param placeholderType   The placeholder type that is used to distinguish the constructor's signature.
413
                 */
414
                protected RebasedConstructor(InDefinedShape methodDescription, TypeDescription placeholderType) {
1✔
415
                    this.methodDescription = methodDescription;
1✔
416
                    this.placeholderType = placeholderType;
1✔
417
                }
1✔
418

419
                /**
420
                 * {@inheritDoc}
421
                 */
422
                public TypeDescription.Generic getReturnType() {
423
                    return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(void.class);
1✔
424
                }
425

426
                /**
427
                 * {@inheritDoc}
428
                 */
429
                public ParameterList<ParameterDescription.InDefinedShape> getParameters() {
430
                    return new ParameterList.Explicit.ForTypes(this, CompoundList.of(methodDescription.getParameters().asTypeList().asErasures(), placeholderType));
1✔
431
                }
432

433
                /**
434
                 * {@inheritDoc}
435
                 */
436
                public TypeList.Generic getExceptionTypes() {
437
                    return methodDescription.getExceptionTypes().asRawTypes();
1✔
438
                }
439

440
                /**
441
                 * {@inheritDoc}
442
                 */
443
                @AlwaysNull
444
                public AnnotationValue<?, ?> getDefaultValue() {
445
                    return AnnotationValue.UNDEFINED;
×
446
                }
447

448
                /**
449
                 * {@inheritDoc}
450
                 */
451
                public TypeList.Generic getTypeVariables() {
452
                    return new TypeList.Generic.Empty();
1✔
453
                }
454

455
                /**
456
                 * {@inheritDoc}
457
                 */
458
                public AnnotationList getDeclaredAnnotations() {
459
                    return new AnnotationList.Empty();
1✔
460
                }
461

462
                /**
463
                 * {@inheritDoc}
464
                 */
465
                @Nonnull
466
                public TypeDescription getDeclaringType() {
467
                    return methodDescription.getDeclaringType();
1✔
468
                }
469

470
                /**
471
                 * {@inheritDoc}
472
                 */
473
                public int getModifiers() {
474
                    return Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PRIVATE;
1✔
475
                }
476

477
                /**
478
                 * {@inheritDoc}
479
                 */
480
                public String getInternalName() {
481
                    return MethodDescription.CONSTRUCTOR_INTERNAL_NAME;
1✔
482
                }
483
            }
484
        }
485
    }
486

487
    /**
488
     * A default implementation of a method rebase resolver.
489
     */
490
    @HashCodeAndEqualsPlugin.Enhance
491
    class Default implements MethodRebaseResolver {
492

493
        /**
494
         * A mapping of rebased methods to their existing resolutions.
495
         */
496
        private final Map<MethodDescription.InDefinedShape, Resolution> resolutions;
497

498
        /**
499
         * A list of dynamic types that need to be appended to the created type in order to allow for the rebasement.
500
         */
501
        private final List<DynamicType> dynamicTypes;
502

503
        /**
504
         * Creates a new default method rebased resolver.
505
         *
506
         * @param resolutions  A mapping of rebased methods to their existing resolutions.
507
         * @param dynamicTypes A list of dynamic types that need to be appended to the created type in order to allow for the rebasement.
508
         */
509
        protected Default(Map<MethodDescription.InDefinedShape, Resolution> resolutions, List<DynamicType> dynamicTypes) {
1✔
510
            this.resolutions = resolutions;
1✔
511
            this.dynamicTypes = dynamicTypes;
1✔
512
        }
1✔
513

514
        /**
515
         * Creates a new method rebase resolver.
516
         *
517
         * @param instrumentedType            The instrumented type.
518
         * @param rebaseables                 Tokens describing all methods that can possibly be rebased.
519
         * @param classFileVersion            The class file version for the instrumentation.
520
         * @param auxiliaryTypeNamingStrategy The naming strategy for naming a potential auxiliary type.
521
         * @param methodNameTransformer       A transformer for method names.
522
         * @return A method rebase resolver that is capable of rebasing any of the provided methods.
523
         */
524
        public static MethodRebaseResolver make(TypeDescription instrumentedType,
525
                                                Set<? extends MethodDescription.SignatureToken> rebaseables,
526
                                                ClassFileVersion classFileVersion,
527
                                                AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
528
                                                MethodNameTransformer methodNameTransformer) {
529
            DynamicType placeholderType = null;
1✔
530
            Map<MethodDescription.InDefinedShape, Resolution> resolutions = new HashMap<MethodDescription.InDefinedShape, Resolution>();
1✔
531
            for (MethodDescription.InDefinedShape instrumentedMethod : instrumentedType.getDeclaredMethods()) {
1✔
532
                if (rebaseables.contains(instrumentedMethod.asSignatureToken())) {
1✔
533
                    Resolution resolution;
534
                    if (instrumentedMethod.isConstructor()) {
1✔
535
                        if (placeholderType == null) {
1✔
536
                            placeholderType = TrivialType.SIGNATURE_RELEVANT.make(auxiliaryTypeNamingStrategy.name(instrumentedType, TrivialType.SIGNATURE_RELEVANT),
1✔
537
                                    classFileVersion,
538
                                    MethodAccessorFactory.Illegal.INSTANCE);
539
                        }
540
                        resolution = Resolution.ForRebasedConstructor.of(instrumentedMethod, placeholderType.getTypeDescription());
1✔
541
                    } else {
542
                        resolution = Resolution.ForRebasedMethod.of(instrumentedType, instrumentedMethod, methodNameTransformer);
1✔
543
                    }
544
                    resolutions.put(instrumentedMethod, resolution);
1✔
545
                }
546
            }
1✔
547
            return placeholderType == null
1✔
548
                    ? new Default(resolutions, Collections.<DynamicType>emptyList())
1✔
549
                    : new Default(resolutions, Collections.singletonList(placeholderType));
1✔
550
        }
551

552
        /**
553
         * {@inheritDoc}
554
         */
555
        public Resolution resolve(MethodDescription.InDefinedShape methodDescription) {
556
            Resolution resolution = resolutions.get(methodDescription);
1✔
557
            return resolution == null
1✔
558
                    ? new Resolution.Preserved(methodDescription)
559
                    : resolution;
560
        }
561

562
        /**
563
         * {@inheritDoc}
564
         */
565
        public List<DynamicType> getAuxiliaryTypes() {
566
            return dynamicTypes;
1✔
567
        }
568

569
        /**
570
         * {@inheritDoc}
571
         */
572
        public Map<MethodDescription.SignatureToken, Resolution> asTokenMap() {
573
            Map<MethodDescription.SignatureToken, Resolution> tokenMap = new HashMap<MethodDescription.SignatureToken, Resolution>();
1✔
574
            for (Map.Entry<MethodDescription.InDefinedShape, Resolution> entry : resolutions.entrySet()) {
1✔
575
                tokenMap.put(entry.getKey().asSignatureToken(), entry.getValue());
1✔
576
            }
1✔
577
            return tokenMap;
1✔
578
        }
579
    }
580
}
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