4343
4444/**
4545 * Models generic Java type signatures, as defined in JVMS {@jvms 4.7.9.1}.
46+ * <p>
47+ * Names in signatures are <dfn id="identifier">identifiers</dfn>, which must
48+ * not be empty and must not contain any of the ASCII characters {@code
49+ * . ; [ / < > :}. Top-level class and interface names are denoted by
50+ * slash-separated identifiers.
4651 *
4752 * @see Type
4853 * @see SignatureAttribute
@@ -73,6 +78,8 @@ public static Signature parseFrom(String javaTypeSignature) {
7378 * signature represents a reifiable type (JLS {@jls 4.7}).
7479 *
7580 * @param classDesc the symbolic description of the Java type
81+ * @throws IllegalArgumentException if the field descriptor cannot be
82+ * {@linkplain ##identifier denoted}
7683 */
7784 public static Signature of (ClassDesc classDesc ) {
7885 requireNonNull (classDesc );
@@ -139,6 +146,31 @@ public sealed interface RefTypeSig
139146
140147 /**
141148 * Models the signature of a possibly-parameterized class or interface type.
149+ * <p>
150+ * These are examples of class type signatures:
151+ * <ul>
152+ * <li>{@code Lcom/example/Outer;} for {@code Outer}
153+ * <br>Has class name {@code com/example/Outer} and no outer type or type
154+ * argument.
155+ * <li>{@code Lcom/example/Outer$Nested<TA;>;} for {@code Outer.Nested<A>}
156+ * <br>Has class name {@code com/example/Outer$Nested} representing a nested
157+ * class, no outer type, and a single type argument of type variable
158+ * {@code A}.
159+ * <li>{@code Lcom/example/GenericOuter<TA;>.Inner;} for {@code
160+ * GenericOuter<A>.Inner}
161+ * <br>Has class name {@code Inner}, a simple class name, outer type
162+ * {@code Lcom/example/GenericOuter<TA;>;} for {@code GenericOuter<A>},
163+ * and no type argument.
164+ * </ul>
165+ * <p>
166+ * If the {@linkplain #outerType() outer type} exists, the {@linkplain
167+ * #className() class name} is the simple name of the nested type.
168+ * Otherwise, it is a {@linkplain ClassEntry##internalname binary name in
169+ * internal form} (separated by {@code /}).
170+ * <p>
171+ * If a nested type does not have any enclosing parameterization, it may
172+ * be represented without an outer type and as an internal binary name,
173+ * in which nesting is represented by {@code $} instead of {@code .}.
142174 *
143175 * @see Type
144176 * @see ParameterizedType
@@ -152,7 +184,8 @@ public sealed interface ClassTypeSig
152184 /**
153185 * {@return the signature of the class that this class is a member of,
154186 * only if this is a member class} Note that the outer class may be
155- * absent if it is not a parameterized type.
187+ * absent if this is a member class without any parameterized enclosing
188+ * type.
156189 *
157190 * @jls 4.5 Parameterized Types
158191 */
@@ -161,7 +194,8 @@ public sealed interface ClassTypeSig
161194 /**
162195 * {@return the class or interface name; includes the {@linkplain
163196 * ClassEntry##internalname slash-separated} package name if there is no
164- * outer type}
197+ * outer type} Note this may indicate a nested class name with {@code $}
198+ * separators if there is no parameterized enclosing type.
165199 */
166200 String className ();
167201
@@ -188,10 +222,11 @@ default ClassDesc classDesc() {
188222 * @param className the name of the class or interface
189223 * @param typeArgs the type arguments
190224 * @throws IllegalArgumentException if {@code className} does not
191- * represent a class or interface
225+ * represent a class or interface, or if it cannot be
226+ * {@linkplain Signature##identifier denoted}
192227 */
193228 public static ClassTypeSig of (ClassDesc className , TypeArg ... typeArgs ) {
194- return of (null , className , typeArgs );
229+ return of (null , Util . toInternalName ( className ) , typeArgs );
195230 }
196231
197232 /**
@@ -201,8 +236,15 @@ public static ClassTypeSig of(ClassDesc className, TypeArg... typeArgs) {
201236 * @param className the name of this class or interface
202237 * @param typeArgs the type arguments
203238 * @throws IllegalArgumentException if {@code className} does not
204- * represent a class or interface
239+ * represent a class or interface, or if it cannot be
240+ * {@linkplain Signature##identifier denoted}
241+ * @deprecated
242+ * The resulting signature does not denote the class represented by
243+ * {@code className} when {@code outerType} is not null. Use {@link
244+ * #of(ClassTypeSig, String, TypeArg...) of(ClassTypeSig, String, TypeArg...)}
245+ * instead.
205246 */
247+ @ Deprecated (since = "26" , forRemoval = true )
206248 public static ClassTypeSig of (ClassTypeSig outerType , ClassDesc className , TypeArg ... typeArgs ) {
207249 requireNonNull (className );
208250 return of (outerType , Util .toInternalName (className ), typeArgs );
@@ -211,8 +253,11 @@ public static ClassTypeSig of(ClassTypeSig outerType, ClassDesc className, TypeA
211253 /**
212254 * {@return a class or interface signature without an outer type}
213255 *
214- * @param className the name of the class or interface
256+ * @param className the name of the class or interface, may use
257+ * {@code /} to separate
215258 * @param typeArgs the type arguments
259+ * @throws IllegalArgumentException if {@code className} cannot be
260+ * {@linkplain Signature##identifier denoted}
216261 */
217262 public static ClassTypeSig of (String className , TypeArg ... typeArgs ) {
218263 return of (null , className , typeArgs );
@@ -222,12 +267,19 @@ public static ClassTypeSig of(String className, TypeArg... typeArgs) {
222267 * {@return a class type signature}
223268 *
224269 * @param outerType signature of the outer type, may be {@code null}
225- * @param className the name of this class or interface
270+ * @param className the name of this class or interface, may use
271+ * {@code /} to separate if outer type is absent
226272 * @param typeArgs the type arguments
273+ * @throws IllegalArgumentException if {@code className} cannot be
274+ * {@linkplain Signature##identifier denoted}
227275 */
228276 public static ClassTypeSig of (ClassTypeSig outerType , String className , TypeArg ... typeArgs ) {
229- requireNonNull (className );
230- return new SignaturesImpl .ClassTypeSigImpl (Optional .ofNullable (outerType ), className .replace ("." , "/" ), List .of (typeArgs ));
277+ if (outerType != null ) {
278+ SignaturesImpl .validateIdentifier (className );
279+ } else {
280+ SignaturesImpl .validatePackageSpecifierPlusIdentifier (className );
281+ }
282+ return new SignaturesImpl .ClassTypeSigImpl (Optional .ofNullable (outerType ), className , List .of (typeArgs ));
231283 }
232284 }
233285
@@ -383,9 +435,11 @@ public sealed interface TypeVarSig
383435 * {@return a signature for a type variable}
384436 *
385437 * @param identifier the name of the type variable
438+ * @throws IllegalArgumentException if the name cannot be {@linkplain
439+ * Signature##identifier denoted}
386440 */
387441 public static TypeVarSig of (String identifier ) {
388- return new SignaturesImpl .TypeVarSigImpl (requireNonNull (identifier ));
442+ return new SignaturesImpl .TypeVarSigImpl (SignaturesImpl . validateIdentifier (identifier ));
389443 }
390444 }
391445
@@ -408,20 +462,22 @@ public sealed interface ArrayTypeSig
408462 /**
409463 * {@return an array type with the given component type}
410464 * @param componentSignature the component type
465+ * @throws IllegalArgumentException if the component type is void
411466 */
412467 public static ArrayTypeSig of (Signature componentSignature ) {
413- return of (1 , requireNonNull (componentSignature ));
468+ return of (1 , SignaturesImpl . validateNonVoid (componentSignature ));
414469 }
415470
416471 /**
417472 * {@return a signature for an array type}
418473 * @param dims the dimension of the array
419474 * @param componentSignature the component type
420475 * @throws IllegalArgumentException if {@code dims < 1} or the
421- * resulting array type exceeds 255 dimensions
476+ * resulting array type exceeds 255 dimensions or the component
477+ * type is void
422478 */
423479 public static ArrayTypeSig of (int dims , Signature componentSignature ) {
424- requireNonNull (componentSignature );
480+ SignaturesImpl . validateNonVoid (componentSignature );
425481 if (componentSignature instanceof SignaturesImpl .ArrayTypeSigImpl arr ) {
426482 if (dims < 1 || dims > 255 - arr .arrayDepth ())
427483 throw new IllegalArgumentException ("illegal array depth value" );
@@ -469,10 +525,12 @@ public sealed interface TypeParam
469525 * @param identifier the name of the type parameter
470526 * @param classBound the class bound of the type parameter, may be {@code null}
471527 * @param interfaceBounds the interface bounds of the type parameter
528+ * @throws IllegalArgumentException if the name cannot be {@linkplain
529+ * Signature##identifier denoted}
472530 */
473531 public static TypeParam of (String identifier , RefTypeSig classBound , RefTypeSig ... interfaceBounds ) {
474532 return new SignaturesImpl .TypeParamImpl (
475- requireNonNull (identifier ),
533+ SignaturesImpl . validateIdentifier (identifier ),
476534 Optional .ofNullable (classBound ),
477535 List .of (interfaceBounds ));
478536 }
@@ -483,10 +541,12 @@ public static TypeParam of(String identifier, RefTypeSig classBound, RefTypeSig.
483541 * @param identifier the name of the type parameter
484542 * @param classBound the optional class bound of the type parameter
485543 * @param interfaceBounds the interface bounds of the type parameter
544+ * @throws IllegalArgumentException if the name cannot be {@linkplain
545+ * Signature##identifier denoted}
486546 */
487547 public static TypeParam of (String identifier , Optional <RefTypeSig > classBound , RefTypeSig ... interfaceBounds ) {
488548 return new SignaturesImpl .TypeParamImpl (
489- requireNonNull (identifier ),
549+ SignaturesImpl . validateIdentifier (identifier ),
490550 requireNonNull (classBound ),
491551 List .of (interfaceBounds ));
492552 }
0 commit comments