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

16 package net.bytebuddy.dynamic.scaffold;
17
18 import net.bytebuddy.build.CachedReturnPlugin;
19 import net.bytebuddy.description.annotation.AnnotationDescription;
20 import net.bytebuddy.description.annotation.AnnotationList;
21 import net.bytebuddy.description.annotation.AnnotationValue;
22 import net.bytebuddy.description.field.FieldDescription;
23 import net.bytebuddy.description.field.FieldList;
24 import net.bytebuddy.description.method.MethodDescription;
25 import net.bytebuddy.description.method.MethodList;
26 import net.bytebuddy.description.method.ParameterDescription;
27 import net.bytebuddy.description.modifier.ModifierContributor;
28 import net.bytebuddy.description.type.*;
29 import net.bytebuddy.dynamic.TargetType;
30 import net.bytebuddy.dynamic.Transformer;
31 import net.bytebuddy.implementation.LoadedTypeInitializer;
32 import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
33 import net.bytebuddy.matcher.ElementMatcher;
34 import net.bytebuddy.utility.CompoundList;
35 import net.bytebuddy.utility.JavaType;
36
37 import java.lang.annotation.ElementType;
38 import java.util.*;
39
40 import static net.bytebuddy.matcher.ElementMatchers.is;
41 import static net.bytebuddy.matcher.ElementMatchers.not;
42
43 /**
44  * Implementations of this interface represent an instrumented type that is subject to change. Implementations
45  * should however be immutable and return new instance when its builder methods are invoked.
46  */

47 public interface InstrumentedType extends TypeDescription {
48
49     /**
50      * Creates a new instrumented type that includes a new field.
51      *
52      * @param token A token that represents the field's shape.
53      * @return A new instrumented type that is equal to this instrumented type but with the additional field.
54      */

55     InstrumentedType withField(FieldDescription.Token token);
56
57     /**
58      * Creates a new instrumented type that includes a new method or constructor.
59      *
60      * @param token A token that represents the method's shape.
61      * @return A new instrumented type that is equal to this instrumented type but with the additional method.
62      */

63     InstrumentedType withMethod(MethodDescription.Token token);
64
65     /**
66      * Creates a new instrumented type that includes a new record component.
67      *
68      * @param token A token that represents the record component's shape.
69      * @return A new instrumented type that is equal to this instrumented type but with the additional record component.
70      */

71     InstrumentedType withRecordComponent(RecordComponentDescription.Token token);
72
73     /**
74      * Creates a new instrumented type with changed modifiers.
75      *
76      * @param modifiers The instrumented type's modifiers.
77      * @return A new instrumented type that is equal to this instrumented type but with the given modifiers.
78      */

79     InstrumentedType withModifiers(int modifiers);
80
81     /**
82      * Creates a new instrumented type with the given interfaces implemented.
83      *
84      * @param interfaceTypes The interface types to implement.
85      * @return A new instrumented type that is equal to this instrumented type but with the given interfaces implemented.
86      */

87     InstrumentedType withInterfaces(TypeList.Generic interfaceTypes);
88
89     /**
90      * Creates a new instrumented type with the given type variable defined.
91      *
92      * @param typeVariable The type variable to declare.
93      * @return A new instrumented type that is equal to this instrumented type but with the given type variable declared.
94      */

95     InstrumentedType withTypeVariable(TypeVariableToken typeVariable);
96
97     /**
98      * Creates a new instrumented type with the given annotations.
99      *
100      * @param annotationDescriptions The annotations to add to the instrumented type.
101      * @return A new instrumented type that is equal to this instrumented type but annotated with the given annotations
102      */

103     InstrumentedType withAnnotations(List<? extends AnnotationDescription> annotationDescriptions);
104
105     /**
106      * Creates a new instrumented type with the supplied nest host. An instrumented type can be its own nest host.
107      * Setting a nest host removes all nest members from the instrumented type.
108      *
109      * @param nestHost The nest host of the created instrumented type.
110      * @return A new instrumented type with the supplied type as its nest host.
111      */

112     InstrumentedType withNestHost(TypeDescription nestHost);
113
114     /**
115      * Creates a new instrumented types with the supplied nest members added to this instrumented type. The instrumented
116      * type is defined as a nest host if this method is invoked. Any previous nest members are prepended to the supplied types.
117      *
118      * @param nestMembers The nest members to add to the created instrumented type.
119      * @return A new instrumented type that applies the supplied nest members.
120      */

121     InstrumentedType withNestMembers(TypeList nestMembers);
122
123     /**
124      * Creates a new instrumented type with the supplied enclosing type.
125      *
126      * @param enclosingType The type to define as the created instrumented type's enclosing type.
127      * @return A new instrumented type with the supplied type as its enclosing type.
128      */

129     InstrumentedType withEnclosingType(TypeDescription enclosingType);
130
131     /**
132      * Creates a new instrumented type with the supplied enclosing method.
133      *
134      * @param enclosingMethod The method to define as the created instrumented type's enclosing method.
135      * @return A new instrumented type with the supplied method as its enclosing method.
136      */

137     InstrumentedType withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod);
138
139     /**
140      * Creates a new instrumented type that is declared by the supplied type..
141      *
142      * @param declaringType The type that declares the instrumented type.
143      * @return A new instrumented type that is declared by the instrumented type.
144      */

145     InstrumentedType withDeclaringType(TypeDescription declaringType);
146
147     /**
148      * Creates a new instrumented type that indicates that it declared the supplied types.
149      *
150      * @param declaredTypes The types to add to the created instrumented type as declared types.
151      * @return A new instrumented type that indicates that it has declared the supplied types.
152      */

153     InstrumentedType withDeclaredTypes(TypeList declaredTypes);
154
155     /**
156      * Creates a new instrumented type that includes the supplied permitted subclasses.
157      *
158      * @param permittedSubclasses A list of permitted subclasses to include.
159      * @return A new instrumented type that includes the supplied permitted subclasses.
160      */

161     InstrumentedType withPermittedSubclasses(TypeList permittedSubclasses);
162
163     /**
164      * Creates a new instrumented type that indicates that is defined as a local class. Setting this property
165      * resets the anonymous class property.
166      *
167      * @param localClass {@code trueif the instrumented type is supposed to be treated as a local class.
168      * @return A new instrumented type that is treated as a local class.
169      */

170     InstrumentedType withLocalClass(boolean localClass);
171
172     /**
173      * Creates a new instrumented type that indicates that it is defined as an anonymous class. Setting this property
174      * resets the local class property.
175      *
176      * @param anonymousClass {@code trueif the instrumented type is supposed to be treated as an anonymous class.
177      * @return A new instrumented type that is treated as an anonymous class.
178      */

179     InstrumentedType withAnonymousClass(boolean anonymousClass);
180
181     /**
182      * Creates a new instrumented type that indicates that it defined as a record type. Setting this property to false
183      * removes all record components.
184      *
185      * @param record {@code trueif the instrumented type is supposed to be a record.
186      * @return A new instrumented type that is defined as a record.
187      */

188     InstrumentedType withRecord(boolean record);
189
190     /**
191      * Creates a new instrumented type that indicates that it defined as a sealed type.
192      *
193      * @param sealed {@code trueif the instrumented type is supposed to be sealed.
194      * @return A new instrumented type that is defined as a sealed type if any permitted subclasses are set.
195      */

196     InstrumentedType withSealed(boolean sealed);
197
198     /**
199      * Creates a new instrumented type that includes the given {@link net.bytebuddy.implementation.LoadedTypeInitializer}.
200      *
201      * @param loadedTypeInitializer The type initializer to include.
202      * @return A new instrumented type that is equal to this instrumented type but with the additional type initializer.
203      */

204     InstrumentedType withInitializer(LoadedTypeInitializer loadedTypeInitializer);
205
206     /**
207      * Creates a new instrumented type that executes the given initializer in the instrumented type's
208      * type initializer.
209      *
210      * @param byteCodeAppender The byte code to add to the type initializer.
211      * @return A new instrumented type that is equal to this instrumented type but with the given stack manipulation
212      * attached to its type initializer.
213      */

214     InstrumentedType withInitializer(ByteCodeAppender byteCodeAppender);
215
216     /**
217      * Returns the {@link net.bytebuddy.implementation.LoadedTypeInitializer}s that were registered
218      * for this instrumented type.
219      *
220      * @return The registered loaded type initializers for this instrumented type.
221      */

222     LoadedTypeInitializer getLoadedTypeInitializer();
223
224     /**
225      * Returns this instrumented type's type initializer.
226      *
227      * @return This instrumented type's type initializer.
228      */

229     TypeInitializer getTypeInitializer();
230
231     /**
232      * Validates the instrumented type to define a legal Java type.
233      *
234      * @return This instrumented type as a non-modifiable type description.
235      */

236     TypeDescription validated();
237
238     /**
239      * Implementations represent an {@link InstrumentedType} with a flexible name.
240      */

241     interface WithFlexibleName extends InstrumentedType {
242
243         /**
244          * {@inheritDoc}
245          */

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

251         WithFlexibleName withMethod(MethodDescription.Token token);
252
253         /**
254          * {@inheritDoc}
255          */

256         WithFlexibleName withRecordComponent(RecordComponentDescription.Token token);
257
258         /**
259          * {@inheritDoc}
260          */

261         WithFlexibleName withModifiers(int modifiers);
262
263         /**
264          * {@inheritDoc}
265          */

266         WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes);
267
268         /**
269          * {@inheritDoc}
270          */

271         WithFlexibleName withNestHost(TypeDescription nestHost);
272
273         /**
274          * {@inheritDoc}
275          */

