diff --git a/java.source.base/apichanges.xml b/java.source.base/apichanges.xml
--- a/java.source.base/apichanges.xml
+++ b/java.source.base/apichanges.xml
@@ -49,6 +49,20 @@
Java Source API
+
+
+ ClassIndex SearchKind extended by FUNCTIONAL_IMPLEMENTORS
+
+
+
+
+
+ Added a possibility to ClassIndex
to search a lambda
+ implementations.
+
+
+
+
ClassIndex returns resources from binaryroots
diff --git a/java.source.base/nbproject/project.properties b/java.source.base/nbproject/project.properties
--- a/java.source.base/nbproject/project.properties
+++ b/java.source.base/nbproject/project.properties
@@ -47,7 +47,7 @@
javadoc.title=Java Source Base
javadoc.arch=${basedir}/arch.xml
javadoc.apichanges=${basedir}/apichanges.xml
-spec.version.base=2.8.0
+spec.version.base=2.9.0
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/nb-javac-api.jar
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
${o.n.core.dir}/lib/boot.jar:\
diff --git a/java.source.base/src/org/netbeans/api/java/source/ClassIndex.java b/java.source.base/src/org/netbeans/api/java/source/ClassIndex.java
--- a/java.source.base/src/org/netbeans/api/java/source/ClassIndex.java
+++ b/java.source.base/src/org/netbeans/api/java/source/ClassIndex.java
@@ -198,6 +198,8 @@
/**
* The returned class has to extend or implement given element
+ *//**
+ * The returned class has to extend or implement given element
*/
IMPLEMENTORS,
@@ -214,7 +216,13 @@
/**
* The returned class contains references to the element type
*/
- TYPE_REFERENCES,
+ TYPE_REFERENCES,
+
+ /**
+ * The returned class contains a lambda implementation of given functional interface.
+ * @since 2.9
+ */
+ FUNCTIONAL_IMPLEMENTORS;
};
/**
@@ -831,8 +839,8 @@
final Set result = EnumSet.noneOf(ClassIndexImpl.UsageType.class);
for (ClassIndex.SearchKind sk : kind) {
switch (sk) {
- case METHOD_REFERENCES:
- result.add(ClassIndexImpl.UsageType.METHOD_REFERENCE);
+ case METHOD_REFERENCES:
+ result.add(ClassIndexImpl.UsageType.METHOD_REFERENCE);
break;
case FIELD_REFERENCES:
result.add(ClassIndexImpl.UsageType.FIELD_REFERENCE);
@@ -860,6 +868,9 @@
throw new IllegalArgumentException ();
}
break;
+ case FUNCTIONAL_IMPLEMENTORS:
+ result.add(ClassIndexImpl.UsageType.FUNCTIONAL_IMPLEMENTORS);
+ break;
default:
throw new IllegalArgumentException ();
}
diff --git a/java.source.base/src/org/netbeans/modules/java/source/indexing/JavaIndex.java b/java.source.base/src/org/netbeans/modules/java/source/indexing/JavaIndex.java
--- a/java.source.base/src/org/netbeans/modules/java/source/indexing/JavaIndex.java
+++ b/java.source.base/src/org/netbeans/modules/java/source/indexing/JavaIndex.java
@@ -81,7 +81,7 @@
public final class JavaIndex {
public static final String NAME = "java"; //NOI18N
- public static final int VERSION = 14;
+ public static final int VERSION = 15;
static final Logger LOG = Logger.getLogger(JavaIndex.class.getName());
private static final String CLASSES = "classes"; //NOI18N
private static final String APT_SOURCES = "sources"; //NOI18N
diff --git a/java.source.base/src/org/netbeans/modules/java/source/usages/ClassIndexImpl.java b/java.source.base/src/org/netbeans/modules/java/source/usages/ClassIndexImpl.java
--- a/java.source.base/src/org/netbeans/modules/java/source/usages/ClassIndexImpl.java
+++ b/java.source.base/src/org/netbeans/modules/java/source/usages/ClassIndexImpl.java
@@ -87,7 +87,8 @@
SUPER_INTERFACE,
FIELD_REFERENCE,
METHOD_REFERENCE,
- TYPE_REFERENCE;
+ TYPE_REFERENCE,
+ FUNCTIONAL_IMPLEMENTORS;
}
/**
diff --git a/java.source.base/src/org/netbeans/modules/java/source/usages/SourceAnalyzerFactory.java b/java.source.base/src/org/netbeans/modules/java/source/usages/SourceAnalyzerFactory.java
--- a/java.source.base/src/org/netbeans/modules/java/source/usages/SourceAnalyzerFactory.java
+++ b/java.source.base/src/org/netbeans/modules/java/source/usages/SourceAnalyzerFactory.java
@@ -778,6 +778,25 @@
}
@Override
+ public Void visitLambdaExpression(
+ @NonNull final LambdaExpressionTree node,
+ @NonNull final Map, UsagesData> p) {
+ final Type type = ((JCTree.JCLambda)node).type;
+ if (type != null) {
+ final Symbol sym = type.tsym;
+ if (sym != null) {
+ if (sym != null && sym.getKind().isInterface()) {
+ addUsage(sym,
+ activeClass.peek(),
+ p,
+ ClassIndexImpl.UsageType.FUNCTIONAL_IMPLEMENTORS);
+ }
+ }
+ }
+ return super.visitLambdaExpression(node, p);
+ }
+
+ @Override
@CheckForNull
public Void visitVariable(@NonNull final VariableTree node, @NonNull final Map, UsagesData> p) {
Symbol s = ((JCTree.JCVariableDecl)node).sym;
diff --git a/refactoring.java/nbproject/project.xml b/refactoring.java/nbproject/project.xml
--- a/refactoring.java/nbproject/project.xml
+++ b/refactoring.java/nbproject/project.xml
@@ -177,7 +177,7 @@
- 2.6
+ 2.9
diff --git a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaWhereUsedQueryPlugin.java b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaWhereUsedQueryPlugin.java
--- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaWhereUsedQueryPlugin.java
+++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaWhereUsedQueryPlugin.java
@@ -56,6 +56,7 @@
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
+import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.fileinfo.NonRecursiveFolder;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.platform.JavaPlatform;
@@ -296,17 +297,27 @@
}
} else if (el.getKind().isClass() || el.getKind().isInterface()) {
if (isFindSubclasses || isFindDirectSubclassesOnly) {
- EnumSet searchKind = EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS);
if (isFindDirectSubclassesOnly) {
+ EnumSet searchKind = EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS);
+ if (el.getKind() == ElementKind.INTERFACE) {
+ searchKind.add(ClassIndex.SearchKind.FUNCTIONAL_IMPLEMENTORS);
+ }
//get direct implementors from index
sourceSet.addAll(idx.getResources(ElementHandle.create((TypeElement) el), searchKind, searchScopeType, resourceType));
} else {
- Set> implementorsAsHandles = RefactoringUtils.getImplementorsAsHandles(idx, cpInfo, (TypeElement)el, cancel);
+ Set> implementorsAsHandles = RefactoringUtils.getImplementorsAsHandles(idx, cpInfo, (TypeElement)el, cancel);
if (cancel != null && cancel.get()) {
sourceSet.clear();
return;
}
- sourceSet.addAll(SourceUtilsEx.getFiles((Collection>) implementorsAsHandles, cpInfo, cancel));
+ sourceSet.addAll(SourceUtilsEx.getFiles((Collection>)(Collection>)implementorsAsHandles, cpInfo, cancel));
+ if (el.getKind() == ElementKind.INTERFACE) {
+ sourceSet.addAll(getFunctionalSubtypes(
+ ElementHandle.create((TypeElement)el),
+ implementorsAsHandles,
+ cpInfo,
+ searchScopeType));
+ }
}
} else {
//get type references from index
@@ -550,6 +561,25 @@
}
}
+ @NonNull
+ private static Collection extends FileObject> getFunctionalSubtypes(
+ @NonNull final ElementHandle base,
+ @NonNull final Collection> subtypes,
+ @NonNull final ClasspathInfo cpInfo,
+ @NonNull final Set scope) {
+ assert base.getKind() == ElementKind.INTERFACE;
+ final ClassIndex index = cpInfo.getClassIndex();
+ final Set fncKind = EnumSet.of(ClassIndex.SearchKind.FUNCTIONAL_IMPLEMENTORS);
+ final Set result = new HashSet<>();
+ result.addAll(index.getResources(base, fncKind, scope));
+ for (ElementHandle e : subtypes) {
+ if (e.getKind() == ElementKind.INTERFACE) {
+ result.addAll(index.getResources(e, fncKind, scope));
+ }
+ }
+ return result;
+ }
+
private class FindTask implements CancellableTask {
private final RefactoringElementsBag elements;