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

raphw / byte-buddy / #786

25 Jun 2025 09:08AM UTC coverage: 85.124% (-0.001%) from 85.125%
#786

push

raphw
Adjust formatting and naming.

6 of 6 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

29549 of 34713 relevant lines covered (85.12%)

0.85 hits per line

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

95.9
/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/InstrumentedType.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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19
import net.bytebuddy.ClassFileVersion;
20
import net.bytebuddy.description.annotation.AnnotationDescription;
21
import net.bytebuddy.description.annotation.AnnotationList;
22
import net.bytebuddy.description.annotation.AnnotationValue;
23
import net.bytebuddy.description.field.FieldDescription;
24
import net.bytebuddy.description.field.FieldList;
25
import net.bytebuddy.description.method.MethodDescription;
26
import net.bytebuddy.description.method.MethodList;
27
import net.bytebuddy.description.method.ParameterDescription;
28
import net.bytebuddy.description.modifier.ModifierContributor;
29
import net.bytebuddy.description.type.*;
30
import net.bytebuddy.dynamic.TargetType;
31
import net.bytebuddy.dynamic.Transformer;
32
import net.bytebuddy.implementation.LoadedTypeInitializer;
33
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
34
import net.bytebuddy.matcher.ElementMatcher;
35
import net.bytebuddy.utility.CompoundList;
36
import net.bytebuddy.utility.JavaType;
37
import net.bytebuddy.utility.nullability.MaybeNull;
38
import org.objectweb.asm.Opcodes;
39

40
import java.lang.annotation.ElementType;
41
import java.util.*;
42

43
import static net.bytebuddy.matcher.ElementMatchers.is;
44
import static net.bytebuddy.matcher.ElementMatchers.not;
45

46
/**
47
 * Implementations of this interface represent an instrumented type that is subject to change. Implementations
48
 * should however be immutable and return new instance when its builder methods are invoked.
49
 */
50
public interface InstrumentedType extends TypeDescription {
51

52
    /**
53
     * Creates a new instrumented type that includes a new field.
54
     *
55
     * @param token A token that represents the field's shape.
56
     * @return A new instrumented type that is equal to this instrumented type but with the additional field.
57
     */
58
    InstrumentedType withField(FieldDescription.Token token);
59

60
    /**
61
     * Creates a new instrumented type that includes a new field.
62
     *
63
     * @param token A token that represents the field's shape.
64
     * @param value The value that this assigned to this field.
65
     * @return A new instrumented type that is equal to this instrumented type but with the additional field.
66
     */
67
    InstrumentedType withAuxiliaryField(FieldDescription.Token token, Object value);
68

69
    /**
70
     * Creates a new instrumented type that includes a new method or constructor.
71
     *
72
     * @param token A token that represents the method's shape.
73
     * @return A new instrumented type that is equal to this instrumented type but with the additional method.
74
     */
75
    InstrumentedType withMethod(MethodDescription.Token token);
76

77
    /**
78
     * Creates a new instrumented type that includes a new record component.
79
     *
80
     * @param token A token that represents the record component's shape.
81
     * @return A new instrumented type that is equal to this instrumented type but with the additional record component.
82
     */
83
    InstrumentedType withRecordComponent(RecordComponentDescription.Token token);
84

85
    /**
86
     * Creates a new instrumented type with changed modifiers.
87
     *
88
     * @param modifiers The instrumented type's modifiers.
89
     * @return A new instrumented type that is equal to this instrumented type but with the given modifiers.
90
     */
91
    InstrumentedType withModifiers(int modifiers);
92

93
    /**
94
     * Creates a new instrumented type with the given interfaces implemented.
95
     *
96
     * @param interfaceTypes The interface types to implement.
97
     * @return A new instrumented type that is equal to this instrumented type but with the given interfaces implemented.
98
     */
99
    InstrumentedType withInterfaces(TypeList.Generic interfaceTypes);
100

101
    /**
102
     * Creates a new instrumented type with the given type variable defined.
103
     *
104
     * @param typeVariable The type variable to declare.
105
     * @return A new instrumented type that is equal to this instrumented type but with the given type variable declared.
106
     */
107
    InstrumentedType withTypeVariable(TypeVariableToken typeVariable);
108

109
    /**
110
     * Creates a new instrumented type with the given annotations.
111
     *
112
     * @param annotationDescriptions The annotations to add to the instrumented type.
113
     * @return A new instrumented type that is equal to this instrumented type but annotated with the given annotations
114
     */
115
    InstrumentedType withAnnotations(List<? extends AnnotationDescription> annotationDescriptions);
116

117
    /**
118
     * Creates a new instrumented type with the supplied nest host. An instrumented type can be its own nest host.
119
     * Setting a nest host removes all nest members from the instrumented type.
120
     *
121
     * @param nestHost The nest host of the created instrumented type.
122
     * @return A new instrumented type with the supplied type as its nest host.
123
     */
124
    InstrumentedType withNestHost(TypeDescription nestHost);
125

126
    /**
127
     * Creates a new instrumented types with the supplied nest members added to this instrumented type. The instrumented
128
     * type is defined as a nest host if this method is invoked. Any previous nest members are prepended to the supplied types.
129
     *
130
     * @param nestMembers The nest members to add to the created instrumented type.
131
     * @return A new instrumented type that applies the supplied nest members.
132
     */
133
    InstrumentedType withNestMembers(TypeList nestMembers);
134

135
    /**
136
     * Creates a new instrumented type with the supplied enclosing type.
137
     *
138
     * @param enclosingType The type to define as the created instrumented type's enclosing type.
139
     * @return A new instrumented type with the supplied type as its enclosing type.
140
     */
141
    InstrumentedType withEnclosingType(TypeDescription enclosingType);
142

143
    /**
144
     * Creates a new instrumented type with the supplied enclosing method.
145
     *
146
     * @param enclosingMethod The method to define as the created instrumented type's enclosing method.
147
     * @return A new instrumented type with the supplied method as its enclosing method.
148
     */
149
    InstrumentedType withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod);
150

151
    /**
152
     * Creates a new instrumented type that is declared by the supplied type.
153
     *
154
     * @param declaringType The type that declares the instrumented type or {@code null} if no such type exists.
155
     * @return A new instrumented type that is declared by the instrumented type.
156
     */
157
    InstrumentedType withDeclaringType(@MaybeNull TypeDescription declaringType);
158

159
    /**
160
     * Creates a new instrumented type that indicates that it declared the supplied types.
161
     *
162
     * @param declaredTypes The types to add to the created instrumented type as declared types.
163
     * @return A new instrumented type that indicates that it has declared the supplied types.
164
     */
165
    InstrumentedType withDeclaredTypes(TypeList declaredTypes);
166

167
    /**
168
     * Creates a new instrumented type that includes the supplied permitted subclasses or unseals the type.
169
     *
170
     * @param permittedSubclasses A list of permitted subclasses to include or {@code null} to unseal the type.
171
     * @return A new instrumented type that includes the supplied permitted subclasses or unseals the type.
172
     */
173
    InstrumentedType withPermittedSubclasses(@MaybeNull TypeList permittedSubclasses);
174

175
    /**
176
     * Creates a new instrumented type that indicates that is defined as a local class. Setting this property
177
     * resets the anonymous class property.
178
     *
179
     * @param localClass {@code true} if the instrumented type is supposed to be treated as a local class.
180
     * @return A new instrumented type that is treated as a local class.
181
     */
182
    InstrumentedType withLocalClass(boolean localClass);
183

184
    /**
185
     * Creates a new instrumented type that indicates that it is defined as an anonymous class. Setting this property
186
     * resets the local class property.
187
     *
188
     * @param anonymousClass {@code true} if the instrumented type is supposed to be treated as an anonymous class.
189
     * @return A new instrumented type that is treated as an anonymous class.
190
     */
191
    InstrumentedType withAnonymousClass(boolean anonymousClass);
192

193
    /**
194
     * Creates a new instrumented type that indicates that it defined as a record type. Setting this property to false
195
     * removes all record components.
196
     *
197
     * @param record {@code true} if the instrumented type is supposed to be a record.
198
     * @return A new instrumented type that is defined as a record.
199
     */
200
    InstrumentedType withRecord(boolean record);
201

202
    /**
203
     * Creates a new instrumented type that includes the given {@link net.bytebuddy.implementation.LoadedTypeInitializer}.
204
     *
205
     * @param loadedTypeInitializer The type initializer to include.
206
     * @return A new instrumented type that is equal to this instrumented type but with the additional type initializer.
207
     */
208
    InstrumentedType withInitializer(LoadedTypeInitializer loadedTypeInitializer);
209

210
    /**
211
     * Creates a new instrumented type that executes the given initializer in the instrumented type's
212
     * type initializer.
213
     *
214
     * @param byteCodeAppender The byte code to add to the type initializer.
215
     * @return A new instrumented type that is equal to this instrumented type but with the given stack manipulation
216
     * attached to its type initializer.
217
     */
218
    InstrumentedType withInitializer(ByteCodeAppender byteCodeAppender);
219

220
    /**
221
     * Returns the {@link net.bytebuddy.implementation.LoadedTypeInitializer}s that were registered
222
     * for this instrumented type.
223
     *
224
     * @return The registered loaded type initializers for this instrumented type.
225
     */
226
    LoadedTypeInitializer getLoadedTypeInitializer();
227

228
    /**
229
     * Returns this instrumented type's type initializer.
230
     *
231
     * @return This instrumented type's type initializer.
232
     */
233
    TypeInitializer getTypeInitializer();
234

235
    /**
236
     * Validates the instrumented type to define a legal Java type.
237
     *
238
     * @return This instrumented type as a non-modifiable type description.
239
     */
240
    TypeDescription validated();
241

242
    /**
243
     * Implementations represent an {@link InstrumentedType} with a flexible name.
244
     */
245
    interface WithFlexibleName extends InstrumentedType {
246

247
        /**
248
         * {@inheritDoc}
249
         */
250
        WithFlexibleName withField(FieldDescription.Token token);
251

252
        /**
253
         * {@inheritDoc}
254
         */
255
        WithFlexibleName withAuxiliaryField(FieldDescription.Token token, Object value);
256

257
        /**
258
         * {@inheritDoc}
259
         */
260
        WithFlexibleName withMethod(MethodDescription.Token token);
261

262
        /**
263
         * {@inheritDoc}
264
         */
265
        WithFlexibleName withRecordComponent(RecordComponentDescription.Token token);
266

267
        /**
268
         * {@inheritDoc}
269
         */
270
        WithFlexibleName withModifiers(int modifiers);
271

272
        /**
273
         * {@inheritDoc}
274
         */
275
        WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes);
276

277
        /**
278
         * {@inheritDoc}
279
         */
280
        WithFlexibleName withNestHost(TypeDescription nestHost);
281

282
        /**
283
         * {@inheritDoc}
284
         */
285
        WithFlexibleName withNestMembers(TypeList nestMembers);
286

287
        /**
288
         * {@inheritDoc}
289
         */
290
        WithFlexibleName withEnclosingType(@MaybeNull TypeDescription enclosingType);
291

292
        /**
293
         * {@inheritDoc}
294
         */
295
        WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod);
296

297
        /**
298
         * {@inheritDoc}
299
         */
300
        WithFlexibleName withDeclaringType(@MaybeNull TypeDescription declaringType);
301

302
        /**
303
         * {@inheritDoc}
304
         */
