10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.lang.constant;
26
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Set;
30
31 import static java.util.Objects.requireNonNull;
32
33 /**
34 * Helper methods for the implementation of {@code java.lang.constant}.
35 */
36 class ConstantUtils {
37 /** an empty constant descriptor */
38 public static final ConstantDesc[] EMPTY_CONSTANTDESC = new ConstantDesc[0];
39 static final Constable[] EMPTY_CONSTABLE = new Constable[0];
40 static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;
41
42 private static final Set<String> pointyNames = Set.of("<init>", "<clinit>");
43
44 /**
45 * Validates the correctness of a binary class name. In particular checks for the presence of
46 * invalid characters in the name.
47 *
48 * @param name the class name
49 * @return the class name passed if valid
50 * @throws IllegalArgumentException if the class name is invalid
51 */
218 static boolean verifyUnqualifiedClassName(String name) {
219 for (int index = 0; index < name.length(); index++) {
220 char ch = name.charAt(index);
221 if (ch < 128) {
222 if (ch == '.' || ch == ';' || ch == '[' ) {
223 return false; // do not permit '.', ';', or '['
224 }
225 if (ch == '/') {
226 // check for '//' or leading or trailing '/' which are not legal
227 // unqualified name must not be empty
228 if (index == 0 || index + 1 >= name.length() || name.charAt(index + 1) == '/') {
229 return false;
230 }
231 }
232 } else {
233 index ++;
234 }
235 }
236 return true;
237 }
238 }
|
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.lang.constant;
26
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Set;
30 import java.util.stream.Stream;
31
32 import sun.invoke.util.Wrapper;
33
34 import static java.util.Objects.requireNonNull;
35 import static java.util.stream.Collectors.joining;
36
37 /**
38 * Helper methods for the implementation of {@code java.lang.constant}.
39 */
40 class ConstantUtils {
41 /** an empty constant descriptor */
42 public static final ConstantDesc[] EMPTY_CONSTANTDESC = new ConstantDesc[0];
43 static final Constable[] EMPTY_CONSTABLE = new Constable[0];
44 static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;
45
46 private static final Set<String> pointyNames = Set.of("<init>", "<clinit>");
47
48 /**
49 * Validates the correctness of a binary class name. In particular checks for the presence of
50 * invalid characters in the name.
51 *
52 * @param name the class name
53 * @return the class name passed if valid
54 * @throws IllegalArgumentException if the class name is invalid
55 */
222 static boolean verifyUnqualifiedClassName(String name) {
223 for (int index = 0; index < name.length(); index++) {
224 char ch = name.charAt(index);
225 if (ch < 128) {
226 if (ch == '.' || ch == ';' || ch == '[' ) {
227 return false; // do not permit '.', ';', or '['
228 }
229 if (ch == '/') {
230 // check for '//' or leading or trailing '/' which are not legal
231 // unqualified name must not be empty
232 if (index == 0 || index + 1 >= name.length() || name.charAt(index + 1) == '/') {
233 return false;
234 }
235 }
236 } else {
237 index ++;
238 }
239 }
240 return true;
241 }
242
243 static String getClassDisplayName(ClassDesc cd, boolean detail) {
244 String descriptor = cd.descriptorString();
245 if (cd.isPrimitive()) {
246 return Wrapper.forBasicType(descriptor
247 .charAt(0))
248 .primitiveSimpleName();
249 } else if (cd.isClassOrInterface()) {
250 String internalClassName = ConstantUtils.dropFirstAndLastChar(descriptor);
251 String binaryClassName = internalToBinary(internalClassName);
252 if (detail) {
253 return binaryClassName;
254
255 }
256 int index = binaryClassName.lastIndexOf('.');
257 return index == -1 ? binaryClassName : binaryClassName.substring(index + 1);
258 } else if (cd.isArray()) {
259 int depth = ConstantUtils.arrayDepth(descriptor);
260 ClassDesc c = cd;
261 for (int i=0; i<depth; i++)
262 c = c.componentType();
263 return getClassDisplayName(c, detail) + "[]".repeat(depth);
264 } else {
265 throw new IllegalStateException(descriptor);
266 }
267 }
268
269 static String getDisplayDescriptor(MethodTypeDesc mtd, boolean detail) {
270 return String.format("(%s)%s",
271 Stream.of(mtd.parameterArray())
272 .map(cd -> getClassDisplayName(cd, detail))
273 .collect(joining(",")),
274 getClassDisplayName(mtd.returnType(), detail));
275 }
276
277 }
|