package krasa.languageSupport; import static krasa.languageSupport.IntegrationTestFileReferenceContributor.resolveFolderNameFromFluentCall; import org.jetbrains.annotations.NotNull; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.icons.AllIcons; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; public class IntegrationTestCompletionContributor extends CompletionContributor { public IntegrationTestCompletionContributor() { extend(CompletionType.BASIC, PlatformPatterns.psiElement(PsiJavaToken.class).withElementType(JavaTokenType.STRING_LITERAL) .inVirtualFile(IntegrationTestFileReferenceContributor.IN_IT) .withLanguage(JavaLanguage.INSTANCE), new CompletionParametersCompletionProvider()); extend(CompletionType.BASIC, PlatformPatterns.psiElement(PsiIdentifier.class).withLanguage(JavaLanguage.INSTANCE), new CompletionParametersCompletionProvider()); } @Override public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) { PlatformPatterns.psiElement(PsiJavaToken.class).withElementType(JavaTokenType.STRING_LITERAL) .withLanguage(JavaLanguage.INSTANCE).accepts(parameters.getPosition(), new ProcessingContext()); PlatformPatterns.psiElement(PsiIdentifier.class).withLanguage(JavaLanguage.INSTANCE) .accepts(parameters.getPosition(), new ProcessingContext()); super.fillCompletionVariants(parameters, result); } private static class CompletionParametersCompletionProvider extends CompletionProvider<CompletionParameters> { public void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet resultSet) { PsiElement position = parameters.getPosition(); boolean addQuote = false; if (position instanceof PsiIdentifier) { addQuote = true; } PsiMethodCallExpressionImpl inMethod = PsiTreeUtil.getParentOfType(position, PsiMethodCallExpressionImpl.class); if (inMethod != null) { String methodName = inMethod.getMethodExpression().getReferenceName(); if ("expectCall".equals(methodName)) { for (PsiDirectory psiDirectory : getSubFolders(position, inMethod, "dummy-responses")) { String name = psiDirectory.getName(); String tailText = " (dummy-responses/" + name + ")"; resultSet.addElement(LookupElementBuilder.create(decorateName(name, addQuote)).bold() .withIcon(AllIcons.Toolwindows.ToolWindowMessages).appendTailText(tailText, true)); } } else if ("response".equals(methodName)) { String folderName = resolveFolderNameFromFluentCall(inMethod); if (folderName != null) { for (PsiDirectory psiDirectory : getSubFolders(position, inMethod, "dummy-responses")) { if (folderName.equals(psiDirectory.getName())) { PsiFile[] files = psiDirectory.getFiles(); for (PsiFile file : files) { String name = file.getName(); String tailText = " (dummy-responses/" + psiDirectory.getName() + "/" + name + ")"; resultSet.addElement(LookupElementBuilder.create(decorateName(name, addQuote)) .bold().withIcon(AllIcons.Toolwindows.ToolWindowMessages) .appendTailText(tailText, true)); } } } } } else if ("request".equals(methodName)) { String folderName = resolveFolderNameFromFluentCall(inMethod); if (folderName != null) { for (PsiDirectory psiDirectory : getSubFolders(position, inMethod, "dummy-requests")) { if (folderName.equals(psiDirectory.getName())) { PsiFile[] files = psiDirectory.getFiles(); for (PsiFile file : files) { String name = file.getName(); String tailText = " (dummy-requests/" + psiDirectory.getName() + "/" + name + ")"; resultSet.addElement(LookupElementBuilder.create(decorateName(name, addQuote)) .bold().withIcon(AllIcons.Toolwindows.ToolWindowMessages) .appendTailText(tailText, true)); } } } } } } } private String decorateName(String name, boolean addQuote) { if (addQuote) { return "\"" + name + "\""; } return name; } @NotNull private PsiDirectory[] getSubFolders(PsiElement position, PsiMethodCallExpressionImpl inMethod, String folderName) { PsiDirectory[] subdirectories = new PsiDirectory[0]; final PsiManager psiManager = PsiManager.getInstance(inMethod.getProject()); Module thisModule = ModuleUtilCore.findModuleForPsiElement(position); if (thisModule != null) { ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(thisModule); VirtualFile[] sourceRoots = moduleRootManager.orderEntries().recursively().withoutSdk() .withoutLibraries().sources().usingCache().getRoots(); for (VirtualFile sourceRoot : sourceRoots) { final PsiDirectory directory = psiManager.findDirectory(sourceRoot); if (directory != null) { PsiDirectory subdirectory = directory.findSubdirectory(folderName); if (subdirectory != null) { subdirectories = subdirectory.getSubdirectories(); } } } } return subdirectories; } } }