305
        WithFlexibleName withDeclaredTypes(TypeList declaredTypes);
306

307
        /**
308
         * {@inheritDoc}
309
         */
310
        WithFlexibleName withPermittedSubclasses(@MaybeNull TypeList permittedSubclasses);
311

312
        /**
313
         * {@inheritDoc}
314
         */
315
        WithFlexibleName withLocalClass(boolean localClass);
316

317
        /**
318
         * {@inheritDoc}
319
         */
320
        WithFlexibleName withAnonymousClass(boolean anonymousClass);
321

322
        /**
323
         * {@inheritDoc}
324
         */
325
        WithFlexibleName withRecord(boolean record);
326

327
        /**
328
         * {@inheritDoc}
329
         */
330
        WithFlexibleName withTypeVariable(TypeVariableToken typeVariable);
331

332
        /**
333
         * {@inheritDoc}
334
         */
335
        WithFlexibleName withAnnotations(List<? extends AnnotationDescription> annotationDescriptions);
336

337
        /**
338
         * {@inheritDoc}
339
         */
340
        WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer);
341

342
        /**
343
         * {@inheritDoc}
344
         */
345
        WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender);
346

347
        /**
348
         * Creates a new instrumented type with a changed name.
349
         *
350
         * @param name The name of the instrumented type.
351
         * @return A new instrumented type that has the given name.
352
         */
353
        WithFlexibleName withName(String name);
354

355
        /**
356
         * Applies a transformation onto all existing type variables of this instrumented type. A transformation is potentially unsafe
357
         * and it is the responsibility of the supplier to return a valid type variable token from the transformer.
358
         *
359
         * @param matcher     The matcher to decide what type variables to transform.
360
         * @param transformer The transformer to apply on all matched type variables.
361
         * @return A new instrumented type with all matched type variables transformed.
362
         */
363
        WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer);
364
    }
365

366
    /**
367
     * Implementations are able to prepare an {@link InstrumentedType}.
368
     */
369
    interface Prepareable {
370

371
        /**
372
         * Prepares a given instrumented type.
373
         *
374
         * @param instrumentedType The instrumented type in its current form.
375
         * @return The prepared instrumented type.
376
         */
377
        InstrumentedType prepare(InstrumentedType instrumentedType);
378

379
        /**
380
         * A prepareable that does not alter the instrumented type.
381
         */
382
        enum NoOp implements Prepareable {
1✔
383

384
            /**
385
             * The singleton instance.
386
             */
387
            INSTANCE;
1✔
388

389
            /**
390
             * {@inheritDoc}
391
             */
392
            public InstrumentedType prepare(InstrumentedType instrumentedType) {
393
                return instrumentedType;
1✔
394
            }
395
        }
396
    }
397

398
    /**
399
     * A factory for creating an {@link InstrumentedType}.
400
     */
401
    interface Factory {
402

403
        /**
404
         * Creates an instrumented type that represents the provided type.
405
         *
406
         * @param typeDescription The type to represent.
407
         * @return An appropriate instrumented type.
408
         */
409
        InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription);
410

411
        /**
412
         * Creates a new instrumented type as a subclass.
413
         *
414
         * @param name       The type's name.
415
         * @param modifiers  The type's modifiers.
416
         * @param superClass The type's super class.
417
         * @return A new instrumented type representing a subclass of the given parameters.
418
         */
419
        InstrumentedType.WithFlexibleName subclass(String name, int modifiers, TypeDescription.Generic superClass);
420

421
        /**
422
         * Default implementations of instrumented type factories.
423
         */
424
        enum Default implements Factory {
1✔
425

426
            /**
427
             * A factory for an instrumented type that allows to modify represented types.
428
             */
429
            MODIFIABLE {
1✔
430
                /** {@inheritDoc} */
431
                public InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription) {
432
                    return new InstrumentedType.Default(typeDescription.getName(),
1✔
433
                            typeDescription.getModifiers(),
1✔
434
                            typeDescription.getSuperClass(),
1✔
435
                            typeDescription.getTypeVariables().asTokenList(is(typeDescription)),
1✔
436
                            typeDescription.getInterfaces().accept(Generic.Visitor.Substitutor.ForDetachment.of(typeDescription)),
1✔
437
                            typeDescription.getDeclaredFields().asTokenList(is(typeDescription)),
1✔
438
                            Collections.<String, Object>emptyMap(),
1✔
439
                            typeDescription.getDeclaredMethods().asTokenList(is(typeDescription)),
1✔
440
                            typeDescription.getRecordComponents().asTokenList(is(typeDescription)),
1✔
441
                            typeDescription.getDeclaredAnnotations(),
1✔
442
                            TypeInitializer.None.INSTANCE,
443
                            LoadedTypeInitializer.NoOp.INSTANCE,
444
                            typeDescription.getDeclaringType(),
1✔
445
                            typeDescription.getEnclosingMethod(),
1✔
446
                            typeDescription.getEnclosingType(),
1✔
447
                            typeDescription.getDeclaredTypes(),
1✔
448
                            typeDescription.isSealed()
1✔
449
                                    ? typeDescription.getPermittedSubtypes()
1✔
450
                                    : TypeList.UNDEFINED,
451
                            typeDescription.isAnonymousType(),
1✔
452
                            typeDescription.isLocalType(),
1✔
453
                            typeDescription.isRecord(),
1✔
454
                            typeDescription.isNestHost()
1✔
455
                                    ? TargetType.DESCRIPTION
456
                                    : typeDescription.getNestHost(),
1✔
457
                            typeDescription.isNestHost()
1✔
458
                                    ? typeDescription.getNestMembers().filter(not(is(typeDescription)))
1✔
459
                                    : Collections.<TypeDescription>emptyList());
1✔
460
                }
461
            },
462

463
            /**
464
             * A factory for an instrumented type that does not allow to modify represented types.
465
             */
466
            FROZEN {
1✔
467
                /** {@inheritDoc} */
468
                public InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription) {
469
                    return new Frozen(typeDescription, LoadedTypeInitializer.NoOp.INSTANCE);
1✔
470
                }
471
            };
472

473
            /**
474
             * {@inheritDoc}
475
             */
476
            public InstrumentedType.WithFlexibleName subclass(String name, int modifiers, TypeDescription.Generic superClass) {
477
                return new InstrumentedType.Default(name,
1✔
478
                        modifiers,
479
                        superClass,
480
                        Collections.<TypeVariableToken>emptyList(),
1✔
481
                        Collections.<Generic>emptyList(),
1✔
482
                        Collections.<FieldDescription.Token>emptyList(),
1✔
483
                        Collections.<String, Object>emptyMap(),
1✔
484
                        Collections.<MethodDescription.Token>emptyList(),
1✔
485
                        Collections.<RecordComponentDescription.Token>emptyList(),
1✔
486
                        Collections.<AnnotationDescription>emptyList(),
1✔
487
                        TypeInitializer.None.INSTANCE,
488
                        LoadedTypeInitializer.NoOp.INSTANCE,
489
                        TypeDescription.UNDEFINED,
490
                        MethodDescription.UNDEFINED,
491
                        TypeDescription.UNDEFINED,
492
                        Collections.<TypeDescription>emptyList(),
1✔
493
                        TypeList.UNDEFINED,
494
                        false,
495
                        false,
496
                        false,
497
                        TargetType.DESCRIPTION,
498
                        Collections.<TypeDescription>emptyList());
1✔
499
            }
500
        }
501
    }
502

503
    /**
504
     * A default implementation of an instrumented type.
505
     */
