1 11 package org.eclipse.swt.tools.internal; 12 13 import java.lang.reflect.*; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 17 public class StructsGenerator extends JNIGenerator { 18 19 boolean header; 20 21 public StructsGenerator(boolean header) { 22 this.header = header; 23 } 24 25 public void generateCopyright() { 26 generateMetaData("swt_copyright"); 27 } 28 29 public void generateIncludes() { 30 if (header) { 31 output("#include \""); 32 output(getOutputName()); 33 outputln(".h\""); 34 } else { 35 outputln("#include \"swt.h\""); 36 output("#include \""); 37 output(getOutputName()); 38 outputln("_structs.h\""); 39 } 40 outputln(); 41 } 42 43 public void generate(Class clazz) { 44 int j = 0; 45 Field[] fields = clazz.getDeclaredFields(); 46 for (; j < fields.length; j++) { 47 Field field = fields[j]; 48 int mods = field.getModifiers(); 49 if ((mods & Modifier.PUBLIC) != 0 && (mods & Modifier.STATIC) == 0) { 50 break; 51 } 52 } 53 if (j == fields.length) return; 54 if (header) { 55 generateHeaderFile(clazz); 56 } else { 57 generateSourceFile(clazz); 58 } 59 } 60 61 public void generate() { 62 if (!header && getClasses().length == 0) return; 63 super.generate(); 64 } 65 66 public String getExtension() { 67 return header ? ".h" : super.getExtension(); 68 } 69 70 public String getSuffix() { 71 return "_structs"; 72 } 73 74 void generateExcludes(Class [] classes) { 75 HashSet excludes = new HashSet (); 76 for (int i = 0; i < classes.length; i++) { 77 Class clazz = classes[i]; 78 ClassData classData = getMetaData().getMetaData(clazz); 79 String exclude = classData.getExclude(); 80 if (exclude.length() != 0) { 81 excludes.add(exclude); 82 } 83 } 84 for (Iterator iter = excludes.iterator(); iter.hasNext();) { 85 String exclude = (String )iter.next(); 86 outputln(exclude); 87 for (int i = 0; i < classes.length; i++) { 88 Class clazz = classes[i]; 89 ClassData classData = getMetaData().getMetaData(clazz); 90 String classExclude = classData.getExclude(); 91 if (exclude.equals(classExclude)) { 92 output("#define NO_"); 93 outputln(getClassName(clazz)); 94 } 95 } 96 outputln("#endif"); 97 outputln(); 98 } 99 } 100 101 void generateHeaderFile(Class clazz) { 102 generateSourceStart(clazz); 103 generatePrototypes(clazz); 104 generateBlankMacros(clazz); 105 generateSourceEnd(clazz); 106 outputln(); 107 } 108 109 void generateSourceFile(Class clazz) { 110 generateSourceStart(clazz); 111 generateFIDsStructure(clazz); 112 outputln(); 113 generateGlobalVar(clazz); 114 outputln(); 115 generateFunctions(clazz); 116 generateSourceEnd(clazz); 117 outputln(); 118 } 119 120 void generateSourceStart(Class clazz) { 121 String clazzName = getClassName(clazz); 122 output("#ifndef NO_"); 123 outputln(clazzName); 124 } 125 126 void generateSourceEnd(Class clazz) { 127 outputln("#endif"); 128 } 129 130 void generateGlobalVar(Class clazz) { 131 String clazzName = getClassName(clazz); 132 output(clazzName); 133 output("_FID_CACHE "); 134 output(clazzName); 135 outputln("Fc;"); 136 } 137 138 void generateBlankMacros(Class clazz) { 139 String clazzName = getClassName(clazz); 140 outputln("#else"); 141 output("#define cache"); 142 output(clazzName); 143 outputln("Fields(a,b)"); 144 output("#define get"); 145 output(clazzName); 146 outputln("Fields(a,b,c) NULL"); 147 output("#define set"); 148 output(clazzName); 149 outputln("Fields(a,b,c)"); 150 output("#define "); 151 output(clazzName); 152 outputln("_sizeof() 0"); 153 } 154 155 void generatePrototypes(Class clazz) { 156 String clazzName = getClassName(clazz); 157 output("void cache"); 158 output(clazzName); 159 outputln("Fields(JNIEnv *env, jobject lpObject);"); 160 output(clazzName); 161 output(" *get"); 162 output(clazzName); 163 output("Fields(JNIEnv *env, jobject lpObject, "); 164 output(clazzName); 165 outputln(" *lpStruct);"); 166 output("void set"); 167 output(clazzName); 168 output("Fields(JNIEnv *env, jobject lpObject, "); 169 output(clazzName); 170 outputln(" *lpStruct);"); 171 output("#define "); 172 output(clazzName); 173 output("_sizeof() sizeof("); 174 output(clazzName); 175 outputln(")"); 176 } 177 178 void generateFIDsStructure(Class clazz) { 179 String clazzName = getClassName(clazz); 180 output("typedef struct "); 181 output(clazzName); 182 outputln("_FID_CACHE {"); 183 outputln("\tint cached;"); 184 outputln("\tjclass clazz;"); 185 output("\tjfieldID "); 186 Field[] fields = clazz.getDeclaredFields(); 187 boolean first = true; 188 for (int i = 0; i < fields.length; i++) { 189 Field field = fields[i]; 190 if (ignoreField(field)) continue; 191 if (!first) output(", "); 192 output(field.getName()); 193 first = false; 194 } 195 outputln(";"); 196 output("} "); 197 output(clazzName); 198 outputln("_FID_CACHE;"); 199 } 200 201 void generateCacheFunction(Class clazz) { 202 String clazzName = getClassName(clazz); 203 output("void cache"); 204 output(clazzName); 205 outputln("Fields(JNIEnv *env, jobject lpObject)"); 206 outputln("{"); 207 output("\tif ("); 208 output(clazzName); 209 outputln("Fc.cached) return;"); 210 Class superclazz = clazz.getSuperclass(); 211 if (superclazz != Object .class) { 212 String superName = getClassName(superclazz); 213 output("\tcache"); 214 output(superName); 215 outputln("Fields(env, lpObject);"); 216 } 217 output("\t"); 218 output(clazzName); 219 if (isCPP) { 220 output("Fc.clazz = env->GetObjectClass(lpObject);"); 221 } else { 222 output("Fc.clazz = (*env)->GetObjectClass(env, lpObject);"); 223 } 224 outputln(); 225 Field[] fields = clazz.getDeclaredFields(); 226 for (int i = 0; i < fields.length; i++) { 227 Field field = fields[i]; 228 if (ignoreField(field)) continue; 229 output("\t"); 230 output(clazzName); 231 output("Fc."); 232 output(field.getName()); 233 if (isCPP) { 234 output(" = env->GetFieldID("); 235 } else { 236 output(" = (*env)->GetFieldID(env, "); 237 } 238 output(clazzName); 239 output("Fc.clazz, \""); 240 output(field.getName()); 241 output("\", \""); 242 output(getTypeSignature(field.getType())); 243 outputln("\");"); 244 } 245 output("\t"); 246 output(clazzName); 247 outputln("Fc.cached = 1;"); 248 outputln("}"); 249 } 250 251 void generateGetFields(Class clazz) { 252 Class superclazz = clazz.getSuperclass(); 253 String clazzName = getClassName(clazz); 254 String superName = getClassName(superclazz); 255 if (superclazz != Object .class) { 256 257 if (!(clazzName.equals(superName + "A") || clazzName.equals(superName + "W"))) { 258 output("\tget"); 259 output(superName); 260 output("Fields(env, lpObject, ("); 261 output(superName); 262 outputln(" *)lpStruct);"); 263 } else { 264 generateGetFields(superclazz); 265 } 266 } 267 Field[] fields = clazz.getDeclaredFields(); 268 for (int i = 0; i < fields.length; i++) { 269 Field field = fields[i]; 270 if (ignoreField(field)) continue; 271 FieldData fieldData = getMetaData().getMetaData(field); 272 String exclude = fieldData.getExclude(); 273 if (exclude.length() != 0) { 274 outputln(exclude); 275 } 276 boolean noWinCE = fieldData.getFlag("no_wince"); 277 if (noWinCE) { 278 outputln("#ifndef _WIN32_WCE"); 279 } 280 Class type = field.getType(); 281 String typeName = getClassName(type); 282 String accessor = fieldData.getAccessor(); 283 if (accessor == null || accessor.length() == 0) accessor = field.getName(); 284 if (type.isPrimitive()) { 285 output("\tlpStruct->"); 286 output(accessor); 287 output(" = "); 288 output(fieldData.getCast()); 289 if (isCPP) { 290 output("env->Get"); 291 } else { 292 output("(*env)->Get"); 293 } 294 output(getTypeSignature1(field.getType())); 295 if (isCPP) { 296 output("Field(lpObject, "); 297 } else { 298 output("Field(env, lpObject, "); 299 } 300 output(getClassName(field.getDeclaringClass())); 301 output("Fc."); 302 output(field.getName()); 303 output(");"); 304 } else if (type.isArray()) { 305 Class componentType = type.getComponentType(); 306 if (componentType.isPrimitive()) { 307 outputln("\t{"); 308 output("\t"); 309 output(getTypeSignature2(field.getType())); 310 output(" lpObject1 = ("); 311 output(getTypeSignature2(field.getType())); 312 if (isCPP) { 313 output(")env->GetObjectField(lpObject, "); 314 } else { 315 output(")(*env)->GetObjectField(env, lpObject, "); 316 } 317 output(getClassName(field.getDeclaringClass())); 318 output("Fc."); 319 output(field.getName()); 320 outputln(");"); 321 if (isCPP) { 322 output("\tenv->Get"); 323 } else { 324 output("\t(*env)->Get"); 325 } 326 output(getTypeSignature1(componentType)); 327 if (isCPP) { 328 output("ArrayRegion(lpObject1, 0, sizeof(lpStruct->"); 329 } else { 330 output("ArrayRegion(env, lpObject1, 0, sizeof(lpStruct->"); 331 } 332 output(accessor); 333 output(")"); 334 int byteCount = getByteCount(componentType); 335 if (byteCount > 1) { 336 output(" / "); 337 output(String.valueOf(byteCount)); 338 } 339 output(", ("); 340 output(getTypeSignature4(type)); 341 output(")lpStruct->"); 342 output(accessor); 343 outputln(");"); 344 output("\t}"); 345 } else { 346 throw new Error ("not done"); 347 } 348 } else { 349 outputln("\t{"); 350 if (isCPP) { 351 output("\tjobject lpObject1 = env->GetObjectField(lpObject, "); 352 } else { 353 output("\tjobject lpObject1 = (*env)->GetObjectField(env, lpObject, "); 354 } 355 output(getClassName(field.getDeclaringClass())); 356 output("Fc."); 357 output(field.getName()); 358 outputln(");"); 359 output("\tget"); 360 output(typeName); 361 output("Fields(env, lpObject1, &lpStruct->"); 362 output(accessor); 363 outputln(");"); 364 output("\t}"); 365 } 366 outputln(); 367 if (noWinCE) { 368 outputln("#endif"); 369 } 370 if (exclude.length() != 0) { 371 outputln("#endif"); 372 } 373 } 374 } 375 376 void generateGetFunction(Class clazz) { 377 String clazzName = getClassName(clazz); 378 output(clazzName); 379 output(" *get"); 380 output(clazzName); 381 output("Fields(JNIEnv *env, jobject lpObject, "); 382 output(clazzName); 383 outputln(" *lpStruct)"); 384 outputln("{"); 385 output("\tif (!"); 386 output(clazzName); 387 output("Fc.cached) cache"); 388 output(clazzName); 389 outputln("Fields(env, lpObject);"); 390 generateGetFields(clazz); 391 outputln("\treturn lpStruct;"); 392 outputln("}"); 393 } 394 395 void generateSetFields(Class clazz) { 396 Class superclazz = clazz.getSuperclass(); 397 String clazzName = getClassName(clazz); 398 String superName = getClassName(superclazz); 399 if (superclazz != Object .class) { 400 401 if (!(clazzName.equals(superName + "A") || clazzName.equals(superName + "W"))) { 402 output("\tset"); 403 output(superName); 404 output("Fields(env, lpObject, ("); 405 output(superName); 406 outputln(" *)lpStruct);"); 407 } else { 408 generateSetFields(superclazz); 409 } 410 } 411 Field[] fields = clazz.getDeclaredFields(); 412 for (int i = 0; i < fields.length; i++) { 413 Field field = fields[i]; 414 if (ignoreField(field)) continue; 415 FieldData fieldData = getMetaData().getMetaData(field); 416 String exclude = fieldData.getExclude(); 417 if (exclude.length() != 0) { 418 outputln(exclude); 419 } 420 boolean noWinCE = fieldData.getFlag("no_wince"); 421 if (noWinCE) { 422 outputln("#ifndef _WIN32_WCE"); 423 } 424 Class type = field.getType(); 425 String typeName = getClassName(type); 426 String accessor = fieldData.getAccessor(); 427 if (accessor == null || accessor.length() == 0) accessor = field.getName(); 428 if (type.isPrimitive()) { 429 if (isCPP) { 430 output("\tenv->Set"); 431 } else { 432 output("\t(*env)->Set"); 433 } 434 output(getTypeSignature1(field.getType())); 435 if (isCPP) { 436 output("Field(lpObject, "); 437 } else { 438 output("Field(env, lpObject, "); 439 } 440 output(getClassName(field.getDeclaringClass())); 441 output("Fc."); 442 output(field.getName()); 443 output(", ("); 444 output(getTypeSignature2(field.getType())); 445 output(")lpStruct->"); 446 output(accessor); 447 output(");"); 448 } else if (type.isArray()) { 449 Class componentType = type.getComponentType(); 450 if (componentType.isPrimitive()) { 451 outputln("\t{"); 452 output("\t"); 453 output(getTypeSignature2(field.getType())); 454 output(" lpObject1 = ("); 455 output(getTypeSignature2(field.getType())); 456 if (isCPP) { 457 output(")env->GetObjectField(lpObject, "); 458 } else { 459 output(")(*env)->GetObjectField(env, lpObject, "); 460 } 461 output(getClassName(field.getDeclaringClass())); 462 output("Fc."); 463 output(field.getName()); 464 outputln(");"); 465 if (isCPP) { 466 output("\tenv->Set"); 467 } else { 468 output("\t(*env)->Set"); 469 } 470 output(getTypeSignature1(componentType)); 471 if (isCPP) { 472 output("ArrayRegion(lpObject1, 0, sizeof(lpStruct->"); 473 } else { 474 output("ArrayRegion(env, lpObject1, 0, sizeof(lpStruct->"); 475 } 476 output(accessor); 477 output(")"); 478 int byteCount = getByteCount(componentType); 479 if (byteCount > 1) { 480 output(" / "); 481 output(String.valueOf(byteCount)); 482 } 483 output(", ("); 484 output(getTypeSignature4(type)); 485 output(")lpStruct->"); 486 output(accessor); 487 outputln(");"); 488 output("\t}"); 489 } else { 490 throw new Error ("not done"); 491 } 492 } else { 493 outputln("\t{"); 494 output("\tjobject lpObject1 = (*env)->GetObjectField(env, lpObject, "); 495 output(getClassName(field.getDeclaringClass())); 496 output("Fc."); 497 output(field.getName()); 498 outputln(");"); 499 output("\tset"); 500 output(typeName); 501 output("Fields(env, lpObject1, &lpStruct->"); 502 output(accessor); 503 outputln(");"); 504 output("\t}"); 505 } 506 outputln(); 507 if (noWinCE) { 508 outputln("#endif"); 509 } 510 if (exclude.length() != 0) { 511 outputln("#endif"); 512 } 513 } 514 } 515 516 void generateSetFunction(Class clazz) { 517 String clazzName = getClassName(clazz); 518 output("void set"); 519 output(clazzName); 520 output("Fields(JNIEnv *env, jobject lpObject, "); 521 output(clazzName); 522 outputln(" *lpStruct)"); 523 outputln("{"); 524 output("\tif (!"); 525 output(clazzName); 526 output("Fc.cached) cache"); 527 output(clazzName); 528 outputln("Fields(env, lpObject);"); 529 generateSetFields(clazz); 530 outputln("}"); 531 } 532 533 void generateFunctions(Class clazz) { 534 generateCacheFunction(clazz); 535 outputln(); 536 generateGetFunction(clazz); 537 outputln(); 538 generateSetFunction(clazz); 539 } 540 541 boolean ignoreField(Field field) { 542 int mods = field.getModifiers(); 543 return 544 ((mods & Modifier.PUBLIC) == 0) || 545 ((mods & Modifier.FINAL) != 0) || 546 ((mods & Modifier.STATIC) != 0); 547 } 548 549 } 550 | Popular Tags |