package fr.adrienbrault.idea.symfony2plugin.util.completion; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; import com.jetbrains.php.PhpIndex; import com.jetbrains.php.completion.PhpLookupElement; import com.jetbrains.php.completion.insert.PhpReferenceInsertHandler; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.jetbrains.php.lang.psi.elements.PhpNamedElement; import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil; import org.jetbrains.annotations.NotNull; /** * @author Daniel Espendiller <daniel@espendiller.net> */ public class PhpClassCompletionProvider extends CompletionProvider<CompletionParameters> { private final boolean withInterface; private boolean withLeadingBackslash = false; public PhpClassCompletionProvider() { this(false); } public PhpClassCompletionProvider(boolean withInterface) { this.withInterface = withInterface; } public PhpClassCompletionProvider withTrimLeadBackslash(boolean withLeadingBackslash) { this.withLeadingBackslash = withLeadingBackslash; return this; } public void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, final @NotNull CompletionResultSet resultSet) { PsiElement psiElement = parameters.getOriginalPosition(); if(!Symfony2ProjectComponent.isEnabled(psiElement)) { return; } addClassCompletion(parameters, resultSet, psiElement, withInterface, withLeadingBackslash); } public static void addClassCompletion(CompletionParameters parameters, final CompletionResultSet resultSet, PsiElement psiElement, boolean withInterface) { addClassCompletion(parameters, resultSet, psiElement, withInterface, false); } public static void addClassCompletion(CompletionParameters parameters, final CompletionResultSet resultSet, PsiElement psiElement, boolean withInterface, boolean withLeadBackslash) { // Foo\|Bar // Foo|\Bar PhpElementsUtil.visitNamespaceClassForCompletion(psiElement, parameters.getOffset(), (phpClass, presentableFQN, prefix) -> resultSet.addElement(LookupElementBuilder.create(prefix + presentableFQN).withIcon(phpClass.getIcon())) ); PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); for (String className : phpIndex.getAllClassNames(resultSet.getPrefixMatcher())) { for(PhpClass phpClass: phpIndex.getClassesByName(className)) { resultSet.addElement( wrapInsertHandler(new MyPhpLookupElement(phpClass), withLeadBackslash) ); } if(withInterface) { for(PhpClass phpClass: phpIndex.getInterfacesByName(className)) { resultSet.addElement( wrapInsertHandler(new MyPhpLookupElement(phpClass), withLeadBackslash) ); } } } } private static MyPhpLookupElement wrapInsertHandler(MyPhpLookupElement lookupElement, boolean withLeadBackslash) { if(withLeadBackslash) { return lookupElement.withInsertHandler(PhpReferenceInsertHandler.getInstance()); } return lookupElement.withInsertHandler(PhpReferenceTrimBackslashInsertHandler.getInstance()); } private static class MyPhpLookupElement extends PhpLookupElement { public MyPhpLookupElement(@NotNull PhpNamedElement namedElement) { super(namedElement); } public MyPhpLookupElement withInsertHandler(InsertHandler insertHandler) { this.handler = insertHandler; return this; } } }