506
    class Default extends AbstractBase.OfSimpleType implements InstrumentedType.WithFlexibleName {
507

508
        /**
509
         * A set containing all keywords of the Java programming language.
510
         */
511
        private static final Set<String> KEYWORDS = new HashSet<String>(Arrays.asList(
1✔
512
                "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean",
513
                "do", "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import",
514
                "public", "throws", "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int", "short",
515
                "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile",
516
                "const", "float", "native", "super", "while"
517
        ));
518

519
        /**
520
         * The binary name of the instrumented type.
521
         */
522
        private final String name;
523

524
        /**
525
         * The modifiers of the instrumented type.
526
         */
527
        private final int modifiers;
528

529
        /**
530
         * The generic super type of the instrumented type.
531
         */
532
        @MaybeNull
533
        private final Generic superClass;
534

535
        /**
536
         * The instrumented type's type variables in their tokenized form.
537
         */
538
        private final List<? extends TypeVariableToken> typeVariables;
539

540
        /**
541
         * A list of interfaces of the instrumented type.
542
         */
543
        private final List<? extends Generic> interfaceTypes;
544

545
        /**
546
         * A list of field tokens describing the fields of the instrumented type.
547
         */
548
        private final List<? extends FieldDescription.Token> fieldTokens;
549

550
        /**
551
         * A mapping of auxiliary field names to their mapped values.
552
         */
553
        private final Map<String, Object> auxiliaryFields;
554

555
        /**
556
         * A list of method tokens describing the methods of the instrumented type.
557
         */
558
        private final List<? extends MethodDescription.Token> methodTokens;
559

560
        /**
561
         * A list of record component tokens describing the record components of the instrumented type.
562
         */
563
        private final List<? extends RecordComponentDescription.Token> recordComponentTokens;
564

565
        /**
566
         * A list of annotations of the annotated type.
567
         */
568
        private final List<? extends AnnotationDescription> annotationDescriptions;
569

570
        /**
571
         * The type initializer of the instrumented type.
572
         */
573
        private final TypeInitializer typeInitializer;
574

575
        /**
576
         * The loaded type initializer of the instrumented type.
577
         */
578
        private final LoadedTypeInitializer loadedTypeInitializer;
579

580
        /**
581
         * The declaring type of the instrumented type or {@code null} if no such type exists.
582
         */
583
        @MaybeNull
584
        private final TypeDescription declaringType;
585

586
        /**
587
         * The enclosing method of the instrumented type or {@code null} if no such type exists.
588
         */
589
        @MaybeNull
590
        private final MethodDescription.InDefinedShape enclosingMethod;
591

592
        /**
593
         * The enclosing type of the instrumented type or {@code null} if no such type exists.
594
         */
595
        @MaybeNull
596
        private final TypeDescription enclosingType;
597

598
        /**
599
         * A list of types that are declared by this type.
600
         */
601
        private final List<? extends TypeDescription> declaredTypes;
602

603
        /**
604
         * A list of permitted subclasses or {@code null} if this type is not sealed.
605
         */
606
        @MaybeNull
607
        private final List<? extends TypeDescription> permittedSubclasses;
608

609
        /**
610
         * {@code true} if this type is an anonymous class.
611
         */
612
        private final boolean anonymousClass;
613

614
        /**
615
         * {@code true} if this type is a local class.
616
         */
617
        private final boolean localClass;
618

619
        /**
620
         * {@code true} if this class is a record class.
621
         */
622
        private final boolean record;
623

624
        /**
625
         * The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host.
626
         */
627
        private final TypeDescription nestHost;
628

629
        /**
630
         * A list of all members of this types nest group excluding this type.
631
         */
632
        private final List<? extends TypeDescription> nestMembers;
633

634
        /**
635
         * Creates a new instrumented type.
636
         *
637
         * @param name                   The binary name of the instrumented type.
638
         * @param modifiers              The modifiers of the instrumented type.
639
         * @param typeVariables          The instrumented type's type variables in their tokenized form.
640
         * @param superClass             The generic super type of the instrumented type.
641
         * @param interfaceTypes         A list of interfaces of the instrumented type.
642
         * @param fieldTokens            A list of field tokens describing the fields of the instrumented type.
643
         * @param auxiliaryFieldValues   A mapping of auxiliary field names to their mapped values.
644
         * @param methodTokens           A list of method tokens describing the methods of the instrumented type.
645
         * @param recordComponentTokens  A list of record component tokens describing the record components of the instrumented type.
646
         * @param annotationDescriptions A list of annotations of the annotated type.
647
         * @param typeInitializer        The type initializer of the instrumented type.
648
         * @param loadedTypeInitializer  The loaded type initializer of the instrumented type.
649
         * @param declaringType          The declaring type of the instrumented type or {@code null} if no such type exists.
650
         * @param enclosingMethod        The enclosing method of the instrumented type or {@code null} if no such type exists.
651
         * @param enclosingType          The enclosing type of the instrumented type or {@code null} if no such type exists.
652
         * @param declaredTypes          A list of types that are declared by this type.
653
         * @param permittedSubclasses    A list of permitted subclasses or {@code null} if this type is not sealed.
654
         * @param anonymousClass         {@code true} if this type is an anonymous class.
655
         * @param localClass             {@code true} if this type is a local class.
656
         * @param record                 {@code true} if this type is a record class.
657
         * @param nestHost               The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host.
658
         * @param nestMembers            A list of all members of this types nest group excluding this type.
659
         */
660
        protected Default(String name,
661
                          int modifiers,
662
                          @MaybeNull Generic superClass,
663
                          List<? extends TypeVariableToken> typeVariables,
664
                          List<? extends Generic> interfaceTypes,
665
                          List<? extends FieldDescription.Token> fieldTokens,
666
                          Map<String, Object> auxiliaryFieldValues,
667
                          List<? extends MethodDescription.Token> methodTokens,
668
                          List<? extends RecordComponentDescription.Token> recordComponentTokens,
669
                          List<? extends AnnotationDescription> annotationDescriptions,
670
                          TypeInitializer typeInitializer,
671
                          LoadedTypeInitializer loadedTypeInitializer,
672
                          @MaybeNull TypeDescription declaringType,
673
                          @MaybeNull MethodDescription.InDefinedShape enclosingMethod,
674
                          @MaybeNull TypeDescription enclosingType,
675
                          List<? extends TypeDescription> declaredTypes,
676
                          @MaybeNull List<? extends TypeDescription> permittedSubclasses,
677
                          boolean anonymousClass,
678
                          boolean localClass,
679
                          boolean record,
680
                          TypeDescription nestHost,
681
                          List<? extends TypeDescription> nestMembers) {
1✔
682
            this.name = name;
1✔
683
            this.modifiers = modifiers;
1✔
684
            this.typeVariables = typeVariables;
1✔
685
            this.superClass = superClass;
1✔
686
            this.interfaceTypes = interfaceTypes;
1✔
687
            this.fieldTokens = fieldTokens;
1✔
688
            this.auxiliaryFields = auxiliaryFieldValues;
1✔
689
            this.methodTokens = methodTokens;
1✔
690
            this.recordComponentTokens = recordComponentTokens;
1✔
691
            this.annotationDescriptions = annotationDescriptions;
1✔
692
            this.typeInitializer = typeInitializer;
1✔
693
            this.loadedTypeInitializer = loadedTypeInitializer;
1✔
694
            this.declaringType = declaringType;
1✔
695
            this.enclosingMethod = enclosingMethod;
1✔
696
            this.enclosingType = enclosingType;
1✔
697
            this.declaredTypes = declaredTypes;
1✔
698
            this.permittedSubclasses = permittedSubclasses;
1✔
699
            this.anonymousClass = anonymousClass;
1✔
700
            this.localClass = localClass;
1✔
701
            this.record = record;
1✔
702
            this.nestHost = nestHost;
1✔
703
            this.nestMembers = nestMembers;
1✔
704
        }
1✔
705

706
        /**
707
         * Creates a new instrumented type.
708
         *
709
         * @param name                The type's name.
710
         * @param superClass          The type's super class.
711
         * @param modifierContributor The type's modifiers.
712
         * @return An appropriate instrumented type.
713
         */
714
        public static InstrumentedType of(String name, TypeDescription.Generic superClass, ModifierContributor.ForType... modifierContributor) {
715
            return of(name, superClass, ModifierContributor.Resolver.of(modifierContributor).resolve());
1✔
716
        }
717

718
        /**
719
         * Creates a new instrumented type.
720
         *
721
         * @param name       The type's name.
722
         * @param superClass The type's super class.
723
         * @param modifiers  The type's modifiers.
724
         * @return An appropriate instrumented type.
725
         */
726
        public static InstrumentedType of(String name, TypeDescription.Generic superClass, int modifiers) {
727
            return Factory.Default.MODIFIABLE.subclass(name, modifiers, superClass);
1✔
728
        }
729

730
        /**
731
         * {@inheritDoc}
732
         */
733
        public WithFlexibleName withModifiers(int modifiers) {
734
            return new Default(name,
1✔
735
                    modifiers,
736
                    superClass,
737
                    typeVariables,
738
                    interfaceTypes,
739
                    fieldTokens,
740
                    auxiliaryFields,
741
                    methodTokens,
742
                    recordComponentTokens,
743
                    annotationDescriptions,
744
                    typeInitializer,
745
                    loadedTypeInitializer,
746
                    declaringType,
747
                    enclosingMethod,
748
                    enclosingType,
749
                    declaredTypes,
750
                    permittedSubclasses,
751
                    anonymousClass,
752
                    localClass,
753
                    record,
754
                    nestHost,
755
                    nestMembers);
756
        }
757

758
        /**
759
         * {@inheritDoc}
760
         */
761
        public WithFlexibleName withField(FieldDescription.Token token) {
762
            return new Default(name,
1✔
763
                    modifiers,
764
                    superClass,
765
                    typeVariables,
766
                    interfaceTypes,
767
                    CompoundList.of(fieldTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
1✔
768
                    auxiliaryFields,
769
                    methodTokens,
770
                    recordComponentTokens,
771
                    annotationDescriptions,
772
                    typeInitializer,
773
                    loadedTypeInitializer,
774
                    declaringType,
775
                    enclosingMethod,
776
                    enclosingType,
777
                    declaredTypes,
778
                    permittedSubclasses,
779
                    anonymousClass,
780
                    localClass,
781
                    record,
782
                    nestHost,
783
                    nestMembers);
784
        }
785

786
        /**
787
         * {@inheritDoc}
788
         */
789
        public WithFlexibleName withAuxiliaryField(FieldDescription.Token token, Object value) {
790
            Map<String, Object> auxiliaryFields = new HashMap<String, Object>(this.auxiliaryFields);
1✔
791
            Object previous = auxiliaryFields.put(token.getName(), value);
1✔
792
            if (previous != null) {
1✔
793
                if (previous == value) {
1✔
794
                    return this;
1✔
795
                } else {
796
                    throw new IllegalStateException("Field " + token.getName()
1✔
797
                            + " for " + this
798
                            + " already mapped to " + previous
799
                            + " and not " + value);
800
                }
801
            }
802
            return new Default(name,
1✔
803
                    modifiers,
804
                    superClass,
805
                    typeVariables,
806
                    interfaceTypes,
807
                    CompoundList.of(fieldTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
1✔
808
                    auxiliaryFields,
809
                    methodTokens,
810
                    recordComponentTokens,
811
                    annotationDescriptions,
812
                    typeInitializer,
813
                    new LoadedTypeInitializer.Compound(loadedTypeInitializer, new LoadedTypeInitializer.ForStaticField(token.getName(), value)),
1✔
814
                    declaringType,
815
                    enclosingMethod,
816
                    enclosingType,
817
                    declaredTypes,
818
                    permittedSubclasses,
819
                    anonymousClass,
820
                    localClass,
821
                    record,
822
                    nestHost,
823
                    nestMembers);
824
        }
825

826
        /**
827
         * {@inheritDoc}
828
         */
829
        public WithFlexibleName withMethod(MethodDescription.Token token) {
830
            return new Default(name,
1✔
831
                    modifiers,
832
                    superClass,
833
                    typeVariables,
834
                    interfaceTypes,
835
                    fieldTokens,
836
                    auxiliaryFields,
837
                    CompoundList.of(methodTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
1✔
838
                    recordComponentTokens,
839
                    annotationDescriptions,
840
                    typeInitializer,
841
                    loadedTypeInitializer,
842
                    declaringType,
843
                    enclosingMethod,
844
                    enclosingType,
845
                    declaredTypes,
846
                    permittedSubclasses,
847
                    anonymousClass,
848
                    localClass,
849
                    record,
850
                    nestHost,
851
                    nestMembers);
852
        }
853

854
        /**
855
         * {@inheritDoc}
856
         */
857
        public WithFlexibleName withRecordComponent(RecordComponentDescription.Token token) {
858
            return new Default(name,
1✔
859
                    modifiers,
860
                    superClass,
861
                    typeVariables,
862
                    interfaceTypes,
863
                    fieldTokens,
864
                    auxiliaryFields,
865
                    methodTokens,
866
                    CompoundList.of(recordComponentTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
1✔
867
                    annotationDescriptions,
868
                    typeInitializer,
869
                    loadedTypeInitializer,
870
                    declaringType,
871
                    enclosingMethod,
872
                    enclosingType,
873
                    declaredTypes,
874
                    permittedSubclasses,
875
                    anonymousClass,
876
                    localClass,
877
                    true,
878
                    nestHost,
879
                    nestMembers);
880
        }
881

882
        /**
883
         * {@inheritDoc}
884
         */
885
        public WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes) {
886
            return new Default(name,
1✔
887
                    modifiers,
888
                    superClass,
889
                    typeVariables,
890
                    CompoundList.of(this.interfaceTypes, interfaceTypes.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
1✔
891
                    fieldTokens,
892
                    auxiliaryFields,
893
                    methodTokens,
894
                    recordComponentTokens,
895
                    annotationDescriptions,
896
                    typeInitializer,
897
                    loadedTypeInitializer,
898
                    declaringType,
899
                    enclosingMethod,
900
                    enclosingType,
901
                    declaredTypes,
902
                    permittedSubclasses,
903
                    anonymousClass,
904
                    localClass,
905
                    record,
906
                    nestHost,
907
                    nestMembers);
908
        }
909

910
        /**
911
         * {@inheritDoc}
912
         */
913
        public WithFlexibleName withAnnotations(List<? extends AnnotationDescription> annotationDescriptions) {
914
            return new Default(name,
1✔
915
                    modifiers,
916
                    superClass,
917
                    typeVariables,
918
                    interfaceTypes,
919
                    fieldTokens,
920
                    auxiliaryFields,
921
                    methodTokens,
922
                    recordComponentTokens,
923
                    CompoundList.of(this.annotationDescriptions, annotationDescriptions),
1✔
924
                    typeInitializer,
925
                    loadedTypeInitializer,
926
                    declaringType,
927
                    enclosingMethod,
928
                    enclosingType,
929
                    declaredTypes,
930
                    permittedSubclasses,
931
                    anonymousClass,
932
                    localClass,
933
                    record,
934
                    nestHost,
935
                    nestMembers);
936
        }
937

938
        /**
939
         * {@inheritDoc}
940
         */
941
        public WithFlexibleName withNestHost(TypeDescription nestHost) {
942
            return new Default(name,
1✔
943
                    modifiers,
944
                    superClass,
945
                    typeVariables,
946
                    interfaceTypes,
947
                    fieldTokens,
948
                    auxiliaryFields,
949
                    methodTokens,
950
                    recordComponentTokens,
951
                    annotationDescriptions,
952
                    typeInitializer,
953
                    loadedTypeInitializer,
954
                    declaringType,
955
                    enclosingMethod,
956
                    enclosingType,
957
                    declaredTypes,
958
                    permittedSubclasses,
959
                    anonymousClass,
960
                    localClass,
961
                    record,
962
                    nestHost.equals(this)
1✔
963
                            ? TargetType.DESCRIPTION
964
                            : nestHost,
965
                    Collections.<TypeDescription>emptyList());
1✔
966
        }
967

968
        /**
969
         * {@inheritDoc}
970
         */
971
        public WithFlexibleName withNestMembers(TypeList nestMembers) {
972
            return new Default(name,
1✔
973
                    modifiers,
974
                    superClass,
975
                    typeVariables,
976
                    interfaceTypes,
977
                    fieldTokens,
978
                    auxiliaryFields,
979
                    methodTokens,
980
                    recordComponentTokens,
981
                    annotationDescriptions,
982
                    typeInitializer,
983
                    loadedTypeInitializer,
984
                    declaringType,
985
                    enclosingMethod,
986
                    enclosingType,
987
                    declaredTypes,
988
                    permittedSubclasses,
989
                    anonymousClass,
990
                    localClass,
991
                    record,
992
                    TargetType.DESCRIPTION,
993
                    CompoundList.of(this.nestMembers, nestMembers));
1✔
994
        }
995

996
        /**
997
         * {@inheritDoc}
998
         */
999
        public WithFlexibleName withEnclosingType(@MaybeNull TypeDescription enclosingType) {
1000
            return new Default(name,
1✔
1001
                    modifiers,
1002
                    superClass,
1003
                    typeVariables,
1004
                    interfaceTypes,
1005
                    fieldTokens,
1006
                    auxiliaryFields,
1007
                    methodTokens,
1008
                    recordComponentTokens,
1009
                    annotationDescriptions,
1010
                    typeInitializer,
1011
                    loadedTypeInitializer,
1012
                    declaringType,
1013
                    MethodDescription.UNDEFINED,
1014
                    enclosingType,
1015
                    declaredTypes,
1016
                    permittedSubclasses,
1017
                    anonymousClass,
1018
                    localClass,
1019
                    record,
1020
                    nestHost,
1021
                    nestMembers);
1022
        }
1023

1024
        /**
1025
         * {@inheritDoc}
1026
         */
1027
        public WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod) {
1028
            return new Default(name,
1✔
1029
                    modifiers,
1030
                    superClass,
1031
                    typeVariables,
1032
                    interfaceTypes,
1033
                    fieldTokens,
1034
                    auxiliaryFields,
1035
                    methodTokens,
1036
                    recordComponentTokens,
1037
                    annotationDescriptions,
1038
                    typeInitializer,
1039
                    loadedTypeInitializer,
1040
                    declaringType,
1041
                    enclosingMethod,
1042
                    enclosingMethod.getDeclaringType(),
1✔
1043
                    declaredTypes,
1044
                    permittedSubclasses,
1045
                    anonymousClass,
1046
                    localClass,
1047
                    record,
1048
                    nestHost,
1049
                    nestMembers);
1050
        }
1051

1052
        /**
1053
         * {@inheritDoc}
1054
         */
1055
        public WithFlexibleName withDeclaringType(@MaybeNull TypeDescription declaringType) {
1056
            return new Default(name,
1✔
1057
                    modifiers,
1058
                    superClass,
1059
                    typeVariables,
1060
                    interfaceTypes,
1061
                    fieldTokens,
1062
                    auxiliaryFields,
1063
                    methodTokens,
1064
                    recordComponentTokens,
1065
                    annotationDescriptions,
1066
                    typeInitializer,
1067
                    loadedTypeInitializer,
1068
                    declaringType,
1069
                    enclosingMethod,
1070
                    enclosingType,
1071
                    declaredTypes,
1072
                    permittedSubclasses,
1073
                    anonymousClass,
1074
                    localClass,
1075
                    record,
1076
                    nestHost,
1077
                    nestMembers);
1078
        }
1079

1080
        /**
1081
         * {@inheritDoc}
1082
         */
1083
        public WithFlexibleName withDeclaredTypes(TypeList declaredTypes) {
1084
            return new Default(name,
1✔
1085
                    modifiers,
1086
                    superClass,
1087
                    typeVariables,
1088
                    interfaceTypes,
1089
                    fieldTokens,
1090
                    auxiliaryFields,
1091
                    methodTokens,
1092
                    recordComponentTokens,
1093
                    annotationDescriptions,
1094
                    typeInitializer,
1095
                    loadedTypeInitializer,
1096
                    declaringType,
1097
                    enclosingMethod,
1098
                    enclosingType,
1099
                    CompoundList.of(this.declaredTypes, declaredTypes),
1✔
1100
                    permittedSubclasses,
1101
                    anonymousClass,
1102
                    localClass,
1103
                    record,
1104
                    nestHost,
1105
                    nestMembers);
1106
        }
1107

1108
        /**
1109
         * {@inheritDoc}
1110
         */
1111
        public WithFlexibleName withPermittedSubclasses(@MaybeNull TypeList permittedSubclasses) {
1112
            return new Default(name,
1✔
1113
                    modifiers,
1114
                    superClass,
1115
                    typeVariables,
1116
                    interfaceTypes,
1117
                    fieldTokens,
1118
                    auxiliaryFields,
1119
                    methodTokens,
1120
                    recordComponentTokens,
1121
                    annotationDescriptions,
1122
                    typeInitializer,
1123
                    loadedTypeInitializer,
1124
                    declaringType,
1125
                    enclosingMethod,
1126
                    enclosingType,
1127
                    declaredTypes,
1128
                    permittedSubclasses == null || this.permittedSubclasses == null
1129
                            ? permittedSubclasses
1130
                            : CompoundList.of(this.permittedSubclasses, permittedSubclasses),
1✔
1131
                    anonymousClass,
1132
                    localClass,
1133
                    record,
1134
                    nestHost,
1135
                    nestMembers);
1136
        }
1137

1138
        /**
1139
         * {@inheritDoc}
1140
         */
1141
        public WithFlexibleName withTypeVariable(TypeVariableToken typeVariable) {
1142
            return new Default(name,
1✔
1143
                    modifiers,
1144
                    superClass,
1145
                    CompoundList.of(typeVariables, typeVariable.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
1✔
1146
                    interfaceTypes,
1147
                    fieldTokens,
1148
                    auxiliaryFields,
1149
                    methodTokens,
1150
                    recordComponentTokens,
1151
                    annotationDescriptions,
1152
                    typeInitializer,
1153
                    loadedTypeInitializer,
1154
                    declaringType,
1155
                    enclosingMethod,
1156
                    enclosingType,
1157
                    declaredTypes,
1158
                    permittedSubclasses,
1159
                    anonymousClass,
1160
                    localClass,
1161
                    record,
1162
                    nestHost,
1163
                    nestMembers);
1164
        }
1165

1166
        /**
1167
         * {@inheritDoc}
1168
         */
1169
        public WithFlexibleName withName(String name) {
1170
            return new Default(name,
1✔
1171
                    modifiers,
1172
                    superClass,
1173
                    typeVariables,
1174
                    interfaceTypes,
1175
                    fieldTokens,
1176
                    auxiliaryFields,
1177
                    methodTokens,
1178
                    recordComponentTokens,
1179
                    annotationDescriptions,
1180
                    typeInitializer,
1181
                    loadedTypeInitializer,
1182
                    declaringType,
1183
                    enclosingMethod,
1184
                    enclosingType,
1185
                    declaredTypes,
1186
                    permittedSubclasses,
1187
                    anonymousClass,
1188
                    localClass,
1189
                    record,
1190
                    nestHost,
1191
                    nestMembers);
1192
        }
1193

1194
        /**
1195
         * {@inheritDoc}
1196
         */
1197
        public WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer) {
1198
            List<TypeVariableToken> typeVariables = new ArrayList<TypeVariableToken>(this.typeVariables.size());
1✔
1199
            int index = 0;
1✔
1200
            for (TypeVariableToken typeVariableToken : this.typeVariables) {
1✔
1201
                typeVariables.add(matcher.matches(getTypeVariables().get(index++))
1✔
1202
                        ? transformer.transform(this, typeVariableToken)
1✔
1203
                        : typeVariableToken);
1204
            }
1✔
1205
            return new Default(name,
1✔
1206
                    modifiers,
1207
                    superClass,
1208
                    typeVariables,
1209
                    interfaceTypes,
1210
                    fieldTokens,
1211
                    auxiliaryFields,
1212
                    methodTokens,
1213
                    recordComponentTokens,
1214
                    annotationDescriptions,
1215
                    typeInitializer,
1216
                    loadedTypeInitializer,
1217
                    declaringType,
1218
                    enclosingMethod,
1219
                    enclosingType,
1220
                    declaredTypes,
1221
                    permittedSubclasses,
1222
                    anonymousClass,
1223
                    localClass,
1224
                    record,
1225
                    nestHost,
1226
                    nestMembers);
1227
        }
1228

1229
        /**
1230
         * {@inheritDoc}
1231
         */
1232
        public WithFlexibleName withLocalClass(boolean localClass) {
1233
            return new Default(name,
1✔
1234
                    modifiers,
1235
                    superClass,
1236
                    typeVariables,
1237
                    interfaceTypes,
1238
                    fieldTokens,
1239
                    auxiliaryFields,
1240
                    methodTokens,
1241
                    recordComponentTokens,
1242
                    annotationDescriptions,
1243
                    typeInitializer,
1244
                    loadedTypeInitializer,
1245
                    declaringType,
1246
                    enclosingMethod,
1247
                    enclosingType,
1248
                    declaredTypes,
1249
                    permittedSubclasses,
1250
                    false,
1251
                    localClass,
1252
                    record,
1253
                    nestHost,
1254
                    nestMembers);
1255
        }
1256

1257
        /**
1258
         * {@inheritDoc}
1259
         */
1260
        public WithFlexibleName withAnonymousClass(boolean anonymousClass) {
1261
            return new Default(name,
1✔
1262
                    modifiers,
1263
                    superClass,
1264
                    typeVariables,
1265
                    interfaceTypes,
1266
                    fieldTokens,
1267
                    auxiliaryFields,
1268
                    methodTokens,
1269
                    recordComponentTokens,
1270
                    annotationDescriptions,
1271
                    typeInitializer,
1272
                    loadedTypeInitializer,
1273
                    declaringType,
1274
                    enclosingMethod,
1275
                    enclosingType,
1276
                    declaredTypes,
1277
                    permittedSubclasses,
1278
                    anonymousClass,
1279
                    false,
1280
                    record,
1281
                    nestHost,
1282
                    nestMembers);
1283
        }
1284

1285
        /**
1286
         * {@inheritDoc}
1287
         */
1288
        public WithFlexibleName withRecord(boolean record) {
1289
            return new Default(name,
1✔
1290
                    modifiers,
1291
                    superClass,
1292
                    typeVariables,
1293
                    interfaceTypes,
1294
                    fieldTokens,
1295
                    auxiliaryFields,
1296
                    methodTokens,
1297
                    record
1298
                            ? recordComponentTokens
1299
                            : Collections.<RecordComponentDescription.Token>emptyList(),
1✔
1300
                    annotationDescriptions,
1301
                    typeInitializer,
1302
                    loadedTypeInitializer,
1303
                    declaringType,
1304
                    enclosingMethod,
1305
                    enclosingType,
1306
                    declaredTypes,
1307
                    permittedSubclasses,
1308
                    anonymousClass,
1309
                    localClass,
1310
                    record,
1311
                    nestHost,
1312
                    nestMembers);
1313
        }
1314

1315
        /**
1316
         * {@inheritDoc}
1317
         */
1318
        public WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer) {
1319
            return new Default(name,
1✔
1320
                    modifiers,
1321
                    superClass,
1322
                    typeVariables,
1323
                    interfaceTypes,
1324
                    fieldTokens,
1325
                    auxiliaryFields,
1326
                    methodTokens,
1327
                    recordComponentTokens,
1328
                    annotationDescriptions,
1329
                    typeInitializer,
1330
                    new LoadedTypeInitializer.Compound(this.loadedTypeInitializer, loadedTypeInitializer),
1331
                    declaringType,
1332
                    enclosingMethod,
1333
                    enclosingType,
1334
                    declaredTypes,
1335
                    permittedSubclasses,
1336
                    anonymousClass,
1337
                    localClass,
1338
                    record,
1339
                    nestHost,
1340
                    nestMembers);
1341
        }
1342

1343
        /**
1344
         * {@inheritDoc}
1345
         */
1346
        public WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender) {
1347
            return new Default(name,
1✔
1348
                    modifiers,
1349
                    superClass,
1350
                    typeVariables,
1351
                    interfaceTypes,
1352
                    fieldTokens,
1353
                    auxiliaryFields,
1354
                    methodTokens,
1355
                    recordComponentTokens,
1356
                    annotationDescriptions,
1357
                    typeInitializer.expandWith(byteCodeAppender),
1✔
1358
                    loadedTypeInitializer,
1359
                    declaringType,
1360
                    enclosingMethod,
1361
                    enclosingType,
1362
                    declaredTypes,
1363
                    permittedSubclasses,
1364
                    anonymousClass,
1365
                    localClass,
1366
                    record,
1367
                    nestHost,
1368
                    nestMembers);
1369
        }
1370

1371
        /**
1372
         * {@inheritDoc}
1373
         */
1374
        public LoadedTypeInitializer getLoadedTypeInitializer() {
1375
            return loadedTypeInitializer;
1✔
1376
        }
1377

1378
        /**
1379
         * {@inheritDoc}
1380
         */
1381
        public TypeInitializer getTypeInitializer() {
1382
            return typeInitializer;
1✔
1383
        }
1384

1385
        /**
1386
         * {@inheritDoc}
1387
         */
1388
        @MaybeNull
1389
        public MethodDescription.InDefinedShape getEnclosingMethod() {
1390
            return enclosingMethod;
1✔
1391
        }
1392

1393
        /**
1394
         * {@inheritDoc}
1395
         */
1396
        @MaybeNull
1397
        public TypeDescription getEnclosingType() {
1398
            return enclosingType;
1✔
1399
        }
1400

1401
        /**
1402
         * {@inheritDoc}
1403
         */
1404
        public TypeList getDeclaredTypes() {
1405
            return new TypeList.Explicit(declaredTypes);
1✔
1406
        }
1407

1408
        /**
1409
         * {@inheritDoc}
1410
         */
1411
        public boolean isAnonymousType() {
1412
            return anonymousClass;
1✔
1413
        }
1414

1415
        /**
1416
         * {@inheritDoc}
1417
         */
1418
        public boolean isLocalType() {
1419
            return localClass;
1✔
1420
        }
1421

1422
        /**
1423
         * {@inheritDoc}
1424
         */
1425
        @MaybeNull
1426
        public PackageDescription getPackage() {
1427
            int packageIndex = name.lastIndexOf('.');
1✔
1428
            return packageIndex == -1
1✔
1429
                    ? PackageDescription.DEFAULT
1430
                    : new PackageDescription.Simple(name.substring(0, packageIndex));
1✔
1431
        }
1432

1433
        /**
1434
         * {@inheritDoc}
1435
         */
1436
        public AnnotationList getDeclaredAnnotations() {
1437
            return new AnnotationList.Explicit(annotationDescriptions);
1✔
1438
        }
1439

1440
        /**
1441
         * {@inheritDoc}
1442
         */
1443
        @MaybeNull
1444
        public TypeDescription getDeclaringType() {
1445
            return declaringType;
1✔
1446
        }
1447

1448
        /**
1449
         * {@inheritDoc}
1450
         */
1451
        @MaybeNull
1452
        public Generic getSuperClass() {
1453
            return superClass == null
1✔
1454
                    ? Generic.UNDEFINED
1455
                    : new Generic.LazyProjection.WithResolvedErasure(superClass, Generic.Visitor.Substitutor.ForAttachment.of(this));
1✔
1456
        }
1457

1458
        /**
1459
         * {@inheritDoc}
1460
         */
1461
        public TypeList.Generic getInterfaces() {
1462
            return new TypeList.Generic.ForDetachedTypes.WithResolvedErasure(interfaceTypes, TypeDescription.Generic.Visitor.Substitutor.ForAttachment.of(this));
1✔
1463
        }
1464

1465
        /**
1466
         * {@inheritDoc}
1467
         */
1468
        public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
1469
            return new FieldList.ForTokens(this, fieldTokens);
1✔
1470
        }
1471

1472
        /**
1473
         * {@inheritDoc}
1474
         */
1475
        public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
1476
            return new MethodList.ForTokens(this, methodTokens);
1✔
1477
        }
