Skip to content

Commit 74ad80f

Browse files
committed
fix roles completing/goto not working with array call #886
1 parent 76b5dcf commit 74ad80f

File tree

4 files changed

+189
-1
lines changed

4 files changed

+189
-1
lines changed

src/fr/adrienbrault/idea/symfony2plugin/TwigHelper.java

+95
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ public static ElementPattern<PsiElement> getTagTernaryPattern(@NotNull IElementT
549549
.withLanguage(TwigLanguage.INSTANCE)
550550
);
551551
}
552+
552553
/**
553554
* Check for {{ include('|') }}, {% include('|') %}
554555
*
@@ -581,6 +582,100 @@ public static ElementPattern<PsiElement> getPrintBlockOrTagFunctionPattern(Strin
581582
.withLanguage(TwigLanguage.INSTANCE);
582583
}
583584

585+
/**
586+
* Literal are fine in lexer so just extract the parameter
587+
*
588+
* {{ foo({'foobar', 'foo<caret>bar'}) }}
589+
* {{ foo({'fo<caret>obar'}) }}
590+
*/
591+
public static ElementPattern<PsiElement> getFunctionWithFirstParameterAsLiteralPattern(@NotNull String... functionName) {
592+
//noinspection unchecked
593+
return PlatformPatterns
594+
.psiElement(TwigTokenTypes.STRING_TEXT).afterLeafSkipping(
595+
PlatformPatterns.or(
596+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
597+
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE),
598+
PlatformPatterns.psiElement(TwigTokenTypes.SINGLE_QUOTE),
599+
PlatformPatterns.psiElement(TwigTokenTypes.DOUBLE_QUOTE)
600+
),
601+
PlatformPatterns.or(
602+
PlatformPatterns.psiElement(TwigTokenTypes.LBRACE_CURL),
603+
PlatformPatterns.psiElement(TwigTokenTypes.COMMA)
604+
)
605+
)
606+
.withParent(
607+
PlatformPatterns.psiElement(TwigElementTypes.LITERAL).afterLeafSkipping(
608+
PlatformPatterns.or(
609+
PlatformPatterns.psiElement(TwigTokenTypes.LBRACE),
610+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
611+
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE)
612+
),
613+
PlatformPatterns.psiElement(TwigTokenTypes.IDENTIFIER).withText(PlatformPatterns.string().oneOf(functionName))
614+
)
615+
)
616+
.withLanguage(TwigLanguage.INSTANCE);
617+
}
618+
619+
/**
620+
* Array values are not detected by lexer, lets do the magic on our own
621+
*
622+
* {{ foo(['foobar', 'foo<caret>bar']) }}
623+
* {{ foo(['fo<caret>obar']) }}
624+
*/
625+
public static ElementPattern<PsiElement> getFunctionWithFirstParameterAsArrayPattern(@NotNull String... functionName) {
626+
//noinspection unchecked
627+
628+
// "foo(<caret>"
629+
PsiElementPattern.Capture<PsiElement> functionPattern = PlatformPatterns
630+
.psiElement(TwigTokenTypes.LBRACE_SQ)
631+
.afterLeafSkipping(
632+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
633+
PlatformPatterns.psiElement(TwigTokenTypes.LBRACE).afterLeafSkipping(
634+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
635+
PlatformPatterns.psiElement(TwigTokenTypes.IDENTIFIER).withText(PlatformPatterns.string().oneOf(functionName))
636+
)
637+
);
638+
639+
return
640+
PlatformPatterns.or(
641+
// {{ foo(['fo<caret>obar']) }}
642+
PlatformPatterns
643+
.psiElement(TwigTokenTypes.STRING_TEXT).afterLeafSkipping(
644+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
645+
PlatformPatterns.psiElement().withElementType(PlatformPatterns.elementType().or(
646+
TwigTokenTypes.SINGLE_QUOTE,
647+
TwigTokenTypes.DOUBLE_QUOTE
648+
)).afterLeafSkipping(
649+
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE),
650+
functionPattern
651+
)
652+
).withLanguage(TwigLanguage.INSTANCE),
653+
654+
// {{ foo(['foobar', 'foo<caret>bar']) }}
655+
PlatformPatterns
656+
.psiElement(TwigTokenTypes.STRING_TEXT).afterLeafSkipping(
657+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
658+
PlatformPatterns.psiElement().withElementType(PlatformPatterns.elementType().or(
659+
TwigTokenTypes.SINGLE_QUOTE,
660+
TwigTokenTypes.DOUBLE_QUOTE
661+
)).afterLeafSkipping(
662+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
663+
PlatformPatterns.psiElement(TwigTokenTypes.COMMA).afterLeafSkipping(
664+
PlatformPatterns.or(
665+
PlatformPatterns.psiElement(TwigTokenTypes.WHITE_SPACE),
666+
PlatformPatterns.psiElement(PsiWhiteSpace.class),
667+
PlatformPatterns.psiElement(TwigTokenTypes.STRING_TEXT),
668+
PlatformPatterns.psiElement(TwigTokenTypes.SINGLE_QUOTE),
669+
PlatformPatterns.psiElement(TwigTokenTypes.DOUBLE_QUOTE),
670+
PlatformPatterns.psiElement(TwigTokenTypes.COMMA)
671+
),
672+
functionPattern
673+
)
674+
)
675+
).withLanguage(TwigLanguage.INSTANCE)
676+
);
677+
}
678+
584679
/**
585680
* {% render "foo"
586681
*

src/fr/adrienbrault/idea/symfony2plugin/security/VoterGotoCompletionRegistrar.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,15 @@ public class VoterGotoCompletionRegistrar implements GotoCompletionRegistrar {
2828
@Override
2929
public void register(GotoCompletionRegistrarParameter registrar) {
3030
// {% is_granted('foobar') %}
31+
// {% is_granted({'foobar'}) %}
32+
// {% is_granted(['foobar']) %}
3133
registrar.register(
32-
TwigHelper.getPrintBlockOrTagFunctionPattern("is_granted"), MyVisitorGotoCompletionProvider::new
34+
PlatformPatterns.or(
35+
TwigHelper.getPrintBlockOrTagFunctionPattern("is_granted"),
36+
TwigHelper.getFunctionWithFirstParameterAsArrayPattern("is_granted"),
37+
TwigHelper.getFunctionWithFirstParameterAsLiteralPattern("is_granted")
38+
),
39+
MyVisitorGotoCompletionProvider::new
3340
);
3441

3542
// Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface::isGranted %}

tests/fr/adrienbrault/idea/symfony2plugin/tests/TwigHelperLightTest.java

+46
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,52 @@ public void testGetPrintBlockOrTagFunctionPattern() {
263263
));
264264
}
265265

266+
/**
267+
* @see TwigHelper#getFunctionWithFirstParameterAsArrayPattern
268+
*/
269+
public void testGetFunctionWithFirstParameterAsArrayPattern() {
270+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsArrayPattern("foobar").accepts(
271+
findElementAt(TwigFileType.INSTANCE, "{{ foobar(['fo<caret>o']) }}")
272+
));
273+
274+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsArrayPattern("foobar").accepts(
275+
findElementAt(TwigFileType.INSTANCE, "{{ foobar(['foo', 'fo<caret>o']) }}")
276+
));
277+
278+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsArrayPattern("foobar").accepts(
279+
findElementAt(TwigFileType.INSTANCE, "{{ foobar([\"foo\", \"fo<caret>o\"]) }}")
280+
));
281+
282+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsArrayPattern("foobar").accepts(
283+
findElementAt(TwigFileType.INSTANCE, "{{ foobar ( [ 'foo' , 'fo<caret>o']) }}")
284+
));
285+
}
286+
287+
/**
288+
* @see TwigHelper#getFunctionWithFirstParameterAsLiteralPattern
289+
*/
290+
public void testFunctionWithFirstParameterAsLiteralPattern() {
291+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsLiteralPattern("foobar").accepts(
292+
findElementAt(TwigFileType.INSTANCE, "{{ foobar({'f<caret>o'}) }}")
293+
));
294+
295+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsLiteralPattern("foobar").accepts(
296+
findElementAt(TwigFileType.INSTANCE, "{{ foobar ( { 'f<caret>o'}) }}")
297+
));
298+
299+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsLiteralPattern("foobar").accepts(
300+
findElementAt(TwigFileType.INSTANCE, "{{ foobar({'foo', 'f<caret>o'}) }}")
301+
));
302+
303+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsLiteralPattern("foobar").accepts(
304+
findElementAt(TwigFileType.INSTANCE, "{{ foobar({\"f<caret>o\"}) }}")
305+
));
306+
307+
assertTrue(TwigHelper.getFunctionWithFirstParameterAsLiteralPattern("foobar").accepts(
308+
findElementAt(TwigFileType.INSTANCE, "{{ foobar({\"foo\", \"f<caret>o\"}) }}")
309+
));
310+
}
311+
266312
private void assertEqual(Collection<String> c, String... values) {
267313
if(!StringUtils.join(c, ",").equals(StringUtils.join(Arrays.asList(values), ","))) {
268314
fail(String.format("Fail that '%s' is equal '%s'", StringUtils.join(c, ","), StringUtils.join(Arrays.asList(values), ",")));

tests/fr/adrienbrault/idea/symfony2plugin/tests/security/VoterGotoCompletionRegistrarTest.java

+40
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,46 @@ public void testTwigIsGrantedNavigation() {
4646
);
4747
}
4848

49+
public void testTwigIsGrantedAsArrayCompletion() {
50+
assertCompletionContains(
51+
TwigFileType.INSTANCE,
52+
"{{ is_granted(['<caret>']) }}",
53+
"YAML_ROLE_USER_FOOBAR"
54+
);
55+
56+
assertCompletionContains(
57+
TwigFileType.INSTANCE,
58+
"{{ is_granted({'<caret>'}) }}",
59+
"YAML_ROLE_USER_FOOBAR"
60+
);
61+
62+
assertCompletionContains(
63+
TwigFileType.INSTANCE,
64+
"{{ is_granted(['foobar', '<caret>']) }}",
65+
"YAML_ROLE_USER_FOOBAR"
66+
);
67+
}
68+
69+
public void testTwigIsGrantedAsArrayNavigation() {
70+
assertNavigationMatch(
71+
TwigFileType.INSTANCE,
72+
"{{ is_granted(['YAML_ROLE<caret>_USER_FOOBAR']) }}",
73+
PlatformPatterns.psiElement()
74+
);
75+
76+
assertNavigationMatch(
77+
TwigFileType.INSTANCE,
78+
"{{ is_granted({'YAML_ROLE<caret>_USER_FOOBAR'}) }}",
79+
PlatformPatterns.psiElement()
80+
);
81+
82+
assertNavigationMatch(
83+
TwigFileType.INSTANCE,
84+
"{{ is_granted(['foobar', 'YAML_ROLE<caret>_USER_FOOBAR']) }}",
85+
PlatformPatterns.psiElement()
86+
);
87+
}
88+
4989
public void testPhpIsGrantedCompletion() {
5090
assertCompletionContains(PhpFileType.INSTANCE,"<?php\n" +
5191
"/** @var $x \\Symfony\\Component\\Security\\Core\\Authorization\\AuthorizationCheckerInterface */\n" +

0 commit comments

Comments
 (0)