Skip to content

Commit 7f86d8f

Browse files
authored
Merge pull request #2456 from Haehnchen/feature/twig-deprecated-options
Add support for Twig extension options "parser_callable" and deprecation markers
2 parents 640d1b0 + 21d7dfc commit 7f86d8f

File tree

4 files changed

+69
-21
lines changed

4 files changed

+69
-21
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/dict/TwigExtension.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,16 @@ public String getSignature() {
5858
}
5959

6060
@Nullable
61-
String getOption(String key) {
61+
public String getOption(String key) {
6262
return options.getOrDefault(key, null);
6363
}
6464

6565
@NotNull
6666
public Collection<String> getTypes() {
6767
return types;
6868
}
69+
70+
public boolean isDeprecated() {
71+
return options.containsKey("deprecated") || options.containsKey("deprecation_info");
72+
}
6973
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigExtensionParser.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,11 @@ private static void visitNewExpression(@NotNull NewExpression element, @NotNull
368368

369369
Collection<String> typed = new HashSet<>();
370370
Project project = method.getProject();
371-
for (PhpNamedElement phpNamedElement : PhpElementsUtil.getPsiElementsBySignature(project, signature)) {
372-
if (phpNamedElement instanceof Function) {
373-
typed.addAll(PhpElementsUtil.getClassFromPhpTypeSet(project, phpNamedElement.getType().getTypes()).stream().map(PhpNamedElement::getFQN).toList());
371+
if (signature != null) {
372+
for (PhpNamedElement phpNamedElement : PhpElementsUtil.getPsiElementsBySignature(project, signature)) {
373+
if (phpNamedElement instanceof Function) {
374+
typed.addAll(PhpElementsUtil.getClassFromPhpTypeSet(project, phpNamedElement.getType().getTypes()).stream().map(PhpNamedElement::getFQN).toList());
375+
}
374376
}
375377
}
376378

@@ -441,8 +443,17 @@ private static void visitNewExpression(@NotNull NewExpression element, @NotNull
441443
static private Map<String, String> getOptions(@NotNull ArrayCreationExpression arrayCreationExpression) {
442444
Map<String, String> options = new HashMap<>();
443445

444-
for (String optionTrue: new String[] {"needs_environment", "needs_context"}) {
446+
for (String optionTrue: new String[] {"needs_environment", "needs_context", "parser_callable", "deprecation_info", "deprecated"}) {
445447
PhpPsiElement phpPsiElement = PhpElementsUtil.getArrayValue(arrayCreationExpression, optionTrue);
448+
if (phpPsiElement == null) {
449+
continue;
450+
}
451+
452+
if (optionTrue.equals("deprecation_info") || optionTrue.equals("deprecated")) {
453+
options.put(optionTrue, "true");
454+
continue;
455+
}
456+
446457
if (phpPsiElement instanceof ConstantReference) {
447458
String value = phpPsiElement.getName();
448459
if (value != null && value.equalsIgnoreCase("true")) {
@@ -469,6 +480,13 @@ private static void visitNewExpression(@NotNull NewExpression element, @NotNull
469480
signature = getCallableSignature(psiElement[1], method);
470481
}
471482

483+
if (signature == null && psiElement.length > 2 && psiElement[2] instanceof ArrayCreationExpression arrayCreationExpression) {
484+
PhpPsiElement phpPsiElement = PhpElementsUtil.getArrayValue(arrayCreationExpression, "parser_callable");
485+
if (phpPsiElement != null) {
486+
signature = getCallableSignature(phpPsiElement, method);
487+
}
488+
}
489+
472490
// creation options like: needs_environment
473491
Map<String, String> options;
474492
if (psiElement.length > 2 && psiElement[2] instanceof ArrayCreationExpression) {

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigExtensionParserTest.java

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,33 @@ public String getTestDataPath() {
2222
}
2323

2424
public void testExtensionAreCollected() {
25+
Map<String, TwigExtension> functions = TwigExtensionParser.getFunctions(getProject());
26+
Map<String, TwigExtension> simpleTest = TwigExtensionParser.getSimpleTest(getProject());
27+
Map<String, TwigExtension> filters = TwigExtensionParser.getFilters(getProject());
28+
2529
assertEquals(
2630
"#M#C\\Twig\\Extensions.foobar",
27-
TwigExtensionParser.getFilters(getProject()).get("trans").getSignature()
31+
filters.get("trans").getSignature()
2832
);
2933

3034
assertEquals(
3135
"#Fmax",
32-
TwigExtensionParser.getFunctions(getProject()).get("max").getSignature()
36+
functions.get("max").getSignature()
3337
);
3438

3539
assertEquals(
3640
"SIMPLE_TEST",
37-
TwigExtensionParser.getSimpleTest(getProject()).get("my_test").getType()
41+
simpleTest.get("my_test").getType()
3842
);
3943

4044
assertEquals(
4145
"#M#C\\My_Node_Test.compile",
42-
TwigExtensionParser.getSimpleTest(getProject()).get("my_test").getSignature()
46+
simpleTest.get("my_test").getSignature()
4347
);
4448

4549
assertEquals(
4650
"#Ffoo_test",
47-
TwigExtensionParser.getSimpleTest(getProject()).get("my_test_2").getSignature()
51+
simpleTest.get("my_test_2").getSignature()
4852
);
4953

5054
assertEquals(
@@ -59,62 +63,77 @@ public void testExtensionAreCollected() {
5963

6064
assertEquals(
6165
"#M#C\\ClassInstance.getFoobar",
62-
TwigExtensionParser.getFunctions(getProject()).get("class_instance_foobar").getSignature()
66+
functions.get("class_instance_foobar").getSignature()
6367
);
6468

6569
assertEquals(
6670
"#M#C\\Twig\\Extensions.getFoobar",
67-
TwigExtensionParser.getFunctions(getProject()).get("class_php_callable_method_foobar").getSignature()
71+
functions.get("class_php_callable_method_foobar").getSignature()
6872
);
6973

7074
assertEquals(
7175
"#Fmax",
72-
TwigExtensionParser.getFunctions(getProject()).get("class_php_callable_function_foobar").getSignature()
76+
functions.get("class_php_callable_function_foobar").getSignature()
7377
);
7478

7579
assertEquals(
7680
"#Fmax",
77-
TwigExtensionParser.getFunctions(getProject()).get("conditional_return").getSignature()
81+
functions.get("conditional_return").getSignature()
7882
);
7983

8084
assertEquals(
8185
"#M#C\\App\\Twig\\AppExtension.formatProductNumberFilter",
82-
TwigExtensionParser.getFilters(getProject()).get("product_number_filter").getSignature()
86+
filters.get("product_number_filter").getSignature()
8387
);
8488

8589
assertEquals(
8690
"#M#C\\App\\Twig\\AppExtension.formatProductNumberFunction",
87-
TwigExtensionParser.getFunctions(getProject()).get("product_number_function").getSignature()
91+
functions.get("product_number_function").getSignature()
8892
);
8993

9094
assertEquals(
9195
"#M#C\\App\\Twig\\AppExtension.formatProductNumberTest",
92-
TwigExtensionParser.getSimpleTest(getProject()).get("product_number_test").getSignature()
96+
simpleTest.get("product_number_test").getSignature()
97+
);
98+
99+
assertEquals(
100+
"#M#C\\Twig\\Extensions.parseAttributeFunction",
101+
functions.get("attribute_parser_callable").getSignature()
93102
);
94103
}
95104

96105
public void testExtensionAreCollectedForDeprecated() {
106+
Map<String, TwigExtension> functions = TwigExtensionParser.getFunctions(getProject());
107+
Map<String, TwigExtension> filters = TwigExtensionParser.getFilters(getProject());
108+
97109
assertEquals(
98110
"#M#C\\Symfony\\Bridge\\Twig\\Node\\FormEnctypeNode.compile",
99-
TwigExtensionParser.getFunctions(getProject()).get("form_enctype").getSignature()
111+
functions.get("form_enctype").getSignature()
100112
);
101113

102114
assertEquals(
103115
"#M#C\\Twig\\Extensions.foobar",
104-
TwigExtensionParser.getFunctions(getProject()).get("hwi_oauth_login_url").getSignature()
116+
functions.get("hwi_oauth_login_url").getSignature()
105117
);
106118

107119
assertEquals(
108120
"#M#C\\Twig\\Extensions.foobar",
109-
TwigExtensionParser.getFilters(getProject()).get("doctrine_minify_query").getSignature()
121+
filters.get("doctrine_minify_query").getSignature()
110122
);
111123

112124
assertEquals(
113125
"#Ffoobar",
114-
TwigExtensionParser.getFilters(getProject()).get("localizeddate").getSignature()
126+
filters.get("localizeddate").getSignature()
115127
);
116128
}
117129

130+
public void testExtensionDeprecatedOptions() {
131+
Map<String, TwigExtension> filters = TwigExtensionParser.getFilters(getProject());
132+
133+
assertTrue(filters.get("spaceless_deprecation_info").isDeprecated());
134+
assertTrue(filters.get("spaceless_deprecation_deprecated").isDeprecated());
135+
}
136+
118137
public void testExtensionAreCollectedForVersion2() {
119138
assertEquals(
120139
"#M#C\\Twig\\Extensions.foobar",

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/fixtures/twig_extensions.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class Twig_Function
6565

6666
namespace Twig
6767
{
68+
final class DeprecatedCallableInfo {}
69+
class DefaultFilter {}
70+
6871
// Twig 3.0
6972
class TwigFilter {}
7073
class TwigFunction {}
@@ -87,6 +90,9 @@ public function getFilters()
8790
'localizeddate' => new \Twig_Filter_Function('foobar'),
8891
new \Twig_Filter('trans_2', [$this, 'foobar']),
8992
new TwigFilter('trans_3', [$this, 'foobar']),
93+
new TwigFilter('default', [self::class, 'default'], ['node_class' => DefaultFilter::class]),
94+
new TwigFilter('spaceless_deprecation_info', [self::class, 'spaceless'], ['is_safe' => ['html'], 'deprecation_info' => new \Twig\DeprecatedCallableInfo('twig/twig', '3.12')]),
95+
new TwigFilter('spaceless_deprecation_deprecated', [self::class, 'spaceless'], ['is_safe' => ['html'], 'deprecated' => 12.12]),
9096
];
9197
}
9298

@@ -115,6 +121,7 @@ public function getFunctions()
115121
new TwigFunction('class_instance_foobar', [\ClassInstance::class, 'getFoobar']),
116122
new TwigFunction('class_php_callable_method_foobar', $this->getFoobar(...)),
117123
new TwigFunction('class_php_callable_function_foobar', max(...)),
124+
new TwigFunction('attribute_parser_callable', null, ['parser_callable' => [self::class, 'parseAttributeFunction']]),
118125
];
119126
}
120127

0 commit comments

Comments
 (0)