Skip to content

Commit 7950048

Browse files
authored
Merge pull request #1965 from Haehnchen/feature/linemarker-routes
provide linemarker for route annotations imports
2 parents 4edf41c + ee9b75e commit 7950048

File tree

4 files changed

+103
-5
lines changed

4 files changed

+103
-5
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/linemarker/XmlLineMarkerProvider.java

-4
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> psiElemen
4848
continue;
4949
}
5050

51-
if(!XmlHelper.getXmlTagNameLeafStartPattern().accepts(psiElement)) {
52-
continue;
53-
}
54-
5551
PsiElement xmlTag = psiElement.getParent();
5652
if(!(xmlTag instanceof XmlTag)) {
5753
continue;

src/main/java/fr/adrienbrault/idea/symfony2plugin/routing/XmlLineMarkerProvider.java

+42
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.intellij.codeInsight.daemon.LineMarkerProvider;
55
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
66
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
7+
import com.intellij.icons.AllIcons;
8+
import com.intellij.openapi.util.NotNullLazyValue;
79
import com.intellij.patterns.XmlPatterns;
810
import com.intellij.patterns.XmlTagPattern;
911
import com.intellij.psi.PsiElement;
@@ -12,13 +14,20 @@
1214
import com.intellij.psi.xml.XmlTag;
1315
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
1416
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
17+
import fr.adrienbrault.idea.symfony2plugin.config.ServiceLineMarkerProvider;
1518
import fr.adrienbrault.idea.symfony2plugin.config.xml.XmlHelper;
19+
import fr.adrienbrault.idea.symfony2plugin.dic.container.util.ServiceContainerUtil;
20+
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
1621
import fr.adrienbrault.idea.symfony2plugin.util.resource.FileResourceUtil;
22+
import org.apache.commons.lang.StringUtils;
1723
import org.jetbrains.annotations.NotNull;
1824
import org.jetbrains.annotations.Nullable;
1925

26+
import java.util.Arrays;
2027
import java.util.Collection;
28+
import java.util.Collections;
2129
import java.util.List;
30+
import java.util.function.Supplier;
2231

2332
/**
2433
* @author Daniel Espendiller <daniel@espendiller.net>
@@ -39,6 +48,10 @@ public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> psiElemen
3948
for(PsiElement psiElement: psiElements) {
4049
if(XmlHelper.getXmlTagNameLeafStartPattern().accepts(psiElement)) {
4150
attachRouteActions(psiElement, lineMarkerInfos);
51+
attachRouteImport(psiElement, lineMarkerInfos);
52+
53+
54+
4255
} else if(psiElement instanceof XmlFile) {
4356
RelatedItemLineMarkerInfo<PsiElement> lineMarker = FileResourceUtil.getFileImplementsLineMarker((PsiFile) psiElement);
4457
if(lineMarker != null) {
@@ -68,6 +81,30 @@ private void attachRouteActions(@NotNull PsiElement psiElement, @NotNull Collect
6881
}
6982
}
7083

84+
private void attachRouteImport(@NotNull PsiElement psiElement, @NotNull Collection<? super LineMarkerInfo<?>> lineMarkerInfos) {
85+
PsiElement xmlTag = psiElement.getParent();
86+
if(!(xmlTag instanceof XmlTag) || !Pattern.getRouteImport().accepts(xmlTag)) {
87+
return;
88+
}
89+
90+
if (!"annotation".equals(((XmlTag) xmlTag).getAttributeValue("type"))) {
91+
return;
92+
}
93+
94+
String resource = ((XmlTag) xmlTag).getAttributeValue("resource");
95+
if (StringUtils.isBlank(resource)) {
96+
return;
97+
}
98+
99+
lineMarkerInfos.add(
100+
FileResourceUtil.getNavigationGutterForRouteAnnotationResources(
101+
psiElement.getProject(),
102+
psiElement.getContainingFile().getVirtualFile(),
103+
resource
104+
).createLineMarkerInfo(psiElement)
105+
);
106+
}
107+
71108
@Nullable
72109
@Override
73110
public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement psiElement) {
@@ -82,6 +119,11 @@ public static XmlTagPattern.Capture getRouteTag() {
82119
).inFile(XmlHelper.getXmlFilePattern());
83120
}
84121

122+
public static XmlTagPattern.Capture getRouteImport() {
123+
return XmlPatterns.xmlTag().withName("import").withParent(
124+
XmlPatterns.xmlTag().withName("routes")
125+
).inFile(XmlHelper.getXmlFilePattern());
126+
}
85127
}
86128

87129
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/routing/YamlLineMarkerProvider.java

+35
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import fr.adrienbrault.idea.symfony2plugin.doctrine.metadata.util.DoctrineMetadataUtil;
1414
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
1515
import fr.adrienbrault.idea.symfony2plugin.util.resource.FileResourceUtil;
16+
import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper;
1617
import org.apache.commons.lang.StringUtils;
1718
import org.jetbrains.annotations.NotNull;
1819
import org.jetbrains.annotations.Nullable;
@@ -37,6 +38,7 @@ public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> psiElemen
3738
attachRouteActions(lineMarkerInfos, psiElement);
3839
attachEntityClass(lineMarkerInfos, psiElement);
3940
attachRelationClass(lineMarkerInfos, psiElement);
41+
attachRoutingForResources(lineMarkerInfos, psiElement);
4042

4143
if(psiElement instanceof YAMLFile) {
4244
RelatedItemLineMarkerInfo<PsiElement> lineMarker = FileResourceUtil.getFileImplementsLineMarker((PsiFile) psiElement);
@@ -47,6 +49,39 @@ public void collectSlowLineMarkers(@NotNull List<? extends PsiElement> psiElemen
4749
}
4850
}
4951

52+
/**
53+
* controllers:
54+
* resource: '../../src/Controller/'
55+
* type: annotation
56+
*/
57+
private void attachRoutingForResources(@NotNull Collection<? super LineMarkerInfo<?>> result, @NotNull PsiElement leafTarget) {
58+
if (leafTarget.getNode().getElementType() != YAMLTokenTypes.SCALAR_KEY) {
59+
return;
60+
}
61+
62+
PsiElement yamlKeyValue = leafTarget.getParent();
63+
if (!(yamlKeyValue instanceof YAMLKeyValue)) {
64+
return;
65+
}
66+
67+
String resource = YamlHelper.getYamlKeyValueAsString((YAMLKeyValue) yamlKeyValue, "resource");
68+
if (resource == null) {
69+
return;
70+
}
71+
72+
if (!"annotation".equals(YamlHelper.getYamlKeyValueAsString((YAMLKeyValue) yamlKeyValue, "type"))) {
73+
return;
74+
}
75+
76+
result.add(
77+
FileResourceUtil.getNavigationGutterForRouteAnnotationResources(
78+
leafTarget.getProject(),
79+
leafTarget.getContainingFile().getVirtualFile(),
80+
resource
81+
).createLineMarkerInfo(leafTarget)
82+
);
83+
}
84+
5085
private void attachEntityClass(@NotNull Collection<? super LineMarkerInfo<?>> lineMarkerInfos, @NotNull PsiElement psiElement) {
5186
if(psiElement.getNode().getElementType() != YAMLTokenTypes.SCALAR_KEY) {
5287
return;

src/main/java/fr/adrienbrault/idea/symfony2plugin/util/resource/FileResourceUtil.java

+26-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
44
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
5+
import com.intellij.icons.AllIcons;
56
import com.intellij.openapi.project.Project;
67
import com.intellij.openapi.util.NotNullLazyValue;
78
import com.intellij.openapi.util.Pair;
@@ -47,7 +48,7 @@ public class FileResourceUtil {
4748
* chars that trigger a glob resolving on symfony
4849
* extracted from: \Symfony\Component\Config\Loader\FileLoader::import
4950
*/
50-
private static final String[] GLOB_DETECTION_CHARS = {"*", "?", "{", "["};
51+
public static final String[] GLOB_DETECTION_CHARS = {"*", "?", "{", "["};
5152

5253
/**
5354
* Search for files refers to given file
@@ -395,6 +396,30 @@ public static Pair<String, String> getGlobalPatternDirectory(@NotNull String res
395396
return new Pair<>(join, null);
396397
}
397398

399+
public static @NotNull NavigationGutterIconBuilder<PsiElement> getNavigationGutterForRouteAnnotationResources(@NotNull Project project, @NotNull VirtualFile virtualFile, @NotNull String resource) {
400+
return NavigationGutterIconBuilder.create(AllIcons.Modules.SourceRoot)
401+
.setTargets(NotNullLazyValue.lazy(() -> {
402+
String r = resource;
403+
404+
// try to resolve the following pattern; all are recursive search for php
405+
// ../../Core/**/**/Controller/*Controller.php
406+
// ../src/Controller/
407+
// ../src/Kernel.php
408+
if (resource.endsWith("/") || resource.endsWith("\\")) {
409+
r += "**.php";
410+
} else if (Arrays.stream(FileResourceUtil.GLOB_DETECTION_CHARS).noneMatch(r::contains) && !resource.toLowerCase().endsWith(".php")) {
411+
r += "**.php";
412+
}
413+
414+
Collection<VirtualFile> filesForResources = FileResourceUtil.getFilesForResources(project, virtualFile, r)
415+
.stream()
416+
.filter(virtualFile1 -> "php".equalsIgnoreCase(virtualFile1.getExtension())).collect(Collectors.toSet());
417+
418+
return PsiElementUtils.convertVirtualFilesToPsiFiles(project, filesForResources);
419+
}))
420+
.setTooltipText("Navigate to matching files");
421+
}
422+
398423
/**
399424
* Find a file based on "glob" and its content path.
400425
*

0 commit comments

Comments
 (0)