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.description.method;
17
18 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import net.bytebuddy.build.HashCodeAndEqualsPlugin;
20 import net.bytebuddy.description.ByteCodeElement;
21 import net.bytebuddy.description.type.TypeDefinition;
22 import net.bytebuddy.description.type.TypeDescription;
23 import net.bytebuddy.description.type.TypeList;
24 import net.bytebuddy.matcher.ElementMatcher;
25 import net.bytebuddy.matcher.FilterableList;
26
27 import java.lang.reflect.Constructor;
28 import java.lang.reflect.InvocationTargetException;
29 import java.lang.reflect.Method;
30 import java.security.AccessController;
31 import java.security.PrivilegedAction;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35
36 /**
37  * Represents a list of parameters of a method or a constructor.
38  *
39  * @param <T> The type of parameter descriptions represented by this list.
40  */

41 public interface ParameterList<T extends ParameterDescription> extends FilterableList<T, ParameterList<T>> {
42
43     /**
44      * Transforms this list of parameters into a list of the types of the represented parameters.
45      *
46      * @return A list of types representing the parameters of this list.
47      */

48     TypeList.Generic asTypeList();
49
50     /**
51      * Transforms the list of parameter descriptions into a list of detached tokens. All types that are matched by the provided
52      * target type matcher are substituted by {@link net.bytebuddy.dynamic.TargetType}.
53      *
54      * @param matcher A matcher that indicates type substitution.
55      * @return The transformed token list.
56      */

57     ByteCodeElement.Token.TokenList<ParameterDescription.Token> asTokenList(ElementMatcher<? super TypeDescription> matcher);
58
59     /**
60      * Returns this list of these parameter descriptions resolved to their defined shape.
61      *
62      * @return A list of parameters in their defined shape.
63      */

64     ParameterList<ParameterDescription.InDefinedShape> asDefined();
65
66     /**
67      * Checks if all parameters in this list define both an explicit name and an explicit modifier.
68      *
69      * @return {@code trueif all parameters in this list define both an explicit name and an explicit modifier.
70      */

71     boolean hasExplicitMetaData();
72
73     /**
74      * An base implementation for a {@link ParameterList}.
75      *
76      * @param <S> The type of parameter descriptions represented by this list.
77      */

78     abstract class AbstractBase<S extends ParameterDescription> extends FilterableList.AbstractBase<S, ParameterList<S>> implements ParameterList<S> {
79
80         /**
81          * {@inheritDoc}
82          */

83         public boolean hasExplicitMetaData() {
84             for (ParameterDescription parameterDescription : this) {
85                 if (!parameterDescription.isNamed() || !parameterDescription.hasModifiers()) {
86                     return false;
87                 }
88             }
89             return true;
90         }
91
92         /**
93          * {@inheritDoc}
94          */

95         public ByteCodeElement.Token.TokenList<ParameterDescription.Token> asTokenList(ElementMatcher<? super TypeDescription> matcher) {
96             List<ParameterDescription.Token> tokens = new ArrayList<ParameterDescription.Token>(size());
97             for (ParameterDescription parameterDescription : this) {
98                 tokens.add(parameterDescription.asToken(matcher));
99             }
100             return new ByteCodeElement.Token.TokenList<ParameterDescription.Token>(tokens);
101         }
102
103         /**
104          * {@inheritDoc}
105          */

106         public TypeList.Generic asTypeList() {
107             List<TypeDescription.Generic> types = new ArrayList<TypeDescription.Generic>(size());
108             for (ParameterDescription parameterDescription : this) {
109                 types.add(parameterDescription.getType());
110             }
111             return new TypeList.Generic.Explicit(types);
112         }
113
114         /**
115          * {@inheritDoc}
116          */

117         public ParameterList<ParameterDescription.InDefinedShape> asDefined() {
118             List<ParameterDescription.InDefinedShape> declaredForms = new ArrayList<ParameterDescription.InDefinedShape>(size());
119             for (ParameterDescription parameterDescription : this) {
120                 declaredForms.add(parameterDescription.asDefined());
121             }
122             return new Explicit<ParameterDescription.InDefinedShape>(declaredForms);
123         }
124
125         @Override
126         protected ParameterList<S> wrap(List<S> values) {
127             return new Explicit<S>(values);
128         }
129     }
130
131     /**
132      * Represents a list of parameters for an executable, i.e. a {@link java.lang.reflect.Method} or {@link java.lang.reflect.Constructor}.
133      *
134      * @param <T> The type of the {@code java.lang.reflect.Executable} that this list represents.
135      */

136     abstract class ForLoadedExecutable<T> extends AbstractBase<ParameterDescription.InDefinedShape> {
137
138         /**
139          * The dispatcher used creating parameter list instances and for accessing {@code java.lang.reflect.Executable} instances.
140          */

141         private static final Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE);
142
143         /**
144          * The executable for which a parameter list is represented.
145          */

146         protected final T executable;
147
148         /**
149          * The parameter annotation source to query.
150          */

151         protected final ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource;
152
153         /**
154          * Creates a new description for a loaded executable.
155          *
156          * @param executable                The executable for which a parameter list is represented.
157          * @param parameterAnnotationSource The parameter annotation source to query.
158          */

159         protected ForLoadedExecutable(T executable, ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
160             this.executable = executable;
161             this.parameterAnnotationSource = parameterAnnotationSource;
162         }
163
164         /**
165          * Creates a new list that describes the parameters of the given {@link Constructor}.
166          *
167          * @param constructor The constructor for which the parameters should be described.
168          * @return A list describing the constructor's parameters.
169          */

170         public static ParameterList<ParameterDescription.InDefinedShape> of(Constructor<?> constructor) {
171             return of(constructor, new ParameterDescription.ForLoadedParameter.ParameterAnnotationSource.ForLoadedConstructor(constructor));
172         }
173
174         /**
175          * Creates a new list that describes the parameters of the given {@link Constructor}.
176          *
177          * @param constructor               The constructor for which the parameters should be described.
178          * @param parameterAnnotationSource The parameter annotation source to query.
179          * @return A list describing the constructor's parameters.
180          */

181         public static ParameterList<ParameterDescription.InDefinedShape> of(Constructor<?> constructor,
182                                                                             ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
183             return DISPATCHER.describe(constructor, parameterAnnotationSource);
184         }
185
186         /**
187          * Creates a new list that describes the parameters of the given {@link Method}.
188          *
189          * @param method The method for which the parameters should be described.
190          * @return A list describing the method's parameters.
191          */

192         public static ParameterList<ParameterDescription.InDefinedShape> of(Method method) {
193             return of(method, new ParameterDescription.ForLoadedParameter.ParameterAnnotationSource.ForLoadedMethod(method));
194         }
195
196         /**
197          * Creates a new list that describes the parameters of the given {@link Method}.
198          *
199          * @param method                    The method for which the parameters should be described.
200          * @param parameterAnnotationSource The parameter annotation source to query.
201          * @return A list describing the method's parameters.
202          */

203         public static ParameterList<ParameterDescription.InDefinedShape> of(Method method,
204                                                                             ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
205             return DISPATCHER.describe(method, parameterAnnotationSource);
206         }
207
208         /**
209          * {@inheritDoc}
210          */

211         public int size() {
212             return DISPATCHER.getParameterCount(executable);
213         }
214
215         /**
216          * A dispatcher for creating descriptions of parameter lists and for evaluating the size of an {@code java.lang.reflect.Executable}'s parameters.
217          */

218         protected interface Dispatcher {
219
220             /**
221              * Returns the amount of parameters of a given executable..
222              *
223              * @param executable The executable for which the amount of parameters should be found.
224              * @return The amount of parameters of the given executable.
225              */

226             int getParameterCount(Object executable);
227
228             /**
229              * Describes a {@link Constructor}'s parameters of the given VM.
230              *
231              * @param constructor               The constructor for which the parameters should be described.
232              * @param parameterAnnotationSource The parameter annotation source to query.
233              * @return A list describing the constructor's parameters.
234              */

235             ParameterList<ParameterDescription.InDefinedShape> describe(Constructor<?> constructor,
236                                                                         ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource);
237
238             /**
239              * Describes a {@link Method}'s parameters of the given VM.
240              *
241              * @param method                    The method for which the parameters should be described.
242              * @param parameterAnnotationSource The parameter annotation source to query.
243              * @return A list describing the method's parameters.
244              */

245             ParameterList<ParameterDescription.InDefinedShape> describe(Method method,
246                                                                         ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource);
247
248             /**
249              * A creation action for a dispatcher.
250              */

251             enum CreationAction implements PrivilegedAction<Dispatcher> {
252
253                 /**
254                  * The singleton instance.
255                  */

256                 INSTANCE;
257
258                 /**
259                  * {@inheritDoc}
260                  */

261                 @SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception should not be rethrown but trigger a fallback")
262                 public Dispatcher run() {
263                     try {
264                         return new Dispatcher.ForJava8CapableVm(Class.forName("java.lang.reflect.Executable").getMethod("getParameterCount"));
265                     } catch (Exception ignored) {
266                         return Dispatcher.ForLegacyVm.INSTANCE;
267                     }
268                 }
269             }
270
271             /**
272              * A dispatcher for a legacy VM that does not support the {@code java.lang.reflect.Parameter} type.
273              */

274             enum ForLegacyVm implements Dispatcher {
275
276                 /**
277                  * The singleton instance.
278                  */

279                 INSTANCE;
280
281                 /**
282                  * {@inheritDoc}
283                  */

284                 public int getParameterCount(Object executable) {
285                     throw new IllegalStateException("Cannot dispatch method for java.lang.reflect.Executable");
286                 }
287
288                 /**
289                  * {@inheritDoc}
290                  */

291                 public ParameterList<ParameterDescription.InDefinedShape> describe(Constructor<?> constructor,
292                                                                                    ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
293                     return new OfLegacyVmConstructor(constructor, parameterAnnotationSource);
294                 }
295
296                 /**
297                  * {@inheritDoc}
298                  */

299                 public ParameterList<ParameterDescription.InDefinedShape> describe(Method method,
300                                                                                    ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
301                     return new OfLegacyVmMethod(method, parameterAnnotationSource);
302                 }
303             }
304
305             /**
306              * A dispatcher for a legacy VM that does support the {@code java.lang.reflect.Parameter} type.
307              */

308             @HashCodeAndEqualsPlugin.Enhance
309             class ForJava8CapableVm implements Dispatcher {
310
311                 /**
312                  * An empty array that can be used to indicate no arguments to avoid an allocation on a reflective call.
313                  */

314                 private static final Object[] NO_ARGUMENTS = new Object[0];
315
316                 /**
317                  * The {@code java.lang.reflect.Executable#getParameterCount()} method.
318                  */

319                 private final Method getParameterCount;
320
321                 /**
322                  * Creates a new dispatcher for a modern VM.
323                  *
324                  * @param getParameterCount The {@code java.lang.reflect.Executable#getParameterCount()} method.
325                  */

326                 protected ForJava8CapableVm(Method getParameterCount) {
327                     this.getParameterCount = getParameterCount;
328                 }
329
330                 /**
331                  * {@inheritDoc}
332                  */

333                 public int getParameterCount(Object executable) {
334                     try {
335                         return (Integer) getParameterCount.invoke(executable, NO_ARGUMENTS);
336                     } catch (IllegalAccessException exception) {
337                         throw new IllegalStateException("Cannot access java.lang.reflect.Parameter#getModifiers", exception);
338                     } catch (InvocationTargetException exception) {
339                         throw new IllegalStateException("Error invoking java.lang.reflect.Parameter#getModifiers", exception.getCause());
340                     }
341                 }
342
343                 /**
344                  * {@inheritDoc}
345                  */

346                 public ParameterList<ParameterDescription.InDefinedShape> describe(Constructor<?> constructor,
347                                                                                    ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
348                     return new OfConstructor(constructor, parameterAnnotationSource);
349                 }
350
351                 /**
352                  * {@inheritDoc}
353                  */

354                 public ParameterList<ParameterDescription.InDefinedShape> describe(Method method,
355                                                                                    ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
356                     return new OfMethod(method, parameterAnnotationSource);
357                 }
358             }
359         }
360
361         /**
362          * Describes the list of {@link Constructor} parameters on a modern VM.
363          */

364         protected static class OfConstructor extends ForLoadedExecutable<Constructor<?>> {
365
366             /**
367              * Creates a new description of the parameters of a constructor.
368              *
369              * @param constructor               The constructor that is represented by this instance.
370              * @param parameterAnnotationSource The parameter annotation source to query.
371              */

372             protected OfConstructor(Constructor<?> constructor, ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
373                 super(constructor, parameterAnnotationSource);
374             }
375
376             /**
377              * {@inheritDoc}
378              */

379             public ParameterDescription.InDefinedShape get(int index) {
380                 return new ParameterDescription.ForLoadedParameter.OfConstructor(executable, index, parameterAnnotationSource);
381             }
382         }
383
384         /**
385          * Describes the list of {@link Method} parameters on a modern VM.
386          */

387         protected static class OfMethod extends ForLoadedExecutable<Method> {
388
389             /**
390              * Creates a new description of the parameters of a method.
391              *
392              * @param method                    The method that is represented by this instance.
393              * @param parameterAnnotationSource The parameter annotation source to query.
394              */

395             protected OfMethod(Method method, ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
396                 super(method, parameterAnnotationSource);
397             }
398
399             /**
400              * {@inheritDoc}
401              */

402             public ParameterDescription.InDefinedShape get(int index) {
403                 return new ParameterDescription.ForLoadedParameter.OfMethod(executable, index, parameterAnnotationSource);
404             }
405         }
406
407         /**
408          * Represents a list of constructor parameters on virtual machines where the {@code java.lang.reflect.Parameter}
409          * type is not available.
410          */

411         protected static class OfLegacyVmConstructor extends ParameterList.AbstractBase<ParameterDescription.InDefinedShape> {
412
413             /**
414              * The represented constructor.
415              */

416             private final Constructor<?> constructor;
417
418             /**
419              * An array of this method's parameter types.
420              */

421             private final Class<?>[] parameterType;
422
423             /**
424              * The parameter annotation source to query.
425              */

426             private final ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource;
427
428             /**
429              * Creates a legacy representation of a constructor's parameters.
430              *
431              * @param constructor               The constructor to represent.
432              * @param parameterAnnotationSource The parameter annotation source to query.
433              */

434             protected OfLegacyVmConstructor(Constructor<?> constructor, ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
435                 this.constructor = constructor;
436                 this.parameterType = constructor.getParameterTypes();
437                 this.parameterAnnotationSource = parameterAnnotationSource;
438             }
439
440             /**
441              * {@inheritDoc}
442              */

443             public ParameterDescription.InDefinedShape get(int index) {
444                 return new ParameterDescription.ForLoadedParameter.OfLegacyVmConstructor(constructor, index, parameterType, parameterAnnotationSource);
445             }
446
447             /**
448              * {@inheritDoc}
449              */

450             public int size() {
451                 return parameterType.length;
452             }
453         }
454
455         /**
456          * Represents a list of method parameters on virtual machines where the {@code java.lang.reflect.Parameter}
457          * type is not available.
458          */

459         protected static class OfLegacyVmMethod extends ParameterList.AbstractBase<ParameterDescription.InDefinedShape> {
460
461             /**
462              * The represented method.
463              */

464             private final Method method;
465
466             /**
467              * An array of this method's parameter types.
468              */

469             private final Class<?>[] parameterType;
470
471             /**
472              * The parameter annotation source to query.
473              */

474             private final ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource;
475
476             /**
477              * Creates a legacy representation of a method's parameters.
478              *
479              * @param method                    The method to represent.
480              * @param parameterAnnotationSource The parameter annotation source to query.
481              */

482             protected OfLegacyVmMethod(Method method, ParameterDescription.ForLoadedParameter.ParameterAnnotationSource parameterAnnotationSource) {
483                 this.method = method;
484                 this.parameterType = method.getParameterTypes();
485                 this.parameterAnnotationSource = parameterAnnotationSource;
486             }
487
488             /**
489              * {@inheritDoc}
490              */

491             public ParameterDescription.InDefinedShape get(int index) {
492                 return new ParameterDescription.ForLoadedParameter.OfLegacyVmMethod(method, index, parameterType, parameterAnnotationSource);
493             }
494
495             /**
496              * {@inheritDoc}
497              */

498             public int size() {
499                 return parameterType.length;
500             }
501         }
502     }
503
504     /**
505      * A list of explicitly provided parameter descriptions.
506      *
507      * @param <S> The type of parameter descriptions represented by this list.
508      */

