Skip to content

Commit 1747605

Browse files
committed
visit parent blocks for Twig variables #1035
1 parent d4b9769 commit 1747605

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

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

+18-14
Original file line numberDiff line numberDiff line change
@@ -169,22 +169,27 @@ public static Collection<TwigTypeContainer> resolveTwigMethodName(@NotNull PsiEl
169169
*
170170
* "@var foo \Foo"
171171
*/
172-
private static Map<String, String> findInlineStatementVariableDocBlock(PsiElement psiInsideBlock, final IElementType parentStatement) {
173-
PsiElement twigCompositeElement = PsiTreeUtil.findFirstParent(psiInsideBlock, psiElement -> {
174-
if (psiElement instanceof TwigCompositeElement) {
175-
if (PlatformPatterns.psiElement(parentStatement).accepts(psiElement)) {
176-
return true;
177-
}
178-
}
179-
return false;
180-
});
172+
private static Map<String, String> findInlineStatementVariableDocBlock(@NotNull PsiElement psiInsideBlock, @NotNull IElementType parentStatement, boolean nextParent) {
173+
PsiElement twigCompositeElement = PsiTreeUtil.findFirstParent(psiInsideBlock, psiElement ->
174+
PlatformPatterns.psiElement(parentStatement).accepts(psiElement)
175+
);
181176

182177
Map<String, String> variables = new HashMap<>();
183178
if(twigCompositeElement == null) {
184179
return variables;
185180
}
186181

187-
return getInlineCommentDocsVars(twigCompositeElement);
182+
Map<String, String> inlineCommentDocsVars = getInlineCommentDocsVars(twigCompositeElement);
183+
184+
// visit parent elements for extending scope
185+
if(nextParent) {
186+
PsiElement parent = twigCompositeElement.getParent();
187+
if(parent != null) {
188+
inlineCommentDocsVars.putAll(findInlineStatementVariableDocBlock(twigCompositeElement.getParent(), parentStatement, true));
189+
}
190+
}
191+
192+
return inlineCommentDocsVars;
188193
}
189194

190195
/**
@@ -237,7 +242,6 @@ public static Map<String, PsiVariable> collectScopeVariables(@NotNull PsiElement
237242

238243
@NotNull
239244
public static Map<String, PsiVariable> collectScopeVariables(@NotNull PsiElement psiElement, @NotNull Set<VirtualFile> visitedFiles) {
240-
241245
Map<String, Set<String>> globalVars = new HashMap<>();
242246
Map<String, PsiVariable> controllerVars = new HashMap<>();
243247

@@ -255,9 +259,9 @@ public static Map<String, PsiVariable> collectScopeVariables(@NotNull PsiElement
255259
}
256260

257261
// globals first
258-
globalVars.putAll(convertHashMapToTypeSet(findInlineStatementVariableDocBlock(psiElement, TwigElementTypes.BLOCK_STATEMENT)));
259-
globalVars.putAll(convertHashMapToTypeSet(findInlineStatementVariableDocBlock(psiElement, TwigElementTypes.MACRO_STATEMENT)));
260-
globalVars.putAll(convertHashMapToTypeSet(findInlineStatementVariableDocBlock(psiElement, TwigElementTypes.FOR_STATEMENT)));
262+
globalVars.putAll(convertHashMapToTypeSet(findInlineStatementVariableDocBlock(psiElement, TwigElementTypes.BLOCK_STATEMENT, true)));
263+
globalVars.putAll(convertHashMapToTypeSet(findInlineStatementVariableDocBlock(psiElement, TwigElementTypes.MACRO_STATEMENT, false)));
264+
globalVars.putAll(convertHashMapToTypeSet(findInlineStatementVariableDocBlock(psiElement, TwigElementTypes.FOR_STATEMENT, false)));
261265

262266
for(Map.Entry<String, Set<String>> entry: globalVars.entrySet()) {
263267
Set<String> types = entry.getValue();

tests/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigTypeResolveUtilTest.java

+28
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package fr.adrienbrault.idea.symfony2plugin.tests.templating.util;
22

3+
import com.intellij.psi.PsiElement;
34
import com.intellij.psi.PsiFile;
45
import com.intellij.psi.PsiFileFactory;
56
import com.jetbrains.php.lang.psi.PhpPsiElementFactory;
67
import com.jetbrains.php.lang.psi.elements.Method;
78
import com.jetbrains.twig.TwigFile;
9+
import com.jetbrains.twig.TwigFileType;
810
import com.jetbrains.twig.TwigLanguage;
911
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigTypeResolveUtil;
12+
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
1013
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
1114
import org.jetbrains.annotations.NotNull;
1215

@@ -56,6 +59,31 @@ public void testReqExForInlineDocVariables() {
5659
assertMatches("{# foo_1 \\AppBundle\\Entity\\MeterValueDTO #}", TwigTypeResolveUtil.DOC_TYPE_PATTERN_SINGLE);
5760
}
5861

62+
/**
63+
* @see TwigTypeResolveUtil#collectScopeVariables
64+
*/
65+
public void testCollectScopeVariables() {
66+
myFixture.configureByText(TwigFileType.INSTANCE,
67+
"{# @var b \\Foo\\Bar #}" +
68+
"{% block one %}\n" +
69+
" {# @var a \\Foo\\Bar #}\n" +
70+
"\n" +
71+
" {% block two %}\n" +
72+
" {% block two %}\n" +
73+
" {{ <caret> }}\n" +
74+
" {% endblock %}\n" +
75+
" {% endblock %}\n" +
76+
"{% endblock %}"
77+
);
78+
79+
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
80+
81+
Map<String, PsiVariable> stringPsiVariableMap = TwigTypeResolveUtil.collectScopeVariables(psiElement);
82+
83+
assertContainsElements(stringPsiVariableMap.get("a").getTypes(), "\\Foo\\Bar");
84+
assertContainsElements(stringPsiVariableMap.get("b").getTypes(), "\\Foo\\Bar");
85+
}
86+
5987
private void assertMatches(@NotNull String content, @NotNull String... regularExpressions) {
6088
for (String regularExpression : regularExpressions) {
6189
if(content.matches(regularExpression)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Foo
4+
{
5+
interface Bar
6+
{
7+
public function getFoobar();
8+
}
9+
}

0 commit comments

Comments
 (0)