1 /* 2 * Copyright (c) 2019, 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 import java.util.ArrayList; 26 import java.util.List; 27 import java.util.Set; 28 import com.sun.tools.jextract.tree.FunctionTree; 29 import com.sun.tools.jextract.tree.VarTree; 30 31 /** 32 * A helper class to generate static forwarder header class in source form. 33 * After aggregating various constituents of a .java source, build method 34 * is called to get overall generated source string. 35 */ 36 final class JavaSourceBuilderExt extends JavaSourceBuilder { 37 JavaSourceBuilderExt(int align) { 38 super(align); 39 } 40 41 JavaSourceBuilderExt() { 42 super(); 43 } 44 45 protected void addImportSection() { 46 sb.append("import java.foreign.*;\n"); 47 sb.append("import java.foreign.memory.*;\n"); 48 sb.append("import java.lang.invoke.*;\n\n"); 49 } 50 51 protected void classBegin(String name, boolean isStatic) { 52 classBegin(name, isStatic, null); 53 } 54 55 protected void classBegin(String name, boolean isStatic, String superType) { 56 check(); 57 indent(); 58 sb.append("public "); 59 if (isStatic) { 60 sb.append("static "); 61 } 62 sb.append("class "); 63 sb.append(name); 64 if (superType != null) { 65 sb.append(" extends "); 66 sb.append(superType); 67 } 68 sb.append(" {\n\n"); 69 } 70 71 protected void classEnd() { 72 interfaceEnd(); 73 } 74 75 // implement LibraryScope scope(LibraryInterfaceObject) method 76 protected void emitScopeAccessor(String libraryField) { 77 check(); 78 incrAlign(); 79 indent(); 80 sb.append("public static Scope scope() {\n"); 81 incrAlign(); 82 indent(); 83 sb.append("return Libraries.libraryScope("); 84 sb.append(libraryField); 85 sb.append(");\n"); 86 decrAlign(); 87 indent(); 88 sb.append("}\n\n"); 89 decrAlign(); 90 } 91 92 // add private static field for the underlying header interface (bound) object 93 protected void addLibraryField(String className, String libraryField) { 94 check(); 95 incrAlign(); 96 indent(); 97 sb.append("private static final "); 98 sb.append(className); 99 sb.append(' '); 100 sb.append(libraryField); 101 sb.append(" = Libraries.bind(MethodHandles.lookup(), "); 102 sb.append(className); 103 sb.append(".class);\n\n"); 104 decrAlign(); 105 } 106 107 // add a static final field for enum constant or a C macro 108 protected void addField(String name, JType type, Object value, String libraryField) { 109 check(); 110 incrAlign(); 111 indent(); 112 sb.append("public static final "); 113 sb.append(type.getSourceSignature(false)); 114 sb.append(' '); 115 sb.append(name); 116 sb.append(" = "); 117 if (value != null) { 118 boolean isChar = value instanceof Character; 119 if (isChar) { 120 sb.append('\''); 121 } 122 sb.append(value); 123 if (isChar) { 124 sb.append('\''); 125 } 126 if (value instanceof Long) { 127 sb.append('L'); 128 } else if (value instanceof Double) { 129 sb.append('D'); 130 } 131 } else { 132 sb.append(libraryField); 133 sb.append('.'); 134 sb.append(name); 135 sb.append("()"); 136 } 137 sb.append(";\n\n"); 138 decrAlign(); 139 } 140 141 // emit static forwarder methods for a variable getter, setter and pointer getter 142 protected void emitStaticForwarder(VarTree varTree, JType type, String libraryField) { 143 check(); 144 incrAlign(); 145 146 String fieldName = varTree.name(); 147 148 // getter 149 indent(); 150 sb.append("public static "); 151 sb.append(type.getSourceSignature(false)); 152 sb.append(' '); 153 sb.append(fieldName); 154 sb.append("$get() {\n"); 155 incrAlign(); 156 indent(); 157 sb.append("return "); 158 sb.append(libraryField); 159 sb.append('.'); 160 sb.append(fieldName); 161 sb.append("$get();\n"); 162 decrAlign(); 163 indent(); 164 sb.append("}\n\n"); 165 166 // setter 167 indent(); 168 sb.append("public static void "); 169 sb.append(fieldName); 170 sb.append("$set("); 171 sb.append(type.getSourceSignature(true)); 172 sb.append(" value) {\n"); 173 incrAlign(); 174 indent(); 175 sb.append(libraryField); 176 sb.append('.'); 177 sb.append(fieldName); 178 sb.append("$set(value);\n"); 179 decrAlign(); 180 indent(); 181 sb.append("}\n\n"); 182 183 // ptr getter 184 JType ptrType = JType.GenericType.ofPointer(type); 185 indent(); 186 sb.append("public static "); 187 sb.append(ptrType.getSourceSignature(false)); 188 sb.append(' '); 189 sb.append(fieldName); 190 sb.append("$ptr() {\n"); 191 incrAlign(); 192 indent(); 193 sb.append("return "); 194 sb.append(libraryField); 195 sb.append('.'); 196 sb.append(fieldName); 197 sb.append("$ptr();\n"); 198 decrAlign(); 199 indent(); 200 sb.append("}\n\n"); 201 202 decrAlign(); 203 } 204 205 // emit static forwarder method of a function 206 protected void emitStaticForwarder(FunctionTree funcTree, JType.Function fn, String libraryField) { 207 check(); 208 209 final int numArgs = fn.isVarArgs? fn.args.length + 1 : fn.args.length; 210 final String[] argTypes = new String[numArgs]; 211 final String[] argNames = new String[numArgs]; 212 fillArgTypes(fn, argTypes); 213 fillArgNames(fn, funcTree, argNames); 214 215 incrAlign(); 216 indent(); 217 sb.append("public static "); 218 sb.append(fn.returnType.getSourceSignature(false)); 219 sb.append(' '); 220 sb.append(funcTree.name()); 221 sb.append('('); 222 for (int i = 0; i < numArgs; i++) { 223 sb.append(argTypes[i]); 224 sb.append(' '); 225 sb.append(argNames[i]); 226 if (i != numArgs - 1) { 227 sb.append(", "); 228 } 229 } 230 sb.append(") {\n"); 231 incrAlign(); 232 indent(); 233 if (fn.returnType != JType.Void) { 234 sb.append("return "); 235 } 236 sb.append(libraryField); 237 sb.append('.'); 238 sb.append(funcTree.name()); 239 sb.append('('); 240 for (int j = 0; j < numArgs; j++) { 241 sb.append(argNames[j]); 242 if (j != numArgs - 1) { 243 sb.append(", "); 244 } 245 } 246 sb.append(");\n"); 247 decrAlign(); 248 indent(); 249 sb.append("}\n\n"); 250 decrAlign(); 251 } 252 }