509     class Explicit<S extends ParameterDescription> extends AbstractBase<S> {
510
511         /**
512          * The list of parameter descriptions that are represented by this list.
513          */

514         private final List<? extends S> parameterDescriptions;
515
516         /**
517          * Creates a new list of explicit parameter descriptions.
518          *
519          * @param parameterDescription The list of parameter descriptions that are represented by this list.
520          */

521         @SuppressWarnings("unchecked")
522         public Explicit(S... parameterDescription) {
523             this(Arrays.asList(parameterDescription));
524         }
525
526         /**
527          * Creates a new list of explicit parameter descriptions.
528          *
529          * @param parameterDescriptions The list of parameter descriptions that are represented by this list.
530          */

531         public Explicit(List<? extends S> parameterDescriptions) {
532             this.parameterDescriptions = parameterDescriptions;
533         }
534
535         /**
536          * {@inheritDoc}
537          */

538         public S get(int index) {
539             return parameterDescriptions.get(index);
540         }
541
542         /**
543          * {@inheritDoc}
544          */

545         public int size() {
546             return parameterDescriptions.size();
547         }
548
549         /**
550          * A parameter list representing parameters without meta data or annotations.
551          */

552         public static class ForTypes extends ParameterList.AbstractBase<ParameterDescription.InDefinedShape> {
553
554             /**
555              * The method description that declares the parameters.
556              */

557             private final MethodDescription.InDefinedShape methodDescription;
558
559             /**
560              * A list of detached types representing the parameters.
561              */

562             private final List<? extends TypeDefinition> typeDefinitions;
563
564             /**
565              * Creates a new parameter type list.
566              *
567              * @param methodDescription The method description that declares the parameters.
568              * @param typeDefinition    A list of detached types representing the parameters.
569              */

570             public ForTypes(MethodDescription.InDefinedShape methodDescription, TypeDefinition... typeDefinition) {
571                 this(methodDescription, Arrays.asList(typeDefinition));
572             }
573
574             /**
575              * Creates a new parameter type list.
576              *
577              * @param methodDescription The method description that declares the parameters.
578              * @param typeDefinitions   A list of detached types representing the parameters.
579              */

580             public ForTypes(MethodDescription.InDefinedShape methodDescription, List<? extends TypeDefinition> typeDefinitions) {
581                 this.methodDescription = methodDescription;
582                 this.typeDefinitions = typeDefinitions;
583             }
584
585             /**
586              * {@inheritDoc}
587              */

588             public ParameterDescription.InDefinedShape get(int index) {
589                 int offset = methodDescription.isStatic() ? 0 : 1;
590                 for (int previous = 0; previous < index; previous++) {
591                     offset += typeDefinitions.get(previous).getStackSize().getSize();
592                 }
593                 return new ParameterDescription.Latent(methodDescription, typeDefinitions.get(index).asGenericType(), index, offset);
594             }
595
596             /**
597              * {@inheritDoc}
598              */

599             public int size() {
600                 return typeDefinitions.size();
601             }
602         }
603     }
604
605     /**
606      * A list of parameter descriptions for a list of detached tokens. For the returned parameter, each token is attached to its parameter representation.
607      */