276         WithFlexibleName withNestMembers(TypeList nestMembers);
277
278         /**
279          * {@inheritDoc}
280          */

281         WithFlexibleName withEnclosingType(TypeDescription enclosingType);
282
283         /**
284          * {@inheritDoc}
285          */

286         WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod);
287
288         /**
289          * {@inheritDoc}
290          */

291         WithFlexibleName withDeclaringType(TypeDescription declaringType);
292
293         /**
294          * {@inheritDoc}
295          */

296         WithFlexibleName withDeclaredTypes(TypeList declaredTypes);
297
298         /**
299          * {@inheritDoc}
300          */

301         WithFlexibleName withPermittedSubclasses(TypeList permittedSubclasses);
302
303         /**
304          * {@inheritDoc}
305          */

306         WithFlexibleName withLocalClass(boolean localClass);
307
308         /**
309          * {@inheritDoc}
310          */

311         WithFlexibleName withAnonymousClass(boolean anonymousClass);
312
313         /**
314          * {@inheritDoc}
315          */

316         WithFlexibleName withRecord(boolean record);
317
318         /**
319          * {@inheritDoc}
320          */

321         WithFlexibleName withSealed(boolean sealed);
322
323         /**
324          * {@inheritDoc}
325          */

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

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

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

341         WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender);
342
343         /**
344          * Creates a new instrumented type with a changed name.
345          *
346          * @param name The name of the instrumented type.
347          * @return A new instrumented type that has the given name.
348          */

349         WithFlexibleName withName(String name);
350
351         /**
352          * Applies a transformation onto all existing type variables of this instrumented type. A transformation is potentially unsafe
353          * and it is the responsibility of the supplier to return a valid type variable token from the transformer.
354          *
355          * @param matcher     The matcher to decide what type variables to transform.
356          * @param transformer The transformer to apply on all matched type variables.
357          * @return A new instrumented type with all matched type variables transformed.
358          */

359         WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer);
360     }
361
362     /**
363      * Implementations are able to prepare an {@link InstrumentedType}.
364      */

365     interface Prepareable {
366
367         /**
368          * Prepares a given instrumented type.
369          *
370          * @param instrumentedType The instrumented type in its current form.
371          * @return The prepared instrumented type.
372          */

373         InstrumentedType prepare(InstrumentedType instrumentedType);
374     }
375
376     /**
377      * A factory for creating an {@link InstrumentedType}.
378      */

379     interface Factory {
380
381         /**
382          * Creates an instrumented type that represents the provided type.
383          *
384          * @param typeDescription The type to represent.
385          * @return An appropriate instrumented type.
386          */

387         InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription);
388
389         /**
390          * Creates a new instrumented type as a subclass.
391          *
392          * @param name       The type's name.
393          * @param modifiers  The type's modifiers.
394          * @param superClass The type's super class.
395          * @return A new instrumented type representing a subclass of the given parameters.
396          */

397         InstrumentedType.WithFlexibleName subclass(String name, int modifiers, TypeDescription.Generic superClass);
398
399         /**
400          * Default implementations of instrumented type factories.
401          */

402         enum Default implements Factory {
403
404             /**
405              * A factory for an instrumented type that allows to modify represented types.
406              */

407             MODIFIABLE {
408                 /** {@inheritDoc} */
409                 public InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription) {
410                     return new InstrumentedType.Default(typeDescription.getName(),
411                             typeDescription.getModifiers(),
412                             typeDescription.getSuperClass(),
413                             typeDescription.getTypeVariables().asTokenList(is(typeDescription)),
414                             typeDescription.getInterfaces().accept(Generic.Visitor.Substitutor.ForDetachment.of(typeDescription)),
415                             typeDescription.getDeclaredFields().asTokenList(is(typeDescription)),
416                             typeDescription.getDeclaredMethods().asTokenList(is(typeDescription)),
417                             typeDescription.getRecordComponents().asTokenList(is(typeDescription)),
418                             typeDescription.getDeclaredAnnotations(),
419                             TypeInitializer.None.INSTANCE,
420                             LoadedTypeInitializer.NoOp.INSTANCE,
421                             typeDescription.getDeclaringType(),
422                             typeDescription.getEnclosingMethod(),
423                             typeDescription.getEnclosingType(),
424                             typeDescription.getDeclaredTypes(),
425                             typeDescription.getPermittedSubclasses(),
426                             typeDescription.isAnonymousType(),
427                             typeDescription.isLocalType(),
428                             typeDescription.isRecord(),
429                             typeDescription.isNestHost()
430                                     ? TargetType.DESCRIPTION
431                                     : typeDescription.getNestHost(),
432                             typeDescription.isNestHost()
433                                     ? typeDescription.getNestMembers().filter(not(is(typeDescription)))
434                                     : Collections.<TypeDescription>emptyList());
435                 }
436             },
437
438             /**
439              * A factory for an instrumented type that does not allow to modify represented types.
440              */

441             FROZEN {
442                 /** {@inheritDoc} */
443                 public InstrumentedType.WithFlexibleName represent(TypeDescription typeDescription) {
444                     return new Frozen(typeDescription, LoadedTypeInitializer.NoOp.INSTANCE);
445                 }
446             };
447
448             /**
449              * {@inheritDoc}
450              */

451             public InstrumentedType.WithFlexibleName subclass(String name, int modifiers, TypeDescription.Generic superClass) {
452                 return new InstrumentedType.Default(name,
453                         modifiers,
454                         superClass,
455                         Collections.<TypeVariableToken>emptyList(),
456                         Collections.<Generic>emptyList(),
457                         Collections.<FieldDescription.Token>emptyList(),
458                         Collections.<MethodDescription.Token>emptyList(),
459                         Collections.<RecordComponentDescription.Token>emptyList(),
460                         Collections.<AnnotationDescription>emptyList(),
461                         TypeInitializer.None.INSTANCE,
462                         LoadedTypeInitializer.NoOp.INSTANCE,
463                         TypeDescription.UNDEFINED,
464                         MethodDescription.UNDEFINED,
465                         TypeDescription.UNDEFINED,
466                         Collections.<TypeDescription>emptyList(),
467                         Collections.<TypeDescription>emptyList(),
468                         false,
469                         false,
470                         false,
471                         TargetType.DESCRIPTION,
472                         Collections.<TypeDescription>emptyList());
473             }
474         }
475     }
476
477     /**
478      * A default implementation of an instrumented type.
479      */

