Skip to content

Commit 0ea696d

Browse files
committed
Named arguments in bind should provide navigation with #1241
1 parent 54b058a commit 0ea696d

File tree

5 files changed

+107
-8
lines changed

5 files changed

+107
-8
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlElementPatternHelper.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,22 @@ public static PsiElementPattern.Capture<PsiElement> getTagsAsSequencePattern() {
679679
);
680680
}
681681

682+
/**
683+
* services:
684+
* _defaults:
685+
* bind:
686+
* $fo<caret>obar: '@foobar'
687+
*/
688+
public static PsiElementPattern.Capture<PsiElement> getBindArgumentPattern() {
689+
return PlatformPatterns.psiElement().withParent(
690+
PlatformPatterns.psiElement(YAMLKeyValue.class).withParent(
691+
PlatformPatterns.psiElement(YAMLMapping.class).withParent(
692+
PlatformPatterns.psiElement(YAMLKeyValue.class).withName("bind")
693+
)
694+
)
695+
);
696+
}
697+
682698
/**
683699
* !tagged twig.extension
684700
*/

src/main/java/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlGoToDeclarationHandler.java

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@
3131
import org.jetbrains.annotations.NotNull;
3232
import org.jetbrains.annotations.Nullable;
3333
import org.jetbrains.yaml.YAMLTokenTypes;
34-
import org.jetbrains.yaml.psi.YAMLKeyValue;
35-
import org.jetbrains.yaml.psi.YAMLMapping;
36-
import org.jetbrains.yaml.psi.YAMLScalar;
37-
import org.jetbrains.yaml.psi.YAMLSequenceItem;
34+
import org.jetbrains.yaml.psi.*;
3835

3936
import java.util.*;
4037

@@ -92,8 +89,16 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit
9289
if (elementType == YAMLTokenTypes.SCALAR_KEY) {
9390
String psiText = PsiElementUtils.getText(psiElement);
9491

95-
if(psiText.startsWith("$")) {
96-
targets.addAll(namedArgumentGoto(psiElement)) ;
92+
if (psiText.startsWith("$")) {
93+
targets.addAll(namedArgumentGoto(psiElement));
94+
95+
// services:
96+
// _defaults:
97+
// bind:
98+
// $fo<caret>obar: '@foobar'
99+
if (YamlElementPatternHelper.getBindArgumentPattern().accepts(psiElement)) {
100+
targets.addAll(namedDefaultBindArgumentGoto(psiElement, psiText));
101+
}
97102
}
98103
}
99104

@@ -176,7 +181,29 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit
176181
return targets.toArray(new PsiElement[targets.size()]);
177182
}
178183

