Skip to content

Commit 39dd098

Browse files
committed
provide root variable completion and support doc block detection inside file scope
1 parent b072af7 commit 39dd098

File tree

2 files changed

+80
-2
lines changed

2 files changed

+80
-2
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.intellij.psi.PsiElement;
1010
import com.intellij.psi.PsiWhiteSpace;
1111
import com.intellij.util.ProcessingContext;
12+
import com.jetbrains.php.PhpIcons;
1213
import com.jetbrains.php.lang.psi.elements.Method;
1314
import com.jetbrains.php.lang.psi.elements.PhpClass;
1415
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
@@ -37,6 +38,7 @@
3738

3839
import java.util.ArrayList;
3940
import java.util.Arrays;
41+
import java.util.HashMap;
4042
import java.util.Map;
4143

4244
/**
@@ -243,6 +245,10 @@ public void addCompletions(@NotNull CompletionParameters parameters,
243245
resultSet.addElement(LookupElementBuilder.create(twigSet.getName()).withTypeText("set"));
244246
}
245247

248+
for(Map.Entry<String,String> entry: TwigTypeResolveUtil.collectorRootScopeVariables(psiElement).entrySet()) {
249+
resultSet.addElement(LookupElementBuilder.create(entry.getKey()).withTypeText(entry.getValue()).withIcon(PhpIcons.CLASS));
250+
}
251+
246252
}
247253
}
248254

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

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@
44
import com.intellij.patterns.PlatformPatterns;
55
import com.intellij.psi.PsiComment;
66
import com.intellij.psi.PsiElement;
7+
import com.intellij.psi.PsiFile;
78
import com.intellij.psi.PsiWhiteSpace;
89
import com.intellij.psi.util.PsiTreeUtil;
910
import com.jetbrains.php.lang.psi.elements.Method;
1011
import com.jetbrains.php.lang.psi.elements.PhpClass;
1112
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
1213
import com.jetbrains.php.lang.psi.resolve.types.PhpType;
14+
import com.jetbrains.twig.TwigFile;
1315
import com.jetbrains.twig.elements.TwigCompositeElement;
1416
import com.jetbrains.twig.elements.TwigElementTypes;
17+
import fr.adrienbrault.idea.symfony2plugin.TwigHelper;
1518
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
19+
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
20+
import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper;
1621

1722
import java.util.ArrayList;
1823
import java.util.Collection;
@@ -43,7 +48,7 @@ public static String[] formatPsiTypeName(PsiElement psiElement) {
4348
public static Collection<? extends PhpNamedElement> resolveTwigMethodName(PsiElement psiElement, String[] typeName) {
4449

4550
if(typeName.length == 0) {
46-
return null;
51+
return Collections.emptyList();
4752
}
4853

4954
Collection<? extends PhpNamedElement> rootVariable = getRootVariableByName(psiElement, typeName[0]);
@@ -101,13 +106,80 @@ public boolean value(PsiElement psiElement) {
101106
return null;
102107
}
103108

109+
/**
110+
* duplicate use a collector interface
111+
*/
112+
private static HashMap<String, String> findInlineVariableDocBlock(PsiElement psiInsideBlock) {
113+
114+
PsiElement twigCompositeElement = PsiTreeUtil.findFirstParent(psiInsideBlock, new Condition<PsiElement>() {
115+
@Override
116+
public boolean value(PsiElement psiElement) {
117+
if (psiElement instanceof TwigCompositeElement) {
118+
if (PlatformPatterns.psiElement(TwigElementTypes.BLOCK_STATEMENT).accepts(psiElement)) {
119+
return true;
120+
}
121+
}
122+
return false;
123+
}
124+
});
125+
126+
Pattern pattern = Pattern.compile("\\{#[\\s]+([\\w]+)[\\s]+(.*)[\\s]+#}");
127+
128+
// wtf in completion { | } root we have no comments in child context !?
129+
HashMap<String, String> variables = new HashMap<String, String>();
130+
for(PsiElement psiComment: YamlHelper.getChildrenFix(twigCompositeElement)) {
131+
if(psiComment instanceof PsiComment) {
132+
Matcher matcher = pattern.matcher(psiComment.getText());
133+
if (matcher.find()) {
134+
variables.put(matcher.group(1), matcher.group(2));
135+
}
136+
}
137+
}
138+
139+
return variables;
140+
}
141+
142+
/**
143+
* duplicate use a collector interface
144+
*/
145+
private static HashMap<String, String> findFileVariableDocBlock(TwigFile twigFile) {
146+
147+
Pattern pattern = Pattern.compile("\\{#[\\s]+([\\w]+)[\\s]+(.*)[\\s]+#}");
148+
149+
// wtf in completion { | } root we have no comments in child context !?
150+
HashMap<String, String> variables = new HashMap<String, String>();
151+
for(PsiElement psiComment: YamlHelper.getChildrenFix(twigFile)) {
152+
if(psiComment instanceof PsiComment) {
153+
Matcher matcher = pattern.matcher(psiComment.getText());
154+
if (matcher.find()) {
155+
variables.put(matcher.group(1), matcher.group(2));
156+
}
157+
}
158+
}
159+
160+
return variables;
161+
}
162+
163+
public static HashMap<String, String> collectorRootScopeVariables(PsiElement psiElement) {
164+
165+
HashMap<String, String> globalVars = new HashMap<String, String>();
166+
globalVars.put("app", "\\Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables");
167+
168+
globalVars.putAll(findInlineVariableDocBlock(psiElement));
169+
170+
globalVars.putAll(findFileVariableDocBlock((TwigFile) psiElement.getContainingFile()));
171+
172+
return globalVars;
173+
}
174+
104175
private static Collection<? extends PhpNamedElement> getRootVariableByName(PsiElement psiElement, String variableName) {
105176

106177
HashMap<String, String> globalVars = new HashMap<String, String>();
178+
107179
globalVars.put("app", "\\Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables");
180+
globalVars.putAll(findFileVariableDocBlock((TwigFile) psiElement.getContainingFile()));
108181

109182
ArrayList<PhpNamedElement> phpNamedElements = new ArrayList<PhpNamedElement>();
110-
111183
// parameter prio?
112184
if(globalVars.containsKey(variableName)) {
113185
PhpClass phpClass = PhpElementsUtil.getClass(psiElement.getProject(), globalVars.get(variableName));

0 commit comments

Comments
 (0)