608     class ForTokens extends AbstractBase<ParameterDescription.InDefinedShape> {
609
610         /**
611          * The method that is declaring the represented token.
612          */

613         private final MethodDescription.InDefinedShape declaringMethod;
614
615         /**
616          * The list of tokens to represent.
617          */

618         private final List<? extends ParameterDescription.Token> tokens;
619
620         /**
621          * Creates a new parameter list for the provided tokens.
622          *
623          * @param declaringMethod The method that is declaring the represented token.
624          * @param tokens          The list of tokens to represent.
625          */

626         public ForTokens(MethodDescription.InDefinedShape declaringMethod, List<? extends ParameterDescription.Token> tokens) {
627             this.declaringMethod = declaringMethod;
628             this.tokens = tokens;
629         }
630
631         /**
632          * {@inheritDoc}
633          */

634         public ParameterDescription.InDefinedShape get(int index) {
635             int offset = declaringMethod.isStatic() ? 0 : 1;
636             for (ParameterDescription.Token token : tokens.subList(0, index)) {
637                 offset += token.getType().getStackSize().getSize();
638             }
639             return new ParameterDescription.Latent(declaringMethod, tokens.get(index), index, offset);
640         }
641
642         /**
643          * {@inheritDoc}
644          */

645         public int size() {
646             return tokens.size();
647         }
648     }
649
650     /**
651      * A list of parameter descriptions that yields {@link net.bytebuddy.description.method.ParameterDescription.TypeSubstituting}.
652      */

