11package fr .adrienbrault .idea .symfony2plugin .templating .dict ;
22
33import com .intellij .openapi .vfs .VirtualFile ;
4+ import com .intellij .psi .PsiElement ;
45import com .intellij .psi .PsiFile ;
56import com .intellij .psi .PsiManager ;
7+ import com .intellij .psi .PsiRecursiveElementWalkingVisitor ;
8+ import com .intellij .psi .util .PsiTreeUtil ;
69import com .jetbrains .twig .TwigFile ;
10+ import com .jetbrains .twig .elements .TwigCompositeElement ;
11+ import com .jetbrains .twig .elements .TwigElementTypes ;
712import fr .adrienbrault .idea .symfony2plugin .TwigHelper ;
13+ import fr .adrienbrault .idea .symfony2plugin .templating .util .TwigUtil ;
14+ import fr .adrienbrault .idea .symfony2plugin .util .PsiElementUtils ;
15+ import org .apache .commons .lang .StringUtils ;
816import org .jetbrains .annotations .Nullable ;
917
10- import java .util .ArrayList ;
11- import java .util .List ;
12- import java .util .Map ;
18+ import java .util .*;
1319import java .util .regex .Matcher ;
1420import java .util .regex .Pattern ;
1521
1622public class TwigBlockParser {
1723
1824 public static String EXTENDS_TEMPLATE_NAME_PATTERN = "^[\\ s+]*\\ {%\\ s+extends[\\ s+]*['|\" ](.*?)['|\" ]" ;
1925
26+ private boolean withSelfBlock = false ;
27+
2028 private Map <String , VirtualFile > twigFilesByName ;
2129
2230 public TwigBlockParser (Map <String , VirtualFile > twigFilesByName ) {
@@ -36,7 +44,8 @@ public List<TwigBlock> walk(@Nullable PsiFile file, String shortcutName, List<Tw
3644 // @TODO: we dont use psielements here, check if Pattern faster or not
3745
3846 // dont match on self file !?
39- if (depth > 0 ) {
47+ if (depth > 0 || (withSelfBlock && depth == 0 )) {
48+ // @TODO: migrate to psi elements
4049 Matcher matcherBlocks = Pattern .compile ("\\ {%[\\ s+]*block[\\ s+]*(.*?)[\\ s+]*%}" ).matcher (file .getText ());
4150 while (matcherBlocks .find ()){
4251 current .add (new TwigBlock (matcherBlocks .group (1 ), shortcutName , file ));
@@ -48,20 +57,57 @@ public List<TwigBlock> walk(@Nullable PsiFile file, String shortcutName, List<Tw
4857 return current ;
4958 }
5059
60+ final Map <VirtualFile , String > virtualFiles = new HashMap <VirtualFile , String >();
61+
62+ // @TODO: migrate to psi elements
63+ // {% extends 'foo' %}
5164 // find extend in self
5265 Matcher matcher = Pattern .compile (EXTENDS_TEMPLATE_NAME_PATTERN ).matcher (file .getText ());
5366 while (matcher .find ()){
5467 String templateName = TwigHelper .normalizeTemplateName (matcher .group (1 ));
5568 if (twigFilesByName .containsKey (templateName )) {
56- VirtualFile virtualFile = twigFilesByName .get (templateName );
57- PsiFile psiFile = PsiManager .getInstance (file .getProject ()).findFile (virtualFile );
58- if (psiFile instanceof TwigFile ) {
59- this .walk (psiFile , matcher .group (1 ), current , depth );
60- }
69+ virtualFiles .put (twigFilesByName .get (templateName ), templateName );
70+ }
71+ }
72+
73+ // {% use 'foo' %}
74+ for (TwigCompositeElement twigCompositeElement : PsiTreeUtil .getChildrenOfTypeAsList (file , TwigCompositeElement .class )) {
75+ if (twigCompositeElement .getNode ().getElementType () == TwigElementTypes .TAG ) {
76+ twigCompositeElement .acceptChildren (new PsiRecursiveElementWalkingVisitor () {
77+ @ Override
78+ public void visitElement (PsiElement element ) {
79+
80+ if (TwigHelper .getTwigTagUseNamePattern ().accepts (element )) {
81+
82+ String templateName = PsiElementUtils .trimQuote (element .getText ());
83+ if (StringUtils .isNotBlank (templateName )) {
84+ String templateNameNormalized = TwigHelper .normalizeTemplateName (TwigHelper .normalizeTemplateName (templateName ));
85+ if (twigFilesByName .containsKey (templateNameNormalized )) {
86+ virtualFiles .put (twigFilesByName .get (templateName ), templateNameNormalized );
87+ }
88+ }
89+
90+ }
91+
92+ super .visitElement (element );
93+ }
94+ });
95+ }
96+ }
97+
98+ for (Map .Entry <VirtualFile , String > entry : virtualFiles .entrySet ()) {
99+ PsiFile psiFile = PsiManager .getInstance (file .getProject ()).findFile (entry .getKey ());
100+ if (psiFile instanceof TwigFile ) {
101+ this .walk (psiFile , TwigUtil .getFoldingTemplateNameOrCurrent (entry .getValue ()), current , depth );
61102 }
62103 }
63104
64105 return current ;
65106 }
66107
108+ public TwigBlockParser withSelfBlocks (boolean withSelfBlock ) {
109+ this .withSelfBlock = withSelfBlock ;
110+ return this ;
111+ }
112+
67113}
0 commit comments