33import com .intellij .lang .Language ;
44import com .intellij .lang .injection .MultiHostInjector ;
55import com .intellij .lang .injection .MultiHostRegistrar ;
6+ import com .intellij .patterns .PlatformPatterns ;
67import com .intellij .psi .PsiElement ;
78import com .intellij .psi .PsiLanguageInjectionHost ;
9+ import com .intellij .psi .PsiWhiteSpace ;
10+ import com .jetbrains .php .lang .documentation .phpdoc .lexer .PhpDocTokenTypes ;
11+ import com .jetbrains .php .lang .documentation .phpdoc .parser .PhpDocElementTypes ;
812import com .jetbrains .php .lang .documentation .phpdoc .psi .tags .PhpDocTag ;
913import com .jetbrains .php .lang .psi .elements .*;
1014import com .jetbrains .php .lang .psi .elements .impl .ParameterListImpl ;
@@ -53,7 +57,7 @@ public class ParameterLanguageInjector implements MultiHostInjector {
5357 new MethodCallArgumentLanguageInjection (LANGUAGE_ID_XPATH , XPATH_SIGNATURES ),
5458 new MethodCallArgumentLanguageInjection (LANGUAGE_ID_JSON , JSON_SIGNATURES ),
5559 new MethodCallArgumentLanguageInjection (LANGUAGE_ID_DQL , DQL_SIGNATURES ),
56- new MethodCallArgumentLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , EXPRESSION_LANGUAGE_SIGNATURES ),
60+ new MethodCallArgumentLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , EXPRESSION_LANGUAGE_SIGNATURES ),
5761 new NewExpressionLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Symfony\\ Component\\ ExpressionLanguage\\ Expression" , "expression" , 0 ),
5862 new FunctionCallArgumentLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Symfony\\ Component\\ DependencyInjection\\ Loader\\ Configurator\\ expr" , "expression" , 0 ),
5963 new AttributeLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Symfony\\ Component\\ Validator\\ Constraints\\ Expression" , "expression" , 0 ),
@@ -64,12 +68,13 @@ public class ParameterLanguageInjector implements MultiHostInjector {
6468 new AttributeLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Entity" , "expr" , 1 ),
6569 new AttributeLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ ParamConverter" , "expr" , 1 ),
6670 new AttributeLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Route" , "condition" , 9 ),
67- new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Symfony\\ Component\\ Routing\\ Annotation\\ Route" , "condition" ),
68- new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Security" , "expression" ),
69- new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Cache" , "lastModified" ),
70- new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Cache" , "Etag" ),
71- new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Entity" , "expr" ),
72- new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ ParamConverter" , "expr" ),
71+ new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Symfony\\ Component\\ Validator\\ Constraints\\ Expression" , "expression" , true ),
72+ new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Symfony\\ Component\\ Routing\\ Annotation\\ Route" , "condition" , false ),
73+ new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Security" , "expression" , true ),
74+ new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Cache" , "lastModified" , false ),
75+ new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Cache" , "Etag" , false ),
76+ new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ Entity" , "expr" , false ),
77+ new AnnotationLanguageInjection (LANGUAGE_ID_EXPRESSION_LANGUAGE , "\\ Sensio\\ Bundle\\ FrameworkExtraBundle\\ Configuration\\ ParamConverter" , "expr" , false ),
7378 };
7479
7580 public static final String LANGUAGE_ID_CSS = "CSS" ;
@@ -406,15 +411,17 @@ public static class AnnotationLanguageInjection extends LanguageInjection {
406411 private final String classFQN ;
407412 @ NotNull
408413 private final String propertyName ;
414+ private final boolean isDefaultProperty ;
409415
410- public AnnotationLanguageInjection (@ NotNull String languageId , @ NotNull String classFQN , @ NotNull String propertyName ) {
411- this (languageId , null , null , classFQN , propertyName );
416+ public AnnotationLanguageInjection (@ NotNull String languageId , @ NotNull String classFQN , @ NotNull String propertyName , boolean defaultProperty ) {
417+ this (languageId , null , null , classFQN , propertyName , defaultProperty );
412418 }
413419
414- public AnnotationLanguageInjection (@ NotNull String languageId , @ Nullable String prefix , @ Nullable String suffix , @ NotNull String classFQN , @ NotNull String propertyName ) {
420+ public AnnotationLanguageInjection (@ NotNull String languageId , @ Nullable String prefix , @ Nullable String suffix , @ NotNull String classFQN , @ NotNull String propertyName , boolean defaultProperty ) {
415421 super (languageId , prefix , suffix );
416422 this .classFQN = classFQN ;
417423 this .propertyName = propertyName ;
424+ this .isDefaultProperty = defaultProperty ;
418425 }
419426
420427 @ Override
@@ -427,11 +434,40 @@ public boolean accepts(@NotNull StringLiteralExpression element) {
427434
428435 var annotationClass = AnnotationUtil .getAnnotationReference (phpDocTag );
429436 if (annotationClass != null && annotationClass .getFQN ().equals (classFQN )) {
430- return element .equals (AnnotationUtil . getPropertyValueAsPsiElement (phpDocTag , propertyName ));
437+ return element .equals (getPropertyValuePsiElement (phpDocTag ));
431438 }
432439
433440 return false ;
434441 }
442+
443+ @ Nullable
444+ private PsiElement getPropertyValuePsiElement (@ NotNull PhpDocTag phpDocTag ) {
445+ PsiElement property = AnnotationUtil .getPropertyValueAsPsiElement (phpDocTag , propertyName );
446+
447+ if (property == null && isDefaultProperty ) {
448+ var phpDocAttrList = phpDocTag .getFirstPsiChild ();
449+ if (phpDocAttrList != null && phpDocAttrList .getNode ().getElementType () == PhpDocElementTypes .phpDocAttributeList ) {
450+ PhpPsiElement firstPhpPsiElement = phpDocAttrList .getFirstPsiChild ();
451+ if (firstPhpPsiElement instanceof StringLiteralExpression && !hasIdentifier (firstPhpPsiElement )) {
452+ property = firstPhpPsiElement ;
453+ }
454+ }
455+ }
456+
457+ return property ;
458+ }
459+
460+ private boolean hasIdentifier (@ NotNull PsiElement property ) {
461+ return PlatformPatterns .psiElement ()
462+ .afterLeafSkipping (
463+ PlatformPatterns .or (
464+ PlatformPatterns .psiElement (PsiWhiteSpace .class ),
465+ PlatformPatterns .psiElement (PhpDocTokenTypes .DOC_TEXT ).withText ("=" )
466+ ),
467+ PlatformPatterns .psiElement (PhpDocTokenTypes .DOC_IDENTIFIER )
468+ )
469+ .accepts (property );
470+ }
435471 }
436472
437473 private static class NewExpressionLanguageInjection extends LanguageInjection {
0 commit comments