Skip to content

Commit

Permalink
Merge pull request #2240 from Haehnchen/feature/embed-index
Browse files Browse the repository at this point in the history
add Twig block embed index
  • Loading branch information
Haehnchen authored Oct 13, 2023
2 parents ff5c0c8 + 1604f80 commit 04fb1ff
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package fr.adrienbrault.idea.symfony2plugin.stubs.indexes;

import com.intellij.psi.PsiFile;
import com.intellij.util.indexing.*;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import com.jetbrains.twig.TwigFile;
import com.jetbrains.twig.TwigFileType;
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.externalizer.StringSetDataExternalizer;
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* @author Daniel Espendiller <[email protected]>
*/
public class TwigBlockEmbedIndex extends FileBasedIndexExtension<String, Set<String>> {

public static final ID<String, Set<String>> KEY = ID.create("fr.adrienbrault.idea.symfony2plugin.twig_block_names_embed");

private final KeyDescriptor<String> KEY_DESCRIPTOR = new EnumeratorStringDescriptor();
private static final StringSetDataExternalizer DATA_EXTERNALIZER = new StringSetDataExternalizer();

@NotNull
@Override
public DataIndexer<String, Set<String>, FileContent> getIndexer() {
return fileContent -> {
Map<String, Set<String>> blocks = new HashMap<>();

PsiFile psiFile = fileContent.getPsiFile();
if (psiFile instanceof TwigFile twigFile) {
TwigUtil.visitEmbedBlocks(twigFile, pair -> {
String templateName = pair.getFirst();

blocks.putIfAbsent(templateName, new HashSet<>());
blocks.get(templateName).add(pair.getSecond());
});
}

return blocks;
};
}

@NotNull
@Override
public ID<String, Set<String>> getName() {
return KEY;
}

@NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return KEY_DESCRIPTOR;
}

@NotNull
@Override
public DataExternalizer<Set<String>> getValueExternalizer() {
return DATA_EXTERNALIZER;
}

@Override
public int getVersion() {
return 2;
}

@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return file -> file.getFileType() == TwigFileType.INSTANCE;
}

@Override
public boolean dependsOnFileContent() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1784,6 +1784,33 @@ public void visitElement(PsiElement element) {
return block;
}

@NotNull
public static void visitEmbedBlocks(@NotNull TwigFile psiFile, @NotNull Consumer<Pair<String, String>> consumer) {
PsiElement[] embedStatements = PsiTreeUtil.collectElements(psiFile, psiElement ->
psiElement instanceof TwigCompositeElement && psiElement.getNode().getElementType() == TwigElementTypes.EMBED_STATEMENT
);

for (PsiElement embedStatement : embedStatements) {
PsiElement firstChild = embedStatement.getFirstChild();
if (firstChild == null) {
continue;
}

String templateNameForEmbedTag = TwigUtil.getTemplateNameForEmbedTag(firstChild);
if (templateNameForEmbedTag == null) {
continue;
}

for (TwigBlockStatement twigBlockStatement : PsiTreeUtil.getChildrenOfAnyType(embedStatement, TwigBlockStatement.class)) {
String blockName = twigBlockStatement.getName();

if (blockName != null && !blockName.isBlank()) {
consumer.consume(Pair.create(templateNameForEmbedTag, blockName));
}
}
}
}

/**
* Find "extends" template in twig TwigExtendsTag
*
Expand Down Expand Up @@ -1922,7 +1949,7 @@ public static Pair<Collection<PsiFile>, Boolean> findScopedFile(@NotNull PsiElem
* {% embed "teasers_skeleton.html.twig" %}
*/
@Nullable
private static String getTemplateNameForEmbedTag(@NotNull PsiElement embedTag) {
public static String getTemplateNameForEmbedTag(@NotNull PsiElement embedTag) {
if(embedTag.getNode().getElementType() == TwigElementTypes.EMBED_TAG) {
PsiElement fileReference = ContainerUtil.find(YamlHelper.getChildrenFix(embedTag), psiElement ->
TwigPattern.getTemplateFileReferenceTagPattern().accepts(psiElement)
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@
<fileBasedIndex implementation="fr.adrienbrault.idea.symfony2plugin.stubs.indexes.FormDataClassStubIndex"/>
<fileBasedIndex implementation="fr.adrienbrault.idea.symfony2plugin.stubs.indexes.SerializerClassUsageStubIndex"/>
<fileBasedIndex implementation="fr.adrienbrault.idea.symfony2plugin.stubs.indexes.UxTemplateStubIndex"/>
<fileBasedIndex implementation="fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigBlockEmbedIndex"/>

<codeInsight.lineMarkerProvider language="PHP" implementationClass="fr.adrienbrault.idea.symfony2plugin.config.ServiceLineMarkerProvider"/>
<codeInsight.lineMarkerProvider language="PHP" implementationClass="fr.adrienbrault.idea.symfony2plugin.dic.ControllerMethodLineMarkerProvider"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package fr.adrienbrault.idea.symfony2plugin.tests.stubs.indexes;

import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigBlockEmbedIndex;
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;

import java.util.Arrays;

/**
* @author Daniel Espendiller <[email protected]>
* @see fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigBlockEmbedIndex
*/
public class TwigBlockEmbedIndexTest extends SymfonyLightCodeInsightFixtureTestCase {
public void setUp() throws Exception {
super.setUp();

myFixture.copyFileToProject("blocks_embed.html.twig");
}

public String getTestDataPath() {
return "src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/fixtures";
}

public void testThatValuesAreInIndex() {
assertIndexContainsKeyWithValue(TwigBlockEmbedIndex.KEY, "teasers/skeleton.html.twig", value -> value.containsAll(Arrays.asList("left_teaser", "right_teaser")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% block foo %}
{% block foo_inner 'foo' %}
{% endblock %}

{{ block('foobar_print') }}

{% embed "teasers/skeleton.html.twig" %}
{% block left_teaser %}
{{ block('foobar_print_embed') }}
{% endblock %}
{% block right_teaser %}
{% endblock %}
{% endembed %}

{% extends 'extends/foo.html.twig' %}
{% use 'use/foo.html.twig' %}

{% embed "teasers\skeleton.html.twig" %}
{% extends 'embed_extends\foo.html.twig' %}
{% use 'embed_use\foo.html.twig' %}
{% endembed %}

0 comments on commit 04fb1ff

Please sign in to comment.