179-
private Collection<? extends PsiElement> namedArgumentGoto(PsiElement psiElement) {
184+
private Collection<? extends PsiElement> namedDefaultBindArgumentGoto(@NotNull PsiElement psiElement, @NotNull String parameterName) {
185+
Collection<PsiElement> psiElements = new HashSet<>();
186+
187+
PsiFile containingFile = psiElement.getContainingFile();
188+
if (containingFile instanceof YAMLFile) {
189+
for (PhpClass phpClass : YamlHelper.getPhpClassesInYamlFile((YAMLFile) containingFile, new ContainerCollectionResolver.LazyServiceCollector(psiElement.getProject()))) {
190+
Method constructor = phpClass.getConstructor();
191+
if (constructor == null) {
192+
continue;
193+
}
194+
195+
for (Parameter parameter : constructor.getParameters()) {
196+
if (parameter.getName().equals(parameterName.substring(1))) {
197+
psiElements.add(parameter);
198+
}
199+
}
200+
}
201+
}
202+
203+
return psiElements;
204+
}
205+
206+
private Collection<? extends PsiElement> namedArgumentGoto(@NotNull PsiElement psiElement) {
180207
Collection<PsiElement> psiElements = new HashSet<>();
181208

182209
Parameter yamlNamedArgument = ServiceContainerUtil.getYamlNamedArgument(psiElement, new ContainerCollectionResolver.LazyServiceCollector(psiElement.getProject()));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public static Parameter getYamlNamedArgument(@NotNull PsiElement psiElement, @No
410410
* arguments: ~
411411
*/
412412
@Nullable
413-
private static String getServiceClassFromServiceMapping(@NotNull YAMLMapping yamlMapping) {
413+
public static String getServiceClassFromServiceMapping(@NotNull YAMLMapping yamlMapping) {
414414
YAMLKeyValue classKeyValue = yamlMapping.getKeyValueByKey("class");
415415

416416
// Symfony 3.3: "class" is optional; use service id for class

src/main/java/fr/adrienbrault/idea/symfony2plugin/util/yaml/YamlHelper.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818
import com.intellij.util.Processor;
1919
import com.intellij.util.containers.ContainerUtil;
2020
import com.jetbrains.php.lang.psi.elements.Parameter;
21+
import com.jetbrains.php.lang.psi.elements.PhpClass;
2122
import com.jetbrains.php.refactoring.PhpNameUtil;
2223
import fr.adrienbrault.idea.symfony2plugin.dic.ParameterResolverConsumer;
24+
import fr.adrienbrault.idea.symfony2plugin.dic.container.util.ServiceContainerUtil;
2325
import fr.adrienbrault.idea.symfony2plugin.dic.tags.yaml.StaticAttributeResolver;
26+
import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver;
27+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
2428
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
29+
import fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil;
2530
import fr.adrienbrault.idea.symfony2plugin.util.yaml.visitor.ParameterVisitor;
2631
import fr.adrienbrault.idea.symfony2plugin.util.yaml.visitor.YamlServiceTag;
2732
import fr.adrienbrault.idea.symfony2plugin.util.yaml.visitor.YamlTagVisitor;
@@ -34,6 +39,7 @@
3439
import org.jetbrains.yaml.YAMLUtil;
3540
import org.jetbrains.yaml.psi.*;
3641
import org.jetbrains.yaml.psi.impl.YAMLHashImpl;
42+
import org.jetbrains.yaml.psi.impl.YAMLPlainTextImpl;
3743

3844
import java.util.*;
3945

@@ -1168,4 +1174,33 @@ public boolean accepts(@NotNull PsiElement psiElement, ProcessingContext process
11681174
return psiElement.getNextSibling() instanceof YAMLMapping;
11691175
}
11701176
}
1177+
1178+
@NotNull
1179+
public static Collection<PhpClass> getPhpClassesInYamlFile(@NotNull YAMLFile yamlFile, @NotNull ContainerCollectionResolver.LazyServiceCollector lazyServiceCollector) {
1180+
Collection<PhpClass> phpClasses = new HashSet<>();
1181+
1182+
for (YAMLKeyValue keyValue : YamlHelper.getQualifiedKeyValuesInFile(yamlFile, "services")) {
1183+
YAMLValue value = keyValue.getValue();
1184+
if (value instanceof YAMLMapping) {
1185+
// foo.bar:
1186+
// classes: ...
1187+
String serviceId = ServiceContainerUtil.getServiceClassFromServiceMapping((YAMLMapping) value);
1188+
if (StringUtils.isNotBlank(serviceId)) {
1189+
PhpClass serviceClass = ServiceUtil.getResolvedClassDefinition(yamlFile.getProject(), serviceId, lazyServiceCollector);
1190+
if (serviceClass != null) {
1191+
phpClasses.add(serviceClass);
1192+
}
1193+
}
1194+
} else if(value instanceof YAMLPlainTextImpl) {
1195+
// Foo\Bar: ~
1196+
String text = keyValue.getKeyText();
1197+
1198+
if (StringUtils.isNotBlank(text) && YamlHelper.isClassServiceId(text)) {
1199+
phpClasses.addAll(PhpElementsUtil.getClassesInterface(yamlFile.getProject(), text));
1200+
}
1201+
}
1202+
}
1203+
1204+
return phpClasses;
1205+
}
11711206
}

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/YamlGoToDeclarationHandlerTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,27 @@ public void testNamedArgumentsNavigationForService() {
237237
);
238238
}
239239

240+
public void testNamedArgumentsNavigationForDefaultBinding() {
241+
assertNavigationMatch("services.yml", "" +
242+
"services:\n" +
243+
" _defaults:\n" +
244+
" bind:\n" +
245+
" $<caret>i: ~\n"+
246+
" Foo\\Bar: ~" +
247+
PlatformPatterns.psiElement(Parameter.class)
248+
);
249+
250+
assertNavigationMatch("services.yml", "" +
251+
"services:\n" +
252+
" _defaults:\n" +
253+
" bind:\n" +
254+
" $<caret>i: ~\n"+
255+
" foobar:\n" +
256+
" class: Foo\\Bar\n" +
257+
PlatformPatterns.psiElement(Parameter.class)
258+
);
259+
}
260+
240261
@NotNull
241262
private PsiElementPattern.Capture<PhpClass> getClassPattern() {
242263
return PlatformPatterns.psiElement(PhpClass.class);

0 commit comments

Comments
 (0)