Skip to content

Commit 2b7f8a3

Browse files
authored
Merge pull request #1967 from Haehnchen/feature/tagged-service
provide navigation for "tagged_iterator" tag in yaml
2 parents dd94b52 + f94033d commit 2b7f8a3

File tree

3 files changed

+116
-4
lines changed

3 files changed

+116
-4
lines changed

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

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.intellij.psi.PsiElement;
1111
import com.intellij.psi.PsiFile;
1212
import com.intellij.psi.tree.IElementType;
13+
import com.intellij.psi.util.PsiTreeUtil;
1314
import com.jetbrains.php.PhpIndex;
1415
import com.jetbrains.php.lang.psi.elements.Method;
1516
import com.jetbrains.php.lang.psi.elements.Parameter;
@@ -54,8 +55,8 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit
5455
// only string values like "foo", foo
5556
if (elementType == YAMLTokenTypes.TEXT || elementType == YAMLTokenTypes.SCALAR_DSTRING || elementType == YAMLTokenTypes.SCALAR_STRING) {
5657
String psiText = PsiElementUtils.getText(psiElement);
57-
if(psiText != null && psiText.length() > 0) {
58-
if(psiText.startsWith("@") && psiText.length() > 1) {
58+
if (psiText.length() > 0) {
59+
if (psiText.startsWith("@") && psiText.length() > 1) {
5960
targets.addAll(serviceGoToDeclaration(psiElement, psiText.substring(1)));
6061
}
6162

@@ -104,9 +105,9 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit
104105
}
105106

106107
// yaml Plugin BC: "!php/const:" is a tag
107-
if(elementType == YAMLTokenTypes.TAG) {
108+
if (elementType == YAMLTokenTypes.TAG) {
108109
String psiText = PsiElementUtils.getText(psiElement);
109-
if(psiText != null && psiText.length() > 0 && psiText.startsWith("!php/const:")) {
110+
if (psiText.startsWith("!php/const:")) {
110111
targets.addAll(constantGoto(psiElement, psiText));
111112
}
112113
}
@@ -193,6 +194,19 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit
193194
targets.addAll(attachResourceOrExcludeGlobNamespaceElements(psiElement));
194195
}
195196

197+
// !tagged_iterator app.handler
198+
if (PlatformPatterns.psiElement(YAMLTokenTypes.TEXT).accepts(psiElement) || PlatformPatterns.psiElement(YAMLTokenTypes.TAG).accepts(psiElement)) {
199+
targets.addAll(attachTaggedIteratorClasses(psiElement));
200+
}
201+
202+
// !tagged_iterator { tag: app.handler, default_priority_method: getPriority }
203+
if (YamlElementPatternHelper.getSingleLineScalarKey("tag").accepts(psiElement)) {
204+
String tag = psiElement.getText();
205+
if (StringUtils.isNotBlank(tag)) {
206+
targets.addAll(ServiceUtil.getTaggedClassesWithCompiled(psiElement.getProject(), tag));
207+
}
208+
}
209+
196210
return targets.toArray(new PsiElement[0]);
197211
}
198212

@@ -512,6 +526,56 @@ private Collection<PsiElement> attachResourceOnPathGoto(@NotNull PsiElement psiE
512526
return new ArrayList<>(FileResourceUtil.getFileResourceTargetsInDirectoryScope(containingFile, text));
513527
}
514528

529+
/**
530+
* Both elements are clickable, as parent element does not allow navigation
531+
*
532+
* "!tagged_iterator app.handler"
533+
*/
534+
@NotNull
535+
private Collection<PsiElement> attachTaggedIteratorClasses(@NotNull PsiElement psiElement) {
536+
if (psiElement.getNode().getElementType() == YAMLTokenTypes.TEXT) {
537+
PsiElement prevLeaf = PsiTreeUtil.prevCodeLeaf(psiElement);
538+
if (prevLeaf != null && prevLeaf.getNode().getElementType() == YAMLTokenTypes.TAG) {
539+
if ("!tagged_iterator".equals(prevLeaf.getText())) {
540+
String tag = psiElement.getText();
541+
if (StringUtils.isNotBlank(tag)) {
542+
return new ArrayList<>(ServiceUtil.getTaggedClassesWithCompiled(psiElement.getProject(), tag));
543+
}
544+
}
545+
}
546+
} else if (psiElement.getNode().getElementType() == YAMLTokenTypes.TAG) {
547+
// - !tagged_iterator ...
548+
549+
if ("!tagged_iterator".equals(psiElement.getText())) {
550+
PsiElement nextLeaf = PsiTreeUtil.nextCodeLeaf(psiElement);
551+
552+
if (nextLeaf != null && nextLeaf.getNode().getElementType() == YAMLTokenTypes.TEXT) {
553+
// - !tagged_iterator app.handler
554+
String tag = nextLeaf.getText();
555+
if (StringUtils.isNotBlank(tag)) {
556+
return new ArrayList<>(ServiceUtil.getTaggedClassesWithCompiled(psiElement.getProject(), tag));
557+
}
558+
} else {
559+
// - !tagged_iterator { tag: app.handler, default_priority_method: getPriority }
560+
YAMLKeyValue tagKeyValue = PsiElementUtils.getNextSiblingOfTypes(psiElement, YAMLKeyValue.class)
561+
.stream()
562+
.filter(yamlKeyValue -> "tag".equals(yamlKeyValue.getKeyText()))
563+
.findFirst()
564+
.orElse(null);
565+
566+
if (tagKeyValue != null) {
567+
String tag = tagKeyValue.getValueText();
568+
if (StringUtils.isNotBlank(tag)) {
569+
return new ArrayList<>(ServiceUtil.getTaggedClassesWithCompiled(psiElement.getProject(), tag));
570+
}
571+
}
572+
}
573+
}
574+
}
575+
576+
return Collections.emptyList();
577+
}
578+
515579
@NotNull
516580
private Collection<PsiElement> getControllerGoto(@NotNull PsiElement psiElement) {
517581
String text = PsiElementUtils.trimQuote(psiElement.getText());

src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PsiElementUtils.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,21 @@ public static <T extends PsiElement> Collection<T> getNextSiblingOfTypes(@Nullab
168168
return foo;
169169
}
170170

171+
@NotNull
172+
public static <T extends PsiElement> Collection<T> getNextSiblingOfTypes(@Nullable PsiElement sibling, Class<T> pattern) {
173+
if (sibling == null) return Collections.emptySet();
174+
175+
Collection<T> results = new ArrayList<>();
176+
for (PsiElement child = sibling.getNextSibling(); child != null; child = child.getNextSibling()) {
177+
if (pattern.isInstance(child)) {
178+
//noinspection unchecked
179+
results.add((T)child);
180+
}
181+
}
182+
183+
return results;
184+
}
185+
171186
@Nullable
172187
public static <T extends PsiElement> T getPrevSiblingOfType(@Nullable PsiElement sibling, ElementPattern<T> pattern) {
173188
if (sibling == null) return null;

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.jetbrains.php.lang.psi.elements.Parameter;
88
import com.jetbrains.php.lang.psi.elements.PhpClass;
99
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
10+
import com.jetbrains.twig.elements.TwigElementTypes;
1011
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
1112
import org.jetbrains.annotations.NotNull;
1213
import org.jetbrains.yaml.YAMLFileType;
@@ -154,6 +155,38 @@ public void testNavigateToTaggedServices() {
154155
}
155156
}
156157

158+
public void testNavigateToTaggedIteratorServices() {
159+
assertNavigationMatch(YAMLFileType.YML, "" +
160+
"App\\HandlerCollection:\n" +
161+
" arguments:\n" +
162+
" - !tagged_iterator my_nic<caret>e_tag\n",
163+
PlatformPatterns.psiElement(PhpClass.class)
164+
);
165+
166+
assertNavigationMatch(YAMLFileType.YML, "" +
167+
"App\\HandlerCollection:\n" +
168+
" arguments:\n" +
169+
" - !tagged_<caret>iterator my_nice_tag\n",
170+
PlatformPatterns.psiElement(PhpClass.class)
171+
);
172+
}
173+
174+
public void testNavigateToTagInsideHash() {
175+
assertNavigationMatch(YAMLFileType.YML, "" +
176+
"App\\HandlerCollection:\n" +
177+
" arguments:\n" +
178+
" - !tagged_iterator { tag: my_ni<caret>ce_tag, default_priority_method: getPriority }\n",
179+
PlatformPatterns.psiElement(PhpClass.class)
180+
);
181+
182+
assertNavigationMatch(YAMLFileType.YML, "" +
183+
"App\\HandlerCollection:\n" +
184+
" arguments:\n" +
185+
" - !tagged_it<caret>erator { tag: my_nice_tag, default_priority_method: getPriority }\n",
186+
PlatformPatterns.psiElement(PhpClass.class)
187+
);
188+
}
189+
157190
public void testNavigateToTaggedServicesForSymfony33Shortcut() {
158191
String[] values = {"my_nice<caret>_tag", "'my_nice<caret>_tag'", "\"my_nice<caret>_tag\""};
159192

0 commit comments

Comments
 (0)