1310 // c) Inner classes (non-static member classes) |
1310 // c) Inner classes (non-static member classes) |
1311 // d) Local classes (named classes declared within a method) |
1311 // d) Local classes (named classes declared within a method) |
1312 // e) Anonymous classes |
1312 // e) Anonymous classes |
1313 |
1313 |
1314 |
1314 |
1315 // JVM Spec 4.8.6: A class must have an EnclosingMethod |
1315 // JVM Spec 4.7.7: A class must have an EnclosingMethod |
1316 // attribute if and only if it is a local class or an |
1316 // attribute if and only if it is a local class or an |
1317 // anonymous class. |
1317 // anonymous class. |
1318 EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); |
1318 EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); |
1319 Class<?> enclosingCandidate; |
1319 Class<?> enclosingCandidate; |
1320 |
1320 |
1355 String simpleName = getSimpleBinaryName(); |
1355 String simpleName = getSimpleBinaryName(); |
1356 if (simpleName == null) { // top level class |
1356 if (simpleName == null) { // top level class |
1357 simpleName = getName(); |
1357 simpleName = getName(); |
1358 return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name |
1358 return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name |
1359 } |
1359 } |
1360 // According to JLS3 "Binary Compatibility" (13.1) the binary |
1360 return simpleName; |
1361 // name of non-package classes (not top level) is the binary |
|
1362 // name of the immediately enclosing class followed by a '$' followed by: |
|
1363 // (for nested and inner classes): the simple name. |
|
1364 // (for local classes): 1 or more digits followed by the simple name. |
|
1365 // (for anonymous classes): 1 or more digits. |
|
1366 |
|
1367 // Since getSimpleBinaryName() will strip the binary name of |
|
1368 // the immediately enclosing class, we are now looking at a |
|
1369 // string that matches the regular expression "\$[0-9]*" |
|
1370 // followed by a simple name (considering the simple of an |
|
1371 // anonymous class to be the empty string). |
|
1372 |
|
1373 // Remove leading "\$[0-9]*" from the name |
|
1374 int length = simpleName.length(); |
|
1375 if (length < 1 || simpleName.charAt(0) != '$') |
|
1376 throw new InternalError("Malformed class name"); |
|
1377 int index = 1; |
|
1378 while (index < length && isAsciiDigit(simpleName.charAt(index))) |
|
1379 index++; |
|
1380 // Eventually, this is the empty string iff this is an anonymous class |
|
1381 return simpleName.substring(index); |
|
1382 } |
1361 } |
1383 |
1362 |
1384 /** |
1363 /** |
1385 * Return an informative string for the name of this type. |
1364 * Return an informative string for the name of this type. |
1386 * |
1365 * |
1487 */ |
1466 */ |
1488 private String getSimpleBinaryName() { |
1467 private String getSimpleBinaryName() { |
1489 Class<?> enclosingClass = getEnclosingClass(); |
1468 Class<?> enclosingClass = getEnclosingClass(); |
1490 if (enclosingClass == null) // top level class |
1469 if (enclosingClass == null) // top level class |
1491 return null; |
1470 return null; |
1492 // Otherwise, strip the enclosing class' name |
1471 String name = getSimpleBinaryName0(); |
1493 try { |
1472 if (name == null) // anonymous class |
1494 return getName().substring(enclosingClass.getName().length()); |
1473 return ""; |
1495 } catch (IndexOutOfBoundsException ex) { |
1474 return name; |
1496 throw new InternalError("Malformed class name", ex); |
1475 } |
1497 } |
1476 |
1498 } |
1477 private native String getSimpleBinaryName0(); |
1499 |
1478 |
1500 /** |
1479 /** |
1501 * Returns {@code true} if this is a local class or an anonymous |
1480 * Returns {@code true} if this is a local class or an anonymous |
1502 * class. Returns {@code false} otherwise. |
1481 * class. Returns {@code false} otherwise. |
1503 */ |
1482 */ |
1504 private boolean isLocalOrAnonymousClass() { |
1483 private boolean isLocalOrAnonymousClass() { |
1505 // JVM Spec 4.8.6: A class must have an EnclosingMethod |
1484 // JVM Spec 4.7.7: A class must have an EnclosingMethod |
1506 // attribute if and only if it is a local class or an |
1485 // attribute if and only if it is a local class or an |
1507 // anonymous class. |
1486 // anonymous class. |
1508 return getEnclosingMethodInfo() != null; |
1487 return getEnclosingMethodInfo() != null; |
1509 } |
1488 } |
1510 |
1489 |