Autocompletion Stops Working When Adding psi.referenceContributor

Answered

I’m currently developing a Laravel IntelliJ plugin, and I’ve implemented both autocompletion and "Go to Declaration" functionality. Everything was working fine until I added the psi.referenceContributor to handle "Go to Declaration" for Laravel config files. Now, the autocompletion in the config context (via completion.contributor) no longer triggers any suggestions but when I remove the psi.referenceContributor everything works again.


Does anyone know why ?

<extensions defaultExtensionNs="com.intellij"> 

	<completion.contributor language="PHP" implementationClass="at.test.project.config.ConfigCompletionContributor"/>
	
	 <psi.referenceContributor language="PHP" implementation="at.test.project.config.ConfigG                  oToDeclarationHandler"/>
	 
</extensions>
0
3 comments

Your PSI Reference can provide completion items via com.intellij.psi.PsiReference#getVariants instead of separate CompletionContributor.

0

Yann Cebron  I implemented the getVariants() method as suggested

public class ConfigReference extends PsiReferenceBase<PsiElement> {
    private static final Map<String, Object[]> cachedSuggestions = new HashMap<>();

    public ConfigReference(@NotNull PsiElement element, TextRange rangeInElement) {
        super(element, rangeInElement);
    }

    @Override
    public @Nullable PsiElement resolve() {
       PsiDirectory configDir = Helper.getDirectory(myElement.getProject(), ProjectDefaultPaths.CONFIG_PATH);

        String[] parts = myElement.getText().split("\\.");
        String configFile = parts[0].replace("\"", "");

        if (parts.length < 2) {
            return null;
        }

        for (PsiFile file : configDir.getFiles()) {
            if (file instanceof PhpFile phpFile && getFilename(phpFile).equals(configFile)) {
                PsiElement target = resolveConfigKeyInFile(phpFile, parts);
                if (target != null) {
                    return target;
                }
            }
        }

        return null;
    }

    @Override
    public Object @NotNull [] getVariants() {
        PsiDirectory configDir = Helper.getDirectory(myElement.getProject(), ProjectDefaultPaths.CONFIG_PATH);

        String configDirPath = configDir.getVirtualFile().getPath();

        if (cachedSuggestions.containsKey(configDirPath)) {
            System.out.println("from cache");
            return cachedSuggestions.get(configDirPath);
        }

        List<LookupElementBuilder> suggestions = new ArrayList<>();
        for (PsiFile file : configDir.getFiles()) {
            if (file instanceof PhpFile) {
                suggestions.addAll(ConfigFileFileProcessor.iterateOverFileChildren(file, ""));
            }
        }

        Object[] suggestionsArray = suggestions.toArray();
        cachedSuggestions.put(configDirPath, suggestionsArray);

        return suggestionsArray;
    }

    private PsiElement resolveConfigKeyInFile(PhpFile configFile, String[] parts) {
        //my code
    }

    private PsiElement resolveNestedArray(ArrayCreationExpressionImpl array, String[] parts, int index){
         //my code
    }

    private String getFilename(PhpFile phpFile) {
        VirtualFile virtualFile = phpFile.getVirtualFile();
        return virtualFile.getNameWithoutExtension();
    }
}

Despite triggering the getVariants method and confirming that it generates suggestions, the completion list is not appearing in PhpStorm.

Am I missing something?

0

Please verify passed rangeInElement is valid, it must contain the range _within_ the element where reference/completion should occur. Otherwise, try debugging your getVariants() method or try first returning simple String[] with dummy completion strings.

0

Please sign in to leave a comment.