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 } 68 69 if (cls.isArray()) { 70 return new ArrayType(JType.of(cls.getComponentType())); 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(); 234 } 235 236 public JType getElementType() { 237 return elementType; 238 } 239 } 240 241 public final static class Function extends JType { 242 final JType returnType; 243 final JType[] args; 244 final boolean isVarArgs; 245 final java.foreign.layout.Function layout; 264 public String getDescriptor() { 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("<"); 350 if (targ == JType.Void && isArgument) { 351 sb.append("*"); 352 } else { 353 if (targ instanceof GenericType && isArgument) { 354 sb.append("+"); 355 } 356 sb.append(targ.box().getSignature(isArgument)); 357 } 358 sb.append(">;"); 359 return sb.toString(); 360 } 361 362 @Override 363 public String getSourceSignature(boolean isArgument) { 364 StringBuilder sb = new StringBuilder(); 365 sb.append(super.getSourceSignature(isArgument)); 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 public abstract String getSourceSignature(boolean isArgument); 42 43 public final static JType Void = new PrimitiveType("V", of(Void.class), "void"); 44 public final static JType Byte = new PrimitiveType("B", of(Byte.class), "byte"); 45 public final static JType Bool = new PrimitiveType("Z", of(Boolean.class), "boolean"); 46 public final static JType Char = new PrimitiveType("C", of(Character.class), "char"); 47 public final static JType Short = new PrimitiveType("S", of(Short.class), "short"); 48 public final static JType Int = new PrimitiveType("I", of(Integer.class), "int"); 49 public final static JType Long = new PrimitiveType("J", of(Long.class), "long"); 50 public final static JType Float = new PrimitiveType("F", of(Float.class), "float"); 51 public final static JType Double = new PrimitiveType("D", of(Double.class), "double"); 52 public final static JType Object = of(java.lang.Object.class); 53 54 public static JType of(final Class<?> cls) { 55 if (cls.getEnclosingClass() != null) { 56 throw new IllegalArgumentException("nested/inner class: " + cls.getName()); 57 } 58 59 if (cls.isArray()) { 60 return new ArrayType(JType.of(cls.getComponentType())); 156 // java.foreign.* is imported 157 if (externalName.startsWith("java.lang.") || 158 externalName.startsWith("java.foreign.")) { 159 return externalName.substring(externalName.lastIndexOf(".") + 1); 160 } else { 161 return externalName; 162 } 163 } 164 165 public String getSimpleName() { 166 int innerEnd = clsName.lastIndexOf('$'); 167 int packageEnd = clsName.lastIndexOf('.'); 168 if (innerEnd != -1) { 169 return clsName.substring(innerEnd + 1); 170 } else if (packageEnd != -1) { 171 return clsName.substring(packageEnd + 1); 172 } else { 173 return clsName; 174 } 175 } 176 } 177 178 public final static class ArrayType extends JType { 179 final JType elementType; 180 181 ArrayType(JType type) { 182 elementType = type; 183 } 184 185 @Override 186 public String getDescriptor() { 187 return JType.of(java.foreign.memory.Array.class).getDescriptor(); 188 } 189 190 @Override 191 public String getSourceSignature(boolean isArgument) { 192 StringBuilder sb = new StringBuilder(); 193 sb.append("Array"); // java.foreign.memory.* will be imported 194 sb.append("<"); 195 JType pt = elementType; 196 sb.append(pt.box().getSourceSignature(isArgument)); 197 sb.append(">"); 198 return sb.toString(); 199 } 200 201 public JType getElementType() { 202 return elementType; 203 } 204 } 205 206 public final static class Function extends JType { 207 final JType returnType; 208 final JType[] args; 209 final boolean isVarArgs; 210 final java.foreign.layout.Function layout; 229 public String getDescriptor() { 230 StringBuilder sb = new StringBuilder(); 231 sb.append('('); 232 // ensure sequence 233 for (int i = 0; i < args.length; i++) { 234 sb.append(args[i].getDescriptor()); 235 } 236 if (isVarArgs) { 237 sb.append("[Ljava/lang/Object;"); 238 } 239 sb.append(')'); 240 sb.append(returnType.getDescriptor()); 241 return sb.toString(); 242 } 243 244 @Override 245 public String getSourceSignature(boolean isArgument) { 246 throw new UnsupportedOperationException(); 247 } 248 249 public String getNativeDescriptor() { 250 return layout.toString(); 251 } 252 } 253 254 final static class FunctionalInterfaceType extends ClassType { 255 final Function fn; 256 257 FunctionalInterfaceType(String enclosingName, String name, Function fn) { 258 super(enclosingName, name); 259 this.fn = fn; 260 } 261 262 Function getFunction() { 263 return fn; 264 } 265 } 266 267 public static class GenericType extends ClassType { 268 JType targ; 269 270 GenericType(String base, JType targ) { 271 super(base); 272 this.targ = targ; 273 } 274 275 public JType getTypeArgument() { 276 return targ; 277 } 278 279 @Override 280 public String getSourceSignature(boolean isArgument) { 281 StringBuilder sb = new StringBuilder(); 282 sb.append(super.getSourceSignature(isArgument)); 283 sb.append("<"); 284 if (targ == JType.Void && isArgument) { 285 sb.append('?'); 286 } else { 287 if (targ instanceof GenericType && isArgument) { 288 sb.append("? extends "); 289 } 290 sb.append(targ.box().getSourceSignature(isArgument)); 291 } 292 sb.append(">"); 293 return sb.toString(); 294 } 295 296 public static GenericType ofPointer(JType targ) { 297 return new GenericType(JType.binaryName(Pointer.class), targ); 298 } 299 300 public static GenericType ofCallback(JType targ) { 301 return new GenericType(JType.binaryName(Callback.class), targ); 302 } 303 } 304 } |