Skip to content

Commit 43aa7bd

Browse files
committed
#1984 support parameter inside "TaggedIterator" attribute
1 parent 8ae5672 commit 43aa7bd

File tree

5 files changed

+111
-9
lines changed

5 files changed

+111
-9
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/util/ServiceContainerUtil.java

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public class ServiceContainerUtil {
7070
};
7171

7272
public static final String AUTOWIRE_ATTRIBUTE_CLASS = "\\Symfony\\Component\\DependencyInjection\\Attribute\\Autowire";
73+
public static final String TAGGET_ITERATOR_ATTRIBUTE_CLASS = "\\Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator";
7374

7475
@NotNull
7576
public static Collection<ServiceSerializable> getServicesInFile(@NotNull PsiFile psiFile) {

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/registrar/DicGotoCompletionRegistrar.java

+49-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.intellij.codeInsight.lookup.LookupElement;
44
import com.intellij.patterns.PlatformPatterns;
55
import com.intellij.psi.PsiElement;
6+
import com.intellij.psi.PsiElementResolveResult;
7+
import com.intellij.psi.ResolveResult;
68
import com.intellij.psi.util.PsiTreeUtil;
79
import com.jetbrains.php.lang.psi.elements.PhpAttribute;
810
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
@@ -16,6 +18,7 @@
1618
import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver;
1719
import fr.adrienbrault.idea.symfony2plugin.util.MethodMatcher;
1820
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
21+
import fr.adrienbrault.idea.symfony2plugin.util.completion.TagNameCompletionProvider;
1922
import fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil;
2023
import org.jetbrains.annotations.NotNull;
2124

@@ -82,10 +85,27 @@ public void register(@NotNull GotoCompletionRegistrarParameter registrar) {
8285

8386
PhpAttribute phpAttribute = PsiTreeUtil.getParentOfType(context, PhpAttribute.class);
8487
if (phpAttribute != null) {
85-
String fqn = phpAttribute.getFQN();
86-
if (fqn != null && PhpElementsUtil.isInstanceOf(psiElement.getProject(), fqn, ServiceContainerUtil.AUTOWIRE_ATTRIBUTE_CLASS)) {
87-
return new ParameterContributor((StringLiteralExpression) context);
88-
}
88+
return new ParameterContributor((StringLiteralExpression) context);
89+
}
90+
91+
return null;
92+
}
93+
);
94+
95+
// #[TaggedIterator('app.handler')] iterable $handlers
96+
registrar.register(
97+
PlatformPatterns.or(
98+
PhpElementsUtil.getFirstAttributeStringPattern(ServiceContainerUtil.TAGGET_ITERATOR_ATTRIBUTE_CLASS),
99+
PhpElementsUtil.getAttributeNamedArgumentStringPattern(ServiceContainerUtil.TAGGET_ITERATOR_ATTRIBUTE_CLASS, "tag")
100+
), psiElement -> {
101+
PsiElement context = psiElement.getContext();
102+
if (!(context instanceof StringLiteralExpression)) {
103+
return null;
104+
}
105+
106+
PhpAttribute phpAttribute = PsiTreeUtil.getParentOfType(context, PhpAttribute.class);
107+
if (phpAttribute != null) {
108+
return new TaggedIteratorContributor((StringLiteralExpression) context);
89109
}
90110

91111
return null;
@@ -104,7 +124,7 @@ public ParameterContributor(StringLiteralExpression element) {
104124
public Collection<LookupElement> getLookupElements() {
105125
Collection<LookupElement> results = new ArrayList<>();
106126

107-
for(Map.Entry<String, ContainerParameter> entry: ContainerCollectionResolver.getParameters(getElement().getProject()).entrySet()) {
127+
for (Map.Entry<String, ContainerParameter> entry: ContainerCollectionResolver.getParameters(getElement().getProject()).entrySet()) {
108128
results.add(new ParameterLookupElement(entry.getValue()));
109129
}
110130

@@ -115,11 +135,34 @@ public Collection<LookupElement> getLookupElements() {
115135
@Override
116136
public Collection<PsiElement> getPsiTargets(PsiElement element) {
117137
String contents = GotoCompletionUtil.getStringLiteralValue(element);
118-
if(contents == null) {
138+
if (contents == null) {
119139
return Collections.emptyList();
120140
}
121141

122142
return ServiceUtil.getParameterDefinition(element.getProject(), contents);
123143
}
124144
}
145+
146+
private static class TaggedIteratorContributor extends GotoCompletionProvider {
147+
public TaggedIteratorContributor(StringLiteralExpression element) {
148+
super(element);
149+
}
150+
151+
@NotNull
152+
@Override
153+
public Collection<LookupElement> getLookupElements() {
154+
return TagNameCompletionProvider.getTagLookupElements(getElement().getProject());
155+
}
156+
157+
@NotNull
158+
@Override
159+
public Collection<PsiElement> getPsiTargets(PsiElement element) {
160+
String contents = GotoCompletionUtil.getStringLiteralValue(element);
161+
if(contents == null) {
162+
return Collections.emptyList();
163+
}
164+
165+
return new ArrayList<>(ServiceUtil.getTaggedClasses(getElement().getProject(), contents));
166+
}
167+
}
125168
}

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/dic/registrar/DicGotoCompletionRegistrarTest.java

+37-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.intellij.patterns.PlatformPatterns;
44
import com.jetbrains.php.lang.PhpFileType;
55
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
6-
import org.jetbrains.yaml.YAMLFileType;
76

87
/**
98
* @author Daniel Espendiller <daniel@espendiller.net>
@@ -13,8 +12,7 @@ public class DicGotoCompletionRegistrarTest extends SymfonyLightCodeInsightFixtu
1312
public void setUp() throws Exception {
1413
super.setUp();
1514
myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject("classes.php"));
16-
myFixture.configureByText(YAMLFileType.YML, "parameters:\n foo: foo");
17-
15+
myFixture.copyFileToProject("services.yml");
1816
}
1917

2018
public String getTestDataPath() {
@@ -132,4 +130,40 @@ public void testParameterContributorForNamedAttribute() {
132130
PlatformPatterns.psiElement()
133131
);
134132
}
133+
134+
public void testTagContributorForTaggedIterator() {
135+
assertCompletionContains(PhpFileType.INSTANCE, "<?php\n" +
136+
"use Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator;\n" +
137+
"\n" +
138+
"class HandlerCollection\n" +
139+
" public function __construct(\n" +
140+
" #[TaggedIterator('<caret>')] iterable $handlers\n" +
141+
" ) {}\n" +
142+
"}",
143+
"yaml_type_tag"
144+
);
145+
146+
assertCompletionContains(PhpFileType.INSTANCE, "<?php\n" +
147+
"use Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator;\n" +
148+
"\n" +
149+
"class HandlerCollection\n" +
150+
" public function __construct(\n" +
151+
" #[TaggedIterator(tag: '<caret>')] iterable $handlers\n" +
152+
" ) {}\n" +
153+
"}",
154+
"yaml_type_tag"
155+
);
156+
157+
assertNavigationMatch(PhpFileType.INSTANCE, "<?php\n" +
158+
"use Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator;\n" +
159+
"\n" +
160+
"class HandlerCollection\n" +
161+
"{\n" +
162+
" public function __construct(\n" +
163+
" #[TaggedIterator('yaml_t<caret>ype_tag')] iterable $handlers\n" +
164+
" ) {}\n" +
165+
"}",
166+
PlatformPatterns.psiElement()
167+
);
168+
}
135169
}

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/dic/registrar/fixtures/classes.php

+17
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ public function __construct(
2424
string $expression = null,
2525
) {}
2626
}
27+
28+
class TaggedIterator
29+
{
30+
public function __construct(
31+
public string $tag,
32+
public ?string $indexAttribute = null,
33+
public ?string $defaultIndexMethod = null,
34+
public ?string $defaultPriorityMethod = null,
35+
public string|array $exclude = [],
36+
) {}
37+
}
2738
}
2839

2940
namespace
@@ -46,4 +57,10 @@ public function bar($parameter) {
4657
}
4758
}
4859

60+
namespace Foo
61+
{
62+
class Bar
63+
{
64+
}
65+
}
4966

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
parameters:
2+
foo: foo
3+
4+
services:
5+
Foo\Bar:
6+
tags:
7+
- { name: yaml_type_tag }

0 commit comments

Comments
 (0)