Skip to content

Commit

Permalink
Merge pull request #1994 from Haehnchen/feature/1990-attribute-autoco…
Browse files Browse the repository at this point in the history
…nfiure

#1991 support "tags" inside "Autoconfigure" attribute
  • Loading branch information
Haehnchen authored Jul 23, 2022
2 parents 29fddd9 + ddfa69c commit 628922f
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class ServiceContainerUtil {
public static final String TAGGED_ITERATOR_ATTRIBUTE_CLASS = "\\Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator";
public static final String TAGGED_LOCATOR_ATTRIBUTE_CLASS = "\\Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator";
public static final String DECORATOR_ATTRIBUTE_CLASS = "\\Symfony\\Component\\DependencyInjection\\Attribute\\AsDecorator";
public static final String AUTOCONFIGURE_ATTRIBUTE_CLASS = "\\Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure";

@NotNull
public static Collection<ServiceSerializable> getServicesInFile(@NotNull PsiFile psiFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,42 @@ public void register(@NotNull GotoCompletionRegistrarParameter registrar) {
}
);

// #[TaggedIterator('app.handler')] iterable $handlers
// #[TaggedLocator('app.handler')] ContainerInterface $handlers
registrar.register(
PlatformPatterns.or(
// #[TaggedIterator('app.handler')] iterable $handlers
// #[TaggedIterator(tag: 'app.handler')] iterable $handlers
PhpElementsUtil.getFirstAttributeStringPattern(ServiceContainerUtil.TAGGED_ITERATOR_ATTRIBUTE_CLASS),
PhpElementsUtil.getAttributeNamedArgumentStringPattern(ServiceContainerUtil.TAGGED_ITERATOR_ATTRIBUTE_CLASS, "tag"),

// #[TaggedLocator('app.handler')] ContainerInterface $handlers
// #[TaggedLocator(tag: 'app.handler')] ContainerInterface $handlers
PhpElementsUtil.getFirstAttributeStringPattern(ServiceContainerUtil.TAGGED_LOCATOR_ATTRIBUTE_CLASS),
PhpElementsUtil.getAttributeNamedArgumentStringPattern(ServiceContainerUtil.TAGGED_LOCATOR_ATTRIBUTE_CLASS, "tag")
PhpElementsUtil.getAttributeNamedArgumentStringPattern(ServiceContainerUtil.TAGGED_LOCATOR_ATTRIBUTE_CLASS, "tag"),

// #[Autoconfigure(['app.some_tag'])]
// #[Autoconfigure(tags: ['app.some_tag'])]
PhpElementsUtil.getFirstAttributeArrayStringPattern(ServiceContainerUtil.AUTOCONFIGURE_ATTRIBUTE_CLASS),
PhpElementsUtil.getAttributeNamedArgumentArrayStringPattern(ServiceContainerUtil.AUTOCONFIGURE_ATTRIBUTE_CLASS, "tags")
), psiElement -> {
PsiElement context = psiElement.getContext();
if (!(context instanceof StringLiteralExpression)) {
return null;
}

PhpAttribute phpAttribute = PsiTreeUtil.getParentOfType(context, PhpAttribute.class);
if (phpAttribute != null) {
return new TaggedIteratorContributor((StringLiteralExpression) context);
}

return null;
}
);

// #[Autoconfigure(tags: ['app.some_tag'])]
// #[Autoconfigure(['app.some_tag'])]
registrar.register(
PlatformPatterns.or(

), psiElement -> {
PsiElement context = psiElement.getContext();
if (!(context instanceof StringLiteralExpression)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ public boolean accepts(@NotNull FunctionReference functionReference, ProcessingC
.withLanguage(PhpLanguage.INSTANCE);
}

private static final PatternCondition<StringLiteralExpression> EMPTY_PREVIOUS_LEAF = new PatternCondition<>("previous leaf empty") {
private static final PatternCondition<PsiElement> EMPTY_PREVIOUS_LEAF = new PatternCondition<>("previous leaf empty") {
@Override
public boolean accepts(@NotNull StringLiteralExpression stringLiteralExpression, ProcessingContext context) {
public boolean accepts(@NotNull PsiElement stringLiteralExpression, ProcessingContext context) {
return stringLiteralExpression.getPrevSibling() == null;
}
};
Expand All @@ -408,6 +408,26 @@ public static PsiElementPattern.Capture<PsiElement> getFirstAttributeStringPatte
);
}

/**
* #[Security("is_granted(['POST_SHOW'])")]
*/
@NotNull
public static PsiElementPattern.Capture<PsiElement> getFirstAttributeArrayStringPattern(@NotNull String clazz) {
return PlatformPatterns.psiElement().withElementType(PlatformPatterns.elementType().or(
PhpTokenTypes.STRING_LITERAL_SINGLE_QUOTE,
PhpTokenTypes.STRING_LITERAL
))
.withParent(PlatformPatterns.psiElement(StringLiteralExpression.class)
.withParent(PlatformPatterns.psiElement(PhpElementTypes.ARRAY_VALUE).withParent(
PlatformPatterns.psiElement(ArrayCreationExpression.class).with(EMPTY_PREVIOUS_LEAF).withParent(PlatformPatterns.psiElement(ParameterList.class)
.withParent(PlatformPatterns.psiElement(PhpAttribute.class)
.with(new AttributeInstancePatternCondition(clazz))
)
)
))
);
}

/**
* #[Security(foobar: "is_granted('POST_SHOW')")]
*/
Expand All @@ -433,6 +453,33 @@ public static PsiElementPattern.Capture<PsiElement> getAttributeNamedArgumentStr
);
}

/**
* #[Security(tags: ['foobar']])]
*/
@NotNull
public static PsiElementPattern.Capture<PsiElement> getAttributeNamedArgumentArrayStringPattern(@NotNull String clazz, @NotNull String namedArgument) {
return PlatformPatterns.psiElement().withElementType(PlatformPatterns.elementType().or(
PhpTokenTypes.STRING_LITERAL_SINGLE_QUOTE,
PhpTokenTypes.STRING_LITERAL
))
.withParent(PlatformPatterns.psiElement(StringLiteralExpression.class)
.withParent(PlatformPatterns.psiElement(PhpElementTypes.ARRAY_VALUE).withParent(
PlatformPatterns.psiElement(ArrayCreationExpression.class).afterLeafSkipping(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(PhpTokenTypes.opCOLON).afterLeafSkipping(
PlatformPatterns.psiElement(PsiWhiteSpace.class),
PlatformPatterns.psiElement(PhpTokenTypes.IDENTIFIER).withText(namedArgument)
)
)
.withParent(PlatformPatterns.psiElement(ParameterList.class)
.withParent(PlatformPatterns.psiElement(PhpAttribute.class)
.with(new AttributeInstancePatternCondition(clazz))
)
)
))
);
}

/**
* Check if given Attribute
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,34 @@ public void testServiceContributorDecoratesAttribute() {
PlatformPatterns.psiElement()
);
}

public void testTagContributorForAutoconfigureTagsAttribute() {
assertCompletionContains(PhpFileType.INSTANCE, "<?php\n" +
"use Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure;\n" +
"#[Autoconfigure(['<caret>'])]\n" +
"class HandlerCollection {}",
"yaml_type_tag"
);

assertNavigationMatch(PhpFileType.INSTANCE, "<?php\n" +
"use Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure;\n" +
"#[Autoconfigure(['yaml_<caret>type_tag'])]\n" +
"class HandlerCollection {}",
PlatformPatterns.psiElement()
);

assertCompletionContains(PhpFileType.INSTANCE, "<?php\n" +
"use Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure;\n" +
"#[Autoconfigure(tags: ['<caret>'])]\n" +
"class HandlerCollection {}",
"yaml_type_tag"
);

assertNavigationMatch(PhpFileType.INSTANCE, "<?php\n" +
"use Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure;\n" +
"#[Autoconfigure(tags: ['yaml_<caret>type_tag'])]\n" +
"class HandlerCollection {}",
PlatformPatterns.psiElement()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ public function __construct(
) {
}
}

class Autoconfigure
{
public function __construct(
public ?array $tags = null,
public ?array $calls = null,
public ?array $bind = null,
public bool|string|null $lazy = null,
public ?bool $public = null,
public ?bool $shared = null,
public ?bool $autowire = null,
public ?array $properties = null,
public array|string|null $configurator = null,
) {
}
}
}

namespace
Expand Down

0 comments on commit 628922f

Please sign in to comment.