1478

1479
        /**
1480
         * {@inheritDoc}
1481
         */
1482
        public TypeList.Generic getTypeVariables() {
1483
            return TypeList.Generic.ForDetachedTypes.attachVariables(this, typeVariables);
1✔
1484
        }
1485

1486
        /**
1487
         * {@inheritDoc}
1488
         */
1489
        public int getModifiers() {
1490
            return modifiers;
1✔
1491
        }
1492

1493
        /**
1494
         * {@inheritDoc}
1495
         */
1496
        public String getName() {
1497
            return name;
1✔
1498
        }
1499

1500
        /**
1501
         * {@inheritDoc}
1502
         */
1503
        public TypeDescription getNestHost() {
1504
            return nestHost.represents(TargetType.class)
1✔
1505
                    ? this
1506
                    : nestHost;
1507
        }
1508

1509
        /**
1510
         * {@inheritDoc}
1511
         */
1512
        public TypeList getNestMembers() {
1513
            return nestHost.represents(TargetType.class)
1✔
1514
                    ? new TypeList.Explicit(CompoundList.of(this, nestMembers))
1✔
1515
                    : nestHost.getNestMembers();
×
1516
        }
1517

1518
        /**
1519
         * {@inheritDoc}
1520
         */
1521
        public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
1522
            return new RecordComponentList.ForTokens(this, recordComponentTokens);
