Skip to content

Commit df90c05

Browse files
committed
Re-implemented a small file cache to provide file definition completion
It turned out that "calculating" the file definitions each time we need them for completion is too slow. Let's see how this here works out.
1 parent 4c243c3 commit df90c05

5 files changed

Lines changed: 62 additions & 24 deletions

File tree

src/de/halirutan/mathematica/codeinsight/completion/providers/FileSymbolCompletion.java

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,17 @@
2626
import com.intellij.codeInsight.completion.*;
2727
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
2828
import com.intellij.codeInsight.lookup.LookupElementBuilder;
29-
import com.intellij.openapi.diagnostic.Logger;
3029
import com.intellij.patterns.PlatformPatterns;
3130
import com.intellij.patterns.PsiElementPattern.Capture;
3231
import com.intellij.psi.PsiElement;
3332
import com.intellij.psi.PsiFile;
34-
import com.intellij.psi.util.PsiTreeUtil;
3533
import com.intellij.util.ProcessingContext;
36-
import de.halirutan.mathematica.lang.psi.LocalizationConstruct;
34+
import de.halirutan.mathematica.lang.psi.api.MathematicaPsiFile;
3735
import de.halirutan.mathematica.lang.psi.api.Symbol;
36+
import de.halirutan.mathematica.lang.resolve.SymbolResolveResult;
3837
import org.jetbrains.annotations.NotNull;
3938

40-
import java.util.Set;
41-
import java.util.stream.Collectors;
39+
import java.util.HashSet;
4240

4341
import static de.halirutan.mathematica.codeinsight.completion.MathematicaCompletionContributor.GLOBAL_VARIABLE_PRIORITY;
4442

