1 /* 2 * Copyright (c) 2015, 2016, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package com.sun.tools.jextract; 24 25 /** 26 * A Java Type descriptor 27 */ 28 public interface JType { 29 30 /** 31 * The descriptor of this type 32 * 33 * @return The type descriptor as defined in JVMS 4.3 34 */ 35 public String getDescriptor(); 36 37 default public String getSignature() { return getDescriptor(); } 38 39 public final static JType Void = () -> "V"; 40 public final static JType Byte = () -> "B"; 41 public final static JType Bool = () -> "Z"; 42 public final static JType Char = () -> "C"; 43 public final static JType Short = () -> "S"; 44 public final static JType Int = () -> "I"; 45 public final static JType Long = () -> "J"; 46 public final static JType Float = () -> "F"; 47 public final static JType Double = () -> "D"; 48 public final static JType Object = new ObjectRef(java.lang.Object.class); 49 50 public static JType of(final Class<?> cls) { 51 if (cls.isArray()) { 52 return ofArray(JType.of(cls.getComponentType())); 53 } 54 if (cls.isPrimitive()) { 55 switch (cls.getTypeName()) { 56 case "int": 57 return JType.Int; 58 case "long": 59 return JType.Long; 60 case "byte": 61 return JType.Byte; 62 case "char": 63 return JType.Char; 64 case "float": 65 return JType.Float; 66 case "double": 67 return JType.Double; 68 case "short": 69 return JType.Short; 70 case "boolean": 71 return JType.Bool; 72 case "void": 73 return JType.Void; 74 } 75 } 76 if (cls == Object.class) { 77 return JType.Object; 78 } 79 // assuming reference 80 return new ObjectRef(cls); 81 } 82 83 public static String boxing(JType t) { 84 if (t instanceof JType2) { 85 t = ((JType2) t).getDelegate(); 86 } 87 88 if (t == JType.Bool) { 89 return "Ljava/lang/Boolean;"; 90 } else if (t == JType.Char) { 91 return "Ljava/lang/Character;"; 92 } else if (t == JType.Int) { 93 return "Ljava/lang/Integer;"; 94 } else if (t == JType.Byte) { 95 return "Ljava/lang/Byte;"; 96 } else if (t == JType.Double) { 97 return "Ljava/lang/Double;"; 98 } else if (t == JType.Float) { 99 return "Ljava/lang/Float;"; 100 } else if (t == JType.Long) { 101 return "Ljava/lang/Long;"; 102 } else if (t == JType.Short) { 103 return "Ljava/lang/Short;"; 104 } else if (t == JType.Void) { 105 return "Ljava/lang/Void;"; 106 } else { 107 return t.getSignature(); 108 } 109 } 110 111 public static JType of(String clsName) { 112 return new ObjectRef(clsName); 113 } 114 public static JType ofArray(JType elementType) { return new ArrayType(elementType); } 115 116 /** 117 * Return Java type signature for JType. If JType is a Pointer<Void>, return as 118 * Pointer<?> 119 * @param jt The JType to get signature for 120 * @return The Java type signature 121 */ 122 static String getPointerVoidAsWildcard(JType jt) { 123 // Return Pointer<?> instead of Pointer<Void> 124 if (jt instanceof JType2) { 125 jt = ((JType2) jt).getDelegate(); 126 } 127 if (jt instanceof TypeAlias) { 128 JType tmp = ((TypeAlias) jt).baseType; 129 // Respect alias signature, like FnIf has its own rule about signature 130 if (tmp instanceof PointerType) { 131 jt = tmp; 132 } 133 } 134 if (jt instanceof PointerType) { 135 return ((PointerType) jt).getSignature(true); 136 } else { 137 return jt.getSignature(); 138 } 139 } 140 141 static class ObjectRef implements JType { 142 final String clsName; 143 144 ObjectRef(Class<?> cls) { 145 this.clsName = cls.getName().replace('.', '/'); 146 } 147 148 ObjectRef(String clsName) { 149 this.clsName = clsName; 150 } 151 152 @Override 153 public String getDescriptor() { 154 return "L" + clsName + ";"; 155 } 156 } 157 158 final static class InnerType implements JType { 159 final String outerName; 160 final String name; 161 162 InnerType(Class<?> outer, String name) { 163 outerName = outer.getName().replace('.', '/'); 164 this.name = name; 165 } 166 167 InnerType(String outerName, String name) { 168 this.outerName = outerName; 169 this.name = name; 170 } 171 172 public String getOuterClassName() { 173 return outerName; 174 } 175 176 public String getName() { 177 return name; 178 } 179 180 @Override 181 public String getDescriptor() { 182 return "L" + outerName + "$" + name + ";"; 183 } 184 } 185 186 final class ArrayType implements JType { 187 final JType elementType; 188 189 ArrayType(JType type) { 190 elementType = type; 191 } 192 193 PointerType asPointer() { 194 return new PointerType(elementType); 195 } 196 197 @Override 198 public String getDescriptor() { 199 return JType.of(java.foreign.memory.Array.class).getDescriptor(); 200 } 201 202 @Override 203 public String getSignature() { 204 StringBuilder sb = new StringBuilder(); 205 sb.append("L"); 206 sb.append(java.foreign.memory.Array.class.getName().replace('.', '/')); 207 sb.append("<"); 208 JType pt = elementType; 209 if (pt instanceof JType2) { 210 pt = ((JType2) pt).getDelegate(); 211 } 212 if (pt instanceof TypeAlias) { 213 pt = ((TypeAlias) pt).canonicalType(); 214 } 215 sb.append(JType.boxing(pt)); 216 sb.append(">;"); 217 return sb.toString(); 218 } 219 220 public JType getElementType() { 221 return elementType; 222 } 223 } 224 225 final static class Function implements JType { 226 final JType returnType; 227 final JType[] args; 228 final boolean isVarArgs; 229 final java.foreign.layout.Function layout; 230 231 Function(java.foreign.layout.Function layout, boolean isVarArgs, JType returnType, JType... args) { 232 this.layout = layout; 233 this.returnType = returnType; 234 this.args = args; 235 for (int i = 0; i < args.length; i++) { 236 args[i] = arrayAsPointer(args[i]); 237 } 238 this.isVarArgs = isVarArgs; 239 } 240 241 private static JType arrayAsPointer(JType t) { 242 if (t instanceof JType2) { 243 t = ((JType2)t).getDelegate(); 244 } 245 if (t instanceof TypeAlias) { 246 t = ((TypeAlias)t).canonicalType(); 247 } 248 return t instanceof ArrayType? ((ArrayType)t).asPointer() : t; 249 } 250 251 @Override 252 public String getDescriptor() { 253 StringBuilder sb = new StringBuilder(); 254 sb.append('('); 255 // ensure sequence 256 for (int i = 0; i < args.length; i++) { 257 sb.append(args[i].getDescriptor()); 258 } 259 if (isVarArgs) { 260 sb.append("[Ljava/lang/Object;"); 261 } 262 sb.append(')'); 263 sb.append(returnType.getDescriptor()); 264 return sb.toString(); 265 } 266 267 @Override 268 public String getSignature() { 269 StringBuilder sb = new StringBuilder(); 270 sb.append('('); 271 // ensure sequence 272 for (int i = 0; i < args.length; i++) { 273 sb.append(getPointerVoidAsWildcard(args[i])); 274 } 275 if (isVarArgs) { 276 sb.append("[Ljava/lang/Object;"); 277 } 278 sb.append(')'); 279 sb.append(returnType.getSignature()); 280 return sb.toString(); 281 } 282 283 public String getNativeDescriptor() { 284 return layout.toString(); 285 } 286 } 287 288 final static class FnIf implements JType { 289 final JType type; 290 final Function fn; 291 292 FnIf(JType type, Function fn) { 293 this.type = type; 294 this.fn = fn; 295 } 296 297 @Override 298 public String getDescriptor() { 299 return type.getDescriptor(); 300 } 301 302 @Override 303 public String getSignature() { 304 return type.getSignature(); 305 } 306 307 Function getFunction() { 308 return fn; 309 } 310 311 @Override 312 public String toString() { 313 return "FunctionalInterface: " + getDescriptor() + " for " + fn.getSignature(); 314 } 315 } 316 } --- EOF ---