5959
6060import java .util .*;
6161import java .util .function .Function ;
62+ import java .util .function .Predicate ;
6263import java .util .stream .Collectors ;
6364
6465/**
@@ -440,6 +441,13 @@ public void addCompletions(@NotNull CompletionParameters parameters, ProcessingC
440441 PlatformPatterns .psiElement (TwigTokenTypes .TAG_NAME ),
441442 new IncompleteForCompletionProvider ()
442443 );
444+
445+ // {% if => "if app.debug"
446+ extend (
447+ CompletionType .BASIC ,
448+ PlatformPatterns .psiElement (TwigTokenTypes .TAG_NAME ),
449+ new IncompleteIfCompletionProvider ()
450+ );
443451 }
444452
445453 private boolean isCompletionStartingMatch (@ NotNull String fullText , @ NotNull CompletionParameters completionParameters , int minLength ) {
@@ -821,7 +829,7 @@ public boolean accepts(@NotNull String s, ProcessingContext processingContext) {
821829 private class IncompleteForCompletionProvider extends CompletionProvider <CompletionParameters > {
822830 @ Override
823831 protected void addCompletions (@ NotNull CompletionParameters completionParameters , @ NotNull ProcessingContext processingContext , @ NotNull CompletionResultSet resultSet ) {
824- if (!Symfony2ProjectComponent .isEnabled (completionParameters .getPosition ())) {
832+ if (!Symfony2ProjectComponent .isEnabled (completionParameters .getPosition ())) {
825833 return ;
826834 }
827835
@@ -836,59 +844,99 @@ public boolean accepts(@NotNull String s, ProcessingContext processingContext) {
836844 return ;
837845 }
838846
839- Set <Map .Entry <String , PsiVariable >> entries = TwigTypeResolveUtil .collectScopeVariables (completionParameters .getPosition ()).entrySet ();
847+ resultSet .addAllElements (processVariables (
848+ completionParameters .getPosition (),
849+ PhpType ::isArray ,
850+ pair -> {
851+ String var = pair .getValue ().getFirst ();
852+ String unpluralize = StringUtil .unpluralize (var );
853+ if (unpluralize != null ) {
854+ var = unpluralize ;
855+ }
840856
841- Map <String , Pair <String , LookupElement >> arrays = new HashMap <>();
857+ return String .format ("for %s in %s" , var , pair .getKey ());
858+ }
859+ ));
860+ }
861+ }
842862
843- Project project = completionParameters .getPosition ().getProject ();
863+ /**
864+ * {% if => "if app.debug"
865+ */
866+ private class IncompleteIfCompletionProvider extends CompletionProvider <CompletionParameters > {
867+ @ Override
868+ protected void addCompletions (@ NotNull CompletionParameters completionParameters , @ NotNull ProcessingContext processingContext , @ NotNull CompletionResultSet resultSet ) {
869+ if (!Symfony2ProjectComponent .isEnabled (completionParameters .getPosition ())) {
870+ return ;
871+ }
844872
845- for (Map .Entry <String , PsiVariable > entry : entries ) {
846- Collection <PhpClass > classFromPhpTypeSet = PhpElementsUtil .getClassFromPhpTypeSet (project , entry .getValue ().getTypes ());
847- for (PhpClass phpClass : classFromPhpTypeSet ) {
848- for (Method method : phpClass .getMethods ()) {
849- if (!(!method .getModifier ().isPublic () || method .getName ().startsWith ("set" ) || method .getName ().startsWith ("__" ))) {
850- if (PhpType .isArray (PhpIndex .getInstance (project ).completeType (project , method .getType (), new HashSet <>()))) {
851- String propertyShortcutMethodName = TwigTypeResolveUtil .getPropertyShortcutMethodName (method );
852- arrays .put (entry .getKey () + "." + propertyShortcutMethodName , Pair .create (propertyShortcutMethodName , new PhpTwigMethodLookupElement (method )));
853- }
873+ resultSet .restartCompletionOnPrefixChange (StandardPatterns .string ().longerThan (1 ).with (new PatternCondition <>("if startsWith" ) {
874+ @ Override
875+ public boolean accepts (@ NotNull String s , ProcessingContext processingContext ) {
876+ return "if" .startsWith (s );
877+ }
878+ }));
879+
880+ if (!isCompletionStartingMatch ("if" , completionParameters , 2 )) {
881+ return ;
882+ }
883+
884+ resultSet .addAllElements (processVariables (
885+ completionParameters .getPosition (),
886+ PhpType ::isBoolean ,
887+ entry -> String .format ("if %s" , entry .getKey ())
888+ ));
889+ }
890+ }
891+
892+ @ NotNull
893+ private Collection <LookupElement > processVariables (@ NotNull PsiElement psiElement , @ NotNull Predicate <PhpType > filter , @ NotNull Function <Map .Entry <String , Pair <String , LookupElement >>, String > map ) {
894+ Project project = psiElement .getProject ();
895+
896+ Map <String , Pair <String , LookupElement >> arrays = new HashMap <>();
897+ for (Map .Entry <String , PsiVariable > entry : TwigTypeResolveUtil .collectScopeVariables (psiElement ).entrySet ()) {
898+ Collection <PhpClass > classFromPhpTypeSet = PhpElementsUtil .getClassFromPhpTypeSet (project , entry .getValue ().getTypes ());
899+ for (PhpClass phpClass : classFromPhpTypeSet ) {
900+ for (Method method : phpClass .getMethods ()) {
901+ if (!(!method .getModifier ().isPublic () || method .getName ().startsWith ("set" ) || method .getName ().startsWith ("__" ))) {
902+ if (filter .test (PhpIndex .getInstance (project ).completeType (project , method .getType (), new HashSet <>()))) {
903+ String propertyShortcutMethodName = TwigTypeResolveUtil .getPropertyShortcutMethodName (method );
904+ arrays .put (entry .getKey () + "." + propertyShortcutMethodName , Pair .create (propertyShortcutMethodName , new PhpTwigMethodLookupElement (method )));
854905 }
855906 }
907+ }
856908
857- for (Field field : phpClass .getFields ()) {
858- if (field .getModifier ().isPublic ()) {
859- if (PhpType .isArray (PhpIndex .getInstance (project ).completeType (project , field .getType (), new HashSet <>()))) {
860- arrays .put (entry .getKey () + "." + field .getName (), Pair .create (field .getName (), new PhpTwigMethodLookupElement (field )));
861- }
909+ for (Field field : phpClass .getFields ()) {
910+ if (field .getModifier ().isPublic ()) {
911+ if (filter .test (PhpIndex .getInstance (project ).completeType (project , field .getType (), new HashSet <>()))) {
912+ arrays .put (entry .getKey () + "." + field .getName (), Pair .create (field .getName (), new PhpTwigMethodLookupElement (field )));
862913 }
863914 }
864915 }
865916 }
917+ }
866918
867- for (Map .Entry <String , Pair <String , LookupElement >> entry : arrays .entrySet ()) {
868- String var = entry .getValue ().getFirst ();
869- String unpluralize = StringUtil .unpluralize (var );
870- if (unpluralize != null ) {
871- var = unpluralize ;
872- }
919+ Collection <LookupElement > items = new ArrayList <>();
873920
874- LookupElementPresentation lookupElementPresentation = new LookupElementPresentation ();
875- entry .getValue ().getSecond ().renderElement (lookupElementPresentation );
921+ for (Map .Entry <String , Pair <String , LookupElement >> entry : arrays .entrySet ()) {
922+ LookupElementPresentation lookupElementPresentation = new LookupElementPresentation ();
923+ entry .getValue ().getSecond ().renderElement (lookupElementPresentation );
876924
877- Set <String > types = new HashSet <>();
878- PsiElement psiElement = entry .getValue ().getSecond ().getPsiElement ();
879- if (psiElement instanceof PhpTypedElement ) {
880- types .addAll (((PhpTypedElement ) psiElement ).getType ().getTypes ());
881- }
925+ Set <String > types = new HashSet <>();
926+ PsiElement typeElement = entry .getValue ().getSecond ().getPsiElement ();
927+ if (typeElement instanceof PhpTypedElement ) {
928+ types .addAll (((PhpTypedElement ) typeElement ).getType ().getTypes ());
929+ }
882930
883- String content = String .format ("for %s in %s" , var , entry .getKey ());
884- LookupElementBuilder lookupElement = LookupElementBuilder .create (content )
885- .withIcon (lookupElementPresentation .getIcon ())
886- .withStrikeoutness (lookupElementPresentation .isStrikeout ())
887- .withTypeText (StringUtils .stripStart (TwigTypeResolveUtil .getTypeDisplayName (project , types ), "\\ " ));
931+ LookupElementBuilder lookupElement = LookupElementBuilder .create (map .apply (entry ))
932+ .withIcon (lookupElementPresentation .getIcon ())
933+ .withStrikeoutness (lookupElementPresentation .isStrikeout ())
934+ .withTypeText (StringUtils .stripStart (TwigTypeResolveUtil .getTypeDisplayName (project , types ), "\\ " ));
888935
889- resultSet .addElement (lookupElement );
890- }
936+ items .add (lookupElement );
891937 }
938+
939+ return items ;
892940 }
893941}
894942
0 commit comments