480     class Default extends AbstractBase.OfSimpleType implements InstrumentedType.WithFlexibleName {
481
482         /**
483          * A set containing all keywords of the Java programming language.
484          */

485         private static final Set<String> KEYWORDS = new HashSet<String>(Arrays.asList(
486                 "abstract""continue""for""new""switch""assert""default""goto""package""synchronized""boolean",
487                 "do""if""private""this""break""double""implements""protected""throw""byte""else""import",
488                 "public""throws""case""enum""instanceof""return""transient""catch""extends""int""short",
489                 "try""char""final""interface""static""void""class""finally""long""strictfp""volatile",
490                 "const""float""native""super""while"
491         ));
492
493         /**
494          * The binary name of the instrumented type.
495          */

496         private final String name;
497
498         /**
499          * The modifiers of the instrumented type.
500          */

501         private final int modifiers;
502
503         /**
504          * The generic super type of the instrumented type.
505          */

506         private final Generic superClass;
507
508         /**
509          * The instrumented type's type variables in their tokenized form.
510          */

511         private final List<? extends TypeVariableToken> typeVariables;
512
513         /**
514          * A list of interfaces of the instrumented type.
515          */

516         private final List<? extends Generic> interfaceTypes;
517
518         /**
519          * A list of field tokens describing the fields of the instrumented type.
520          */

521         private final List<? extends FieldDescription.Token> fieldTokens;
522
523         /**
524          * A list of method tokens describing the methods of the instrumented type.
525          */

526         private final List<? extends MethodDescription.Token> methodTokens;
527
528         /**
529          * A list of record component tokens describing the record components of the instrumented type.
530          */

531         private final List<? extends RecordComponentDescription.Token> recordComponentTokens;
532
533         /**
534          * A list of annotations of the annotated type.
535          */

536         private final List<? extends AnnotationDescription> annotationDescriptions;
537
538         /**
539          * The type initializer of the instrumented type.
540          */

541         private final TypeInitializer typeInitializer;
542
543         /**
544          * The loaded type initializer of the instrumented type.
545          */

546         private final LoadedTypeInitializer loadedTypeInitializer;
547
548         /**
549          * The declaring type of the instrumented type or {@code nullif no such type exists.
550          */

551         private final TypeDescription declaringType;
552
553         /**
554          * The enclosing method of the instrumented type or {@code nullif no such type exists.
555          */

556         private final MethodDescription.InDefinedShape enclosingMethod;
557
558         /**
559          * The enclosing type of the instrumented type or {@code nullif no such type exists.
560          */

561         private final TypeDescription enclosingType;
562
563         /**
564          * A list of types that are declared by this type.
565          */

566         private final List<? extends TypeDescription> declaredTypes;
567
568         /**
569          * A list of permitted subclasses.
570          */

571         private final List<? extends TypeDescription> permittedSubclasses;
572
573         /**
574          * {@code trueif this type is a anonymous class.
575          */

576         private final boolean anonymousClass;
577
578         /**
579          * {@code trueif this type is a local class.
580          */

581         private final boolean localClass;
582
583         /**
584          * {@code trueif this class is a record class.
585          */

586         private final boolean record;
587
588         /**
589          * The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host.
590          */

591         private final TypeDescription nestHost;
592
593         /**
594          * A list of all members of this types nest group excluding this type.
595          */

596         private final List<? extends TypeDescription> nestMembers;
597
598         /**
599          * Creates a new instrumented type.
600          *
601          * @param name                   The binary name of the instrumented type.
602          * @param modifiers              The modifiers of the instrumented type.
603          * @param typeVariables          The instrumented type's type variables in their tokenized form.
604          * @param superClass             The generic super type of the instrumented type.
605          * @param interfaceTypes         A list of interfaces of the instrumented type.
606          * @param fieldTokens            A list of field tokens describing the fields of the instrumented type.
607          * @param methodTokens           A list of method tokens describing the methods of the instrumented type.
608          * @param recordComponentTokens  A list of record component tokens describing the record components of the instrumented type.
609          * @param annotationDescriptions A list of annotations of the annotated type.
610          * @param typeInitializer        The type initializer of the instrumented type.
611          * @param loadedTypeInitializer  The loaded type initializer of the instrumented type.
612          * @param declaringType          The declaring type of the instrumented type or {@code nullif no such type exists.
613          * @param enclosingMethod        The enclosing method of the instrumented type or {@code nullif no such type exists.
614          * @param enclosingType          The enclosing type of the instrumented type or {@code nullif no such type exists.
615          * @param declaredTypes          A list of types that are declared by this type.
616          * @param permittedSubclasses    A list of permitted subclasses.
617          * @param anonymousClass         {@code trueif this type is a anonymous class.
618          * @param localClass             {@code trueif this type is a local class.
619          * @param record                 {@code trueif this type is a record class.
620          * @param nestHost               The nest host of this instrumented type or a description of {@link TargetType} if this type is its own nest host.
621          * @param nestMembers            A list of all members of this types nest group excluding this type.
622          */

623         protected Default(String name,
624                           int modifiers,
625                           Generic superClass,
626                           List<? extends TypeVariableToken> typeVariables,
627                           List<? extends Generic> interfaceTypes,
628                           List<? extends FieldDescription.Token> fieldTokens,
629                           List<? extends MethodDescription.Token> methodTokens,
630                           List<? extends RecordComponentDescription.Token> recordComponentTokens,
631                           List<? extends AnnotationDescription> annotationDescriptions,
632                           TypeInitializer typeInitializer,
633                           LoadedTypeInitializer loadedTypeInitializer,
634                           TypeDescription declaringType,
635                           MethodDescription.InDefinedShape enclosingMethod,
636                           TypeDescription enclosingType,
637                           List<? extends TypeDescription> declaredTypes,
638                           List<? extends TypeDescription> permittedSubclasses,
639                           boolean anonymousClass,
640                           boolean localClass,
641                           boolean record,
642                           TypeDescription nestHost,
643                           List<? extends TypeDescription> nestMembers) {
644             this.name = name;
645             this.modifiers = modifiers;
646             this.typeVariables = typeVariables;
647             this.superClass = superClass;
648             this.interfaceTypes = interfaceTypes;
649             this.fieldTokens = fieldTokens;
650             this.methodTokens = methodTokens;
651             this.recordComponentTokens = recordComponentTokens;
652             this.annotationDescriptions = annotationDescriptions;
653             this.typeInitializer = typeInitializer;
654             this.loadedTypeInitializer = loadedTypeInitializer;
655             this.declaringType = declaringType;
656             this.enclosingMethod = enclosingMethod;
657             this.enclosingType = enclosingType;
658             this.declaredTypes = declaredTypes;
659             this.permittedSubclasses = permittedSubclasses;
660             this.anonymousClass = anonymousClass;
661             this.localClass = localClass;
662             this.record = record;
663             this.nestHost = nestHost;
664             this.nestMembers = nestMembers;
665         }
666
667         /**
668          * Creates a new instrumented type.
669          *
670          * @param name                The type's name.
671          * @param superClass          The type's super class.
672          * @param modifierContributor The type's modifiers.
673          * @return An appropriate instrumented type.
674          */

675         public static InstrumentedType of(String name, TypeDescription.Generic superClass, ModifierContributor.ForType... modifierContributor) {
676             return of(name, superClass, ModifierContributor.Resolver.of(modifierContributor).resolve());
677         }
678
679         /**
680          * Creates a new instrumented type.
681          *
682          * @param name       The type's name.
683          * @param superClass The type's super class.
684          * @param modifiers  The type's modifiers.
685          * @return An appropriate instrumented type.
686          */

687         public static InstrumentedType of(String name, TypeDescription.Generic superClass, int modifiers) {
688             return Factory.Default.MODIFIABLE.subclass(name, modifiers, superClass);
689         }
690
691         /**
692          * {@inheritDoc}
693          */

694         public WithFlexibleName withModifiers(int modifiers) {
695             return new Default(name,
696                     modifiers,
697                     superClass,
698                     typeVariables,
699                     interfaceTypes,
700                     fieldTokens,
701                     methodTokens,
702                     recordComponentTokens,
703                     annotationDescriptions,
704                     typeInitializer,
705                     loadedTypeInitializer,
706                     declaringType,
707                     enclosingMethod,
708                     enclosingType,
709                     declaredTypes,
710                     permittedSubclasses,
711                     anonymousClass,
712                     localClass,
713                     record,
714                     nestHost,
715                     nestMembers);
716         }
717
718         /**
719          * {@inheritDoc}
720          */

721         public WithFlexibleName withField(FieldDescription.Token token) {
722             return new Default(this.name,
723                     modifiers,
724                     superClass,
725                     typeVariables,
726                     interfaceTypes,
727                     CompoundList.of(fieldTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
728                     methodTokens,
729                     recordComponentTokens,
730                     annotationDescriptions,
731                     typeInitializer,
732                     loadedTypeInitializer,
733                     declaringType,
734                     enclosingMethod,
735                     enclosingType,
736                     declaredTypes,
737                     permittedSubclasses,
738                     anonymousClass,
739                     localClass,
740                     record,
741                     nestHost,
742                     nestMembers);
743         }
744
745         /**
746          * {@inheritDoc}
747          */

748         public WithFlexibleName withMethod(MethodDescription.Token token) {
749             return new Default(name,
750                     modifiers,
751                     superClass,
752                     typeVariables,
753                     interfaceTypes,
754                     fieldTokens,
755                     CompoundList.of(methodTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
756                     recordComponentTokens,
757                     annotationDescriptions,
758                     typeInitializer,
759                     loadedTypeInitializer,
760                     declaringType,
761                     enclosingMethod,
762                     enclosingType,
763                     declaredTypes,
764                     permittedSubclasses,
765                     anonymousClass,
766                     localClass,
767                     record,
768                     nestHost,
769                     nestMembers);
770         }
771
772         /**
773          * {@inheritDoc}
774          */

775         public WithFlexibleName withRecordComponent(RecordComponentDescription.Token token) {
776             return new Default(name,
777                     modifiers,
778                     superClass,
779                     typeVariables,
780                     interfaceTypes,
781                     fieldTokens,
782                     methodTokens,
783                     CompoundList.of(recordComponentTokens, token.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
784                     annotationDescriptions,
785                     typeInitializer,
786                     loadedTypeInitializer,
787                     declaringType,
788                     enclosingMethod,
789                     enclosingType,
790                     declaredTypes,
791                     permittedSubclasses,
792                     anonymousClass,
793                     localClass,
794                     true,
795                     nestHost,
796                     nestMembers);
797         }
798
799         /**
800          * {@inheritDoc}
801          */

802         public WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes) {
803             return new Default(name,
804                     modifiers,
805                     superClass,
806                     typeVariables,
807                     CompoundList.of(this.interfaceTypes, interfaceTypes.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
808                     fieldTokens,
809                     methodTokens,
810                     recordComponentTokens,
811                     annotationDescriptions,
812                     typeInitializer,
813                     loadedTypeInitializer,
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 withAnnotations(List<? extends AnnotationDescription> annotationDescriptions) {
830             return new Default(name,
831                     modifiers,
832                     superClass,
833                     typeVariables,
834                     interfaceTypes,
835                     fieldTokens,
836                     methodTokens,
837                     recordComponentTokens,
838                     CompoundList.of(this.annotationDescriptions, annotationDescriptions),
839                     typeInitializer,
840                     loadedTypeInitializer,
841                     declaringType,
842                     enclosingMethod,
843                     enclosingType,
844                     declaredTypes,
845                     permittedSubclasses,
846                     anonymousClass,
847                     localClass,
848                     record,
849                     nestHost,
850                     nestMembers);
851         }
852
853         /**
854          * {@inheritDoc}
855          */

856         public WithFlexibleName withNestHost(TypeDescription nestHost) {
857             return new Default(name,
858                     modifiers,
859                     superClass,
860                     typeVariables,
861                     interfaceTypes,
862                     fieldTokens,
863                     methodTokens,
864                     recordComponentTokens,
865                     annotationDescriptions,
866                     typeInitializer,
867                     loadedTypeInitializer,
868                     declaringType,
869                     enclosingMethod,
870                     enclosingType,
871                     declaredTypes,
872                     permittedSubclasses,
873                     anonymousClass,
874                     localClass,
875                     record,
876                     nestHost.equals(this)
877                             ? TargetType.DESCRIPTION
878                             : nestHost,
879                     Collections.<TypeDescription>emptyList());
880         }
881
882         /**
883          * {@inheritDoc}
884          */

885         public WithFlexibleName withNestMembers(TypeList nestMembers) {
886             return new Default(name,
887                     modifiers,
888                     superClass,
889                     typeVariables,
890                     interfaceTypes,
891                     fieldTokens,
892                     methodTokens,
893                     recordComponentTokens,
894                     annotationDescriptions,
895                     typeInitializer,
896                     loadedTypeInitializer,
897                     declaringType,
898                     enclosingMethod,
899                     enclosingType,
900                     declaredTypes,
901                     permittedSubclasses,
902                     anonymousClass,
903                     localClass,
904                     record,
905                     TargetType.DESCRIPTION,
906                     CompoundList.of(this.nestMembers, nestMembers));
907         }
908
909         /**
910          * {@inheritDoc}
911          */

912         public WithFlexibleName withEnclosingType(TypeDescription enclosingType) {
913             return new Default(name,
914                     modifiers,
915                     superClass,
916                     typeVariables,
917                     interfaceTypes,
918                     fieldTokens,
919                     methodTokens,
920                     recordComponentTokens,
921                     annotationDescriptions,
922                     typeInitializer,
923                     loadedTypeInitializer,
924                     declaringType,
925                     MethodDescription.UNDEFINED,
926                     enclosingType,
927                     declaredTypes,
928                     permittedSubclasses,
929                     anonymousClass,
930                     localClass,
931                     record,
932                     nestHost,
933                     nestMembers);
934         }
935
936         /**
937          * {@inheritDoc}
938          */

939         public WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod) {
940             return new Default(name,
941                     modifiers,
942                     superClass,
943                     typeVariables,
944                     interfaceTypes,
945                     fieldTokens,
946                     methodTokens,
947                     recordComponentTokens,
948                     annotationDescriptions,
949                     typeInitializer,
950                     loadedTypeInitializer,
951                     declaringType,
952                     enclosingMethod,
953                     enclosingMethod.getDeclaringType(),
954                     declaredTypes,
955                     permittedSubclasses,
956                     anonymousClass,
957                     localClass,
958                     record,
959                     nestHost,
960                     nestMembers);
961         }
962
963         /**
964          * {@inheritDoc}
965          */

966         public WithFlexibleName withDeclaringType(TypeDescription declaringType) {
967             return new Default(name,
968                     modifiers,
969                     superClass,
970                     typeVariables,
971                     interfaceTypes,
972                     fieldTokens,
973                     methodTokens,
974                     recordComponentTokens,
975                     annotationDescriptions,
976                     typeInitializer,
977                     loadedTypeInitializer,
978                     declaringType,
979                     enclosingMethod,
980                     enclosingType,
981                     declaredTypes,
982                     permittedSubclasses,
983                     anonymousClass,
984                     localClass,
985                     record,
986                     nestHost,
987                     nestMembers);
988         }
989
990         /**
991          * {@inheritDoc}
992          */

993         public WithFlexibleName withDeclaredTypes(TypeList declaredTypes) {
994             return new Default(name,
995                     modifiers,
996                     superClass,
997                     typeVariables,
998                     interfaceTypes,
999                     fieldTokens,
1000                     methodTokens,
1001                     recordComponentTokens,
1002                     annotationDescriptions,
1003                     typeInitializer,
1004                     loadedTypeInitializer,
1005                     declaringType,
1006                     enclosingMethod,
1007                     enclosingType,
1008                     CompoundList.of(this.declaredTypes, declaredTypes),
1009                     permittedSubclasses,
1010                     anonymousClass,
1011                     localClass,
1012                     record,
1013                     nestHost,
1014                     nestMembers);
1015         }
1016
1017         /**
1018          * {@inheritDoc}
1019          */

1020         public WithFlexibleName withPermittedSubclasses(TypeList permittedSubclasses) {
1021             return new Default(name,
1022                     modifiers,
1023                     superClass,
1024                     typeVariables,
1025                     interfaceTypes,
1026                     fieldTokens,
1027                     methodTokens,
1028                     recordComponentTokens,
1029                     annotationDescriptions,
1030                     typeInitializer,
1031                     loadedTypeInitializer,
1032                     declaringType,
1033                     enclosingMethod,
1034                     enclosingType,
1035                     declaredTypes,
1036                     CompoundList.of(this.permittedSubclasses, permittedSubclasses),
1037                     anonymousClass,
1038                     localClass,
1039                     record,
1040                     nestHost,
1041                     nestMembers);
1042         }
1043
1044         /**
1045          * {@inheritDoc}
1046          */

1047         public WithFlexibleName withTypeVariable(TypeVariableToken typeVariable) {
1048             return new Default(name,
1049                     modifiers,
1050                     superClass,
1051                     CompoundList.of(typeVariables, typeVariable.accept(Generic.Visitor.Substitutor.ForDetachment.of(this))),
1052                     interfaceTypes,
1053                     fieldTokens,
1054                     methodTokens,
1055                     recordComponentTokens,
1056                     annotationDescriptions,
1057                     typeInitializer,
1058                     loadedTypeInitializer,
1059                     declaringType,
1060                     enclosingMethod,
1061                     enclosingType,
1062                     declaredTypes,
1063                     permittedSubclasses,
1064                     anonymousClass,
1065                     localClass,
1066                     record,
1067                     nestHost,
1068                     nestMembers);
1069         }
1070
1071         /**
1072          * {@inheritDoc}
1073          */

1074         public WithFlexibleName withName(String name) {
1075             return new Default(name,
1076                     modifiers,
1077                     superClass,
1078                     typeVariables,
1079                     interfaceTypes,
1080                     fieldTokens,
1081                     methodTokens,
1082                     recordComponentTokens,
1083                     annotationDescriptions,
1084                     typeInitializer,
1085                     loadedTypeInitializer,
1086                     declaringType,
1087                     enclosingMethod,
1088                     enclosingType,
1089                     declaredTypes,
1090                     permittedSubclasses,
1091                     anonymousClass,
1092                     localClass,
1093                     record,
1094                     nestHost,
1095                     nestMembers);
1096         }
1097
1098         /**
1099          * {@inheritDoc}
1100          */

1101         public WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer) {
1102             List<TypeVariableToken> typeVariables = new ArrayList<TypeVariableToken>(this.typeVariables.size());
1103             int index = 0;
1104             for (TypeVariableToken typeVariableToken : this.typeVariables) {
1105                 typeVariables.add(matcher.matches(getTypeVariables().get(index++))
1106                         ? transformer.transform(this, typeVariableToken)
1107                         : typeVariableToken);
1108             }
1109             return new Default(name,
1110                     modifiers,
1111                     superClass,
1112                     typeVariables,
1113                     interfaceTypes,
1114                     fieldTokens,
1115                     methodTokens,
1116                     recordComponentTokens,
1117                     annotationDescriptions,
1118                     typeInitializer,
1119                     loadedTypeInitializer,
1120                     declaringType,
1121                     enclosingMethod,
1122                     enclosingType,
1123                     declaredTypes,
1124                     permittedSubclasses,
1125                     anonymousClass,
1126                     localClass,
1127                     record,
1128                     nestHost,
1129                     nestMembers);
1130         }
1131
1132         /**
1133          * {@inheritDoc}
1134          */

1135         public WithFlexibleName withLocalClass(boolean localClass) {
1136             return new Default(name,
1137                     modifiers,
1138                     superClass,
1139                     typeVariables,
1140                     interfaceTypes,
1141                     fieldTokens,
1142                     methodTokens,
1143                     recordComponentTokens,
1144                     annotationDescriptions,
1145                     typeInitializer,
1146                     loadedTypeInitializer,
1147                     declaringType,
1148                     enclosingMethod,
1149                     enclosingType,
1150                     declaredTypes,
1151                     permittedSubclasses,
1152                     false,
1153                     localClass,
1154                     record,
1155                     nestHost,
1156                     nestMembers);
1157         }
1158
1159         /**
1160          * {@inheritDoc}
1161          */

1162         public WithFlexibleName withAnonymousClass(boolean anonymousClass) {
1163             return new Default(name,
1164                     modifiers,
1165                     superClass,
1166                     typeVariables,
1167                     interfaceTypes,
1168                     fieldTokens,
1169                     methodTokens,
1170                     recordComponentTokens,
1171                     annotationDescriptions,
1172                     typeInitializer,
1173                     loadedTypeInitializer,
1174                     declaringType,
1175                     enclosingMethod,
1176                     enclosingType,
1177                     declaredTypes,
1178                     permittedSubclasses,
1179                     anonymousClass,
1180                     false,
1181                     record,
1182                     nestHost,
1183                     nestMembers);
1184         }
1185
1186         /**
1187          * {@inheritDoc}
1188          */

1189         public WithFlexibleName withRecord(boolean record) {
1190             return new Default(name,
1191                     modifiers,
1192                     superClass,
1193                     typeVariables,
1194                     interfaceTypes,
1195                     fieldTokens,
1196                     methodTokens,
1197                     record
1198                             ? recordComponentTokens
1199                             : Collections.<RecordComponentDescription.Token>emptyList(),
1200                     annotationDescriptions,
1201                     typeInitializer,
1202                     loadedTypeInitializer,
1203                     declaringType,
1204                     enclosingMethod,
1205                     enclosingType,
1206                     declaredTypes,
1207                     permittedSubclasses,
1208                     anonymousClass,
1209                     localClass,
1210                     record,
1211                     nestHost,
1212                     nestMembers);
1213         }
1214
1215         /**
1216          * {@inheritDoc}
1217          */

1218         public WithFlexibleName withSealed(boolean sealed) {
1219             return new Default(name,
1220                     modifiers,
1221                     superClass,
1222                     typeVariables,
1223                     interfaceTypes,
1224                     fieldTokens,
1225                     methodTokens,
1226                     recordComponentTokens,
1227                     annotationDescriptions,
1228                     typeInitializer,
1229                     loadedTypeInitializer,
1230                     declaringType,
1231                     enclosingMethod,
1232                     enclosingType,
1233                     declaredTypes,
1234                     sealed
1235                         ? permittedSubclasses
1236                         : Collections.<TypeDescription>emptyList(),
1237                     anonymousClass,
1238                     localClass,
1239                     record,
1240                     nestHost,
1241                     nestMembers);
1242         }
1243
1244         /**
1245          * {@inheritDoc}
1246          */

1247         public WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer) {
1248             return new Default(name,
1249                     modifiers,
1250                     superClass,
1251                     typeVariables,
1252                     interfaceTypes,
1253                     fieldTokens,
1254                     methodTokens,
1255                     recordComponentTokens,
1256                     annotationDescriptions,
1257                     typeInitializer,
1258                     new LoadedTypeInitializer.Compound(this.loadedTypeInitializer, loadedTypeInitializer),
1259                     declaringType,
1260                     enclosingMethod,
1261                     enclosingType,
1262                     declaredTypes,
1263                     permittedSubclasses,
1264                     anonymousClass,
1265                     localClass,
1266                     record,
1267                     nestHost,
1268                     nestMembers);
1269         }
1270
1271         /**
1272          * {@inheritDoc}
1273          */

1274         public WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender) {
1275             return new Default(name,
1276                     modifiers,
1277                     superClass,
1278                     typeVariables,
1279                     interfaceTypes,
1280                     fieldTokens,
1281                     methodTokens,
1282                     recordComponentTokens,
1283                     annotationDescriptions,
1284                     typeInitializer.expandWith(byteCodeAppender),
1285                     loadedTypeInitializer,
1286                     declaringType,
1287                     enclosingMethod,
1288                     enclosingType,
1289                     declaredTypes,
1290                     permittedSubclasses,
1291                     anonymousClass,
1292                     localClass,
1293                     record,
1294                     nestHost,
1295                     nestMembers);
1296         }
1297
1298         /**
1299          * {@inheritDoc}
1300          */

1301         public LoadedTypeInitializer getLoadedTypeInitializer() {
1302             return loadedTypeInitializer;
1303         }
1304
1305         /**
1306          * {@inheritDoc}
1307          */

1308         public TypeInitializer getTypeInitializer() {
1309             return typeInitializer;
1310         }
1311
1312         /**
1313          * {@inheritDoc}
1314          */

1315         public MethodDescription.InDefinedShape getEnclosingMethod() {
1316             return enclosingMethod;
1317         }
1318
1319         /**
1320          * {@inheritDoc}
1321          */

1322         public TypeDescription getEnclosingType() {
1323             return enclosingType;
1324         }
1325
1326         /**
1327          * {@inheritDoc}
1328          */

1329         public TypeList getDeclaredTypes() {
1330             return new TypeList.Explicit(declaredTypes);
1331         }
1332
1333         /**
1334          * {@inheritDoc}
1335          */

1336         public boolean isAnonymousType() {
1337             return anonymousClass;
1338         }
1339
1340         /**
1341          * {@inheritDoc}
1342          */

1343         public boolean isLocalType() {
1344             return localClass;
1345         }
1346
1347         /**
1348          * {@inheritDoc}
1349          */

1350         public PackageDescription getPackage() {
1351             int packageIndex = name.lastIndexOf('.');
1352             return new PackageDescription.Simple(packageIndex == -1
1353                     ? EMPTY_NAME
1354                     : name.substring(0, packageIndex));
1355         }
1356
1357         /**
1358          * {@inheritDoc}
1359          */

1360         public AnnotationList getDeclaredAnnotations() {
1361             return new AnnotationList.Explicit(annotationDescriptions);
1362         }
1363
1364         /**
1365          * {@inheritDoc}
1366          */

1367         public TypeDescription getDeclaringType() {
1368             return declaringType;
1369         }
1370
1371         /**
1372          * {@inheritDoc}
1373          */

1374         @CachedReturnPlugin.Enhance
1375         public Generic getSuperClass() {
1376             return superClass == null
1377                     ? Generic.UNDEFINED
1378                     : new Generic.LazyProjection.WithResolvedErasure(superClass, Generic.Visitor.Substitutor.ForAttachment.of(this));
1379         }
1380
1381         /**
1382          * {@inheritDoc}
1383          */

1384         @CachedReturnPlugin.Enhance
1385         public TypeList.Generic getInterfaces() {
1386             return new TypeList.Generic.ForDetachedTypes.WithResolvedErasure(interfaceTypes, TypeDescription.Generic.Visitor.Substitutor.ForAttachment.of(this));
1387         }
1388
1389         /**
1390          * {@inheritDoc}
1391          */

1392         @CachedReturnPlugin.Enhance
1393         public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
1394             return new FieldList.ForTokens(this, fieldTokens);
1395         }
1396
1397         /**
1398          * {@inheritDoc}
1399          */

1400         @CachedReturnPlugin.Enhance
1401         public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
1402             return new MethodList.ForTokens(this, methodTokens);
1403         }
1404
1405         /**
1406          * {@inheritDoc}
1407          */