1✔
1523
        }
1524

1525
        /**
1526
         * {@inheritDoc}
1527
         */
1528
        @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Assuming super class for given instance.")
1529
        public boolean isRecord() {
1530
            return record
1✔
1531
                    && superClass != null
1532
                    && getSuperClass().asErasure().equals(JavaType.RECORD.getTypeStub());
1✔
1533
        }
1534

1535
        @Override
1536
        public boolean isSealed() {
1537
            return permittedSubclasses != null;
1✔
1538
        }
1539

1540
        /**
1541
         * {@inheritDoc}
1542
         */
1543
        public TypeList getPermittedSubtypes() {
1544
            return permittedSubclasses == null
1✔
1545
                    ? new TypeList.Empty()
1546
                    : new TypeList.Explicit(permittedSubclasses);
1547
        }
1548

1549
        /**
1550
         * {@inheritDoc}
1551
         */
1552
        public TypeDescription validated() {
1553
            if (!isValidIdentifier(getName().split("\\."))) {
1✔
1554
                throw new IllegalStateException("Illegal type name: " + getName() + " for " + this);
1✔
1555
            } else if ((getModifiers() & ~ModifierContributor.ForType.MASK) != EMPTY_MASK) {
1✔
1556
                throw new IllegalStateException("Illegal modifiers " + getModifiers() + " for " + this);
1✔
1557
            } else if (isPackageType() && getModifiers() != PackageDescription.PACKAGE_MODIFIERS) {
1✔
1558
                throw new IllegalStateException("Illegal modifiers " + getModifiers() + " for package " + this);
1✔
1559
            }
1560
            TypeDescription.Generic superClass = getSuperClass();
1✔
1561
            if (superClass != null) {
1✔
1562
                if (!superClass.accept(Generic.Visitor.Validator.SUPER_CLASS)) {
1✔
1563
                    throw new IllegalStateException("Illegal super class " + superClass + " for " + this);
1✔
1564
                } else if (!superClass.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1565
                    throw new IllegalStateException("Illegal type annotations on super class " + superClass + " for " + this);
1✔
1566
                } else if (!superClass.asErasure().isVisibleTo(this)) {
1✔
1567
                    throw new IllegalStateException("Invisible super type " + superClass + " for " + this);
1✔
1568
                }
1569
            }
1570
            Set<TypeDescription> interfaceErasures = new HashSet<TypeDescription>();
1✔
1571
            for (TypeDescription.Generic interfaceType : getInterfaces()) {
1✔
1572
                if (!interfaceType.accept(Generic.Visitor.Validator.INTERFACE)) {
1✔
1573
                    throw new IllegalStateException("Illegal interface " + interfaceType + " for " + this);
1✔
1574
                } else if (!interfaceType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1575
                    throw new IllegalStateException("Illegal type annotations on interface " + interfaceType + " for " + this);
1✔
1576
                } else if (!interfaceErasures.add(interfaceType.asErasure())) {
1✔
1577
                    throw new IllegalStateException("Already implemented interface " + interfaceType + " for " + this);
1✔
1578
                } else if (!interfaceType.asErasure().isVisibleTo(this)) {
1✔
1579
                    throw new IllegalStateException("Invisible interface type " + interfaceType + " for " + this);
1✔
1580
                }
1581
            }
1✔
1582
            TypeList.Generic typeVariables = getTypeVariables();
1✔
1583
            if (!typeVariables.isEmpty() && isAssignableTo(Throwable.class)) {
1✔
1584
                throw new IllegalStateException("Cannot define throwable " + this + " to be generic");
1✔
1585
            }
1586
            Set<String> typeVariableNames = new HashSet<String>();
1✔
1587
            for (TypeDescription.Generic typeVariable : typeVariables) {
1✔
1588
                String variableSymbol = typeVariable.getSymbol();
1✔
1589
                if (!typeVariableNames.add(variableSymbol)) {
1✔
1590
                    throw new IllegalStateException("Duplicate type variable symbol '" + typeVariable + "' for " + this);
1✔
1591
                } else if (!isValidIdentifier(variableSymbol)) {
1✔
1592
                    throw new IllegalStateException("Illegal type variable name '" + typeVariable + "' for " + this);
1✔
1593
                } else if (!Generic.Visitor.Validator.ForTypeAnnotations.ofFormalTypeVariable(typeVariable)) {
1✔
1594
                    throw new IllegalStateException("Illegal type annotation on '" + typeVariable + "' for " + this);
1✔
1595
                }
1596
                boolean interfaceBound = false;
1✔
1597
                Set<TypeDescription.Generic> bounds = new HashSet<Generic>();
1✔
1598
                for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) {
1✔
1599
                    if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) {
1✔
1600
                        throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + " for " + this);
1✔
1601
                    } else if (!bound.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1602
                        throw new IllegalStateException("Illegal type annotations on type variable " + bound + " for " + this);
1✔
1603
                    } else if (!bounds.add(bound)) {
1✔
1604
                        throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + " for " + this);