@@ -48,9 +46,6 @@
4846
*/
4947
public class FileSymbolCompletion extends MathematicaCompletionProvider {
5048

51-
private static final Logger LOG =
52-
Logger.getInstance("#de.halirutan.mathematica.codeinsight.completion.providers.FileSymbolCompletion");
53-
5449
@Override
5550
public void addTo(CompletionContributor contributor) {
5651
final Capture<PsiElement> symbolPattern = PlatformPatterns.psiElement().withParent(Symbol.class);
@@ -62,21 +57,23 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
6257
final PsiFile containingFile = parameters.getOriginalFile();
6358

6459
String prefix = findCurrentText(parameters, parameters.getPosition());
65-
if (!parameters.isExtendedCompletion() && !prefix.isEmpty()) {
60+
if (!parameters.isExtendedCompletion() && !prefix.isEmpty() && containingFile instanceof MathematicaPsiFile) {
6661
final CamelHumpMatcher matcher = new CamelHumpMatcher(prefix, true);
6762
CompletionResultSet result2 = result.withPrefixMatcher(matcher);
68-
69-
LOG.debug("Running file symbol completion");
70-
final Set<String> symbols = PsiTreeUtil.findChildrenOfType(containingFile, Symbol.class).stream().filter(
71-
s -> {
72-
final LocalizationConstruct.MScope localizationConstruct = s.getLocalizationConstruct();
73-
return s.isValid() && localizationConstruct == LocalizationConstruct.MScope.FILE_SCOPE;
74-
}
75-
).map(
76-
Symbol::getSymbolName
77-
).collect(Collectors.toSet());
78-
symbols.forEach(s -> result2.addElement(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(s),
79-
GLOBAL_VARIABLE_PRIORITY)));
63+
final HashSet<SymbolResolveResult> cachedDefinitions =
64+
((MathematicaPsiFile) containingFile).getCachedDefinitions();
65+
for (SymbolResolveResult cachedDefinition : cachedDefinitions) {
66+
if (cachedDefinition.isValidResult() && cachedDefinition.getElement() != null) {
67+
result2.addElement(
68+
PrioritizedLookupElement
69+
.withPriority(
70+
LookupElementBuilder
71+
.create(cachedDefinition.getElement())
72+
.bold()
73+
.withTypeText("(" + containingFile.getName() + ")", true),
74+
GLOBAL_VARIABLE_PRIORITY));
75+
}
76+
}
8077
}
8178
}
8279

src/de/halirutan/mathematica/codeinsight/completion/providers/ImportedSymbolCompletion.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.intellij.patterns.PlatformPatterns;
3232
import com.intellij.patterns.PsiElementPattern.Capture;
3333
import com.intellij.psi.PsiElement;
34+
import com.intellij.psi.PsiFile;
3435
import com.intellij.psi.search.GlobalSearchScope;
3536
import com.intellij.psi.search.ProjectScope;
3637
import com.intellij.util.ProcessingContext;
@@ -39,6 +40,8 @@
3940
import de.halirutan.mathematica.lang.psi.api.Symbol;
4041
import org.jetbrains.annotations.NotNull;
4142

43+
import java.util.Objects;
44+
4245
import static de.halirutan.mathematica.codeinsight.completion.MathematicaCompletionContributor.IMPORT_VARIABLE_PRIORITY;
4346

4447

@@ -59,18 +62,18 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
5962
final Project project = callingSymbol.getProject();
6063

6164
String prefix = findCurrentText(parameters, parameters.getPosition());
65+
final PsiFile originalFile = parameters.getOriginalFile();
6266
final Module module =
63-
ModuleUtilCore.findModuleForFile(parameters.getOriginalFile().getVirtualFile(), project);
67+
ModuleUtilCore.findModuleForFile(originalFile.getVirtualFile(), project);
6468
if (module != null) {
65-
6669
if (!parameters.isExtendedCompletion() || !(prefix.isEmpty() || Character.isDigit(prefix.charAt(0)))) {
6770
final GlobalSearchScope moduleScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)
6871
.union(ProjectScope.getLibrariesScope(project));
6972
final FileBasedIndex index = FileBasedIndex.getInstance();
7073
index.processAllKeys(
7174
MathematicaPackageExportIndex.INDEX_ID,
7275
key -> {
73-
if (key.isExported()) {
76+
if (key.isExported() && !Objects.equals(key.getFileName(), originalFile.getName())) {
7477
result.addElement(PrioritizedLookupElement.withPriority(
7578
LookupElementBuilder.create(key.getSymbol()).withTypeText("(" + key.getFileName() + ")", true),
7679
IMPORT_VARIABLE_PRIORITY));

src/de/halirutan/mathematica/lang/psi/api/MathematicaPsiFile.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@
2424
package de.halirutan.mathematica.lang.psi.api;
2525

2626
import com.intellij.psi.PsiFile;
27+
import de.halirutan.mathematica.lang.resolve.SymbolResolveResult;
28+
29+
import java.util.HashSet;
2730

2831
/**
2932
* Created with IntelliJ IDEA. User: patrick Date: 1/3/13 Time: 12:09 PM Purpose:
3033
*/
3134
public interface MathematicaPsiFile extends PsiFile, Expression {
3235

36+
void cacheLocalDefinition(SymbolResolveResult result);
37+
38+
HashSet<SymbolResolveResult> getCachedDefinitions();
3339
}

src/de/halirutan/mathematica/lang/psi/impl/MathematicaPsiFileImpl.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,23 @@
2929
import com.intellij.psi.PsiElement;
3030
import com.intellij.psi.ResolveState;
3131
import com.intellij.psi.scope.PsiScopeProcessor;
32+
import com.intellij.util.containers.ContainerUtil;
3233
import de.halirutan.mathematica.file.MathematicaFileType;
3334
import de.halirutan.mathematica.lang.MathematicaLanguage;
3435
import de.halirutan.mathematica.lang.psi.api.MathematicaPsiFile;
36+
import de.halirutan.mathematica.lang.resolve.SymbolResolveResult;
3537
import org.jetbrains.annotations.NotNull;
3638

39+
import java.util.HashSet;
40+
3741
/**
3842
* Created with IntelliJ IDEA. User: patrick Date: 1/3/13 Time: 12:09 PM Purpose:
3943
*/
4044
public class MathematicaPsiFileImpl extends PsiFileBase implements MathematicaPsiFile {
4145

46+
private final HashSet<SymbolResolveResult> cachedDefintions = ContainerUtil.newHashSet();
47+
private boolean isCacheOutdated = true;
48+
4249
public MathematicaPsiFileImpl(@NotNull FileViewProvider viewProvider) {
4350
super(viewProvider, MathematicaLanguage.INSTANCE);
4451
}
@@ -58,4 +65,25 @@ public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNul
5865
public boolean headMatches(final Class clazz) {
5966
return clazz.isInstance(this);
6067
}
68+
69+
@Override
70+
public void cacheLocalDefinition(SymbolResolveResult result) {
71+
if (isCacheOutdated) {
72+
cachedDefintions.clear();
73+
isCacheOutdated = false;
74+
}
75+
if (result != null) {
76+
cachedDefintions.add(result);
77+
}
78+
}
79+
80+
@Override
81+
public HashSet<SymbolResolveResult> getCachedDefinitions() {
82+
return cachedDefintions;
83+
}
84+
85+
@Override
86+
public void subtreeChanged() {
87+
isCacheOutdated = true;
88+
}
6189
}

src/de/halirutan/mathematica/lang/resolve/MathematicaGlobalSymbolResolver.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.intellij.psi.util.PsiTreeUtil;
3636
import com.intellij.util.indexing.FileBasedIndex;
3737
import de.halirutan.mathematica.index.packageexport.MathematicaPackageExportIndex;
38+
import de.halirutan.mathematica.lang.psi.api.MathematicaPsiFile;
3839
import de.halirutan.mathematica.lang.psi.api.Symbol;
3940
import de.halirutan.mathematica.lang.resolve.processors.GlobalDefinitionResolveProcessor;
4041
import org.jetbrains.annotations.NotNull;
@@ -81,6 +82,9 @@ public ResolveResult[] resolve(@NotNull Symbol ref, @NotNull PsiFile containingF
8182
final Symbol resolveResult = globalProcessor.getResolveResult();
8283
if (resolveResult != null) {
8384
final SymbolResolveResult result = symbolCache.cacheFileSymbol(resolveResult, containingFile);
85+
if (containingFile instanceof MathematicaPsiFile) {
86+
((MathematicaPsiFile) containingFile).cacheLocalDefinition(result);
87+
}
8488
return new ResolveResult[]{result};
8589
}
8690

0 commit comments

Comments
 (0)