Skip to content

Commit ff5a145

Browse files
committed
cleanup api for TwigBlock lookup elements
1 parent eea46d6 commit ff5a145

File tree

9 files changed

+85
-115
lines changed

9 files changed

+85
-115
lines changed

src/fr/adrienbrault/idea/symfony2plugin/templating/BlockGotoCompletionRegistrar.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,24 @@
66
import fr.adrienbrault.idea.symfony2plugin.codeInsight.GotoCompletionProvider;
77
import fr.adrienbrault.idea.symfony2plugin.codeInsight.GotoCompletionRegistrar;
88
import fr.adrienbrault.idea.symfony2plugin.codeInsight.GotoCompletionRegistrarParameter;
9-
import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigBlock;
10-
import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigBlockLookupElement;
119
import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigBlockParser;
1210
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
1311
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
1412
import org.apache.commons.lang.StringUtils;
1513
import org.jetbrains.annotations.NotNull;
1614

17-
import java.util.*;
15+
import java.util.Collection;
16+
import java.util.Collections;
17+
import java.util.HashSet;
1818
import java.util.stream.Collectors;
1919

2020
/**
21+
* {{ block('foo_block') }}
22+
*
2123
* @author Daniel Espendiller <daniel@espendiller.net>
2224
*/
2325
public class BlockGotoCompletionRegistrar implements GotoCompletionRegistrar {
24-
2526
public void register(@NotNull GotoCompletionRegistrarParameter registrar) {
26-
2727
// {{ block('foo_block') }}
2828
registrar.register(TwigPattern.getPrintBlockFunctionPattern("block"), psiElement -> {
2929
if (!Symfony2ProjectComponent.isEnabled(psiElement)) {
@@ -64,18 +64,10 @@ public Collection<PsiElement> getPsiTargets(PsiElement element) {
6464

6565
@NotNull
6666
public Collection<LookupElement> getLookupElements() {
67-
68-
Collection<LookupElement> lookupElements = new ArrayList<>();
69-
70-
List<String> uniqueList = new ArrayList<>();
71-
for (TwigBlock block : new TwigBlockParser(true).walk(getElement().getContainingFile())) {
72-
if(!uniqueList.contains(block.getName())) {
73-
uniqueList.add(block.getName());
74-
lookupElements.add(new TwigBlockLookupElement(block));
75-
}
76-
}
77-
78-
return lookupElements;
67+
return TwigUtil.getBlockLookupElements(
68+
getProject(),
69+
new TwigBlockParser(true).walk(getElement().getContainingFile())
70+
);
7971
}
8072
}
8173
}

src/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateCompletionContributor.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@
2525
import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper;
2626
import fr.adrienbrault.idea.symfony2plugin.templating.completion.QuotedInsertionLookupElement;
2727
import fr.adrienbrault.idea.symfony2plugin.templating.dict.*;
28-
import fr.adrienbrault.idea.symfony2plugin.twig.variable.globals.TwigGlobalEnum;
29-
import fr.adrienbrault.idea.symfony2plugin.twig.variable.globals.TwigGlobalVariable;
30-
import fr.adrienbrault.idea.symfony2plugin.twig.variable.globals.TwigGlobalsServiceParser;
3128
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigExtensionParser;
3229
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigTypeResolveUtil;
3330
import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil;
3431
import fr.adrienbrault.idea.symfony2plugin.templating.variable.TwigTypeContainer;
35-
import fr.adrienbrault.idea.symfony2plugin.twig.variable.collector.ControllerDocVariableCollector;
3632
import fr.adrienbrault.idea.symfony2plugin.templating.variable.dict.PsiVariable;
3733
import fr.adrienbrault.idea.symfony2plugin.translation.dict.TranslationUtil;
34+
import fr.adrienbrault.idea.symfony2plugin.twig.variable.collector.ControllerDocVariableCollector;
35+
import fr.adrienbrault.idea.symfony2plugin.twig.variable.globals.TwigGlobalEnum;
36+
import fr.adrienbrault.idea.symfony2plugin.twig.variable.globals.TwigGlobalVariable;
37+
import fr.adrienbrault.idea.symfony2plugin.twig.variable.globals.TwigGlobalsServiceParser;
3838
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
3939
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
4040
import fr.adrienbrault.idea.symfony2plugin.util.completion.FunctionInsertHandler;
@@ -45,7 +45,9 @@
4545
import org.apache.commons.lang.StringUtils;
4646
import org.jetbrains.annotations.NotNull;
4747

48-
import java.util.*;
48+
import java.util.Arrays;
49+
import java.util.List;
50+
import java.util.Map;
4951
import java.util.function.Function;
5052
import java.util.stream.Collectors;
5153

@@ -572,15 +574,10 @@ public void addCompletions(@NotNull CompletionParameters parameters, ProcessingC
572574
// collect blocks in all related files
573575
Pair<PsiFile[], Boolean> scopedContext = TwigUtil.findScopedFile(position);
574576

575-
Set<String> uniqueList = new HashSet<>();
576-
for (TwigBlock block : new TwigBlockParser(scopedContext.getSecond()).visit(scopedContext.getFirst())) {
577-
if(uniqueList.contains(block.getName())) {
578-
continue;
579-
}
580-
581-
uniqueList.add(block.getName());
582-
myResultSet.addElement(new TwigBlockLookupElement(block));
583-
}
577+
myResultSet.addAllElements(TwigUtil.getBlockLookupElements(
578+
position.getProject(),
579+
new TwigBlockParser(scopedContext.getSecond()).visit(scopedContext.getFirst())
580+
));
584581
}
585582
}
586583

src/fr/adrienbrault/idea/symfony2plugin/templating/TwigTemplateGoToDeclarationHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ static Collection<PsiElement> getBlockNameGoTo(PsiFile psiFile, String blockName
306306

307307
for (TwigBlock block : new TwigBlockParser(withSelfBlocks).walk(psiFile)) {
308308
if(block.getName().equals(blockName)) {
309-
Collections.addAll(psiElements, block.getBlock());
309+
Collections.addAll(psiElements, block.getTarget());
310310
}
311311
}
312312

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
package fr.adrienbrault.idea.symfony2plugin.templating.dict;
22

33
import com.intellij.psi.PsiElement;
4-
import com.intellij.psi.PsiFile;
54
import org.jetbrains.annotations.NotNull;
6-
import org.jetbrains.annotations.Nullable;
75

86
/**
97
* @author Daniel Espendiller <daniel@espendiller.net>
108
*/
119
public class TwigBlock {
12-
1310
@NotNull
1411
private String name;
1512

1613
@NotNull
1714
private final PsiElement target;
1815

19-
@Nullable
20-
private String shortcutName;
21-
2216
public TwigBlock(@NotNull String name, @NotNull PsiElement target) {
2317
this.name = name;
2418
this.target = target;
@@ -29,24 +23,9 @@ public String getName() {
2923
return name;
3024
}
3125

32-
@Nullable
33-
public String getShortcutName() {
34-
return shortcutName;
35-
}
36-
3726
@NotNull
38-
public PsiFile getPsiFile() {
39-
return target.getContainingFile();
40-
}
41-
42-
@NotNull
43-
public PsiElement[] getBlock() {
44-
return new PsiElement[] {target};
45-
}
46-
47-
public void setShortcutName(@Nullable String shortcutName) {
48-
// @TODO: remove this
49-
this.shortcutName = shortcutName;
27+
public PsiElement getTarget() {
28+
return target;
5029
}
5130
}
5231

src/fr/adrienbrault/idea/symfony2plugin/templating/dict/TwigBlockLookupElement.java

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/fr/adrienbrault/idea/symfony2plugin/templating/dict/TwigBlockParser.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
* @author Daniel Espendiller <daniel@espendiller.net>
2424
*/
2525
public class TwigBlockParser {
26-
2726
private boolean withSelfBlock = false;
2827

2928
public TwigBlockParser() {
@@ -38,32 +37,27 @@ public List<TwigBlock> visit(@NotNull PsiFile[] file) {
3837
List<TwigBlock> blocks = new ArrayList<>();
3938

4039
for (PsiFile psiFile : file) {
41-
blocks.addAll(walk(psiFile, psiFile.getName(), new ArrayList<>(), 0));
40+
blocks.addAll(walk(psiFile, new ArrayList<>(), 0));
4241
}
4342

4443
return blocks;
4544
}
4645

4746
@NotNull
4847
public List<TwigBlock> walk(@Nullable PsiFile file) {
49-
return walk(file, "self", new ArrayList<>(), 0);
48+
return walk(file, new ArrayList<>(), 0);
5049
}
5150

5251
@NotNull
53-
private List<TwigBlock> walk(@Nullable PsiFile file, String shortcutName, List<TwigBlock> current, int depth) {
52+
private List<TwigBlock> walk(@Nullable PsiFile file, @NotNull List<TwigBlock> current, int depth) {
5453
if(file == null) {
5554
return current;
5655
}
5756

5857
// dont match on self file !?
5958
if(depth > 0 || (withSelfBlock && depth == 0)) {
6059
if(file instanceof TwigFile) {
61-
Collection<TwigBlock> blocksInFile = TwigUtil.getBlocksInFile((TwigFile) file);
62-
// @TODO: remove this here just presentation
63-
for (TwigBlock twigBlock : blocksInFile) {
64-
twigBlock.setShortcutName(shortcutName);
65-
}
66-
current.addAll(blocksInFile);
60+
current.addAll(TwigUtil.getBlocksInFile((TwigFile) file));
6761
}
6862
}
6963

@@ -106,7 +100,6 @@ public void visitElement(PsiElement element) {
106100
}
107101

108102
for(Map.Entry<VirtualFile, String> entry : virtualFiles.entrySet()) {
109-
110103
// can be null if deleted during iteration
111104
VirtualFile key = entry.getKey();
112105
if(key == null) {
@@ -115,7 +108,7 @@ public void visitElement(PsiElement element) {
115108

116109
PsiFile psiFile = PsiManager.getInstance(file.getProject()).findFile(key);
117110
if(psiFile instanceof TwigFile) {
118-
walk(psiFile, entry.getValue(), current, depth);
111+
walk(psiFile, current, depth);
119112
}
120113
}
121114

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

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fr.adrienbrault.idea.symfony2plugin.templating.util;
22

33
import com.intellij.codeInsight.lookup.LookupElement;
4+
import com.intellij.codeInsight.lookup.LookupElementBuilder;
45
import com.intellij.openapi.extensions.ExtensionPointName;
56
import com.intellij.openapi.project.Project;
67
import com.intellij.openapi.util.Key;
@@ -58,6 +59,7 @@
5859
import fr.adrienbrault.idea.symfony2plugin.util.psi.PsiElementAssertUtil;
5960
import fr.adrienbrault.idea.symfony2plugin.util.service.ServiceXmlParserFactory;
6061
import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper;
62+
import icons.TwigIcons;
6163
import org.apache.commons.lang.StringUtils;
6264
import org.jetbrains.annotations.NotNull;
6365
import org.jetbrains.annotations.Nullable;
@@ -1208,8 +1210,13 @@ public static Collection<PsiElement> getTemplateTargetOnOffset(@NotNull Project
12081210
* "::test.html.twig"
12091211
*/
12101212
@NotNull
1211-
public static Collection<String> getTemplateNamesForFile(@NotNull TwigFile twigFile) {
1212-
return getTemplateNamesForFile(twigFile.getProject(), twigFile.getVirtualFile());
1213+
public static Collection<String> getTemplateNamesForFile(@NotNull PsiFile twigFile) {
1214+
VirtualFile virtualFile = twigFile.getVirtualFile();
1215+
if(virtualFile == null) {
1216+
return Collections.emptyList();
1217+
}
1218+
1219+
return getTemplateNamesForFile(twigFile.getProject(), virtualFile);
12131220
}
12141221

12151222
/**
@@ -1226,18 +1233,10 @@ public static Collection<String> getTemplateNamesForFile(@NotNull Project projec
12261233
.filter(TwigPath::isEnabled)
12271234
.collect(Collectors.toList());
12281235

1229-
Collection<String> templates = new ArrayList<>();
1230-
1231-
for (TwigPath twigPath : collect) {
1232-
String templateName = getTemplateNameForTwigPath(project, twigPath, virtualFile);
1233-
if(templateName == null) {
1234-
continue;
1235-
}
1236-
1237-
templates.add(templateName);
1238-
}
1239-
1240-
return templates;
1236+
return collect.stream()
1237+
.map(twigPath -> getTemplateNameForTwigPath(project, twigPath, virtualFile))
1238+
.filter(Objects::nonNull)
1239+
.collect(Collectors.toList());
12411240
}
12421241

12431242
@Nullable
@@ -2766,6 +2765,48 @@ private static Map<TwigFile, String> getExtendsTemplates(@NotNull TwigFile twigF
27662765
return templates;
27672766
}
27682767

2768+
/**
2769+
* Convert a given TwigBlock list into LookupElements
2770+
*/
2771+
@NotNull
2772+
public static Collection<LookupElement> getBlockLookupElements(@NotNull Project project, @NotNull Collection<TwigBlock> twigBlocks) {
2773+
Collection<LookupElement> lookupElements = new ArrayList<>();
2774+
2775+
Map<VirtualFile, Collection<String>> templateNames = new HashMap<>();
2776+
2777+
// dont visit a block twice
2778+
List<String> uniqueList = new ArrayList<>();
2779+
2780+
for (TwigBlock block : twigBlocks) {
2781+
if(uniqueList.contains(block.getName())) {
2782+
continue;
2783+
}
2784+
2785+
// add block name to known list
2786+
uniqueList.add(block.getName());
2787+
2788+
// performance optimize to not resolve too many elements
2789+
VirtualFile virtualFile = block.getTarget().getContainingFile().getVirtualFile();
2790+
if(virtualFile != null && !templateNames.containsKey(virtualFile)) {
2791+
templateNames.put(virtualFile, TwigUtil.getTemplateNamesForFile(project, virtualFile));
2792+
}
2793+
2794+
LookupElementBuilder lookupElementBuilder = LookupElementBuilder
2795+
.create(block.getName())
2796+
.withIcon(TwigIcons.TwigFileIcon);
2797+
2798+
// decorate with template name
2799+
Collection<String> names = templateNames.getOrDefault(virtualFile, Collections.emptyList());
2800+
if(names.size() > 0) {
2801+
lookupElementBuilder = lookupElementBuilder.withTypeText(names.iterator().next(), true);
2802+
}
2803+
2804+
lookupElements.add(lookupElementBuilder);
2805+
}
2806+
2807+
return lookupElements;
2808+
}
2809+
27692810
public static class DomainScope {
27702811
@NotNull
27712812
private final String defaultDomain;

tests/fr/adrienbrault/idea/symfony2plugin/tests/templating/dict/TwigBlockParserTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void testWalkWithSelf() {
7070

7171
List<TwigBlock> walk = new TwigBlockParser(true).walk(psiFile);
7272

73-
assertEquals(1, walk.stream().filter(twigBlock -> "foo".equals(twigBlock.getName()) && "self".equals(twigBlock.getShortcutName())).count());
73+
assertEquals(1, walk.stream().filter(twigBlock -> "foo".equals(twigBlock.getName())).count());
7474
assertNotNull(walk.stream().filter(twigBlock -> "foo1".equals(twigBlock.getName())).findFirst().get());
7575
}
7676
}

tests/fr/adrienbrault/idea/symfony2plugin/tests/templating/util/TwigUtilTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,7 @@ public void testBlocksInFileCollector() {
621621
assertEquals("foo", buildBlocks("{%- block \"foo\" -%}").iterator().next().getName());
622622
assertEquals("foo", buildBlocks("{%- block 'foo' -%}").iterator().next().getName());
623623

624-
assertNotNull(buildBlocks("{%- block 'foo' -%}").iterator().next().getPsiFile());
625-
assertSize(1, buildBlocks("{%- block 'foo' -%}").iterator().next().getBlock());
624+
assertNotNull(buildBlocks("{%- block 'foo' -%}").iterator().next().getTarget());
626625

627626
assertEquals("foobar_block", buildBlocks("{{ block('foobar_block') }}").iterator().next().getName());
628627
assertEquals("foobar_block", buildBlocks("{{ block(\"foobar_block\") }}").iterator().next().getName());

0 commit comments

Comments
 (0)