1✔
1605
                    } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) {
1✔
1606
                        throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + this);
1✔
1607
                    }
1608
                    interfaceBound = true;
1✔
1609
                }
1✔
1610
                if (!interfaceBound) {
1✔
1611
                    throw new IllegalStateException("Type variable " + typeVariable + " for " + this + " does not define at least one bound");
1✔
1612
                }
1613
            }
1✔
1614
            TypeDescription enclosingType = getEnclosingType();
1✔
1615
            if (enclosingType != null && (enclosingType.isArray() || enclosingType.isPrimitive())) {
1✔
1616
                throw new IllegalStateException("Cannot define array type or primitive type " + enclosingType + " + as enclosing type for " + this);
1✔
1617
            }
1618
            MethodDescription.InDefinedShape enclosingMethod = getEnclosingMethod();
1✔
1619
            if (enclosingMethod != null && enclosingMethod.isTypeInitializer()) {
1✔
1620
                throw new IllegalStateException("Cannot enclose type declaration in class initializer " + enclosingMethod);
×
1621
            }
1622
            TypeDescription declaringType = getDeclaringType();
1✔
1623
            if (declaringType != null) {
1✔
1624
                if (declaringType.isPrimitive() || declaringType.isArray()) {
1✔
1625
                    throw new IllegalStateException("Cannot define array type or primitive type " + declaringType + " as declaring type for " + this);
1✔
1626
                }
1627
            } else if (enclosingType == null && enclosingMethod == null && (isLocalType() || isAnonymousType())) {
1✔
1628
                throw new IllegalStateException("Cannot define an anonymous or local class without a declaring type for " + this);
1✔
1629
            }
1630
            Set<TypeDescription> declaredTypes = new HashSet<TypeDescription>();
1✔
1631
            for (TypeDescription declaredType : getDeclaredTypes()) {
1✔
1632
                if (declaredType.isArray() || declaredType.isPrimitive()) {
1✔
1633
                    throw new IllegalStateException("Cannot define array type or primitive type " + declaredType + " + as declared type for " + this);
1✔
1634
                } else if (!declaredTypes.add(declaredType)) {
1✔
1635
                    throw new IllegalStateException("Duplicate definition of declared type " + declaredType);
1✔
1636
                }
1637
            }
1✔
1638
            TypeDescription nestHost = getNestHost();
1✔
1639
            if (nestHost.equals(this)) {
1✔
1640
                Set<TypeDescription> nestMembers = new HashSet<TypeDescription>();
1✔
1641
                for (TypeDescription nestMember : getNestMembers()) {
1✔
1642
                    if (nestMember.isArray() || nestMember.isPrimitive()) {
1✔
1643
                        throw new IllegalStateException("Cannot define array type or primitive type " + nestMember + " + as nest member of " + this);
1✔
1644
                    } else if (!nestMember.isSamePackage(this)) {
1✔
1645
                        throw new IllegalStateException("Cannot define nest member " + nestMember + " + within different package then " + this);
1✔
1646
                    } else if (!nestMembers.add(nestMember)) {
1✔
1647
                        throw new IllegalStateException("Duplicate definition of nest member " + nestMember);
1✔
1648
                    }
1649
                }
1✔
1650
            } else if (nestHost.isArray() || nestHost.isPrimitive()) {
1✔
1651
                throw new IllegalStateException("Cannot define array type or primitive type " + nestHost + " + as nest host for " + this);
1✔
1652
            } else if (!nestHost.isSamePackage(this)) {
1✔
1653
                throw new IllegalStateException("Cannot define nest host " + nestHost + " within different package then " + this);
1✔
1654
            }
1655
            for (TypeDescription permittedSubclass : getPermittedSubtypes()) {
1✔
1656
                if (!permittedSubclass.isAssignableTo(this) || permittedSubclass.equals(this)) {
1✔
1657
                    throw new IllegalStateException("Cannot assign permitted subclass " + permittedSubclass + " to " + this);
1✔
1658
                }
1659
            }
×
1660
            Set<TypeDescription> typeAnnotationTypes = new HashSet<TypeDescription>();
1✔
1661
            for (AnnotationDescription annotationDescription : getDeclaredAnnotations()) {
1✔
1662
                if (!annotationDescription.isSupportedOn(ElementType.TYPE)
1✔
1663
                        && !(isAnnotation() && annotationDescription.isSupportedOn(ElementType.ANNOTATION_TYPE))
1✔
1664
                        && !(isPackageType() && annotationDescription.isSupportedOn(ElementType.PACKAGE))) {
1✔
1665
                    throw new IllegalStateException("Cannot add " + annotationDescription + " on " + this);
1✔
1666
                } else if (!typeAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1✔
1667
                    throw new IllegalStateException("Duplicate annotation " + annotationDescription + " for " + this);
1✔
1668
                }
1669
            }
1✔
1670
            Set<FieldDescription.SignatureToken> fieldSignatureTokens = new HashSet<FieldDescription.SignatureToken>();
1✔
1671
            for (FieldDescription.InDefinedShape fieldDescription : getDeclaredFields()) {
1✔
1672
                String fieldName = fieldDescription.getName();
1✔
1673
                if (!fieldSignatureTokens.add(fieldDescription.asSignatureToken())) {
1✔
1674
                    throw new IllegalStateException("Duplicate field definition for " + fieldDescription);
1✔
1675
                } else if (!isValidUnqualifiedNameIdentifier(fieldName)) {
1✔
1676
                    throw new IllegalStateException("Illegal field name for " + fieldDescription);
1✔
1677
                } else if ((fieldDescription.getModifiers() & ~ModifierContributor.ForField.MASK) != EMPTY_MASK) {
1✔
1678
                    throw new IllegalStateException("Illegal field modifiers " + fieldDescription.getModifiers() + " for " + fieldDescription);
1✔
1679
                }
1680
                Generic fieldType = fieldDescription.getType();
1✔
1681
                if (!fieldType.accept(Generic.Visitor.Validator.FIELD)) {
1✔
1682
                    throw new IllegalStateException("Illegal field type " + fieldType + " for " + fieldDescription);
×
1683
                } else if (!fieldType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1684
                    throw new IllegalStateException("Illegal type annotations on " + fieldType + " for " + this);
1✔
1685
                } else if (!fieldDescription.isSynthetic() && !fieldType.asErasure().isVisibleTo(this)) {
1✔
1686
                    throw new IllegalStateException("Invisible field type " + fieldDescription.getType() + " for " + fieldDescription);
1✔
1687
                }
1688
                Set<TypeDescription> fieldAnnotationTypes = new HashSet<TypeDescription>();
1✔
1689
                for (AnnotationDescription annotationDescription : fieldDescription.getDeclaredAnnotations()) {
1✔
1690
                    if (!annotationDescription.isSupportedOn(ElementType.FIELD)) {
1✔
1691
                        throw new IllegalStateException("Cannot add " + annotationDescription + " on " + fieldDescription);
1✔
1692
                    } else if (!fieldAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1✔
1693
                        throw new IllegalStateException("Duplicate annotation " + annotationDescription + " for " + fieldDescription);
1✔
1694
                    }
1695
                }
1✔
1696
            }
1✔
1697
            Set<MethodDescription.SignatureToken> methodSignatureTokens = new HashSet<MethodDescription.SignatureToken>();
1✔
1698
            for (MethodDescription.InDefinedShape methodDescription : getDeclaredMethods()) {
1✔
1699
                if (!methodSignatureTokens.add(methodDescription.asSignatureToken())) {
1✔
1700
                    throw new IllegalStateException("Duplicate method signature for " + methodDescription);
1✔
1701
                } else if ((methodDescription.getModifiers() & ~ModifierContributor.ForMethod.MASK) != 0) {
1✔
1702
                    throw new IllegalStateException("Illegal modifiers " + methodDescription.getModifiers() + " for " + methodDescription);
1✔
1703
                } else if (methodDescription.isAbstract() && (methodDescription.getModifiers() & Opcodes.ACC_STRICT) != 0) {
1✔
1704
                    throw new IllegalStateException("Cannot declare strict computations for " + methodDescription);
×
1705
                } else if (isInterface() && !methodDescription.isPublic() && !methodDescription.isPrivate()) {
1✔
1706
                    throw new IllegalStateException("Methods declared by an interface must be public or private " + methodDescription);
1✔
1707
                }
1708
                Set<String> methodTypeVariableNames = new HashSet<String>();
1✔
1709
                for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
1✔
1710
                    String variableSymbol = typeVariable.getSymbol();
1✔
1711
                    if (!methodTypeVariableNames.add(variableSymbol)) {
1✔
1712
                        throw new IllegalStateException("Duplicate type variable symbol '" + typeVariable + "' for " + methodDescription);
1✔
1713
                    } else if (!isValidIdentifier(variableSymbol)) {
1✔
1714
                        throw new IllegalStateException("Illegal type variable name '" + typeVariable + "' for " + methodDescription);
1✔
1715
                    } else if (!Generic.Visitor.Validator.ForTypeAnnotations.ofFormalTypeVariable(typeVariable)) {
1✔
1716
                        throw new IllegalStateException("Illegal type annotation on '" + typeVariable + "' for " + methodDescription);
1✔
1717
                    }
1718
                    boolean interfaceBound = false;
1✔
1719
                    Set<TypeDescription.Generic> bounds = new HashSet<Generic>();
1✔
1720
                    for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) {
1✔
1721
                        if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) {
1✔
1722
                            throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + " for " + methodDescription);
1✔
1723
                        } else if (!bound.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1724
                            throw new IllegalStateException("Illegal type annotations on bound " + bound + " of " + typeVariable + " for " + this);
1✔
1725
                        } else if (!bounds.add(bound)) {
1✔
1726
                            throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + " for " + methodDescription);
1✔
1727
                        } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) {
1✔
1728
                            throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + methodDescription);
1✔
1729
                        }
1730
                        interfaceBound = true;
1✔
1731
                    }
1✔
1732
                    if (!interfaceBound) {
1✔
1733
                        throw new IllegalStateException("Type variable " + typeVariable + " for " + methodDescription + " does not define at least one bound");
1✔
1734
                    }
1735
                }
1✔
1736
                Generic returnType = methodDescription.getReturnType();
