Skip to content

Commit a69dc50

Browse files
committed
add controller resolve for indexed twig render calls
1 parent 60ed3f6 commit a69dc50

File tree

4 files changed

+94
-11
lines changed

4 files changed

+94
-11
lines changed

src/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/PhpTwigTemplateUsageStubIndex.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,21 @@
1717
import org.apache.commons.lang.StringUtils;
1818
import org.jetbrains.annotations.NotNull;
1919

20+
import java.util.HashSet;
2021
import java.util.Map;
22+
import java.util.Set;
2123

2224
public class PhpTwigTemplateUsageStubIndex extends FileBasedIndexExtension<String, Void> {
2325

2426
public static final ID<String, Void> KEY = ID.create("fr.adrienbrault.idea.symfony2plugin.twig_php_usage");
2527
private final KeyDescriptor<String> myKeyDescriptor = new EnumeratorStringDescriptor();
28+
private static int MAX_FILE_BYTE_SIZE = 2097152;
29+
30+
public static Set<String> RENDER_METHODS = new HashSet<String>() {{
31+
add("render");
32+
add("renderView");
33+
add("renderResponse");
34+
}};
2635

2736
@NotNull
2837
@Override
@@ -44,7 +53,7 @@ public Map<String, Void> map(FileContent inputData) {
4453
return map;
4554
}
4655

47-
if(!(inputData.getPsiFile() instanceof PhpFile)) {
56+
if(!(inputData.getPsiFile() instanceof PhpFile) && isValidForIndex(inputData)) {
4857
return map;
4958
}
5059

@@ -59,7 +68,7 @@ public void visitElement(PsiElement element) {
5968

6069
public void visitMethodReference(MethodReference methodReference) {
6170
String methodName = methodReference.getName();
62-
if(!"render".equals(methodName) && !"renderView".equals(methodName) && !"renderResponse".equals(methodName)) {
71+
if(!RENDER_METHODS.contains(methodName)) {
6372
return;
6473
}
6574

@@ -110,6 +119,10 @@ public int getVersion() {
110119
return 1;
111120
}
112121

122+
public static boolean isValidForIndex(FileContent inputData) {
123+
return inputData.getFile().getLength() < MAX_FILE_BYTE_SIZE;
124+
}
125+
113126
}
114127

115128

src/fr/adrienbrault/idea/symfony2plugin/templating/TwigControllerLineMarkerProvider.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,20 @@ public void collectSlowLineMarkers(@NotNull List<PsiElement> psiElements, @NotNu
8484

8585
private void attachController(TwigFile psiElement, Collection<? super RelatedItemLineMarkerInfo> result) {
8686

87+
Set<Method> methods = new HashSet<Method>();
8788
Method method = TwigUtil.findTwigFileController(psiElement);
88-
if(method == null) {
89+
if(method != null) {
90+
methods.add(method);
91+
}
92+
93+
methods.addAll(TwigUtil.getTwigFileMethodUsageOnIndex(psiElement));
94+
95+
if(methods.size() == 0) {
8996
return;
9097
}
9198

9299
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.TWIG_CONTROLLER_LINE_MARKER).
93-
setTargets(method).
100+
setTargets(methods).
94101
setTooltipText("Navigate to controller");
95102

96103
result.add(builder.createLineMarkerInfo(psiElement));

src/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigTypeResolveUtil.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ public static HashMap<String, PsiVariable> collectScopeVariables(@NotNull PsiEle
215215
HashMap<String, PsiVariable> controllerVars = new HashMap<String, PsiVariable>();
216216

217217
VirtualFile virtualFile = psiElement.getContainingFile().getVirtualFile();
218-
System.out.println(virtualFile.toString());
219218
if(visitedFiles.contains(virtualFile)) {
220219
return controllerVars;
221220
}

src/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigUtil.java

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,24 @@
77
import com.intellij.psi.PsiElement;
88
import com.intellij.psi.PsiFile;
99
import com.intellij.psi.PsiManager;
10+
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
11+
import com.intellij.psi.search.GlobalSearchScope;
1012
import com.intellij.psi.util.PsiElementFilter;
1113
import com.intellij.psi.util.PsiTreeUtil;
1214
import com.intellij.util.Processor;
15+
import com.intellij.util.indexing.FileBasedIndexImpl;
1316
import com.jetbrains.php.PhpIndex;
17+
import com.jetbrains.php.lang.PhpFileType;
1418
import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment;
1519
import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag;
16-
import com.jetbrains.php.lang.psi.elements.Method;
17-
import com.jetbrains.php.lang.psi.elements.PhpClass;
18-
import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
20+
import com.jetbrains.php.lang.psi.elements.*;
1921
import com.jetbrains.twig.TwigFile;
2022
import com.jetbrains.twig.TwigFileType;
2123
import com.jetbrains.twig.elements.TwigBlockTag;
2224
import com.jetbrains.twig.elements.TwigElementTypes;
2325
import com.jetbrains.twig.elements.TwigExtendsTag;
2426
import fr.adrienbrault.idea.symfony2plugin.TwigHelper;
27+
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.PhpTwigTemplateUsageStubIndex;
2528
import fr.adrienbrault.idea.symfony2plugin.templating.dict.*;
2629
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
2730
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
@@ -347,12 +350,73 @@ public static HashMap<String, PsiVariable> collectControllerTemplateVariables(Ps
347350
}
348351

349352
Method method = findTwigFileController((TwigFile) psiFile);
350-
if(method == null) {
351-
return vars;
353+
if(method != null) {
354+
return PhpMethodVariableResolveUtil.collectMethodVariables(method);
355+
}
356+
357+
final Set<Method> methods = getTwigFileMethodUsageOnIndex((TwigFile) psiFile);
358+
359+
HashMap<String, PsiVariable> stringPsiVariableHashMap = new HashMap<String, PsiVariable>();
360+
for(Method methodIndex : methods) {
361+
stringPsiVariableHashMap.putAll(PhpMethodVariableResolveUtil.collectMethodVariables(methodIndex));
362+
}
363+
364+
return stringPsiVariableHashMap;
365+
366+
}
367+
368+
@NotNull
369+
public static Set<Method> getTwigFileMethodUsageOnIndex(@NotNull TwigFile psiFile) {
370+
371+
Map<String, VirtualFile> templateName = TwigUtil.getTemplateName(psiFile);
372+
if(templateName.size() == 0) {
373+
return Collections.emptySet();
374+
}
375+
376+
final Set<String> keys = templateName.keySet();
377+
final Set<VirtualFile> virtualFiles = new HashSet<VirtualFile>();
378+
379+
// find virtual files
380+
for(String key: keys) {
381+
FileBasedIndexImpl.getInstance().getFilesWithKey(PhpTwigTemplateUsageStubIndex.KEY, new HashSet<String>(Arrays.asList(key)), new Processor<VirtualFile>() {
382+
@Override
383+
public boolean process(VirtualFile virtualFile) {
384+
virtualFiles.add(virtualFile);
385+
return true;
386+
}
387+
}, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(psiFile.getProject()), PhpFileType.INSTANCE));
352388
}
353389

354-
return PhpMethodVariableResolveUtil.collectMethodVariables(method);
390+
final Set<Method> methods = new HashSet<Method>();
391+
392+
for(VirtualFile virtualFile : virtualFiles) {
393+
394+
PsiFile psiTemplate = PsiManager.getInstance(psiFile.getProject()).findFile(virtualFile);
395+
if(psiTemplate == null) {
396+
continue;
397+
}
398+
399+
psiTemplate.accept(new PsiRecursiveElementWalkingVisitor() {
400+
@Override
401+
public void visitElement(PsiElement element) {
402+
if(element instanceof StringLiteralExpression && element.getParent() instanceof ParameterList && element.getParent().getParent() instanceof MethodReference && keys.contains(((StringLiteralExpression) element).getContents())) {
403+
404+
PsiElement methodReference = element.getParent().getParent();
405+
if(methodReference instanceof MethodReference && PhpTwigTemplateUsageStubIndex.RENDER_METHODS.contains(((MethodReference) methodReference).getName())) {
406+
Method method = PsiTreeUtil.getParentOfType(element, Method.class);
407+
if(method != null) {
408+
methods.add(method);
409+
}
410+
}
411+
}
412+
413+
super.visitElement(element);
414+
}
415+
});
416+
417+
}
355418

419+
return methods;
356420
}
357421

358422
@Nullable

0 commit comments

Comments
 (0)