mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 06:39:38 +07:00
JavaFunctionalExpressionIndex: support array initializers
This commit is contained in:
@@ -159,19 +159,34 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Funct
|
||||
|
||||
@NotNull
|
||||
private static String calcExprType(LighterASTNode funExpr, FileLocalResolver resolver) {
|
||||
LighterASTNode scope = skipExpressionsUp(resolver.getLightTree(), funExpr, TokenSet.create(LOCAL_VARIABLE, FIELD, TYPE_CAST_EXPRESSION, RETURN_STATEMENT, ASSIGNMENT_EXPRESSION));
|
||||
LighterAST tree = resolver.getLightTree();
|
||||
LighterASTNode scope = skipExpressionsUp(tree, funExpr, TokenSet.create(
|
||||
LOCAL_VARIABLE, FIELD, TYPE_CAST_EXPRESSION, RETURN_STATEMENT, ASSIGNMENT_EXPRESSION, ARRAY_INITIALIZER_EXPRESSION));
|
||||
int arrayDepth = 0;
|
||||
while (scope != null && scope.getTokenType() == ARRAY_INITIALIZER_EXPRESSION) {
|
||||
scope = tree.getParent(scope);
|
||||
// should be either new-expression or variable/field declaration
|
||||
arrayDepth++;
|
||||
}
|
||||
if (scope != null) {
|
||||
if (scope.getTokenType() == ASSIGNMENT_EXPRESSION) {
|
||||
LighterASTNode lValue = findExpressionChild(scope, resolver.getLightTree());
|
||||
LighterASTNode lValue = findExpressionChild(scope, tree);
|
||||
scope = lValue == null ? null : resolver.resolveLocally(lValue).getTarget();
|
||||
}
|
||||
else if (scope.getTokenType() == RETURN_STATEMENT) {
|
||||
scope = LightTreeUtil.getParentOfType(resolver.getLightTree(), scope,
|
||||
scope = LightTreeUtil.getParentOfType(tree, scope,
|
||||
TokenSet.create(METHOD),
|
||||
TokenSet.orSet(ElementType.MEMBER_BIT_SET, TokenSet.create(LAMBDA_EXPRESSION)));
|
||||
}
|
||||
else if (scope.getTokenType() == NEW_EXPRESSION) {
|
||||
assert arrayDepth > 0;
|
||||
if (arrayDepth != LightTreeUtil.getChildrenOfType(tree, scope, JavaTokenType.LBRACKET).size()) return "";
|
||||
LighterASTNode typeRef = LightTreeUtil.firstChildOfType(tree, scope, JAVA_CODE_REFERENCE);
|
||||
String refName = JavaLightTreeUtil.getNameIdentifierText(tree, typeRef);
|
||||
return StringUtil.notNullize(refName);
|
||||
}
|
||||
}
|
||||
return StringUtil.notNullize(scope == null ? null : resolver.getShortClassTypeName(scope));
|
||||
return StringUtil.notNullize(scope == null ? null : resolver.getShortClassTypeName(scope, arrayDepth));
|
||||
}
|
||||
|
||||
private static int getArgIndex(List<? extends LighterASTNode> args, LighterASTNode expr) {
|
||||
|
||||
@@ -135,7 +135,28 @@ public class FileLocalResolver {
|
||||
*/
|
||||
@Nullable
|
||||
public String getShortClassTypeName(@NotNull LighterASTNode var) {
|
||||
LighterASTNode typeRef = LightTreeUtil.firstChildOfType(myTree, LightTreeUtil.firstChildOfType(myTree, var, TYPE), JAVA_CODE_REFERENCE);
|
||||
return getShortClassTypeName(var, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the type name of the given variable, unwrapping the expected array type.
|
||||
* Can be used to later iterate over all classes with this name for lightweight checks
|
||||
* before loading AST and fully resolving the type.
|
||||
* @param var Variable node
|
||||
* @param arrayDepth Expected array depth
|
||||
* @return the short name of the class corresponding to the type of the variable, or null if the variable is not of class type or
|
||||
* the type is generic
|
||||
*/
|
||||
@Nullable
|
||||
public String getShortClassTypeName(@NotNull LighterASTNode var, int arrayDepth) {
|
||||
LighterASTNode typeNode = LightTreeUtil.firstChildOfType(myTree, var, TYPE);
|
||||
while (arrayDepth > 0) {
|
||||
LighterASTNode bracket = LightTreeUtil.firstChildOfType(myTree, typeNode, JavaTokenType.LBRACKET);
|
||||
if (bracket == null) return null;
|
||||
typeNode = LightTreeUtil.firstChildOfType(myTree, typeNode, TYPE);
|
||||
arrayDepth--;
|
||||
}
|
||||
LighterASTNode typeRef = LightTreeUtil.firstChildOfType(myTree, typeNode, JAVA_CODE_REFERENCE);
|
||||
String refName = JavaLightTreeUtil.getNameIdentifierText(myTree, typeRef);
|
||||
if (refName == null) return null;
|
||||
|
||||
@@ -187,7 +208,6 @@ public class FileLocalResolver {
|
||||
@NotNull
|
||||
static LightResolveResult resolved(@NotNull final LighterASTNode target) {
|
||||
return new LightResolveResult() {
|
||||
@Nullable
|
||||
@Override
|
||||
public LighterASTNode getTarget() {
|
||||
return target;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class C {
|
||||
{
|
||||
Foo[] array = {() -> {}, () -> {}, null};
|
||||
Foo[][] array2 = {{() -> {}}};
|
||||
Bar[] array3 = {() -> {}};
|
||||
Bar[] array4 = new Bar[] {() -> {}};
|
||||
}
|
||||
}
|
||||
@@ -134,6 +134,13 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase
|
||||
configure();
|
||||
assertSize(1, FunctionalExpressionSearch.search(findClass("pkg.p1.p2.p3.I")).findAll());
|
||||
}
|
||||
|
||||
public void testInsideArrayInitializer() {
|
||||
myFixture.addClass("public interface Foo { void run() {}}");
|
||||
myFixture.addClass("public interface Bar { void run() {}}");
|
||||
configure();
|
||||
assertSize(3, FunctionalExpressionSearch.search(findClass("Foo")).findAll());
|
||||
}
|
||||
|
||||
public void testCallOnGenericParameter() {
|
||||
configure();
|
||||
|
||||
Reference in New Issue
Block a user