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 import jdk.internal.org.objectweb.asm.ClassVisitor; 26 import java.foreign.memory.Callback; 27 import java.foreign.memory.Pointer; 28 import java.util.Objects; 29 30 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT; 31 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_INTERFACE; 32 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; 33 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; 34 35 /** 36 * A Java Type descriptor 37 */ 38 public abstract class JType { 39 40 /** 41 * The descriptor of this type 42 * 43 * @return The type descriptor as defined in JVMS 4.3 44 */ 45 public abstract String getDescriptor(); 46 47 public void visitInner(ClassVisitor cv) {} 48 49 public String getSignature(boolean isArgument) { return getDescriptor(); } 50 51 public abstract String getSourceSignature(boolean isArgument); 52 53 public final static JType Void = new PrimitiveType("V", of(Void.class), "void"); 54 public final static JType Byte = new PrimitiveType("B", of(Byte.class), "byte"); 55 public final static JType Bool = new PrimitiveType("Z", of(Boolean.class), "boolean"); 56 public final static JType Char = new PrimitiveType("C", of(Character.class), "char"); 57 public final static JType Short = new PrimitiveType("S", of(Short.class), "short"); 58 public final static JType Int = new PrimitiveType("I", of(Integer.class), "int"); 59 public final static JType Long = new PrimitiveType("J", of(Long.class), "long"); 60 public final static JType Float = new PrimitiveType("F", of(Float.class), "float"); 61 public final static JType Double = new PrimitiveType("D", of(Double.class), "double"); 62 public final static JType Object = of(java.lang.Object.class); 63 64 public static JType of(final Class<?> cls) { 65 if (cls.getEnclosingClass() != null) { 66 throw new IllegalArgumentException("nested/inner class: " + cls.getName()); 67 } 166 // java.foreign.* is imported 167 if (externalName.startsWith("java.lang.") || 168 externalName.startsWith("java.foreign.")) { 169 return externalName.substring(externalName.lastIndexOf(".") + 1); 170 } else { 171 return externalName; 172 } 173 } 174 175 public String getSimpleName() { 176 int innerEnd = clsName.lastIndexOf('$'); 177 int packageEnd = clsName.lastIndexOf('.'); 178 if (innerEnd != -1) { 179 return clsName.substring(innerEnd + 1); 180 } else if (packageEnd != -1) { 181 return clsName.substring(packageEnd + 1); 182 } else { 183 return clsName; 184 } 185 } 186 187 @Override 188 public void visitInner(ClassVisitor cv) { 189 if (enclosingName != null) { 190 cv.visitInnerClass(clsName, enclosingName, simpleName, 191 ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE); 192 } 193 } 194 } 195 196 public final static class ArrayType extends JType { 197 final JType elementType; 198 199 ArrayType(JType type) { 200 elementType = type; 201 } 202 203 @Override 204 public String getDescriptor() { 205 return JType.of(java.foreign.memory.Array.class).getDescriptor(); 206 } 207 208 @Override 209 public void visitInner(ClassVisitor cv) { 210 elementType.visitInner(cv); 211 } 212 213 @Override 214 public String getSignature(boolean isArgument) { 215 StringBuilder sb = new StringBuilder(); 216 sb.append("L"); 217 sb.append(java.foreign.memory.Array.class.getName().replace('.', '/')); 218 sb.append("<"); 219 JType pt = elementType; 220 sb.append(pt.box().getSignature(isArgument)); 221 sb.append(">;"); 222 return sb.toString(); 223 } 224 225 @Override 226 public String getSourceSignature(boolean isArgument) { 227 StringBuilder sb = new StringBuilder(); 228 sb.append("Array"); // java.foreign.memory.* will be imported 229 sb.append("<"); 230 JType pt = elementType; 231 sb.append(pt.box().getSourceSignature(isArgument)); 232 sb.append(">"); 233 return sb.toString(); 265 StringBuilder sb = new StringBuilder(); 266 sb.append('('); 267 // ensure sequence 268 for (int i = 0; i < args.length; i++) { 269 sb.append(args[i].getDescriptor()); 270 } 271 if (isVarArgs) { 272 sb.append("[Ljava/lang/Object;"); 273 } 274 sb.append(')'); 275 sb.append(returnType.getDescriptor()); 276 return sb.toString(); 277 } 278 279 @Override 280 public String getSourceSignature(boolean isArgument) { 281 throw new UnsupportedOperationException(); 282 } 283 284 @Override 285 public void visitInner(ClassVisitor cv) { 286 returnType.visitInner(cv); 287 for (JType at : args) { 288 at.visitInner(cv); 289 } 290 } 291 292 @Override 293 public String getSignature(boolean isArgument) { 294 StringBuilder sb = new StringBuilder(); 295 sb.append('('); 296 // ensure sequence 297 for (int i = 0; i < args.length; i++) { 298 sb.append(args[i].getSignature(true)); 299 } 300 if (isVarArgs) { 301 sb.append("[Ljava/lang/Object;"); 302 } 303 sb.append(')'); 304 sb.append(returnType.getSignature(false)); 305 return sb.toString(); 306 } 307 308 public String getNativeDescriptor() { 309 return layout.toString(); 310 } 311 } 312 313 final static class FunctionalInterfaceType extends ClassType { 314 final Function fn; 315 316 FunctionalInterfaceType(String enclosingName, String name, Function fn) { 317 super(enclosingName, name); 318 this.fn = fn; 319 } 320 321 Function getFunction() { 322 return fn; 323 } 324 325 @Override 326 public void visitInner(ClassVisitor cv) { 327 fn.visitInner(cv); 328 super.visitInner(cv); 329 } 330 } 331 332 public static class GenericType extends ClassType { 333 JType targ; 334 335 GenericType(String base, JType targ) { 336 super(base); 337 this.targ = targ; 338 } 339 340 public JType getTypeArgument() { 341 return targ; 342 } 343 344 @Override 345 public String getSignature(boolean isArgument) { 346 StringBuilder sb = new StringBuilder(); 347 sb.append("L"); 348 sb.append(clsName); 349 sb.append("<"); 366 sb.append("<"); 367 if (targ == JType.Void && isArgument) { 368 sb.append('?'); 369 } else { 370 if (targ instanceof GenericType && isArgument) { 371 sb.append("? extends "); 372 } 373 sb.append(targ.box().getSourceSignature(isArgument)); 374 } 375 sb.append(">"); 376 return sb.toString(); 377 } 378 379 public static GenericType ofPointer(JType targ) { 380 return new GenericType(JType.binaryName(Pointer.class), targ); 381 } 382 383 public static GenericType ofCallback(JType targ) { 384 return new GenericType(JType.binaryName(Callback.class), targ); 385 } 386 387 @Override 388 public void visitInner(ClassVisitor cv) { 389 targ.visitInner(cv); 390 super.visitInner(cv); 391 } 392 } 393 } | 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 import java.foreign.memory.Callback; 26 import java.foreign.memory.Pointer; 27 import java.util.Objects; 28 29 /** 30 * A Java Type descriptor 31 */ 32 public abstract class JType { 33 34 /** 35 * The descriptor of this type 36 * 37 * @return The type descriptor as defined in JVMS 4.3 38 */ 39 public abstract String getDescriptor(); 40 41 42 public String getSignature(boolean isArgument) { return getDescriptor(); } 43 44 public abstract String getSourceSignature(boolean isArgument); 45 46 public final static JType Void = new PrimitiveType("V", of(Void.class), "void"); 47 public final static JType Byte = new PrimitiveType("B", of(Byte.class), "byte"); 48 public final static JType Bool = new PrimitiveType("Z", of(Boolean.class), "boolean"); 49 public final static JType Char = new PrimitiveType("C", of(Character.class), "char"); 50 public final static JType Short = new PrimitiveType("S", of(Short.class), "short"); 51 public final static JType Int = new PrimitiveType("I", of(Integer.class), "int"); 52 public final static JType Long = new PrimitiveType("J", of(Long.class), "long"); 53 public final static JType Float = new PrimitiveType("F", of(Float.class), "float"); 54 public final static JType Double = new PrimitiveType("D", of(Double.class), "double"); 55 public final static JType Object = of(java.lang.Object.class); 56 57 public static JType of(final Class<?> cls) { 58 if (cls.getEnclosingClass() != null) { 59 throw new IllegalArgumentException("nested/inner class: " + cls.getName()); 60 } 159 // java.foreign.* is imported 160 if (externalName.startsWith("java.lang.") || 161 externalName.startsWith("java.foreign.")) { 162 return externalName.substring(externalName.lastIndexOf(".") + 1); 163 } else { 164 return externalName; 165 } 166 } 167 168 public String getSimpleName() { 169 int innerEnd = clsName.lastIndexOf('$'); 170 int packageEnd = clsName.lastIndexOf('.'); 171 if (innerEnd != -1) { 172 return clsName.substring(innerEnd + 1); 173 } else if (packageEnd != -1) { 174 return clsName.substring(packageEnd + 1); 175 } else { 176 return clsName; 177 } 178 } 179 } 180 181 public final static class ArrayType extends JType { 182 final JType elementType; 183 184 ArrayType(JType type) { 185 elementType = type; 186 } 187 188 @Override 189 public String getDescriptor() { 190 return JType.of(java.foreign.memory.Array.class).getDescriptor(); 191 } 192 193 @Override 194 public String getSignature(boolean isArgument) { 195 StringBuilder sb = new StringBuilder(); 196 sb.append("L"); 197 sb.append(java.foreign.memory.Array.class.getName().replace('.', '/')); 198 sb.append("<"); 199 JType pt = elementType; 200 sb.append(pt.box().getSignature(isArgument)); 201 sb.append(">;"); 202 return sb.toString(); 203 } 204 205 @Override 206 public String getSourceSignature(boolean isArgument) { 207 StringBuilder sb = new StringBuilder(); 208 sb.append("Array"); // java.foreign.memory.* will be imported 209 sb.append("<"); 210 JType pt = elementType; 211 sb.append(pt.box().getSourceSignature(isArgument)); 212 sb.append(">"); 213 return sb.toString(); 245 StringBuilder sb = new StringBuilder(); 246 sb.append('('); 247 // ensure sequence 248 for (int i = 0; i < args.length; i++) { 249 sb.append(args[i].getDescriptor()); 250 } 251 if (isVarArgs) { 252 sb.append("[Ljava/lang/Object;"); 253 } 254 sb.append(')'); 255 sb.append(returnType.getDescriptor()); 256 return sb.toString(); 257 } 258 259 @Override 260 public String getSourceSignature(boolean isArgument) { 261 throw new UnsupportedOperationException(); 262 } 263 264 @Override 265 public String getSignature(boolean isArgument) { 266 StringBuilder sb = new StringBuilder(); 267 sb.append('('); 268 // ensure sequence 269 for (int i = 0; i < args.length; i++) { 270 sb.append(args[i].getSignature(true)); 271 } 272 if (isVarArgs) { 273 sb.append("[Ljava/lang/Object;"); 274 } 275 sb.append(')'); 276 sb.append(returnType.getSignature(false)); 277 return sb.toString(); 278 } 279 280 public String getNativeDescriptor() { 281 return layout.toString(); 282 } 283 } 284 285 final static class FunctionalInterfaceType extends ClassType { 286 final Function fn; 287 288 FunctionalInterfaceType(String enclosingName, String name, Function fn) { 289 super(enclosingName, name); 290 this.fn = fn; 291 } 292 293 Function getFunction() { 294 return fn; 295 } 296 } 297 298 public static class GenericType extends ClassType { 299 JType targ; 300 301 GenericType(String base, JType targ) { 302 super(base); 303 this.targ = targ; 304 } 305 306 public JType getTypeArgument() { 307 return targ; 308 } 309 310 @Override 311 public String getSignature(boolean isArgument) { 312 StringBuilder sb = new StringBuilder(); 313 sb.append("L"); 314 sb.append(clsName); 315 sb.append("<"); 332 sb.append("<"); 333 if (targ == JType.Void && isArgument) { 334 sb.append('?'); 335 } else { 336 if (targ instanceof GenericType && isArgument) { 337 sb.append("? extends "); 338 } 339 sb.append(targ.box().getSourceSignature(isArgument)); 340 } 341 sb.append(">"); 342 return sb.toString(); 343 } 344 345 public static GenericType ofPointer(JType targ) { 346 return new GenericType(JType.binaryName(Pointer.class), targ); 347 } 348 349 public static GenericType ofCallback(JType targ) { 350 return new GenericType(JType.binaryName(Callback.class), targ); 351 } 352 } 353 } |