package sk.sorien.pimpleplugin.pimple; import com.intellij.codeInsight.completion.*; import com.intellij.openapi.project.Project; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; import com.jetbrains.php.lang.PhpLanguage; import com.jetbrains.php.lang.psi.elements.*; import org.jetbrains.annotations.NotNull; import sk.sorien.pimpleplugin.ProjectComponent; /** * @author Stanislav Turza */ public class PimpleCompletionContributor extends CompletionContributor { public PimpleCompletionContributor() { // $app['<caret>'] extend(CompletionType.BASIC, PlatformPatterns.psiElement().withLanguage(PhpLanguage.INSTANCE), new ArrayAccessCompletionProvider()); // $app[''] = $app->extend('<caret>', ... extend(CompletionType.BASIC, PlatformPatterns.psiElement().withLanguage(PhpLanguage.INSTANCE), new ExtendsMethodParameterListCompletionProvider()); // $app->register(, ['<caret>' =>]) extend(CompletionType.BASIC, PlatformPatterns.psiElement().withLanguage(PhpLanguage.INSTANCE), new RegisterFunctionValuesCompletionProvider()); } private static class ArrayAccessCompletionProvider extends CompletionProvider<CompletionParameters> { public void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet resultSet) { PsiElement element = parameters.getPosition().getParent(); Project project = element.getProject(); if(!ProjectComponent.isEnabled(project)) { return; } if (!(element instanceof StringLiteralExpression)) { return; } Container container = Utils.findContainerForPimpleArrayAccessLiteral((StringLiteralExpression) element); if (container == null) { return; } for (Service service : container.getServices().values()) { resultSet.addElement(new ServiceLookupElement(service, project)); } for (Parameter parameter : container.getParameters().values()) { resultSet.addElement(new ParameterLookupElement(parameter)); } for (String key : container.getContainers().keySet()) { resultSet.addElement(new ContainerLookupElement(key)); } resultSet.stopHere(); } } private static class ExtendsMethodParameterListCompletionProvider extends CompletionProvider<CompletionParameters> { public void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet resultSet) { PsiElement element = parameters.getPosition().getParent(); Project project = element.getProject(); if(!ProjectComponent.isEnabled(project)) { return; } if (!(element instanceof StringLiteralExpression)) { return; } Container container = Utils.findContainerForFirstParameterOfPimpleMethod((StringLiteralExpression) element); if (container == null){ return; } for (Service service : container.getServices().values()) { resultSet.addElement(new ServiceLookupElement(service, project)); } for (Parameter parameter : container.getParameters().values()) { resultSet.addElement(new ParameterLookupElement(parameter)); } resultSet.stopHere(); } } private static class RegisterFunctionValuesCompletionProvider extends CompletionProvider<CompletionParameters> { public void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet resultSet) { PsiElement stringLiteralExpression = parameters.getPosition().getParent(); Project project = stringLiteralExpression.getProject(); if(!ProjectComponent.isEnabled(project)) { return; } if (!(stringLiteralExpression instanceof StringLiteralExpression)) { return; } PsiElement arrayKeyElement = stringLiteralExpression.getParent(); PsiElement element = arrayKeyElement.getParent(); if (element instanceof ArrayHashElement) { if (!arrayKeyElement.isEquivalentTo(element.getFirstChild())) { return; } element = element.getParent(); } if (!(element instanceof ArrayCreationExpression)) { return; } PsiElement parameterList = element.getParent(); if (!(parameterList instanceof ParameterList)) { return; } PsiElement[] params = ((ParameterList) parameterList).getParameters(); if (!(params.length > 1 && params[1].isEquivalentTo(element))) { return; } PsiElement methodReference = parameterList.getParent(); if (!(methodReference instanceof MethodReference)) { return; } String methodReferenceName = ((MethodReference) methodReference).getName(); if ((methodReferenceName == null) || !(methodReferenceName.equals("register"))) { return; } Container container = Utils.findContainerForMethodReference((MethodReference) methodReference); if (container == null) { return; } for (Parameter parameter : container.getParameters().values()) { resultSet.addElement(new ParameterLookupElement(parameter)); } resultSet.stopHere(); } } }