package pers.fw.tplugin.view; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; import com.jetbrains.php.lang.PhpLanguage; import com.jetbrains.php.lang.psi.elements.StringLiteralExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import pers.fw.tplugin.inter.GotoCompletionContributor; import pers.fw.tplugin.inter.GotoCompletionLanguageRegistrar; import pers.fw.tplugin.inter.GotoCompletionProvider; import pers.fw.tplugin.inter.GotoCompletionRegistrarParameter; import pers.fw.tplugin.util.MethodMatcher; import pers.fw.tplugin.util.PsiElementUtil; import pers.fw.tplugin.util.PsiElementUtils; import pers.fw.tplugin.util.Util; import pers.fw.tplugin.view.dict.TemplatePath; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; // view 处理类 public class ViewReferences2 implements GotoCompletionLanguageRegistrar { private static MethodMatcher.CallToSignature[] VIEWS = new MethodMatcher.CallToSignature[]{ new MethodMatcher.CallToSignature("\\think\\View", "fetch"), new MethodMatcher.CallToSignature("\\think\\Controller", "fetch"), new MethodMatcher.CallToSignature("\\think\\Controller", "display"), }; @Override public void register(GotoCompletionRegistrarParameter registrar) { registrar.register(PlatformPatterns.psiElement(), new GotoCompletionContributor() { @Nullable @Override public GotoCompletionProvider getProvider(@Nullable PsiElement psiElement) { if (psiElement == null) {// || !LaravelProjectComponent.isEnabled(psiElement)) { return null; } PsiElement parent = psiElement.getParent(); if (parent != null && (PsiElementUtil.isFunctionReference(parent, "view", 0) || MethodMatcher.getMatchedSignatureWithDepth(parent, VIEWS) != null) && handlePath(psiElement)) { return new ViewDirectiveCompletionProvider(parent); } return null; } }); } @Override public boolean support(@NotNull Language language) { return PhpLanguage.INSTANCE == language; } public boolean handlePath(PsiElement psiElement) { // todo ensure base dir // String application = "application"; // String projectPath = psiElement.getProject().getBasePath();//"D:\\project2\\test"; // String currentFilePath = psiElement.getContainingFile().getVirtualFile().getPath(); //"D:\\project2\\test\\application\\index\\controller\\Index.php"; // String[] arr = currentFilePath.replace(projectPath, "").split("/"); // if (arr.length < 4 || !arr[1].equals(application)) { // return false; // } String application = Util.getApplicationDir(psiElement); // String moduleName = arr[2]; String moduleName = Util.getCurTpModuleName(psiElement); ViewCollector.DEFAULT_TEMPLATE_PATH = new TemplatePath[]{new TemplatePath(application + "/" + moduleName + "/view", false)}; ViewCollector.curModule = moduleName; return true; } private static class ViewDirectiveCompletionProvider extends GotoCompletionProvider { private ViewDirectiveCompletionProvider(PsiElement element) { super(element); } @NotNull @Override public Collection<LookupElement> getLookupElements() { final Collection<LookupElement> lookupElements = new ArrayList<>(); ViewCollector.visitFile(getProject(), new ViewCollector.ViewVisitor() { @Override public void visit(@NotNull VirtualFile virtualFile, @NotNull String name) { lookupElements.add(LookupElementBuilder.create(name).withIcon(virtualFile.getFileType().getIcon())); } } ); // @TODO: no filesystem access in test; fake item if (ApplicationManager.getApplication().isUnitTestMode()) { lookupElements.add(LookupElementBuilder.create("test_view")); } return lookupElements; } @NotNull @Override public Collection<? extends PsiElement> getPsiTargets(@NotNull PsiElement psiElement, int offset, @NotNull Editor editor) { PsiElement stringLiteral = psiElement.getParent(); if (!(stringLiteral instanceof StringLiteralExpression)) { return Collections.emptyList(); } String contents = ((StringLiteralExpression) stringLiteral).getContents(); String viewDir = getProject().getBaseDir() + Util.getApplicationDir(psiElement) + "/" + Util.getCurTpModuleName(psiElement) + "/" + "view" + "/"; String className = ""; String methodName = ""; if (contents.contains("/")) { // index/test String[] split = contents.split("/"); className = split[0]; methodName = contents.substring(className.length() + 1); } else if ("".equals(contents)) { // className = Util.getPhpClass(psiElement).getName().toLowerCase(); methodName = Util.getMethod(psiElement).getName(); } else { // test className = Util.getPhpClass(psiElement).getName().toLowerCase(); methodName = contents; } String dir = viewDir + className;//+ "/" + methodName; String filePath = viewDir + className + "/" + methodName; dir = dir.replace("file://", ""); filePath = filePath.replace("file://", ""); File file = new File(dir); File targetFile = TemplateUtil.recursionMatch(file, filePath); Collection<VirtualFile> virFiles = new ArrayList<>(); if (targetFile != null) { VirtualFile fileByIoFile = VfsUtil.findFileByIoFile(targetFile, false); virFiles.add(fileByIoFile); } Collection<PsiElement> targets = new ArrayList<>(PsiElementUtils.convertVirtualFilesToPsiFiles(getProject(), virFiles)); return targets; } } }