653     class TypeSubstituting extends AbstractBase<ParameterDescription.InGenericShape> {
654
655         /**
656          * The method that is declaring the transformed parameters.
657          */

658         private final MethodDescription.InGenericShape declaringMethod;
659
660         /**
661          * The untransformed parameters that are represented by this list.
662          */

663         private final List<? extends ParameterDescription> parameterDescriptions;
664
665         /**
666          * The visitor to apply to the parameter types before returning them.
667          */

668         private final TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor;
669
670         /**
671          * Creates a new type substituting parameter list.
672          *
673          * @param declaringMethod       The method that is declaring the transformed parameters.
674          * @param parameterDescriptions The untransformed parameters that are represented by this list.
675          * @param visitor               The visitor to apply to the parameter types before returning them.
676          */

677         public TypeSubstituting(MethodDescription.InGenericShape declaringMethod,
678                                 List<? extends ParameterDescription> parameterDescriptions,
679                                 TypeDescription.Generic.Visitor<? extends TypeDescription.Generic> visitor) {
680             this.declaringMethod = declaringMethod;
681             this.parameterDescriptions = parameterDescriptions;
682             this.visitor = visitor;
683         }
684
685         /**
686          * {@inheritDoc}
687          */

688         public ParameterDescription.InGenericShape get(int index) {
689             return new ParameterDescription.TypeSubstituting(declaringMethod, parameterDescriptions.get(index), visitor);
690         }
691
692         /**
693          * {@inheritDoc}
694          */

695         public int size() {
696             return parameterDescriptions.size();
697         }
698     }
699
700     /**
701      * An empty list of parameters.
702      *
703      * @param <S> The type of parameter descriptions represented by this list.
704      */

705     class Empty<S extends ParameterDescription> extends FilterableList.Empty<S, ParameterList<S>> implements ParameterList<S> {
706
707         /**
708          * {@inheritDoc}
709          */

710         public boolean hasExplicitMetaData() {
711             return true;
712         }
713
714         /**
715          * {@inheritDoc}
716          */

717         public TypeList.Generic asTypeList() {
718             return new TypeList.Generic.Empty();
719         }
720
721         /**
722          * {@inheritDoc}
723          */

724         public ByteCodeElement.Token.TokenList<ParameterDescription.Token> asTokenList(ElementMatcher<? super TypeDescription> matcher) {
725             return new ByteCodeElement.Token.TokenList<ParameterDescription.Token>();
726         }
727
728         /**
729          * {@inheritDoc}
730          */

731         @SuppressWarnings("unchecked")
732         public ParameterList<ParameterDescription.InDefinedShape> asDefined() {
733             return (ParameterList<ParameterDescription.InDefinedShape>) this;
734         }
735     }
736 }
737