1 /*
  2  * Copyright (c) 2024, 2026, 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.incubator.code.dialect.java;
 27 
 28 import jdk.incubator.code.dialect.java.impl.JavaTypeUtils;
 29 import jdk.incubator.code.extern.ExternalizedCodeType;
 30 
 31 import java.lang.constant.ClassDesc;
 32 import java.lang.invoke.MethodHandles.Lookup;
 33 import java.lang.reflect.Type;
 34 import java.util.Map;
 35 import java.util.Objects;
 36 import java.util.Optional;
 37 
 38 /**
 39  * A primitive type
 40  */
 41 public final class PrimitiveType implements JavaType {
 42     // Fully qualified name
 43     private final ClassDesc type;
 44 
 45     PrimitiveType(ClassDesc type) {
 46         this.type = type;
 47     }
 48 
 49     @Override
 50     public Type resolve(Lookup lookup) throws ReflectiveOperationException {
 51         return type.resolveConstantDesc(lookup);
 52     }
 53 
 54     @Override
 55     public ExternalizedCodeType externalize() {
 56         return JavaTypeUtils.primitiveType(type.displayName());
 57     }
 58 
 59     @Override
 60     public String toString() {
 61         return JavaTypeUtils.toExternalTypeString(externalize());
 62     }
 63 
 64     @Override
 65     public boolean equals(Object o) {
 66         if (this == o) return true;
 67         return o instanceof PrimitiveType that &&
 68                 Objects.equals(type, that.type);
 69     }
 70 
 71     @Override
 72     public int hashCode() {
 73         return type.hashCode();
 74     }
 75 
 76     @Override
 77     public JavaType erasure() {
 78         return this;
 79     }
 80 
 81     @Override
 82     public JavaType toBasicType() {
 83         return switch (type.descriptorString().charAt(0)) {
 84             case 'V' -> JavaType.VOID;
 85             case 'J' -> JavaType.LONG;
 86             case 'F' -> JavaType.FLOAT;
 87             case 'D' -> JavaType.DOUBLE;
 88             default -> JavaType.INT;
 89         };
 90     }
 91 
 92     /**
 93      * {@return the boxed class type associated with this primitive type (if any)}
 94      */
 95     public Optional<ClassType> box() {
 96         class LazyHolder {
 97             static final Map<PrimitiveType, ClassType> primitiveToWrapper = Map.of(
 98                     BYTE, J_L_BYTE,
 99                     SHORT, J_L_SHORT,
100                     INT, J_L_INTEGER,
101                     LONG, J_L_LONG,
102                     FLOAT, J_L_FLOAT,
103                     DOUBLE, J_L_DOUBLE,
104                     CHAR, J_L_CHARACTER,
105                     BOOLEAN, J_L_BOOLEAN
106             );
107         }
108         return Optional.ofNullable(LazyHolder.primitiveToWrapper.get(this));
109     };
110 
111     @Override
112     public ClassDesc toNominalDescriptor() {
113         return type;
114     }
115 
116     /**
117      * {@return {@code true} if this type is {@link JavaType#VOID}}
118      */
119     public boolean isVoid() {
120         return toBasicType() == JavaType.VOID;
121     }
122 }