mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-09 08:09:39 +07:00
add LightTreeUtil.processLeavesAtOffsets to speed up indices that walk text occurrences (IDEA-211564)
GitOrigin-RevId: cdc48ae3679e43a5ca7b87d0c371ecb6ab78cc19
This commit is contained in:
committed by
intellij-monorepo-bot
parent
34f13deda3
commit
d841318606
@@ -4,30 +4,29 @@ package com.intellij.psi.impl.java;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.lang.LighterAST;
|
||||
import com.intellij.lang.LighterASTNode;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.impl.source.JavaFileElementType;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.impl.source.tree.RecursiveLighterASTNodeWalkingVisitor;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.impl.source.tree.LightTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.io.BooleanDataDescriptor;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.intellij.util.text.StringSearcher;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class JavaBinaryPlusExpressionIndex extends FileBasedIndexExtension<Boolean, JavaBinaryPlusExpressionIndex.PlusOffsets> implements PsiDependentIndex {
|
||||
public static final ID<Boolean, PlusOffsets> INDEX_ID = ID.create("java.binary.plus.expression");
|
||||
@@ -43,24 +42,22 @@ public class JavaBinaryPlusExpressionIndex extends FileBasedIndexExtension<Boole
|
||||
public DataIndexer<Boolean, PlusOffsets, FileContent> getIndexer() {
|
||||
return inputData -> {
|
||||
CharSequence text = inputData.getContentAsText();
|
||||
if (text.chars().noneMatch(c -> c == '+')) return Collections.emptyMap();
|
||||
int[] offsets = new StringSearcher("+", true, true).findAllOccurrences(text);
|
||||
if (offsets.length == 0) return Collections.emptyMap();
|
||||
|
||||
LighterAST tree = ((FileContentImpl)inputData).getLighterASTForPsiDependentIndex();
|
||||
TIntArrayList result = new TIntArrayList(1);
|
||||
new RecursiveLighterASTNodeWalkingVisitor(tree) {
|
||||
@Override
|
||||
public void visitNode(@NotNull LighterASTNode element) {
|
||||
super.visitNode(element);
|
||||
ProgressManager.checkCanceled();
|
||||
if ((element.getTokenType() == JavaElementType.BINARY_EXPRESSION ||
|
||||
element.getTokenType() == JavaElementType.POLYADIC_EXPRESSION)) {
|
||||
int[] offsets = getStringConcatenationPlusOffsets(element, tree);
|
||||
if (offsets != null) {
|
||||
result.add(offsets);
|
||||
}
|
||||
}
|
||||
TIntArrayList result = new TIntArrayList(offsets.length);
|
||||
Map<LighterASTNode, Boolean> stringConcatenations = new HashMap<>();
|
||||
LightTreeUtil.processLeavesAtOffsets(offsets, tree, (leaf, offset) -> {
|
||||
LighterASTNode element = leaf == null ? null : tree.getParent(leaf);
|
||||
if (element == null) return;
|
||||
|
||||
if ((element.getTokenType() == JavaElementType.BINARY_EXPRESSION
|
||||
|| element.getTokenType() == JavaElementType.POLYADIC_EXPRESSION) &&
|
||||
!stringConcatenations.computeIfAbsent(element, __ -> isStringConcatenation(element, tree))) {
|
||||
result.add(offset);
|
||||
}
|
||||
}.visitNode(tree.getRoot());
|
||||
});
|
||||
THashMap<Boolean, PlusOffsets> resultMap = ContainerUtil.newTroveMap();
|
||||
resultMap.put(Boolean.TRUE, new PlusOffsets(result.toNativeArray()));
|
||||
return resultMap;
|
||||
@@ -143,26 +140,10 @@ public class JavaBinaryPlusExpressionIndex extends FileBasedIndexExtension<Boole
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static int[] getStringConcatenationPlusOffsets(@NotNull LighterASTNode concatExpr, @NotNull LighterAST tree) {
|
||||
TIntArrayList result = null;
|
||||
boolean nonLiteralOccurred = false;
|
||||
for (LighterASTNode child : tree.getChildren(concatExpr)) {
|
||||
IElementType childTokenType = child.getTokenType();
|
||||
if (ElementType.EXPRESSION_BIT_SET.contains(childTokenType)) {
|
||||
if (!nonLiteralOccurred && !JavaElementType.LITERAL_EXPRESSION.equals(childTokenType)) {
|
||||
nonLiteralOccurred = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (JavaTokenType.PLUS.equals(childTokenType)) {
|
||||
if (result == null) {
|
||||
result = new TIntArrayList();
|
||||
}
|
||||
result.add(child.getStartOffset());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return result == null || !nonLiteralOccurred ? null : result.toNativeArray();
|
||||
private static boolean isStringConcatenation(@NotNull LighterASTNode concatExpr, @NotNull LighterAST tree) {
|
||||
return LightTreeUtil
|
||||
.getChildrenOfType(tree, concatExpr, ElementType.EXPRESSION_BIT_SET)
|
||||
.stream()
|
||||
.allMatch(e -> e.getTokenType() == JavaElementType.LITERAL_EXPRESSION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,10 +376,9 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Funct
|
||||
LighterAST tree = ((FileContentImpl)inputData).getLighterASTForPsiDependentIndex();
|
||||
FileLocalResolver resolver = new FileLocalResolver(tree);
|
||||
|
||||
for (int offset : offsets) {
|
||||
LighterASTNode leaf = LightTreeUtil.findLeafElementAt(tree, offset);
|
||||
LighterASTNode element = leaf == null ? null : tree.getParent(leaf);
|
||||
if (element == null) continue;
|
||||
LightTreeUtil.processLeavesAtOffsets(offsets, tree, (leaf, offset) -> {
|
||||
LighterASTNode element = tree.getParent(leaf);
|
||||
if (element == null) return;
|
||||
|
||||
if (element.getTokenType() == METHOD_REF_EXPRESSION || element.getTokenType() == LAMBDA_EXPRESSION) {
|
||||
FunctionalExpressionKey key = new FunctionalExpressionKey(getFunExprParameterCount(tree, element),
|
||||
@@ -388,7 +387,7 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Funct
|
||||
Map<Integer, FunExprOccurrence> map = result.computeIfAbsent(key, __ -> new LinkedHashMap<>());
|
||||
map.put(element.getStartOffset(), createOccurrence(element, resolver));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -57,11 +57,10 @@ public class JavaNullMethodArgumentIndex extends ScalarIndexExtension<JavaNullMe
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
StringSearcher searcher = new StringSearcher(PsiKeyword.NULL, true, true);
|
||||
LighterAST lighterAst = ((FileContentImpl)inputData).getLighterASTForPsiDependentIndex();
|
||||
|
||||
CharSequence text = inputData.getContentAsText();
|
||||
Set<LighterASTNode> calls = findCallsWithNulls(lighterAst, text, searcher);
|
||||
Set<LighterASTNode> calls = findCallsWithNulls(lighterAst, text);
|
||||
if (calls.isEmpty()) return Collections.emptyMap();
|
||||
|
||||
Map<MethodCallData, Void> result = new THashMap<>();
|
||||
@@ -81,10 +80,11 @@ public class JavaNullMethodArgumentIndex extends ScalarIndexExtension<JavaNullMe
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<LighterASTNode> findCallsWithNulls(@NotNull LighterAST lighterAst, @NotNull CharSequence text, @NotNull StringSearcher searcher) {
|
||||
private static Set<LighterASTNode> findCallsWithNulls(@NotNull LighterAST lighterAst,
|
||||
@NotNull CharSequence text) {
|
||||
Set<LighterASTNode> calls = new HashSet<>();
|
||||
searcher.processOccurrences(text, offset -> {
|
||||
LighterASTNode leaf = LightTreeUtil.findLeafElementAt(lighterAst, offset);
|
||||
int[] occurrences = new StringSearcher(PsiKeyword.NULL, true, true).findAllOccurrences(text);
|
||||
LightTreeUtil.processLeavesAtOffsets(occurrences, lighterAst, (leaf, offset) -> {
|
||||
LighterASTNode literal = leaf == null ? null : lighterAst.getParent(leaf);
|
||||
if (isNullLiteral(lighterAst, literal)) {
|
||||
LighterASTNode exprList = lighterAst.getParent(literal);
|
||||
@@ -92,7 +92,6 @@ public class JavaNullMethodArgumentIndex extends ScalarIndexExtension<JavaNullMe
|
||||
ContainerUtil.addIfNotNull(calls, LightTreeUtil.getParentOfType(lighterAst, exprList, Lazy.CALL_TYPES, ElementType.MEMBER_BIT_SET));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return calls;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user