1408         @CachedReturnPlugin.Enhance
1409         public TypeList.Generic getTypeVariables() {
1410             return TypeList.Generic.ForDetachedTypes.attachVariables(this, typeVariables);
1411         }
1412
1413         /**
1414          * {@inheritDoc}
1415          */

1416         public int getModifiers() {
1417             return modifiers;
1418         }
1419
1420         /**
1421          * {@inheritDoc}
1422          */

1423         public String getName() {
1424             return name;
1425         }
1426
1427         /**
1428          * {@inheritDoc}
1429          */

1430         public TypeDescription getNestHost() {
1431             return nestHost.represents(TargetType.class)
1432                     ? this
1433                     : nestHost;
1434         }
1435
1436         /**
1437          * {@inheritDoc}
1438          */

1439         public TypeList getNestMembers() {
1440             return nestHost.represents(TargetType.class)
1441                     ? new TypeList.Explicit(CompoundList.of(this, nestMembers))
1442                     : nestHost.getNestMembers();
1443         }
1444
1445         /**
1446          * {@inheritDoc}
1447          */

1448         public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
1449             return new RecordComponentList.ForTokens(this, recordComponentTokens);
1450         }
1451
1452         /**
1453          * {@inheritDoc}
1454          */

1455         public boolean isRecord() {
1456             return record && getSuperClass().asErasure().equals(JavaType.RECORD.getTypeStub());
1457         }
1458
1459         /**
1460          * {@inheritDoc}
1461          */

