8303374: Implement JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview)

Co-authored-by: Jan Lahoda <jlahoda@openjdk.org>
Co-authored-by: Maurizio Cimadamore <mcimadamore@openjdk.org>
Co-authored-by: Gavin Bierman <gbierman@openjdk.org>
Co-authored-by: Brian Goetz <briangoetz@openjdk.org>
Co-authored-by: Raffaello Giulietti <rgiulietti@openjdk.org>
Co-authored-by: Aggelos Biboudis <abimpoudis@openjdk.org>
Reviewed-by: vromero, jlahoda
This commit is contained in:
Aggelos Biboudis 2024-01-31 14:18:13 +00:00
parent 66971600f7
commit 1733d2ea24
43 changed files with 3564 additions and 391 deletions

View file

@ -25,23 +25,25 @@
package sun.invoke.util;
import java.util.Map;
import static sun.invoke.util.Wrapper.NumericClasses.*;
import jdk.internal.vm.annotation.DontInline;
public enum Wrapper {
// wrapperType simple primitiveType simple char emptyArray format
BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0], Format.unsigned( 1)),
// wrapperType simple primitiveType simple char emptyArray format numericClass superClass
BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0], Format.unsigned( 1), 0, 0),
// These must be in the order defined for widening primitive conversions in JLS 5.1.2
// Avoid boxing integral types here to defer initialization of internal caches
BYTE ( Byte.class, "Byte", byte.class, "byte", 'B', new byte[0], Format.signed( 8)),
SHORT ( Short.class, "Short", short.class, "short", 'S', new short[0], Format.signed( 16)),
CHAR (Character.class, "Character", char.class, "char", 'C', new char[0], Format.unsigned(16)),
INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0], Format.signed( 32)),
LONG ( Long.class, "Long", long.class, "long", 'J', new long[0], Format.signed( 64)),
FLOAT ( Float.class, "Float", float.class, "float", 'F', new float[0], Format.floating(32)),
DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0], Format.floating(64)),
OBJECT ( Object.class, "Object", Object.class, "Object", 'L', new Object[0], Format.other( 1)),
BYTE ( Byte.class, "Byte", byte.class, "byte", 'B', new byte[0], Format.signed( 8), BYTE_CLASS, BYTE_SUPERCLASSES),
SHORT ( Short.class, "Short", short.class, "short", 'S', new short[0], Format.signed( 16), SHORT_CLASS, SHORT_SUPERCLASSES),
CHAR (Character.class, "Character", char.class, "char", 'C', new char[0], Format.unsigned(16), CHAR_CLASS, CHAR_SUPERCLASSES),
INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0], Format.signed( 32), INT_CLASS, INT_SUPERCLASSES),
LONG ( Long.class, "Long", long.class, "long", 'J', new long[0], Format.signed( 64), LONG_CLASS, LONG_SUPERCLASSES),
FLOAT ( Float.class, "Float", float.class, "float", 'F', new float[0], Format.floating(32), FLOAT_CLASS, FLOAT_SUPERCLASSES),
DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0], Format.floating(64), DOUBLE_CLASS, DOUBLE_CLASS),
OBJECT ( Object.class, "Object", Object.class, "Object", 'L', new Object[0], Format.other( 1), 0, 0),
// VOID must be the last type, since it is "assignable" from any other type:
VOID ( Void.class, "Void", void.class, "void", 'V', null, Format.other( 0)),
VOID ( Void.class, "Void", void.class, "void", 'V', null, Format.other( 0), 0, 0),
;
public static final int COUNT = 10;
@ -52,16 +54,20 @@ public enum Wrapper {
private final String basicTypeString;
private final Object emptyArray;
private final int format;
private final int numericClass;
private final int superClasses;
private final String wrapperSimpleName;
private final String primitiveSimpleName;
private Wrapper(Class<?> wtype, String wtypeName, Class<?> ptype, String ptypeName, char tchar, Object emptyArray, int format) {
private Wrapper(Class<?> wtype, String wtypeName, Class<?> ptype, String ptypeName, char tchar, Object emptyArray, int format, int numericClass, int superClasses) {
this.wrapperType = wtype;
this.primitiveType = ptype;
this.basicTypeChar = tchar;
this.basicTypeString = String.valueOf(this.basicTypeChar);
this.emptyArray = emptyArray;
this.format = format;
this.numericClass = numericClass;
this.superClasses = superClasses;
this.wrapperSimpleName = wtypeName;
this.primitiveSimpleName = ptypeName;
}
@ -424,6 +430,11 @@ public enum Wrapper {
return findWrapperType(type) != null;
}
/** Query: Is the given type a wrapper, such as {@code Integer}, {@code Byte}, etc excluding {@code Void} and {@code Object}? */
public static boolean isWrapperNumericOrBooleanType(Class<?> type) {
return isWrapperType(type) && findWrapperType(type) != VOID && findWrapperType(type) != OBJECT;
}
/** Query: Is the given type a primitive, such as {@code int} or {@code void}? */
public static boolean isPrimitiveType(Class<?> type) {
return type.isPrimitive();
@ -628,4 +639,34 @@ public enum Wrapper {
values[i+vpos] = value;
}
}
// NumericClasses should be in sync with com.sun.tools.javac.code.TypeTag.NumericClasses
public static class NumericClasses {
public static final int BYTE_CLASS = 1;
public static final int CHAR_CLASS = 2;
public static final int SHORT_CLASS = 4;
public static final int INT_CLASS = 8;
public static final int LONG_CLASS = 16;
public static final int FLOAT_CLASS = 32;
public static final int DOUBLE_CLASS = 64;
static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS |
LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS |
LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS |
LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS;
}
public boolean isStrictSubRangeOf(Wrapper target) {
return (this.superClasses & target.numericClass) != 0 && this != target;
}
}