1✔
1737
                if (methodDescription.isTypeInitializer()) {
1✔
1738
                    throw new IllegalStateException("Illegal explicit declaration of a type initializer by " + this);
1✔
1739
                } else if (methodDescription.isConstructor()) {
1✔
1740
                    if (!returnType.represents(void.class)) {
1✔
1741
                        throw new IllegalStateException("A constructor must return void " + methodDescription);
1✔
1742
                    } else if (!returnType.getDeclaredAnnotations().isEmpty()) {
1✔
1743
                        throw new IllegalStateException("The void non-type must not be annotated for " + methodDescription);
×
1744
                    }
1745
                } else if (!isValidMethodIdentifier(methodDescription.getInternalName())) {
1✔
1746
                    throw new IllegalStateException("Illegal method name " + returnType + " for " + methodDescription);
1✔
1747
                } else if (!returnType.accept(Generic.Visitor.Validator.METHOD_RETURN)) {
1✔
1748
                    throw new IllegalStateException("Illegal return type " + returnType + " for " + methodDescription);
×
1749
                } else if (!returnType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1750
                    throw new IllegalStateException("Illegal type annotations on return type " + returnType + " for " + methodDescription);
1✔
1751
                } else if (!methodDescription.isSynthetic() && !methodDescription.getReturnType().asErasure().isVisibleTo(this)) {
1✔
1752
                    throw new IllegalStateException("Invisible return type " + methodDescription.getReturnType() + " for " + methodDescription);
1✔
1753
                }
1754
                Set<String> parameterNames = new HashSet<String>();
1✔
1755
                for (ParameterDescription.InDefinedShape parameterDescription : methodDescription.getParameters()) {
1✔
1756
                    Generic parameterType = parameterDescription.getType();
1✔
1757
                    if (!parameterType.accept(Generic.Visitor.Validator.METHOD_PARAMETER)) {
1✔
1758
                        throw new IllegalStateException("Illegal parameter type of " + parameterDescription + " for " + methodDescription);
1✔
1759
                    } else if (!parameterType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1760
                        throw new IllegalStateException("Illegal type annotations on parameter " + parameterDescription + " for " + methodDescription);
×
1761
                    } else if (!methodDescription.isSynthetic() && !parameterType.asErasure().isVisibleTo(this)) {
1✔
1762
                        throw new IllegalStateException("Invisible parameter type of " + parameterDescription + " for " + methodDescription);
1✔
1763
                    }
1764
                    if (parameterDescription.isNamed()) {
1✔
1765
                        String parameterName = parameterDescription.getName();
1✔
1766
                        if (!parameterNames.add(parameterName)) {
1✔
1767
                            throw new IllegalStateException("Duplicate parameter name of " + parameterDescription + " for " + methodDescription);
1✔
1768
                        } else if (!isValidUnqualifiedNameIdentifier(parameterName)) {
1✔
1769
                            throw new IllegalStateException("Illegal parameter name of " + parameterDescription + " for " + methodDescription);
1✔
1770
                        }
1771
                    }
1772
                    if (parameterDescription.hasModifiers() && (parameterDescription.getModifiers() & ~ModifierContributor.ForParameter.MASK) != EMPTY_MASK) {
1✔
1773
                        throw new IllegalStateException("Illegal modifiers of " + parameterDescription + " for " + methodDescription);
1✔
1774
                    }
1775
                    Set<TypeDescription> parameterAnnotationTypes = new HashSet<TypeDescription>();
1✔
1776
                    for (AnnotationDescription annotationDescription : parameterDescription.getDeclaredAnnotations()) {
1✔
1777
                        if (!annotationDescription.isSupportedOn(ElementType.PARAMETER)) {
1✔
1778
                            throw new IllegalStateException("Cannot add " + annotationDescription + " on " + parameterDescription);
1✔
1779
                        } else if (!parameterAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1✔
1780
                            throw new IllegalStateException("Duplicate annotation " + annotationDescription + " of " + parameterDescription + " for " + methodDescription);
1✔
1781
                        }
1782
                    }
1✔
1783
                }
1✔
1784
                for (TypeDescription.Generic exceptionType : methodDescription.getExceptionTypes()) {
1✔
1785
                    if (!exceptionType.accept(Generic.Visitor.Validator.EXCEPTION)) {
1✔
1786
                        throw new IllegalStateException("Illegal exception type " + exceptionType + " for " + methodDescription);
1✔
1787
                    } else if (!exceptionType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1✔
1788
                        throw new IllegalStateException("Illegal type annotations on " + exceptionType + " for " + methodDescription);
1✔
1789
                    } else if (!methodDescription.isSynthetic() && !exceptionType.asErasure().isVisibleTo(this)) {
1✔
1790
                        throw new IllegalStateException("Invisible exception type " + exceptionType + " for " + methodDescription);
1✔
1791
                    }
1792
                }
1✔
1793
                Set<TypeDescription> methodAnnotationTypes = new HashSet<TypeDescription>();
1✔
1794
                for (AnnotationDescription annotationDescription : methodDescription.getDeclaredAnnotations()) {
1✔
1795
                    if (!annotationDescription.isSupportedOn(methodDescription.isMethod() ? ElementType.METHOD : ElementType.CONSTRUCTOR)) {
1✔
1796
                        throw new IllegalStateException("Cannot add " + annotationDescription + " on " + methodDescription);
1✔
1797
                    } else if (!methodAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1✔
1798
                        throw new IllegalStateException("Duplicate annotation " + annotationDescription + " for " + methodDescription);
1✔
1799
                    }
1800
                }
1✔
1801
                AnnotationValue<?, ?> defaultValue = methodDescription.getDefaultValue();
1✔
1802
                if (defaultValue != null && !methodDescription.isDefaultValue(defaultValue)) {
1✔
1803
                    throw new IllegalStateException("Illegal default value " + defaultValue + "for " + methodDescription);
1✔
1804
                }
1805
                Generic receiverType = methodDescription.getReceiverType();
1✔
1806
                if (receiverType != null && !receiverType.accept(Generic.Visitor.Validator.RECEIVER)) {
1✔
1807
                    throw new IllegalStateException("Illegal receiver type " + receiverType + " for " + methodDescription);
×
1808
                } else if (methodDescription.isStatic()) {
1✔
1809
                    if (receiverType != null) {
1✔
1810
                        throw new IllegalStateException("Static method " + methodDescription + " defines a non-null receiver " + receiverType);
1✔
1811
                    }
1812
                } else if (methodDescription.isConstructor()) {
1✔
1813
                    if (receiverType == null || !receiverType.asErasure().equals(enclosingType == null ? this : enclosingType)) {
1✔
1814
                        throw new IllegalStateException("Constructor " + methodDescription + " defines an illegal receiver " + receiverType);
×
1815
                    }
1816
                } else if (/* methodDescription.isMethod() */ receiverType == null || !equals(receiverType.asErasure())) {
1✔
1817
                    throw new IllegalStateException("Method " + methodDescription + " defines an illegal receiver " + receiverType);
1✔
1818
                }
1819
            }
1✔
1820
            return this;
1✔
1821
        }
1822

1823
        /**
1824
         * Checks if an array of identifiers is a valid compound Java identifier.
1825
         *
1826
         * @param identifier an array of potentially invalid Java identifiers.
1827
         * @return {@code true} if all identifiers are valid and the array is not empty.
1828
         */
1829
        private static boolean isValidIdentifier(String[] identifier) {
1830
            if (identifier.length == 0) {
1✔
1831
                return false;
×
1832
            }
1833
            for (String part : identifier) {
1✔
1834
                if (!isValidIdentifier(part)) {
1✔
1835
                    return false;
1✔
1836
                }
1837
            }
1838
            return true;
1✔
1839
        }
1840

1841
        /**
1842
         * Checks if a Java identifier is valid.
1843
         *
1844
         * @param identifier The identifier to check for validity.
1845
         * @return {@code true} if the given identifier is valid.
1846
         */
1847
        private static boolean isValidIdentifier(String identifier) {
1848
            if (KEYWORDS.contains(identifier)
1✔
1849
                    || identifier.length() == 0
1✔
1850
                    || !(Character.isJavaIdentifierStart(identifier.charAt(0))
1✔
1851
                    || Character.isUnicodeIdentifierStart(identifier.charAt(0)))) {
×
1852
                return false;
1✔
1853
            } else if (identifier.equals(PackageDescription.PACKAGE_CLASS_NAME)) {
1✔
1854
                return true;
1✔
1855
            }
1856
            for (int index = 1; index < identifier.length(); index++) {
1✔
1857
                if (!(Character.isJavaIdentifierPart(identifier.charAt(index)) || Character.isUnicodeIdentifierPart(identifier.charAt(index)))) {
1✔
1858
                    return false;
1✔
1859
                }
1860
            }
1861
            return true;
1✔
1862
        }
1863

1864
        /**
1865
         * Checks if an identifier is a valid "Unqualified Name" for a field, a local variable or a formal parameter,
1866
         * per JVMS 4.2.2.
1867
         *
1868
         * @param identifier The identifier to check for validity.
1869
         * @return {@code true} if the given identifier is valid.
1870
         */
1871
        private static boolean isValidUnqualifiedNameIdentifier(String identifier) {
1872
            if (identifier.length() == 0) {
1✔
1873
                return false;
×
1874
            }
1875
            for (int index = 0; index < identifier.length(); index++) {
1✔
1876
                switch (identifier.charAt(index)) {
1✔
1877
                    case '.':
1878
                    case ';':
1879
                    case '[':
1880
                    case '/':
1881
                        return false;
1✔
1882
                }
1883
            }
1884
            return true;
1✔
1885
        }
1886

1887
        /**
1888
         * Checks if an identifier is a valid "Unqualified Name" for a method, per JVMS 4.2.2.
1889
         *
1890
         * @param identifier The identifier to check for validity.
1891
         * @return {@code true} if the given identifier is valid.
1892
         */
1893
        private static boolean isValidMethodIdentifier(String identifier) {
1894
            if (identifier.length() == 0) {
1✔
1895
                return false;
×
1896
            }
1897
            if (identifier.equals(MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME)
1✔
1898
                    || identifier.equals(MethodDescription.CONSTRUCTOR_INTERNAL_NAME)) {
1✔
UNCOV
1899
                return true;
×
1900
            }
1901
            for (int index = 0; index < identifier.length(); index++) {
1✔
1902
                switch (identifier.charAt(index)) {
1✔
1903
                    case '.':
1904
                    case ';':
1905
                    case '[':
1906
                    case '/':
1907
                    case '<':
1908
                    case '>':
1909
                        return false;
1✔
1910
                }
1911
            }
1912
            return true;
1✔
1913
        }
1914
    }
1915

1916
    /**
1917
     * A frozen representation of an instrumented type of which the structure must not be modified.
1918
     */
