@@ -382,6 +382,74 @@ public boolean accepts(@NotNull FunctionReference functionReference, ProcessingC
382
382
.withLanguage (PhpLanguage .INSTANCE );
383
383
}
384
384
385
+ private static final PatternCondition <StringLiteralExpression > EMPTY_PREVIOUS_LEAF = new PatternCondition <>("previous leaf empty" ) {
386
+ @ Override
387
+ public boolean accepts (@ NotNull StringLiteralExpression stringLiteralExpression , ProcessingContext context ) {
388
+ return stringLiteralExpression .getPrevSibling () == null ;
389
+ }
390
+ };
391
+
392
+ /**
393
+ * #[Security("is_granted('POST_SHOW')")]
394
+ */
395
+ @ NotNull
396
+ public static PsiElementPattern .Capture <PsiElement > getFirstAttributeStringPattern (@ NotNull String clazz ) {
397
+ return PlatformPatterns .psiElement ().withElementType (PlatformPatterns .elementType ().or (
398
+ PhpTokenTypes .STRING_LITERAL_SINGLE_QUOTE ,
399
+ PhpTokenTypes .STRING_LITERAL
400
+ ))
401
+ .withParent (PlatformPatterns .psiElement (StringLiteralExpression .class )
402
+ .with (EMPTY_PREVIOUS_LEAF )
403
+ .withParent (PlatformPatterns .psiElement (ParameterList .class )
404
+ .withParent (PlatformPatterns .psiElement (PhpAttribute .class )
405
+ .with (new AttributeInstancePatternCondition (clazz ))
406
+ )
407
+ )
408
+ );
409
+ }
410
+
411
+ /**
412
+ * #[Security(foobar: "is_granted('POST_SHOW')")]
413
+ */
414
+ @ NotNull
415
+ public static PsiElementPattern .Capture <PsiElement > getAttributeNamedArgumentStringPattern (@ NotNull String clazz , @ NotNull String namedArgument ) {
416
+ return PlatformPatterns .psiElement ().withElementType (PlatformPatterns .elementType ().or (
417
+ PhpTokenTypes .STRING_LITERAL_SINGLE_QUOTE ,
418
+ PhpTokenTypes .STRING_LITERAL
419
+ ))
420
+ .withParent (PlatformPatterns .psiElement (StringLiteralExpression .class )
421
+ .afterLeafSkipping (
422
+ PlatformPatterns .psiElement (PsiWhiteSpace .class ),
423
+ PlatformPatterns .psiElement (PhpTokenTypes .opCOLON ).afterLeafSkipping (
424
+ PlatformPatterns .psiElement (PsiWhiteSpace .class ),
425
+ PlatformPatterns .psiElement (PhpTokenTypes .IDENTIFIER ).withText (namedArgument )
426
+ )
427
+ )
428
+ .withParent (PlatformPatterns .psiElement (ParameterList .class )
429
+ .withParent (PlatformPatterns .psiElement (PhpAttribute .class )
430
+ .with (new AttributeInstancePatternCondition (clazz ))
431
+ )
432
+ )
433
+ );
434
+ }
435
+
436
+ /**
437
+ * Check if given Attribute
438
+ */
439
+ private static class AttributeInstancePatternCondition extends PatternCondition <PsiElement > {
440
+ private final String clazz ;
441
+
442
+ AttributeInstancePatternCondition (@ NotNull String clazz ) {
443
+ super ("Attribute Instance" );
444
+ this .clazz = clazz ;
445
+ }
446
+
447
+ @ Override
448
+ public boolean accepts (@ NotNull PsiElement psiElement , ProcessingContext processingContext ) {
449
+ return clazz .equals (((PhpAttribute ) psiElement ).getFQN ());
450
+ }
451
+ }
452
+
385
453
/**
386
454
* $foo->bar('<caret>')
387
455
*/
0 commit comments