diff -r e432b3a9fee1 java.source.base/src/org/netbeans/api/java/source/ElementHandle.java --- a/java.source.base/src/org/netbeans/api/java/source/ElementHandle.java Wed May 18 15:50:59 2016 +0400 +++ b/java.source.base/src/org/netbeans/api/java/source/ElementHandle.java Wed May 18 20:13:24 2016 +0300 @@ -57,6 +57,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.NestingKind; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeParameterElement; @@ -113,13 +114,15 @@ } private final ElementKind kind; + private final int nestingLevel; private final String[] signatures; - private ElementHandle(final ElementKind kind, String... signatures) { + private ElementHandle(final ElementKind kind, int nestingLevel, String... signatures) { assert kind != null; assert signatures != null; this.kind = kind; + this.nestingLevel = nestingLevel; this.signatures = signatures; } @@ -380,6 +383,17 @@ public @NonNull ElementKind getKind () { return this.kind; } + + /** + * Returns the {@link NestingKind} of this element handle, + * it is the nesting kind of the {@link TypeElement} from which the handle + * was created. + * @return {@link NestingKind} or null + * + */ + public int getNestingLevel() { + return nestingLevel; + } private static final WeakSet> NORMALIZATION_CACHE = new WeakSet>(); @@ -410,7 +424,7 @@ public static ElementHandle createPackageElementHandle ( @NonNull final String packageName) { Parameters.notNull("packageName", packageName); //NOI18N - return new ElementHandle(ElementKind.PACKAGE, packageName); + return new ElementHandle(ElementKind.PACKAGE, -1, packageName); } /** @@ -432,12 +446,13 @@ if (!kind.isClass() && !kind.isInterface()) { throw new IllegalArgumentException(kind.toString()); } - return new ElementHandle(kind, binaryName); + return new ElementHandle(kind, -1, binaryName); } private static @NonNull ElementHandle createImpl (@NonNull final T element) throws IllegalArgumentException { Parameters.notNull("element", element); ElementKind kind = element.getKind(); + int nestingLevel = -1; String[] signatures; switch (kind) { case PACKAGE: @@ -449,6 +464,7 @@ case ENUM: case ANNOTATION_TYPE: assert element instanceof TypeElement; + nestingLevel = getNestingLevel(element); signatures = new String[] {ClassFileUtil.encodeClassNameOrArray((TypeElement)element)}; break; case METHOD: @@ -456,11 +472,13 @@ case INSTANCE_INIT: case STATIC_INIT: assert element instanceof ExecutableElement; + nestingLevel = getNestingLevel(element.getEnclosingElement()); signatures = ClassFileUtil.createExecutableDescriptor((ExecutableElement)element); break; case FIELD: case ENUM_CONSTANT: assert element instanceof VariableElement; + nestingLevel = getNestingLevel(element.getEnclosingElement()); signatures = ClassFileUtil.createFieldDescriptor((VariableElement)element); break; case TYPE_PARAMETER: @@ -470,12 +488,14 @@ ElementKind gek = ge.getKind(); if (gek.isClass() || gek.isInterface()) { assert ge instanceof TypeElement; + nestingLevel = getNestingLevel(ge); signatures = new String[2]; signatures[0] = ClassFileUtil.encodeClassNameOrArray((TypeElement)ge); signatures[1] = tpe.getSimpleName().toString(); } else if (gek == ElementKind.METHOD || gek == ElementKind.CONSTRUCTOR) { assert ge instanceof ExecutableElement; + nestingLevel = getNestingLevel(ge.getEnclosingElement()); String[] _sigs = ClassFileUtil.createExecutableDescriptor((ExecutableElement)ge); signatures = new String[_sigs.length + 1]; System.arraycopy(_sigs, 0, signatures, 0, _sigs.length); @@ -488,7 +508,20 @@ default: throw new IllegalArgumentException(kind.toString()); } - return new ElementHandle (kind, signatures); + return new ElementHandle (kind, nestingLevel, signatures); + } + + private static int getNestingLevel(Element element) { + int level = 0; + Element current = element; + while (current instanceof TypeElement) { + if (((TypeElement) current).getNestingKind() == NestingKind.TOP_LEVEL) { + return level; + } + ++level; + current = current.getEnclosingElement(); + } + return -1; } /** @@ -563,7 +596,7 @@ if (descriptors.length != 1) { throw new IllegalArgumentException (); } - return new ElementHandle (kind, descriptors); + return new ElementHandle (kind, -1, descriptors); case CLASS: case INTERFACE: case ENUM: @@ -572,25 +605,25 @@ if (descriptors.length != 1) { throw new IllegalArgumentException (); } - return new ElementHandle (kind, descriptors); + return new ElementHandle (kind, -1, descriptors); case METHOD: case CONSTRUCTOR: if (descriptors.length != 3) { throw new IllegalArgumentException (); } - return new ElementHandle (kind, descriptors); + return new ElementHandle (kind, -1, descriptors); case INSTANCE_INIT: case STATIC_INIT: if (descriptors.length != 2) { throw new IllegalArgumentException (); } - return new ElementHandle (kind, descriptors); + return new ElementHandle (kind, -1, descriptors); case FIELD: case ENUM_CONSTANT: if (descriptors.length != 3) { throw new IllegalArgumentException (); } - return new ElementHandle (kind, descriptors); + return new ElementHandle (kind, -1, descriptors); default: throw new IllegalArgumentException (); } diff -r e432b3a9fee1 java.source.base/src/org/netbeans/api/java/source/SourceUtils.java --- a/java.source.base/src/org/netbeans/api/java/source/SourceUtils.java Wed May 18 15:50:59 2016 +0400 +++ b/java.source.base/src/org/netbeans/api/java/source/SourceUtils.java Wed May 18 20:13:24 2016 +0300 @@ -529,7 +529,7 @@ return folders.isEmpty() ? pair.first() : folders.get(0); } else { final boolean caseSensitive = isCaseSensitive (); - final Object fnames = getSourceFileNames (className); + final Object fnames = getSourceFileNames (className, handle.getNestingLevel()); folders.addFirst(pair.first()); if (fnames instanceof String) { FileObject match = findMatchingChild((String)fnames, folders, caseSensitive); @@ -1038,12 +1038,26 @@ * a String (top-level class, no $) or List<String> as the JLS permits $ in * class names. */ - private static Object getSourceFileNames (String classFileName) { + private static Object getSourceFileNames (String classFileName, int nestingLevel) { int max = classFileName.length() - 1; int index = classFileName.indexOf('$'); if (index == -1) { return classFileName; } + if (nestingLevel == 0) { + return classFileName; + } else if (nestingLevel > 0) { + int toIndex = classFileName.length(); + while (nestingLevel > 0 && toIndex > 0) { + toIndex = classFileName.lastIndexOf('$', toIndex - 1); + --nestingLevel; + } + if (toIndex > 0) { + assert nestingLevel == 0; + return classFileName.substring(0, toIndex); + } + } + // Fallback List ll = new ArrayList<>(3); do { ll.add(classFileName.substring(0, index));