1 /*
  2  * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 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 
 26 package jdk.internal.value;
 27 
 28 import jdk.internal.access.JavaLangAccess;
 29 import jdk.internal.access.SharedSecrets;
 30 import jdk.internal.vm.annotation.IntrinsicCandidate;
 31 
 32 /**
 33  * Utilities to access Primitive Classes as described in JEP 401.
 34  */
 35 public class PrimitiveClass {
 36 
 37     /**
 38      * ACC_PRIMITIVE modifier defined by JEP 401. Subject to change.
 39      */
 40     public static final int PRIMITIVE_CLASS = 0x00000800;
 41 
 42     private static final JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess();
 43 
 44 
 45     /**
 46      * Returns a {@code Class} object representing the primary type
 47      * of this class or interface.
 48      * <p>
 49      * If this {@code Class} object represents a primitive type or an array type,
 50      * then this method returns this class.
 51      * <p>
 52      * If this {@code Class} object represents a {@linkplain #isPrimitiveClass(Class)
 53      * primitive class}, then this method returns the <em>primitive reference type</em>
 54      * type of this primitive class.
 55      * <p>
 56      * Otherwise, this {@code Class} object represents a non-primitive class or interface
 57      * and this method returns this class.
 58      *
 59      * @param aClass a class
 60      * @return the {@code Class} representing the primary type of
 61      *         this class or interface
 62      * @since Valhalla
 63      */
 64     @IntrinsicCandidate
 65     public static Class<?> asPrimaryType(Class<?> aClass) {
 66         return javaLangAccess.asPrimaryType(aClass);
 67     }
 68 
 69     /**
 70      * Returns a {@code Class} object representing the <em>primitive value type</em>
 71      * of this class if this class is a {@linkplain #isPrimitiveClass(Class)}  primitive class}.
 72      *
 73      * @apiNote Alternatively, this method returns null if this class is not
 74      *          a primitive class rather than throwing UOE.
 75      *
 76      * @param aClass a class
 77      * @return the {@code Class} representing the {@linkplain #isPrimitiveValueType(Class)
 78      * primitive value type} of this class if this class is a primitive class
 79      * @throws UnsupportedOperationException if this class or interface
 80      *         is not a primitive class
 81      * @since Valhalla
 82      */
 83     @SuppressWarnings("unchecked")
 84     @IntrinsicCandidate
 85     public static Class<?> asValueType(Class<?> aClass) {
 86         return javaLangAccess.asValueType(aClass);
 87     }
 88 
 89     /**
 90      * Returns {@code true} if this {@code Class} object represents the primary type
 91      * of this class or interface.
 92      * <p>
 93      * If this {@code Class} object represents a primitive type or an array type,
 94      * then this method returns {@code true}.
 95      * <p>
 96      * If this {@code Class} object represents a {@linkplain #isPrimitiveClass(Class)
 97      * primitive}, then this method returns {@code true} if this {@code Class}
 98      * object represents a primitive reference type, or returns {@code false}
 99      * if this {@code Class} object represents a primitive value type.
100      * <p>
101      * If this {@code Class} object represents a non-primitive class or interface,
102      * then this method returns {@code true}.
103      *
104      * @param aClass a class
105      * @return {@code true} if this {@code Class} object represents
106      * the primary type of this class or interface
107      * @since Valhalla
108      */
109     public static boolean isPrimaryType(Class<?> aClass) {
110         return javaLangAccess.isPrimaryType(aClass);
111     }
112 
113     /**
114      * Returns {@code true} if this {@code Class} object represents
115      * a {@linkplain #isPrimitiveClass(Class)  primitive} value type.
116      *
117      * @return {@code true} if this {@code Class} object represents
118      * the value type of a primitive class
119      * @since Valhalla
120      */
121     public static boolean isPrimitiveValueType(Class<?> aClass) {
122         return javaLangAccess.isPrimitiveValueType(aClass);
123     }
124 
125     /**
126      * Returns {@code true} if this class is a primitive class.
127      * <p>
128      * Each primitive class has a {@linkplain #isPrimaryType(Class)  primary type}
129      * representing the <em>primitive reference type</em> and a
130      * {@linkplain #isPrimitiveValueType(Class)  secondary type} representing
131      * the <em>primitive value type</em>.  The primitive reference type
132      * and primitive value type can be obtained by calling the
133      * {@link #asPrimaryType(Class)} and {@link PrimitiveClass#asValueType} method
134      * of a primitive class respectively.
135      * <p>
136      * A primitive class is a {@linkplain Class#isValue() value class}.
137      *
138      * @param aClass a class
139      * @return {@code true} if this class is a primitive class, otherwise {@code false}
140      * @see Class#isValue()
141      * @see #asPrimaryType(Class)
142      * @see #asValueType(Class)
143      * @since Valhalla
144      */
145     public static boolean isPrimitiveClass(Class<?> aClass) {
146         return javaLangAccess.isPrimitiveClass(aClass);
147     }
148 }