Skip to content

Commit 7df1e88

Browse files
committed
Attach metadata to resource-based services in resolver, Pipe autoconfigure flag
1 parent 7da2282 commit 7df1e88

File tree

15 files changed

+229
-11
lines changed

15 files changed

+229
-11
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/ContainerService.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import java.util.Collections;
99
import java.util.HashSet;
10+
import java.util.LinkedHashSet;
11+
import java.util.List;
1012
import java.util.Set;
1113

1214
/**
@@ -23,8 +25,11 @@ public class ContainerService {
2325
private boolean isPrivate = false;
2426
private boolean isWeak = false;
2527
private final Set<String> classVariants = new HashSet<>();
28+
private final Set<ContainerServiceMetadata> metadata = new LinkedHashSet<>();
2629
@Nullable
2730
private Set<String> cachedClassNames;
31+
@Nullable
32+
private Boolean cachedMetadataAutowire;
2833

2934
public ContainerService(@NotNull ServiceInterface service, @Nullable String classResolved) {
3035
this.service = new MemoryReducedCollectionService(service);
@@ -63,6 +68,18 @@ public void addClassName(@NotNull String className) {
6368
this.cachedClassNames = null;
6469
}
6570

71+
public void addMetadata(@NotNull ContainerServiceMetadata metadata) {
72+
if (this.metadata.add(metadata)) {
73+
this.cachedMetadataAutowire = null;
74+
}
75+
}
76+
77+
public void addMetadata(@NotNull Iterable<ContainerServiceMetadata> metadata) {
78+
for (ContainerServiceMetadata containerServiceMetadata : metadata) {
79+
addMetadata(containerServiceMetadata);
80+
}
81+
}
82+
6683
@NotNull
6784
public Set<String> getClassNames() {
6885
if (cachedClassNames != null) {
@@ -93,6 +110,29 @@ public String getName() {
93110
return name;
94111
}
95112

113+
@NotNull
114+
public List<ContainerServiceMetadata> getMetadata() {
115+
return List.copyOf(metadata);
116+
}
117+
118+
public boolean isAutowireEnabled() {
119+
if (service != null && service.isAutowire()) {
120+
return true;
121+
}
122+
123+
if (cachedMetadataAutowire != null) {
124+
return cachedMetadataAutowire;
125+
}
126+
127+
for (ContainerServiceMetadata containerServiceMetadata : metadata) {
128+
if (containerServiceMetadata.autowire()) {
129+
return cachedMetadataAutowire = true;
130+
}
131+
}
132+
133+
return cachedMetadataAutowire = false;
134+
}
135+
96136
/**
97137
* legacy support
98138
*/
@@ -101,4 +141,3 @@ public ServiceInterface getService() {
101141
return service;
102142
}
103143
}
104-
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package fr.adrienbrault.idea.symfony2plugin.dic;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
6+
import java.util.Collection;
7+
import java.util.Collections;
8+
import java.util.LinkedHashSet;
9+
import java.util.Set;
10+
11+
/**
12+
* Carries service metadata for one contributing definition so ContainerService can keep
13+
* multiple sources side by side; any merged view is computed by the consumer later.
14+
*
15+
* @author Daniel Espendiller <daniel@espendiller.net>
16+
*/
17+
public record ContainerServiceMetadata(
18+
// Optional resource/prototype definition id that expanded this class, eg "App\\"
19+
@Nullable String resourceServiceId,
20+
boolean autowire,
21+
boolean autoconfigure,
22+
@NotNull Set<String> tags,
23+
// Raw resource glob patterns from the contributing resource/prototype definition
24+
@NotNull Set<String> resource,
25+
// Raw exclude patterns from the contributing resource/prototype definition
26+
@NotNull Set<String> exclude,
27+
@NotNull SourceKind sourceKind
28+
) {
29+
public ContainerServiceMetadata(
30+
@Nullable String resourceServiceId,
31+
boolean autowire,
32+
boolean autoconfigure,
33+
@NotNull Collection<String> tags,
34+
@NotNull Collection<String> resource,
35+
@NotNull Collection<String> exclude,
36+
@NotNull SourceKind sourceKind
37+
) {
38+
this(
39+
resourceServiceId,
40+
autowire,
41+
autoconfigure,
42+
normalize(tags),
43+
normalize(resource),
44+
normalize(exclude),
45+
sourceKind
46+
);
47+
}
48+
49+
private static Set<String> normalize(@NotNull Collection<String> values) {
50+
return values.isEmpty()
51+
? Collections.emptySet()
52+
: Collections.unmodifiableSet(new LinkedHashSet<>(values));
53+
}
54+
55+
public enum SourceKind {
56+
RESOURCE_PROTOTYPE
57+
}
58+
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/ImmutableDecoratorService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public boolean isAutowire() {
4545
return service.isAutowire();
4646
}
4747

48+
@Override
49+
public boolean isAutoconfigure() {
50+
return service.isAutoconfigure();
51+
}
52+
4853
@Override
4954
public boolean isDeprecated() {
5055
return service.isDeprecated();

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/MemoryReducedCollectionService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class MemoryReducedCollectionService implements ServiceInterface {
1818
private final boolean lazy;
1919
private final boolean isAbstract;
2020
private final boolean autowire;
21+
private final boolean autoconfigure;
2122
private final Collection<String> tags;
2223
private final Collection<String> exclude;
2324
private final Collection<String> resource;
@@ -40,6 +41,7 @@ public MemoryReducedCollectionService(@NotNull ServiceInterface serviceInterface
4041
this.lazy = serviceInterface.isLazy();
4142
this.isAbstract = serviceInterface.isAbstract();
4243
this.autowire = serviceInterface.isAutowire();
44+
this.autoconfigure = serviceInterface.isAutoconfigure();
4345
this.decorationInnerName = serviceInterface.getDecorationInnerName();
4446
this.decorates = serviceInterface.getDecorates();
4547
this.parent = serviceInterface.getParent();
@@ -82,6 +84,11 @@ public boolean isAutowire() {
8284
return this.autowire;
8385
}
8486

87+
@Override
88+
public boolean isAutoconfigure() {
89+
return this.autoconfigure;
90+
}
91+
8592
@Override
8693
public boolean isDeprecated() {
8794
return this.deprecated;

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/SerializableService.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ public class SerializableService implements ServiceSerializable {
3939
@Nullable
4040
private Boolean isAutowire;
4141

42+
@SerializedName("autoconfigure")
43+
@Nullable
44+
private Boolean isAutoconfigure;
45+
4246
@SerializedName("deprecated")
4347
@Nullable
4448
private Boolean isDeprecated;
@@ -144,6 +148,21 @@ public SerializableService setIsAutowire(@Nullable Boolean isAutowire) {
144148
return this;
145149
}
146150

151+
@Override
152+
public boolean isAutoconfigure() {
153+
return isAutoconfigure != null ? isAutoconfigure : false;
154+
}
155+
156+
@Nullable
157+
public Boolean isAutoconfigureNullable() {
158+
return isAutoconfigure;
159+
}
160+
161+
public SerializableService setIsAutoconfigure(@Nullable Boolean isAutoconfigure) {
162+
this.isAutoconfigure = isAutoconfigure;
163+
return this;
164+
}
165+
147166
@Override
148167
public boolean isDeprecated() {
149168
return isDeprecated != null ? isDeprecated : false;
@@ -251,6 +270,7 @@ public int hashCode() {
251270
.append(this.isLazy)
252271
.append(this.isAbstract)
253272
.append(this.isAutowire)
273+
.append(this.isAutoconfigure)
254274
.append(this.isDeprecated)
255275
.append(this.alias)
256276
.append(this.decorates)
@@ -272,6 +292,7 @@ public boolean equals(Object obj) {
272292
Objects.equals(((SerializableService) obj).isLazy, this.isLazy) &&
273293
Objects.equals(((SerializableService) obj).isAbstract, this.isAbstract) &&
274294
Objects.equals(((SerializableService) obj).isAutowire, this.isAutowire) &&
295+
Objects.equals(((SerializableService) obj).isAutoconfigure, this.isAutoconfigure) &&
275296
Objects.equals(((SerializableService) obj).isDeprecated, this.isDeprecated) &&
276297
Objects.equals(((SerializableService) obj).alias, this.alias) &&
277298
Objects.equals(((SerializableService) obj).decorates, this.decorates) &&

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/ServiceInterface.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public interface ServiceInterface {
2222

2323
boolean isAutowire();
2424

25+
boolean isAutoconfigure();
26+
2527
boolean isDeprecated();
2628

2729
boolean isPublic();

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/XmlService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ public boolean isAutowire() {
6262
return false;
6363
}
6464

65+
@Override
66+
public boolean isAutoconfigure() {
67+
return false;
68+
}
69+
6570
@Override
6671
public boolean isDeprecated() {
6772
return false;

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/dict/ServiceFileDefaults.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@ public class ServiceFileDefaults {
1515
@Nullable
1616
final private Boolean isAutowire;
1717

18+
@Nullable
19+
final private Boolean isAutoconfigure;
20+
1821
private ServiceFileDefaults() {
1922
isPublic = null;
2023
isAutowire = null;
24+
isAutoconfigure = null;
2125
}
2226

23-
public ServiceFileDefaults(@Nullable Boolean isPublic, @Nullable Boolean isAutowire) {
27+
public ServiceFileDefaults(@Nullable Boolean isPublic, @Nullable Boolean isAutowire, @Nullable Boolean isAutoconfigure) {
2428
this.isPublic = isPublic;
2529
this.isAutowire = isAutowire;
30+
this.isAutoconfigure = isAutoconfigure;
2631
}
2732

2833
@Nullable
@@ -34,4 +39,9 @@ public Boolean isPublic() {
3439
public Boolean isAutowire() {
3540
return isAutowire;
3641
}
42+
43+
@Nullable
44+
public Boolean isAutoconfigure() {
45+
return isAutoconfigure;
46+
}
3747
}

src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/container/util/ServiceContainerUtil.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public static Collection<ServiceSerializable> getServicesInFile(@NotNull PsiFile
120120
new SerializableService(serviceConsumer.getServiceId())
121121
.setAlias(valueText.substring(1))
122122
.setIsAutowire(serviceConsumer.getDefaults().isAutowire())
123+
.setIsAutoconfigure(serviceConsumer.getDefaults().isAutoconfigure())
123124
.setIsPublic(serviceConsumer.getDefaults().isPublic())
124125
);
125126
return;
@@ -164,7 +165,8 @@ private static ServiceFileDefaults createDefaults(@NotNull YAMLFile psiFile) {
164165
if(yamlKeyValueDefaults != null) {
165166
return new ServiceFileDefaults(
166167
YamlHelper.getYamlKeyValueAsBoolean(yamlKeyValueDefaults, "public"),
167-
YamlHelper.getYamlKeyValueAsBoolean(yamlKeyValueDefaults, "autowire")
168+
YamlHelper.getYamlKeyValueAsBoolean(yamlKeyValueDefaults, "autowire"),
169+
YamlHelper.getYamlKeyValueAsBoolean(yamlKeyValueDefaults, "autoconfigure")
168170
);
169171
}
170172

@@ -214,6 +216,7 @@ private static SerializableService createService(@NotNull ServiceConsumer servic
214216
.setParent(attributes.getString("parent"))
215217
.setIsAbstract(anAbstract)
216218
.setIsAutowire(attributes.getBoolean("autowire", serviceConsumer.getDefaults().isAutowire()))
219+
.setIsAutoconfigure(attributes.getBoolean("autoconfigure", serviceConsumer.getDefaults().isAutoconfigure()))
217220
.setIsLazy(attributes.getBoolean("lazy"))
218221
.setIsPublic(attributes.getBoolean("public", serviceConsumer.getDefaults().isPublic()))
219222
.setResource(attributes.getStringArray("resource"))
@@ -601,19 +604,21 @@ private static ServiceFileDefaults createFluentDefaults(@NotNull Function functi
601604
for (MethodReference defaultsRef : PhpElementsUtil.collectMethodReferencesInsideControlFlow(function, "defaults")) {
602605
Boolean isPublic = null;
603606
Boolean isAutowire = null;
607+
Boolean isAutoconfigure = null;
604608

605609
PsiElement parent = defaultsRef.getParent();
606610
while (parent instanceof MethodReference chainedMethod) {
607611
PsiElement[] params = chainedMethod.getParameters();
608612
switch (StringUtils.defaultString(chainedMethod.getName())) {
609613
case "autowire" -> isAutowire = extractFluentBooleanParam(params, true);
614+
case "autoconfigure" -> isAutoconfigure = extractFluentBooleanParam(params, true);
610615
case "public" -> isPublic = extractFluentBooleanParam(params, true);
611616
case "private" -> isPublic = false;
612617
}
613618
parent = parent.getParent();
614619
}
615620

616-
return new ServiceFileDefaults(isPublic, isAutowire);
621+
return new ServiceFileDefaults(isPublic, isAutowire, isAutoconfigure);
617622
}
618623

619624
return ServiceFileDefaults.EMPTY;
@@ -705,6 +710,7 @@ private static void collectFluentChainAttributes(
705710
case "public" -> keyValue.put("public", String.valueOf(extractFluentBooleanParam(params, true)));
706711
case "private" -> keyValue.put("public", "false");
707712
case "autowire" -> keyValue.put("autowire", String.valueOf(extractFluentBooleanParam(params, true)));
713+
case "autoconfigure" -> keyValue.put("autoconfigure", String.valueOf(extractFluentBooleanParam(params, true)));
708714
case "lazy" -> keyValue.put("lazy", "true");
709715
case "abstract" -> keyValue.put("abstract", "true");
710716
case "deprecated" -> keyValue.put("deprecated", "true");
@@ -828,7 +834,8 @@ private static ServiceFileDefaults createPhpArrayDefaults(@NotNull ArrayCreation
828834

829835
return new ServiceFileDefaults(
830836
PhpElementsUtil.getArrayValueBool(defaultsArray, "public"),
831-
PhpElementsUtil.getArrayValueBool(defaultsArray, "autowire")
837+
PhpElementsUtil.getArrayValueBool(defaultsArray, "autowire"),
838+
PhpElementsUtil.getArrayValueBool(defaultsArray, "autoconfigure")
832839
);
833840
}
834841

@@ -876,11 +883,13 @@ private static Collection<ServiceSerializable> createServicesFromPhpArray(@NotNu
876883
PsiElement value = hashElement.getValue();
877884
SerializableService serializableService = new SerializableService(serviceId)
878885
.setIsAutowire(defaults.isAutowire())
886+
.setIsAutoconfigure(defaults.isAutoconfigure())
879887
.setIsPublic(defaults.isPublic());
880888

881889
if (value instanceof ArrayCreationExpression arrayCreationExpression) {
882890
Boolean isAbstract = PhpElementsUtil.getArrayValueBool(arrayCreationExpression, "abstract");
883891
Boolean isAutowire = PhpElementsUtil.getArrayValueBool(arrayCreationExpression, "autowire");
892+
Boolean isAutoconfigure = PhpElementsUtil.getArrayValueBool(arrayCreationExpression, "autoconfigure");
884893
Boolean isPublic = PhpElementsUtil.getArrayValueBool(arrayCreationExpression, "public");
885894
String className = StringUtils.stripStart(getPhpArrayValueString(arrayCreationExpression, "class"), "\\");
886895
if (className == null && isPhpArrayServiceIdAsClassSupported(arrayCreationExpression, isAbstract)) {
@@ -900,6 +909,7 @@ private static Collection<ServiceSerializable> createServicesFromPhpArray(@NotNu
900909
.setParent(getPhpArrayValueString(arrayCreationExpression, "parent"))
901910
.setIsAbstract(isAbstract)
902911
.setIsAutowire(isAutowire != null ? isAutowire : defaults.isAutowire())
912+
.setIsAutoconfigure(isAutoconfigure != null ? isAutoconfigure : defaults.isAutoconfigure())
903913
.setIsLazy(PhpElementsUtil.getArrayValueBool(arrayCreationExpression, "lazy"))
904914
.setIsPublic(isPublic != null ? isPublic : defaults.isPublic())
905915
.setIsDeprecated(PhpElementsUtil.getArrayValueBool(arrayCreationExpression, "deprecated"))
@@ -1077,7 +1087,8 @@ private static ServiceFileDefaults createDefaults(@NotNull XmlTag servicesTag) {
10771087

10781088
return new ServiceFileDefaults(
10791089
getBooleanValueOf(xmlDefaults.getAttributeValue("public")),
1080-
getBooleanValueOf(xmlDefaults.getAttributeValue("autowire"))
1090+
getBooleanValueOf(xmlDefaults.getAttributeValue("autowire")),
1091+
getBooleanValueOf(xmlDefaults.getAttributeValue("autoconfigure"))
10811092
);
10821093
}
10831094

0 commit comments

Comments
 (0)