1919
    class Frozen extends AbstractBase.OfSimpleType implements InstrumentedType.WithFlexibleName {
1920

1921
        /**
1922
         * The represented type description.
1923
         */
1924
        private final TypeDescription typeDescription;
1925

1926
        /**
1927
         * The type's loaded type initializer.
1928
         */
1929
        private final LoadedTypeInitializer loadedTypeInitializer;
1930

1931
        /**
1932
         * Creates a new frozen representation of an instrumented type.
1933
         *
1934
         * @param typeDescription       The represented type description.
1935
         * @param loadedTypeInitializer The type's loaded type initializer.
1936
         */
1937
        protected Frozen(TypeDescription typeDescription, LoadedTypeInitializer loadedTypeInitializer) {
1✔
1938
            this.typeDescription = typeDescription;
1✔
1939
            this.loadedTypeInitializer = loadedTypeInitializer;
1✔
1940
        }
1✔
1941

1942
        /**
1943
         * {@inheritDoc}
1944
         */
1945
        public AnnotationList getDeclaredAnnotations() {
1946
            return typeDescription.getDeclaredAnnotations();
1✔
1947
        }
1948

1949
        /**
1950
         * {@inheritDoc}
1951
         */
1952
        public int getModifiers() {
1953
            return typeDescription.getModifiers();
1✔
1954
        }
1955

1956
        /**
1957
         * {@inheritDoc}
1958
         */
1959
        public TypeList.Generic getTypeVariables() {
1960
            return typeDescription.getTypeVariables();
1✔
1961
        }
1962

1963
        /**
1964
         * {@inheritDoc}
1965
         */
1966
        public String getName() {
1967
            return typeDescription.getName();
1✔
1968
        }
1969

1970
        /**
1971
         * {@inheritDoc}
1972
         */
1973
        @MaybeNull
1974
        public Generic getSuperClass() {
1975
            return typeDescription.getSuperClass();
1✔
1976
        }
1977

1978
        /**
1979
         * {@inheritDoc}
1980
         */
1981
        public TypeList.Generic getInterfaces() {
1982
            return typeDescription.getInterfaces();
1✔
1983
        }
1984

1985
        /**
1986
         * {@inheritDoc}
1987
         */
1988
        public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
1989
            return typeDescription.getDeclaredFields();
1✔
1990
        }
1991

1992
        /**
1993
         * {@inheritDoc}
1994
         */
1995
        public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
1996
            return typeDescription.getDeclaredMethods();
1✔
1997
        }
1998

1999
        /**
2000
         * {@inheritDoc}
2001
         */
2002
        public boolean isAnonymousType() {
2003
            return typeDescription.isAnonymousType();
1✔
2004
        }
2005

2006
        /**
2007
         * {@inheritDoc}
2008
         */
2009
        public boolean isLocalType() {
2010
            return typeDescription.isLocalType();
1✔
2011
        }
2012

2013
        /**
2014
         * {@inheritDoc}
2015
         */
2016
        @MaybeNull
2017
        public PackageDescription getPackage() {
2018
            return typeDescription.getPackage();
1✔
2019
        }
2020

2021
        /**
2022
         * {@inheritDoc}
2023
         */
2024
        @MaybeNull
2025
        public TypeDescription getEnclosingType() {
2026
            return typeDescription.getEnclosingType();
1✔
2027
        }
2028

2029
        /**
2030
         * {@inheritDoc}
2031
         */
2032
        @MaybeNull
2033
        public TypeDescription getDeclaringType() {
2034
            return typeDescription.getDeclaringType();
1✔
2035
        }
2036

2037
        /**
2038
         * {@inheritDoc}
2039
         */
2040
        public TypeList getDeclaredTypes() {
2041
            return typeDescription.getDeclaredTypes();
1✔
2042
        }
2043

2044
        /**
2045
         * {@inheritDoc}
2046
         */
2047
        @MaybeNull
2048
        public MethodDescription.InDefinedShape getEnclosingMethod() {
2049
            return typeDescription.getEnclosingMethod();
1✔
2050
        }
2051

2052
        /**
2053
         * {@inheritDoc}
2054
         */
2055
        @MaybeNull
2056
        public String getGenericSignature() {
2057
            // Embrace use of native generic signature by direct delegation.
2058
            return typeDescription.getGenericSignature();
1✔
2059
        }
2060

2061
        /**
2062
         * {@inheritDoc}
2063
         */
2064
        public int getActualModifiers(boolean superFlag) {
2065
            // Embrace use of native actual modifiers by direct delegation.
2066
            return typeDescription.getActualModifiers(superFlag);
1✔
2067
        }
2068

2069
        /**
2070
         * {@inheritDoc}
2071
         */
2072
        public TypeDescription getNestHost() {
2073
            return typeDescription.getNestHost();
1✔
2074
        }
2075

2076
        /**
2077
         * {@inheritDoc}
2078
         */
2079
        public TypeList getNestMembers() {
2080
            return typeDescription.getNestMembers();
1✔
2081
        }
2082

2083
        /**
2084
         * {@inheritDoc}
2085
         */
2086
        public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
2087
            return typeDescription.getRecordComponents();
1✔
2088
        }
2089

2090
        /**
2091
         * {@inheritDoc}
2092
         */
2093
        public boolean isRecord() {
2094
            return typeDescription.isRecord();
×
2095
        }
2096

2097
        @Override
2098
        public boolean isSealed() {
2099
            return typeDescription.isSealed();
1✔
2100
        }
2101

2102
        /**
2103
         * {@inheritDoc}
2104
         */
2105
        public TypeList getPermittedSubtypes() {
2106
            return typeDescription.getPermittedSubtypes();
1✔
2107
        }
2108

2109
        /**
2110
         * {@inheritDoc}
2111
         */
2112
        public WithFlexibleName withField(FieldDescription.Token token) {
2113
            throw new IllegalStateException("Cannot define field for frozen type: " + typeDescription);
1✔
2114
        }
2115

2116
        /**
2117
         * {@inheritDoc}
2118
         */
2119
        public WithFlexibleName withAuxiliaryField(FieldDescription.Token token, Object value) {
2120
            throw new IllegalStateException("Cannot define auxiliary field for frozen type: " + typeDescription);
1✔
2121
        }
2122

2123
        /**
2124
         * {@inheritDoc}
2125
         */
2126
        public WithFlexibleName withMethod(MethodDescription.Token token) {
2127
            throw new IllegalStateException("Cannot define method for frozen type: " + typeDescription);
1✔
2128
        }
2129

2130
        /**
2131
         * {@inheritDoc}
2132
         */
2133
        public WithFlexibleName withRecordComponent(RecordComponentDescription.Token token) {
2134
            throw new IllegalStateException("Cannot define record component for frozen type: " + typeDescription);
1✔
2135
        }
2136

2137
        /**
2138
         * {@inheritDoc}
2139
         */
2140
        public WithFlexibleName withModifiers(int modifiers) {
2141
            throw new IllegalStateException("Cannot change modifiers for frozen type: " + typeDescription);
×
2142
        }
2143

2144
        /**
2145
         * {@inheritDoc}
2146
         */
2147
        public WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes) {
2148
            throw new IllegalStateException("Cannot add interfaces for frozen type: " + typeDescription);
×
2149
        }
2150

2151
        /**
2152
         * {@inheritDoc}
2153
         */
2154
        public WithFlexibleName withTypeVariable(TypeVariableToken typeVariable) {
2155
            throw new IllegalStateException("Cannot define type variable for frozen type: " + typeDescription);
1✔
2156
        }
2157

2158
        /**
2159
         * {@inheritDoc}
2160
         */
2161
        public WithFlexibleName withAnnotations(List<? extends AnnotationDescription> annotationDescriptions) {
2162
            throw new IllegalStateException("Cannot add annotation to frozen type: " + typeDescription);
1✔
2163
        }
2164

2165
        /**
2166
         * {@inheritDoc}
2167
         */
2168
        public WithFlexibleName withNestHost(TypeDescription nestHost) {
2169
            throw new IllegalStateException("Cannot set nest host of frozen type: " + typeDescription);
1✔
2170
        }
2171

2172
        /**
2173
         * {@inheritDoc}
2174
         */
2175
        public WithFlexibleName withNestMembers(TypeList nestMembers) {
2176
            throw new IllegalStateException("Cannot add nest members to frozen type: " + typeDescription);
1✔
2177
        }
2178

2179
        /**
2180
         * {@inheritDoc}
2181
         */
2182
        public WithFlexibleName withEnclosingType(@MaybeNull TypeDescription enclosingType) {
2183
            throw new IllegalStateException("Cannot set enclosing type of frozen type: " + typeDescription);
1✔
2184
        }
2185

2186
        /**
2187
         * {@inheritDoc}
2188
         */
2189
        public WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod) {
2190
            throw new IllegalStateException("Cannot set enclosing method of frozen type: " + typeDescription);
1✔
2191
        }
2192

2193
        /**
2194
         * {@inheritDoc}
2195
         */
2196
        public WithFlexibleName withDeclaringType(@MaybeNull TypeDescription declaringType) {
2197
            throw new IllegalStateException("Cannot add declaring type to frozen type: " + typeDescription);
1✔
2198
        }
2199

2200
        /**
2201
         * {@inheritDoc}
2202
         */
2203
        public WithFlexibleName withDeclaredTypes(TypeList declaredTypes) {
2204
            throw new IllegalStateException("Cannot add declared types to frozen type: " + typeDescription);
1✔
2205
        }
2206

2207
        /**
2208
         * {@inheritDoc}
2209
         */
2210
        public WithFlexibleName withPermittedSubclasses(@MaybeNull TypeList permittedSubclasses) {
2211
            throw new IllegalStateException("Cannot add permitted subclasses to frozen type: " + typeDescription);
1✔
2212
        }
2213

2214
        /**
2215
         * {@inheritDoc}
2216
         */
2217
        public WithFlexibleName withLocalClass(boolean localClass) {
2218
            throw new IllegalStateException("Cannot define local class state for frozen type: " + typeDescription);
1✔
2219
        }
2220

2221
        /**
2222
         * {@inheritDoc}
2223
         */
2224
        public WithFlexibleName withAnonymousClass(boolean anonymousClass) {
2225
            throw new IllegalStateException("Cannot define anonymous class state for frozen type: " + typeDescription);
1✔
2226
        }
2227

2228
        /**
2229
         * {@inheritDoc}
2230
         */
2231
        public WithFlexibleName withRecord(boolean record) {
2232
            throw new IllegalStateException("Cannot define record state for frozen type: " + typeDescription);
1✔
2233
        }
2234

2235
        /**
2236
         * {@inheritDoc}
2237
         */
2238
        public WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer) {
2239
            return new Frozen(typeDescription, new LoadedTypeInitializer.Compound(this.loadedTypeInitializer, loadedTypeInitializer));
×
2240
        }
2241

2242
        /**
2243
         * {@inheritDoc}
2244
         */
2245
        public WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender) {
2246
            throw new IllegalStateException("Cannot add initializer to frozen type: " + typeDescription);
1✔
2247
        }
2248

2249
        /**
2250
         * {@inheritDoc}
2251
         */
2252
        public WithFlexibleName withName(String name) {
2253
            throw new IllegalStateException("Cannot change name of frozen type: " + typeDescription);
1✔
2254
        }
2255

2256
        /**
2257
         * {@inheritDoc}
2258
         */
2259
        public WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer) {
2260
            throw new IllegalStateException("Cannot add type variables of frozen type: " + typeDescription);
1✔
2261
        }
2262

2263
        /**
2264
         * {@inheritDoc}
2265
         */
2266
        public LoadedTypeInitializer getLoadedTypeInitializer() {
2267
            return loadedTypeInitializer;
1✔
2268
        }
2269

2270
        /**
2271
         * {@inheritDoc}
2272
         */
2273
        public TypeInitializer getTypeInitializer() {
2274
            return TypeInitializer.None.INSTANCE;
1✔
2275
        }
2276

2277
        @MaybeNull
2278
        @Override
2279
        public ClassFileVersion getClassFileVersion() {
2280
            return typeDescription.getClassFileVersion();
1✔
2281
        }
2282

2283
        /**
2284
         * {@inheritDoc}
2285
         */
2286
        public TypeDescription validated() {
2287
            return typeDescription;
1✔
2288
        }
2289
    }
2290
}
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