1462         public TypeList getPermittedSubclasses() {
1463             return new TypeList.Explicit(permittedSubclasses);
1464         }
1465
1466         /**
1467          * {@inheritDoc}
1468          */

1469         public TypeDescription validated() {
1470             if (!isValidIdentifier(getName().split("\\."))) {
1471                 throw new IllegalStateException("Illegal type name: " + getName() + for " + this);
1472             } else if ((getModifiers() & ~ModifierContributor.ForType.MASK) != EMPTY_MASK) {
1473                 throw new IllegalStateException("Illegal modifiers " + getModifiers() + for " + this);
1474             } else if (isPackageType() && getModifiers() != PackageDescription.PACKAGE_MODIFIERS) {
1475                 throw new IllegalStateException("Illegal modifiers " + getModifiers() + for package " + this);
1476             }
1477             TypeDescription.Generic superClass = getSuperClass();
1478             if (superClass != null) {
1479                 if (!superClass.accept(Generic.Visitor.Validator.SUPER_CLASS)) {
1480                     throw new IllegalStateException("Illegal super class " + superClass + for " + this);
1481                 } else if (!superClass.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1482                     throw new IllegalStateException("Illegal type annotations on super class " + superClass + for " + this);
1483                 } else if (!superClass.asErasure().isVisibleTo(this)) {
1484                     throw new IllegalStateException("Invisible super type " + superClass + for " + this);
1485                 }
1486             }
1487             Set<TypeDescription> interfaceErasures = new HashSet<TypeDescription>();
1488             for (TypeDescription.Generic interfaceType : getInterfaces()) {
1489                 if (!interfaceType.accept(Generic.Visitor.Validator.INTERFACE)) {
1490                     throw new IllegalStateException("Illegal interface " + interfaceType + for " + this);
1491                 } else if (!interfaceType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1492                     throw new IllegalStateException("Illegal type annotations on interface " + interfaceType + for " + this);
1493                 } else if (!interfaceErasures.add(interfaceType.asErasure())) {
1494                     throw new IllegalStateException("Already implemented interface " + interfaceType + for " + this);
1495                 } else if (!interfaceType.asErasure().isVisibleTo(this)) {
1496                     throw new IllegalStateException("Invisible interface type " + interfaceType + for " + this);
1497                 }
1498             }
1499             TypeList.Generic typeVariables = getTypeVariables();
1500             if (!typeVariables.isEmpty() && isAssignableTo(Throwable.class)) {
1501                 throw new IllegalStateException("Cannot define throwable " + this + " to be generic");
1502             }
1503             Set<String> typeVariableNames = new HashSet<String>();
1504             for (TypeDescription.Generic typeVariable : typeVariables) {
1505                 String variableSymbol = typeVariable.getSymbol();
1506                 if (!typeVariableNames.add(variableSymbol)) {
1507                     throw new IllegalStateException("Duplicate type variable symbol '" + typeVariable + "' for " + this);
1508                 } else if (!isValidIdentifier(variableSymbol)) {
1509                     throw new IllegalStateException("Illegal type variable name '" + typeVariable + "' for " + this);
1510                 } else if (!Generic.Visitor.Validator.ForTypeAnnotations.ofFormalTypeVariable(typeVariable)) {
1511                     throw new IllegalStateException("Illegal type annotation on '" + typeVariable + "' for " + this);
1512                 }
1513                 boolean interfaceBound = false;
1514                 Set<TypeDescription.Generic> bounds = new HashSet<Generic>();
1515                 for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) {
1516                     if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) {
1517                         throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + for " + this);
1518                     } else if (!bound.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1519                         throw new IllegalStateException("Illegal type annotations on type variable " + bound + for " + this);
1520                     } else if (!bounds.add(bound)) {
1521                         throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + for " + this);
1522                     } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) {
1523                         throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + for " + this);
1524                     }
1525                     interfaceBound = true;
1526                 }
1527                 if (!interfaceBound) {
1528                     throw new IllegalStateException("Type variable " + typeVariable + for " + this + " does not define at least one bound");
1529                 }
1530             }
1531             TypeDescription enclosingType = getEnclosingType();
1532             if (enclosingType != null && (enclosingType.isArray() || enclosingType.isPrimitive())) {
1533                 throw new IllegalStateException("Cannot define array type or primitive type " + enclosingType + " + as enclosing type for " + this);
1534             }
1535             MethodDescription.InDefinedShape enclosingMethod = getEnclosingMethod();
1536             if (enclosingMethod != null && enclosingMethod.isTypeInitializer()) {
1537                 throw new IllegalStateException("Cannot enclose type declaration in class initializer " + enclosingMethod);
1538             }
1539             TypeDescription declaringType = getDeclaringType();
1540             if (declaringType != null) {
1541                 if (declaringType.isPrimitive() || declaringType.isArray()) {
1542                     throw new IllegalStateException("Cannot define array type or primitive type " + declaringType + " as declaring type for " + this);
1543                 }
1544             } else if (enclosingType == null && enclosingMethod == null && (isLocalType() || isAnonymousType())) {
1545                 throw new IllegalStateException("Cannot define an anonymous or local class without a declaring type for " + this);
1546             }
1547             Set<TypeDescription> declaredTypes = new HashSet<TypeDescription>();
1548             for (TypeDescription declaredType : getDeclaredTypes()) {
1549                 if (declaredType.isArray() || declaredType.isPrimitive()) {
1550                     throw new IllegalStateException("Cannot define array type or primitive type " + declaredType + " + as declared type for " + this);
1551                 } else if (!declaredTypes.add(declaredType)) {
1552                     throw new IllegalStateException("Duplicate definition of declared type " + declaredType);
1553                 }
1554             }
1555             TypeDescription nestHost = getNestHost();
1556             if (nestHost.equals(this)) {
1557                 Set<TypeDescription> nestMembers = new HashSet<TypeDescription>();
1558                 for (TypeDescription nestMember : getNestMembers()) {
1559                     if (nestMember.isArray() || nestMember.isPrimitive()) {
1560                         throw new IllegalStateException("Cannot define array type or primitive type " + nestMember + " + as nest member of " + this);
1561                     } else if (!nestMember.isSamePackage(this)) {
1562                         throw new IllegalStateException("Cannot define nest member " + nestMember + " + within different package then " + this);
1563                     } else if (!nestMembers.add(nestMember)) {
1564                         throw new IllegalStateException("Duplicate definition of nest member " + nestMember);
1565                     }
1566                 }
1567             } else if (nestHost.isArray() || nestHost.isPrimitive()) {
1568                 throw new IllegalStateException("Cannot define array type or primitive type " + nestHost + " + as nest host for " + this);
1569             } else if (!nestHost.isSamePackage(this)) {
1570                 throw new IllegalStateException("Cannot define nest host " + nestHost + " + within different package then " + this);
1571             }
1572             for (TypeDescription permittedSubclass : getPermittedSubclasses()) {
1573                 if (!permittedSubclass.isAssignableTo(this) || permittedSubclass.equals(this)) {
1574                     throw new IllegalStateException("Cannot assign permitted subclass " + permittedSubclass + " to " + this);
1575                 }
1576             }
1577             Set<TypeDescription> typeAnnotationTypes = new HashSet<TypeDescription>();
1578             for (AnnotationDescription annotationDescription : getDeclaredAnnotations()) {
1579                 if (!annotationDescription.getElementTypes().contains(ElementType.TYPE)
1580                         && !(isAnnotation() && annotationDescription.getElementTypes().contains(ElementType.ANNOTATION_TYPE))
1581                         && !(isPackageType() && annotationDescription.getElementTypes().contains(ElementType.PACKAGE))) {
1582                     throw new IllegalStateException("Cannot add " + annotationDescription + " on " + this);
1583                 } else if (!typeAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1584                     throw new IllegalStateException("Duplicate annotation " + annotationDescription + for " + this);
1585                 }
1586             }
1587             Set<FieldDescription.SignatureToken> fieldSignatureTokens = new HashSet<FieldDescription.SignatureToken>();
1588             for (FieldDescription.InDefinedShape fieldDescription : getDeclaredFields()) {
1589                 String fieldName = fieldDescription.getName();
1590                 if (!fieldSignatureTokens.add(fieldDescription.asSignatureToken())) {
1591                     throw new IllegalStateException("Duplicate field definition for " + fieldDescription);
1592                 } else if (!isValidIdentifier(fieldName)) {
1593                     throw new IllegalStateException("Illegal field name for " + fieldDescription);
1594                 } else if ((fieldDescription.getModifiers() & ~ModifierContributor.ForField.MASK) != EMPTY_MASK) {
1595                     throw new IllegalStateException("Illegal field modifiers " + fieldDescription.getModifiers() + for " + fieldDescription);
1596                 }
1597                 Generic fieldType = fieldDescription.getType();
1598                 if (!fieldType.accept(Generic.Visitor.Validator.FIELD)) {
1599                     throw new IllegalStateException("Illegal field type " + fieldType + for " + fieldDescription);
1600                 } else if (!fieldType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1601                     throw new IllegalStateException("Illegal type annotations on " + fieldType + for " + this);
1602                 } else if (!fieldDescription.isSynthetic() && !fieldType.asErasure().isVisibleTo(this)) {
1603                     throw new IllegalStateException("Invisible field type " + fieldDescription.getType() + for " + fieldDescription);
1604                 }
1605                 Set<TypeDescription> fieldAnnotationTypes = new HashSet<TypeDescription>();
1606                 for (AnnotationDescription annotationDescription : fieldDescription.getDeclaredAnnotations()) {
1607                     if (!annotationDescription.getElementTypes().contains(ElementType.FIELD)) {
1608                         throw new IllegalStateException("Cannot add " + annotationDescription + " on " + fieldDescription);
1609                     } else if (!fieldAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1610                         throw new IllegalStateException("Duplicate annotation " + annotationDescription + for " + fieldDescription);
1611                     }
1612                 }
1613             }
1614             Set<MethodDescription.SignatureToken> methodSignatureTokens = new HashSet<MethodDescription.SignatureToken>();
1615             for (MethodDescription.InDefinedShape methodDescription : getDeclaredMethods()) {
1616                 if (!methodSignatureTokens.add(methodDescription.asSignatureToken())) {
1617                     throw new IllegalStateException("Duplicate method signature for " + methodDescription);
1618                 } else if ((methodDescription.getModifiers() & ~ModifierContributor.ForMethod.MASK) != 0) {
1619                     throw new IllegalStateException("Illegal modifiers " + methodDescription.getModifiers() + for " + methodDescription);
1620                 } else if (isInterface() && !methodDescription.isPublic() && !methodDescription.isPrivate()) {
1621                     throw new IllegalStateException("Methods declared by an interface must be public or private " + methodDescription);
1622                 }
1623                 Set<String> methodTypeVariableNames = new HashSet<String>();
1624                 for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
1625                     String variableSymbol = typeVariable.getSymbol();
1626                     if (!methodTypeVariableNames.add(variableSymbol)) {
1627                         throw new IllegalStateException("Duplicate type variable symbol '" + typeVariable + "' for " + methodDescription);
1628                     } else if (!isValidIdentifier(variableSymbol)) {
1629                         throw new IllegalStateException("Illegal type variable name '" + typeVariable + "' for " + methodDescription);
1630                     } else if (!Generic.Visitor.Validator.ForTypeAnnotations.ofFormalTypeVariable(typeVariable)) {
1631                         throw new IllegalStateException("Illegal type annotation on '" + typeVariable + "' for " + methodDescription);
1632                     }
1633                     boolean interfaceBound = false;
1634                     Set<TypeDescription.Generic> bounds = new HashSet<Generic>();
1635                     for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) {
1636                         if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) {
1637                             throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + for " + methodDescription);
1638                         } else if (!bound.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1639                             throw new IllegalStateException("Illegal type annotations on bound " + bound + " of " + typeVariable + for " + this);
1640                         } else if (!bounds.add(bound)) {
1641                             throw new IllegalStateException("Duplicate bound " + bound + " of " + typeVariable + for " + methodDescription);
1642                         } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.isInterface())) {
1643                             throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + for " + methodDescription);
1644                         }
1645                         interfaceBound = true;
1646                     }
1647                     if (!interfaceBound) {
1648                         throw new IllegalStateException("Type variable " + typeVariable + for " + methodDescription + " does not define at least one bound");
1649                     }
1650                 }
1651                 Generic returnType = methodDescription.getReturnType();
1652                 if (methodDescription.isTypeInitializer()) {
1653                     throw new IllegalStateException("Illegal explicit declaration of a type initializer by " + this);
1654                 } else if (methodDescription.isConstructor()) {
1655                     if (!returnType.represents(void.class)) {
1656                         throw new IllegalStateException("A constructor must return void " + methodDescription);
1657                     } else if (!returnType.getDeclaredAnnotations().isEmpty()) {
1658                         throw new IllegalStateException("The void non-type must not be annotated for " + methodDescription);
1659                     }
1660                 } else if (!isValidIdentifier(methodDescription.getInternalName())) {
1661                     throw new IllegalStateException("Illegal method name " + returnType + for " + methodDescription);
1662                 } else if (!returnType.accept(Generic.Visitor.Validator.METHOD_RETURN)) {
1663                     throw new IllegalStateException("Illegal return type " + returnType + for " + methodDescription);
1664                 } else if (!returnType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1665                     throw new IllegalStateException("Illegal type annotations on return type " + returnType + for " + methodDescription);
1666                 } else if (!methodDescription.isSynthetic() && !methodDescription.getReturnType().asErasure().isVisibleTo(this)) {
1667                     throw new IllegalStateException("Invisible return type " + methodDescription.getReturnType() + for " + methodDescription);
1668                 }
1669                 Set<String> parameterNames = new HashSet<String>();
1670                 for (ParameterDescription.InDefinedShape parameterDescription : methodDescription.getParameters()) {
1671                     Generic parameterType = parameterDescription.getType();
1672                     if (!parameterType.accept(Generic.Visitor.Validator.METHOD_PARAMETER)) {
1673                         throw new IllegalStateException("Illegal parameter type of " + parameterDescription + for " + methodDescription);
1674                     } else if (!parameterType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1675                         throw new IllegalStateException("Illegal type annotations on parameter " + parameterDescription + for " + methodDescription);
1676                     } else if (!methodDescription.isSynthetic() && !parameterType.asErasure().isVisibleTo(this)) {
1677                         throw new IllegalStateException("Invisible parameter type of " + parameterDescription + for " + methodDescription);
1678                     }
1679                     if (parameterDescription.isNamed()) {
1680                         String parameterName = parameterDescription.getName();
1681                         if (!parameterNames.add(parameterName)) {
1682                             throw new IllegalStateException("Duplicate parameter name of " + parameterDescription + for " + methodDescription);
1683                         } else if (!isValidIdentifier(parameterName)) {
1684                             throw new IllegalStateException("Illegal parameter name of " + parameterDescription + for " + methodDescription);
1685                         }
1686                     }
1687                     if (parameterDescription.hasModifiers() && (parameterDescription.getModifiers() & ~ModifierContributor.ForParameter.MASK) != EMPTY_MASK) {
1688                         throw new IllegalStateException("Illegal modifiers of " + parameterDescription + for " + methodDescription);
1689                     }
1690                     Set<TypeDescription> parameterAnnotationTypes = new HashSet<TypeDescription>();
1691                     for (AnnotationDescription annotationDescription : parameterDescription.getDeclaredAnnotations()) {
1692                         if (!annotationDescription.getElementTypes().contains(ElementType.PARAMETER)) {
1693                             throw new IllegalStateException("Cannot add " + annotationDescription + " on " + parameterDescription);
1694                         } else if (!parameterAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1695                             throw new IllegalStateException("Duplicate annotation " + annotationDescription + " of " + parameterDescription + for " + methodDescription);
1696                         }
1697                     }
1698                 }
1699                 for (TypeDescription.Generic exceptionType : methodDescription.getExceptionTypes()) {
1700                     if (!exceptionType.accept(Generic.Visitor.Validator.EXCEPTION)) {
1701                         throw new IllegalStateException("Illegal exception type " + exceptionType + for " + methodDescription);
1702                     } else if (!exceptionType.accept(Generic.Visitor.Validator.ForTypeAnnotations.INSTANCE)) {
1703                         throw new IllegalStateException("Illegal type annotations on " + exceptionType + for " + methodDescription);
1704                     } else if (!methodDescription.isSynthetic() && !exceptionType.asErasure().isVisibleTo(this)) {
1705                         throw new IllegalStateException("Invisible exception type " + exceptionType + for " + methodDescription);
1706                     }
1707                 }
1708                 Set<TypeDescription> methodAnnotationTypes = new HashSet<TypeDescription>();
1709                 for (AnnotationDescription annotationDescription : methodDescription.getDeclaredAnnotations()) {
1710                     if (!annotationDescription.getElementTypes().contains(methodDescription.isMethod() ? ElementType.METHOD : ElementType.CONSTRUCTOR)) {
1711                         throw new IllegalStateException("Cannot add " + annotationDescription + " on " + methodDescription);
1712                     } else if (!methodAnnotationTypes.add(annotationDescription.getAnnotationType())) {
1713                         throw new IllegalStateException("Duplicate annotation " + annotationDescription + for " + methodDescription);
1714                     }
1715                 }
1716                 AnnotationValue<?, ?> defaultValue = methodDescription.getDefaultValue();
1717                 if (defaultValue != null && !methodDescription.isDefaultValue(defaultValue)) {
1718                     throw new IllegalStateException("Illegal default value " + defaultValue + "for " + methodDescription);
1719                 }
1720                 Generic receiverType = methodDescription.getReceiverType();
1721                 if (receiverType != null && !receiverType.accept(Generic.Visitor.Validator.RECEIVER)) {
1722                     throw new IllegalStateException("Illegal receiver type " + receiverType + for " + methodDescription);
1723                 } else if (methodDescription.isStatic()) {
1724                     if (receiverType != null) {
1725                         throw new IllegalStateException("Static method " + methodDescription + " defines a non-null receiver " + receiverType);
1726                     }
1727                 } else if (methodDescription.isConstructor()) {
1728                     if (receiverType == null || !receiverType.asErasure().equals(enclosingType == null ? this : enclosingType)) {
1729                         throw new IllegalStateException("Constructor " + methodDescription + " defines an illegal receiver " + receiverType);
1730                     }
1731                 } else if (/* methodDescription.isMethod() */ receiverType == null || !equals(receiverType.asErasure())) {
1732                     throw new IllegalStateException("Method " + methodDescription + " defines an illegal receiver " + receiverType);
1733                 }
1734             }
1735             return this;
1736         }
1737
1738         /**
1739          * Checks if an array of identifiers is a valid compound Java identifier.
1740          *
1741          * @param identifier an array of potentially invalid Java identifiers.
1742          * @return {@code trueif all identifiers are valid and the array is not empty.
1743          */

1744         private static boolean isValidIdentifier(String[] identifier) {
1745             if (identifier.length == 0) {
1746                 return false;
1747             }
1748             for (String part : identifier) {
1749                 if (!isValidIdentifier(part)) {
1750                     return false;
1751                 }
1752             }
1753             return true;
1754         }
1755
1756         /**
1757          * Checks if a Java identifier is valid.
1758          *
1759          * @param identifier The identifier to check for validity.
1760          * @return {@code trueif the given identifier is valid.
1761          */

1762         private static boolean isValidIdentifier(String identifier) {
1763             if (KEYWORDS.contains(identifier) || identifier.length() == 0 || !Character.isJavaIdentifierStart(identifier.charAt(0))) {
1764                 return false;
1765             } else if (identifier.equals(PackageDescription.PACKAGE_CLASS_NAME)) {
1766                 return true;
1767             }
1768             for (int index = 1; index < identifier.length(); index++) {
1769                 if (!Character.isJavaIdentifierPart(identifier.charAt(index))) {
1770                     return false;
1771                 }
1772             }
1773             return true;
1774         }
1775     }
1776
1777     /**
1778      * A frozen representation of an instrumented type of which the structure must not be modified.
1779      */

1780     class Frozen extends AbstractBase.OfSimpleType implements InstrumentedType.WithFlexibleName {
1781
1782         /**
1783          * The represented type description.
1784          */

1785         private final TypeDescription typeDescription;
1786
1787         /**
1788          * The type's loaded type initializer.
1789          */

1790         private final LoadedTypeInitializer loadedTypeInitializer;
1791
1792         /**
1793          * Creates a new frozen representation of an instrumented type.
1794          *
1795          * @param typeDescription       The represented type description.
1796          * @param loadedTypeInitializer The type's loaded type initializer.
1797          */

1798         protected Frozen(TypeDescription typeDescription, LoadedTypeInitializer loadedTypeInitializer) {
1799             this.typeDescription = typeDescription;
1800             this.loadedTypeInitializer = loadedTypeInitializer;
1801         }
1802
1803         /**
1804          * {@inheritDoc}
1805          */

1806         public AnnotationList getDeclaredAnnotations() {
1807             return typeDescription.getDeclaredAnnotations();
1808         }
1809
1810         /**
1811          * {@inheritDoc}
1812          */

1813         public int getModifiers() {
1814             return typeDescription.getModifiers();
1815         }
1816
1817         /**
1818          * {@inheritDoc}
1819          */

1820         public TypeList.Generic getTypeVariables() {
1821             return typeDescription.getTypeVariables();
1822         }
1823
1824         /**
1825          * {@inheritDoc}
1826          */

1827         public String getName() {
1828             return typeDescription.getName();
1829         }
1830
1831         /**
1832          * {@inheritDoc}
1833          */

1834         public Generic getSuperClass() {
1835             return typeDescription.getSuperClass();
1836         }
1837
1838         /**
1839          * {@inheritDoc}
1840          */

1841         public TypeList.Generic getInterfaces() {
1842             return typeDescription.getInterfaces();
1843         }
1844
1845         /**
1846          * {@inheritDoc}
1847          */

1848         public FieldList<FieldDescription.InDefinedShape> getDeclaredFields() {
1849             return typeDescription.getDeclaredFields();
1850         }
1851
1852         /**
1853          * {@inheritDoc}
1854          */

1855         public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
1856             return typeDescription.getDeclaredMethods();
1857         }
1858
1859         /**
1860          * {@inheritDoc}
1861          */

1862         public boolean isAnonymousType() {
1863             return typeDescription.isAnonymousType();
1864         }
1865
1866         /**
1867          * {@inheritDoc}
1868          */

1869         public boolean isLocalType() {
1870             return typeDescription.isLocalType();
1871         }
1872
1873         /**
1874          * {@inheritDoc}
1875          */

1876         public PackageDescription getPackage() {
1877             return typeDescription.getPackage();
1878         }
1879
1880         /**
1881          * {@inheritDoc}
1882          */

1883         public TypeDescription getEnclosingType() {
1884             return typeDescription.getEnclosingType();
1885         }
1886
1887         /**
1888          * {@inheritDoc}
1889          */

1890         public TypeDescription getDeclaringType() {
1891             return typeDescription.getDeclaringType();
1892         }
1893
1894         /**
1895          * {@inheritDoc}
1896          */

1897         public TypeList getDeclaredTypes() {
1898             return typeDescription.getDeclaredTypes();
1899         }
1900
1901         /**
1902          * {@inheritDoc}
1903          */

1904         public MethodDescription.InDefinedShape getEnclosingMethod() {
1905             return typeDescription.getEnclosingMethod();
1906         }
1907
1908         /**
1909          * {@inheritDoc}
1910          */

1911         public String getGenericSignature() {
1912             // Embrace use of native generic signature by direct delegation.
1913             return typeDescription.getGenericSignature();
1914         }
1915
1916         /**
1917          * {@inheritDoc}
1918          */

1919         public int getActualModifiers(boolean superFlag) {
1920             // Embrace use of native actual modifiers by direct delegation.
1921             return typeDescription.getActualModifiers(superFlag);
1922         }
1923
1924         /**
1925          * {@inheritDoc}
1926          */

1927         public TypeDescription getNestHost() {
1928             return typeDescription.getNestHost();
1929         }
1930
1931         /**
1932          * {@inheritDoc}
1933          */

1934         public TypeList getNestMembers() {
1935             return typeDescription.getNestMembers();
1936         }
1937
1938         /**
1939          * {@inheritDoc}
1940          */

1941         public RecordComponentList<RecordComponentDescription.InDefinedShape> getRecordComponents() {
1942             return typeDescription.getRecordComponents();
1943         }
1944
1945         /**
1946          * {@inheritDoc}
1947          */

1948         public boolean isRecord() {
1949             return typeDescription.isRecord();
1950         }
1951
1952         /**
1953          * {@inheritDoc}
1954          */

1955         public TypeList getPermittedSubclasses() {
1956             return typeDescription.getPermittedSubclasses();
1957         }
1958
1959         /**
1960          * {@inheritDoc}
1961          */

1962         public WithFlexibleName withField(FieldDescription.Token token) {
1963             throw new IllegalStateException("Cannot define field for frozen type: " + typeDescription);
1964         }
1965
1966         /**
1967          * {@inheritDoc}
1968          */

1969         public WithFlexibleName withMethod(MethodDescription.Token token) {
1970             throw new IllegalStateException("Cannot define method for frozen type: " + typeDescription);
1971         }
1972
1973         /**
1974          * {@inheritDoc}
1975          */

1976         public WithFlexibleName withRecordComponent(RecordComponentDescription.Token token) {
1977             throw new IllegalStateException("Cannot define record component for frozen type: " + typeDescription);
1978         }
1979
1980         /**
1981          * {@inheritDoc}
1982          */

1983         public WithFlexibleName withModifiers(int modifiers) {
1984             throw new IllegalStateException("Cannot change modifiers for frozen type: " + typeDescription);
1985         }
1986
1987         /**
1988          * {@inheritDoc}
1989          */

1990         public WithFlexibleName withInterfaces(TypeList.Generic interfaceTypes) {
1991             throw new IllegalStateException("Cannot add interfaces for frozen type: " + typeDescription);
1992         }
1993
1994         /**
1995          * {@inheritDoc}
1996          */

1997         public WithFlexibleName withTypeVariable(TypeVariableToken typeVariable) {
1998             throw new IllegalStateException("Cannot define type variable for frozen type: " + typeDescription);
1999         }
2000
2001         /**
2002          * {@inheritDoc}
2003          */

2004         public WithFlexibleName withAnnotations(List<? extends AnnotationDescription> annotationDescriptions) {
2005             throw new IllegalStateException("Cannot add annotation to frozen type: " + typeDescription);
2006         }
2007
2008         /**
2009          * {@inheritDoc}
2010          */

2011         public WithFlexibleName withNestHost(TypeDescription nestHost) {
2012             throw new IllegalStateException("Cannot set nest host of frozen type: " + typeDescription);
2013         }
2014
2015         /**
2016          * {@inheritDoc}
2017          */

2018         public WithFlexibleName withNestMembers(TypeList nestMembers) {
2019             throw new IllegalStateException("Cannot add nest members to frozen type: " + typeDescription);
2020         }
2021
2022         /**
2023          * {@inheritDoc}
2024          */

2025         public WithFlexibleName withEnclosingType(TypeDescription enclosingType) {
2026             throw new IllegalStateException("Cannot set enclosing type of frozen type: " + typeDescription);
2027         }
2028
2029         /**
2030          * {@inheritDoc}
2031          */

2032         public WithFlexibleName withEnclosingMethod(MethodDescription.InDefinedShape enclosingMethod) {
2033             throw new IllegalStateException("Cannot set enclosing method of frozen type: " + typeDescription);
2034         }
2035
2036         /**
2037          * {@inheritDoc}
2038          */

2039         public WithFlexibleName withDeclaringType(TypeDescription declaringType) {
2040             throw new IllegalStateException("Cannot add declaring type to frozen type: " + typeDescription);
2041         }
2042
2043         /**
2044          * {@inheritDoc}
2045          */

2046         public WithFlexibleName withDeclaredTypes(TypeList declaredTypes) {
2047             throw new IllegalStateException("Cannot add declared types to frozen type: " + typeDescription);
2048         }
2049
2050         /**
2051          * {@inheritDoc}
2052          */

2053         public WithFlexibleName withPermittedSubclasses(TypeList permittedSubclasses) {
2054             throw new IllegalStateException("Cannot add permitted subclasses to frozen type: " + typeDescription);
2055         }
2056
2057         /**
2058          * {@inheritDoc}
2059          */

2060         public WithFlexibleName withLocalClass(boolean localClass) {
2061             throw new IllegalStateException("Cannot define local class state for frozen type: " + typeDescription);
2062         }
2063
2064         /**
2065          * {@inheritDoc}
2066          */

2067         public WithFlexibleName withAnonymousClass(boolean anonymousClass) {
2068             throw new IllegalStateException("Cannot define anonymous class state for frozen type: " + typeDescription);
2069         }
2070
2071         /**
2072          * {@inheritDoc}
2073          */

2074         public WithFlexibleName withRecord(boolean record) {
2075             throw new IllegalStateException("Cannot define record state for frozen type: " + typeDescription);
2076         }
2077
2078         /**
2079          * {@inheritDoc}
2080          */

2081         public WithFlexibleName withSealed(boolean sealed) {
2082             throw new IllegalStateException("Cannot define seal state for frozen type: " + typeDescription);
2083         }
2084
2085         /**
2086          * {@inheritDoc}
2087          */

2088         public WithFlexibleName withInitializer(LoadedTypeInitializer loadedTypeInitializer) {
2089             return new Frozen(typeDescription, new LoadedTypeInitializer.Compound(this.loadedTypeInitializer, loadedTypeInitializer));
2090         }
2091
2092         /**
2093          * {@inheritDoc}
2094          */

2095         public WithFlexibleName withInitializer(ByteCodeAppender byteCodeAppender) {
2096             throw new IllegalStateException("Cannot add initializer to frozen type: " + typeDescription);
2097         }
2098
2099         /**
2100          * {@inheritDoc}
2101          */

2102         public WithFlexibleName withName(String name) {
2103             throw new IllegalStateException("Cannot change name of frozen type: " + typeDescription);
2104         }
2105
2106         /**
2107          * {@inheritDoc}
2108          */

2109         public WithFlexibleName withTypeVariables(ElementMatcher<? super Generic> matcher, Transformer<TypeVariableToken> transformer) {
2110             throw new IllegalStateException("Cannot add type variables of frozen type: " + typeDescription);
2111         }
2112
2113         /**
2114          * {@inheritDoc}
2115          */

2116         public LoadedTypeInitializer getLoadedTypeInitializer() {
2117             return loadedTypeInitializer;
2118         }
2119
2120         /**
2121          * {@inheritDoc}
2122          */

2123         public TypeInitializer getTypeInitializer() {
2124             return TypeInitializer.None.INSTANCE;
2125         }
2126
2127         /**
2128          * {@inheritDoc}
2129          */

2130         public TypeDescription validated() {
2131             return typeDescription;
2132         }
2133     }
2134 }
2135