Skip to content

Commit 86d7a72

Browse files
committed
provide extension for twig include and extends usage
1 parent bfff508 commit 86d7a72

File tree

5 files changed

+128
-17
lines changed

5 files changed

+128
-17
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package fr.adrienbrault.idea.symfony2plugin;
2+
3+
import com.intellij.patterns.PlatformPatterns;
4+
import com.intellij.psi.PsiElement;
5+
import com.jetbrains.twig.TwigTokenTypes;
6+
import com.jetbrains.twig.elements.TwigElementTypes;
7+
import fr.adrienbrault.idea.symfony2plugin.extension.TwigFileUsage;
8+
import fr.adrienbrault.idea.symfony2plugin.templating.TwigPattern;
9+
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
10+
import org.apache.commons.lang.StringUtils;
11+
import org.jetbrains.annotations.NotNull;
12+
import org.jetbrains.annotations.Nullable;
13+
14+
import java.util.Collection;
15+
import java.util.Collections;
16+
17+
/**
18+
* @author Daniel Espendiller <daniel@espendiller.net>
19+
*/
20+
public class ShopwareTemplateUsage implements TwigFileUsage {
21+
@Override
22+
public Collection<String> getExtendsTemplate(@NotNull PsiElement psiElement) {
23+
return getTemplateParameter(psiElement, "sw_extends");
24+
}
25+
26+
@Override
27+
public Collection<String> getIncludeTemplate(@NotNull PsiElement psiElement) {
28+
return getTemplateParameter(psiElement, "sw_include");
29+
}
30+
31+
@Override
32+
public boolean isExtendsTemplate(@NotNull PsiElement psiElement) {
33+
return isTag(psiElement, "sw_extends");
34+
}
35+
36+
@Override
37+
public boolean isIncludeTemplate(@NotNull PsiElement psiElement) {
38+
return isTag(psiElement, "sw_include");
39+
}
40+
41+
private boolean isTag(@NotNull PsiElement psiElement, @NotNull String tag) {
42+
if (psiElement.getNode().getElementType() == TwigElementTypes.TAG) {
43+
PsiElement tagElement = PsiElementUtils.getChildrenOfType(psiElement, PlatformPatterns.psiElement().withElementType(TwigTokenTypes.TAG_NAME));
44+
if (tagElement != null) {
45+
return tag.equals(tagElement.getText());
46+
}
47+
}
48+
49+
return false;
50+
}
51+
52+
53+
@Nullable
54+
private Collection<String> getTemplateParameter(@NotNull PsiElement psiElement, @NotNull String tag) {
55+
if (psiElement.getNode().getElementType() == TwigElementTypes.TAG) {
56+
PsiElement swImportTag = PsiElementUtils.getChildrenOfType(psiElement, TwigPattern.getTagNameParameterPattern(TwigElementTypes.TAG, tag));
57+
if (swImportTag != null) {
58+
String templateName = swImportTag.getText();
59+
if (StringUtils.isNotBlank(templateName)) {
60+
return Collections.singletonList(templateName);
61+
}
62+
}
63+
}
64+
65+
return null;
66+
}
67+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package fr.adrienbrault.idea.symfony2plugin.extension;
2+
3+
import com.intellij.psi.PsiElement;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.util.Collection;
7+
8+
/**
9+
* @author Daniel Espendiller <daniel@espendiller.net>
10+
*/
11+
public interface TwigFileUsage {
12+
Collection<String> getExtendsTemplate(@NotNull PsiElement psiElement);
13+
14+
Collection<String> getIncludeTemplate(@NotNull PsiElement psiElement);
15+
16+
boolean isExtendsTemplate(@NotNull PsiElement psiElement);
17+
boolean isIncludeTemplate(@NotNull PsiElement psiElement);
18+
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/TwigExtendsStubIndex.java

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package fr.adrienbrault.idea.symfony2plugin.stubs.indexes;
22

3-
import com.intellij.psi.PsiElement;
43
import com.intellij.psi.PsiFile;
5-
import com.intellij.psi.util.PsiTreeUtil;
64
import com.intellij.util.indexing.*;
75
import com.intellij.util.io.DataExternalizer;
86
import com.intellij.util.io.EnumeratorStringDescriptor;
97
import com.intellij.util.io.KeyDescriptor;
108
import com.intellij.util.io.VoidDataExternalizer;
119
import com.jetbrains.twig.TwigFile;
1210
import com.jetbrains.twig.TwigFileType;
13-
import com.jetbrains.twig.elements.TwigExtendsTag;
1411
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
1512
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
1613
import gnu.trove.THashMap;
@@ -47,20 +44,10 @@ public DataIndexer<String, Void, FileContent> getIndexer() {
4744
return map;
4845
}
4946

50-
PsiElement[] twigExtendsTags = PsiTreeUtil.collectElements(psiFile,
51-
psiElement -> psiElement instanceof TwigExtendsTag
47+
TwigUtil.visitTemplateExtends((TwigFile) psiFile, pair ->
48+
map.put(TwigUtil.normalizeTemplateName(pair.getFirst()), null)
5249
);
5350

54-
if(twigExtendsTags.length == 0) {
55-
return map;
56-
}
57-
58-
for(PsiElement twigExtendsTag: twigExtendsTags) {
59-
for (String s : TwigUtil.getTwigExtendsTagTemplates((TwigExtendsTag) twigExtendsTag)) {
60-
map.put(TwigUtil.normalizeTemplateName(s), null);
61-
}
62-
}
63-
6451
return map;
6552
};
6653

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

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import fr.adrienbrault.idea.symfony2plugin.Settings;
3737
import fr.adrienbrault.idea.symfony2plugin.action.comparator.ValueComparator;
3838
import fr.adrienbrault.idea.symfony2plugin.asset.AssetDirectoryReader;
39+
import fr.adrienbrault.idea.symfony2plugin.extension.TwigFileUsage;
3940
import fr.adrienbrault.idea.symfony2plugin.extension.TwigNamespaceExtension;
4041
import fr.adrienbrault.idea.symfony2plugin.extension.TwigNamespaceExtensionParameter;
4142
import fr.adrienbrault.idea.symfony2plugin.stubs.SymfonyProcessors;
@@ -92,10 +93,14 @@ public enum NamespaceType {
9293
BUNDLE, ADD_PATH
9394
}
9495

95-
private static final ExtensionPointName<TwigNamespaceExtension> EXTENSIONS = new ExtensionPointName<>(
96+
private static final ExtensionPointName<TwigNamespaceExtension> TWIG_NAMESPACE_EXTENSIONS = new ExtensionPointName<>(
9697
"fr.adrienbrault.idea.symfony2plugin.extension.TwigNamespaceExtension"
9798
);
9899

100+
private static final ExtensionPointName<TwigFileUsage> TWIG_FILE_USAGE_EXTENSIONS = new ExtensionPointName<>(
101+
"fr.adrienbrault.idea.symfony2plugin.extension.TwigFileUsage"
102+
);
103+
99104
private static final Key<CachedValue<Map<String, Set<VirtualFile>>>> TEMPLATE_CACHE_TWIG = new Key<>("TEMPLATE_CACHE_TWIG");
100105

101106
private static final Key<CachedValue<Map<String, Set<VirtualFile>>>> TEMPLATE_CACHE_ALL = new Key<>("TEMPLATE_CACHE_ALL");
@@ -1312,7 +1317,7 @@ public static List<TwigPath> getTwigNamespaces(@NotNull Project project, boolean
13121317

13131318
// load extension
13141319
TwigNamespaceExtensionParameter parameter = new TwigNamespaceExtensionParameter(project);
1315-
for (TwigNamespaceExtension namespaceExtension : EXTENSIONS.getExtensions()) {
1320+
for (TwigNamespaceExtension namespaceExtension : TWIG_NAMESPACE_EXTENSIONS.getExtensions()) {
13161321
twigPaths.addAll(namespaceExtension.getNamespaces(parameter));
13171322
}
13181323

@@ -2301,6 +2306,14 @@ public static void visitTemplateIncludes(@NotNull TwigFile twigFile, @NotNull Co
23012306
}
23022307
}
23032308
}
2309+
2310+
for (TwigFileUsage extension : TWIG_FILE_USAGE_EXTENSIONS.getExtensions()) {
2311+
if (extension.isIncludeTemplate(psiElement)) {
2312+
for (String template : extension.getIncludeTemplate(psiElement)) {
2313+
consumer.consume(new TemplateInclude(psiElement, template, TemplateInclude.TYPE.INCLUDE));
2314+
}
2315+
}
2316+
}
23042317
}
23052318

23062319
return false;
@@ -2708,6 +2721,31 @@ public static Collection<LookupElement> getBlockLookupElements(@NotNull Project
27082721
return lookupElements;
27092722
}
27102723

2724+
public static void visitTemplateExtends(@NotNull TwigFile twigFile, Consumer<Pair<String, PsiElement>> consumer) {
2725+
twigFile.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
2726+
@Override
2727+
public void visitElement(PsiElement element) {
2728+
if (element instanceof TwigExtendsTag) {
2729+
for (String s : TwigUtil.getTwigExtendsTagTemplates((TwigExtendsTag) element)) {
2730+
consumer.consume(Pair.create(TwigUtil.normalizeTemplateName(s), element));
2731+
}
2732+
}
2733+
2734+
for (TwigFileUsage extension : TWIG_FILE_USAGE_EXTENSIONS.getExtensions()) {
2735+
if (!extension.isExtendsTemplate(element)) {
2736+
continue;
2737+
}
2738+
2739+
for (String template : extension.getExtendsTemplate(element)) {
2740+
consumer.consume(Pair.create(TwigUtil.normalizeTemplateName(template), element));
2741+
}
2742+
}
2743+
2744+
super.visitElement(element);
2745+
}
2746+
});
2747+
}
2748+
27112749
public static class DomainScope {
27122750
@NotNull
27132751
private final String defaultDomain;

src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@
543543
<extensionPoint name="extension.TwigVariableCollector" interface="fr.adrienbrault.idea.symfony2plugin.templating.variable.TwigFileVariableCollector"/>
544544
<extensionPoint name="extension.PluginConfigurationExtension" interface="fr.adrienbrault.idea.symfony2plugin.extension.PluginConfigurationExtension"/>
545545
<extensionPoint name="extension.TranslatorProvider" interface="fr.adrienbrault.idea.symfony2plugin.extension.TranslatorProvider"/>
546+
<extensionPoint name="extension.TwigFileUsage" interface="fr.adrienbrault.idea.symfony2plugin.extension.TwigFileUsage"/>
546547
</extensionPoints>
547548

548549
<extensions defaultExtensionNs="fr.adrienbrault.idea.symfony2plugin.extension">

0 commit comments

Comments
 (0)