Skip to content

Commit 4befdb2

Browse files
committed
add support for named arguments #998
1 parent e6c2e24 commit 4befdb2

File tree

3 files changed

+136
-40
lines changed

3 files changed

+136
-40
lines changed

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

+72-40
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.jetbrains.php.PhpIndex;
1313
import com.jetbrains.php.lang.psi.elements.Field;
1414
import com.jetbrains.php.lang.psi.elements.Method;
15+
import com.jetbrains.php.lang.psi.elements.Parameter;
1516
import com.jetbrains.php.lang.psi.elements.PhpClass;
1617
import fr.adrienbrault.idea.symfony2plugin.config.xml.XmlHelper;
1718
import fr.adrienbrault.idea.symfony2plugin.dic.attribute.value.AttributeValueInterface;
@@ -289,51 +290,82 @@ public static ServiceTypeHint getYamlConstructorTypeHint(@NotNull PsiElement psi
289290
*/
290291
@Nullable
291292
public static ServiceTypeHint getYamlConstructorTypeHint(@NotNull YAMLScalar yamlScalar, @NotNull ContainerCollectionResolver.LazyServiceCollector lazyServiceCollector) {
292-
PsiElement context = yamlScalar.getContext();
293-
if(!(context instanceof YAMLSequenceItem)) {
294-
return null;
295-
}
296-
297-
final YAMLSequenceItem sequenceItem = (YAMLSequenceItem) context;
298-
if (!(sequenceItem.getContext() instanceof YAMLSequence)) {
299-
return null;
300-
}
301-
302-
final YAMLSequence yamlArray = (YAMLSequence) sequenceItem.getContext();
303-
if(!(yamlArray.getContext() instanceof YAMLKeyValue)) {
304-
return null;
305-
}
306-
307-
final YAMLKeyValue yamlKeyValue = (YAMLKeyValue) yamlArray.getContext();
308-
if(!yamlKeyValue.getKeyText().equals("arguments")) {
309-
return null;
310-
}
311-
312-
YAMLMapping parentMapping = yamlKeyValue.getParentMapping();
313-
if(parentMapping == null) {
314-
return null;
315-
}
316-
317-
String serviceId = getServiceClassFromServiceMapping(parentMapping);
318-
if(StringUtils.isBlank(serviceId)) {
319-
return null;
320-
}
293+
// arguments: ['$foobar': '@foo']
321294

322-
PhpClass serviceClass = ServiceUtil.getResolvedClassDefinition(yamlScalar.getProject(), serviceId, lazyServiceCollector);
323-
if(serviceClass == null) {
324-
return null;
295+
PsiElement context = yamlScalar.getContext();
296+
if(context instanceof YAMLKeyValue) {
297+
String key = ((YAMLKeyValue) context).getKeyText();
298+
if(key.startsWith("$")) {
299+
PsiElement yamlMapping = context.getParent();
300+
if(yamlMapping instanceof YAMLMapping) {
301+
PsiElement yamlSequenceItem = yamlMapping.getParent();
302+
if(yamlSequenceItem instanceof YAMLSequenceItem) {
303+
PsiElement parent2 = yamlSequenceItem.getParent();
304+
if(parent2 instanceof YAMLSequence) {
305+
PsiElement parent21 = parent2.getParent();
306+
if (parent21 instanceof YAMLKeyValue) {
307+
String keyText1 = ((YAMLKeyValue) parent21).getKeyText();
308+
if(keyText1.equals("arguments")) {
309+
YAMLMapping parentMapping = ((YAMLKeyValue) parent21).getParentMapping();
310+
if(parentMapping != null) {
311+
String serviceId = getServiceClassFromServiceMapping(parentMapping);
312+
if(StringUtils.isNotBlank(serviceId)) {
313+
PhpClass serviceClass = ServiceUtil.getResolvedClassDefinition(yamlScalar.getProject(), serviceId, lazyServiceCollector);
314+
if(serviceClass != null) {
315+
Method constructor = serviceClass.getConstructor();
316+
if(constructor != null) {
317+
Parameter[] parameters = constructor.getParameters();
318+
for (int i = 0; i < parameters.length; i++) {
319+
Parameter parameter = parameters[i];
320+
if (key.equals("$" + parameter.getName())) {
321+
return new ServiceTypeHint(constructor, i, yamlScalar);
322+
}
323+
}
324+
}
325+
}
326+
}
327+
}
328+
}
329+
}
330+
}
331+
}
332+
}
333+
}
325334
}
326335

327-
Method constructor = serviceClass.getConstructor();
328-
if(constructor == null) {
329-
return null;
336+
// arguments: ['@foobar']
337+
if(context instanceof YAMLSequenceItem) {
338+
YAMLSequenceItem sequenceItem = (YAMLSequenceItem) context;
339+
PsiElement yamlSequenceItem = sequenceItem.getContext();
340+
if (yamlSequenceItem instanceof YAMLSequence) {
341+
YAMLSequence yamlArray = (YAMLSequence) sequenceItem.getContext();
342+
PsiElement yamlKeyValue = yamlArray.getContext();
343+
if(yamlKeyValue instanceof YAMLKeyValue) {
344+
YAMLKeyValue yamlKeyValueArguments = (YAMLKeyValue) yamlKeyValue;
345+
if(yamlKeyValueArguments.getKeyText().equals("arguments")) {
346+
YAMLMapping parentMapping = yamlKeyValueArguments.getParentMapping();
347+
if(parentMapping != null) {
348+
String serviceId = getServiceClassFromServiceMapping(parentMapping);
349+
if(StringUtils.isNotBlank(serviceId)) {
350+
PhpClass serviceClass = ServiceUtil.getResolvedClassDefinition(yamlScalar.getProject(), serviceId, lazyServiceCollector);
351+
if(serviceClass != null) {
352+
Method constructor = serviceClass.getConstructor();
353+
if(constructor != null) {
354+
return new ServiceTypeHint(
355+
constructor,
356+
PsiElementUtils.getPrevSiblingsOfType(sequenceItem, PlatformPatterns.psiElement(YAMLSequenceItem.class)).size(),
357+
yamlScalar
358+
);
359+
}
360+
}
361+
}
362+
}
363+
}
364+
}
365+
}
330366
}
331367

332-
return new ServiceTypeHint(
333-
constructor,
334-
PsiElementUtils.getPrevSiblingsOfType(sequenceItem, PlatformPatterns.psiElement(YAMLSequenceItem.class)).size(),
335-
yamlScalar
336-
);
368+
return null;
337369
}
338370

339371
/**

tests/fr/adrienbrault/idea/symfony2plugin/tests/dic/container/util/ServiceContainerUtilTest.java

+53
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
import com.google.gson.Gson;
44
import com.intellij.openapi.util.Condition;
5+
import com.intellij.psi.PsiElement;
56
import com.intellij.psi.PsiFile;
67
import com.intellij.util.containers.ContainerUtil;
78
import fr.adrienbrault.idea.symfony2plugin.dic.container.ServiceInterface;
89
import fr.adrienbrault.idea.symfony2plugin.dic.container.ServiceSerializable;
10+
import fr.adrienbrault.idea.symfony2plugin.dic.container.dict.ServiceTypeHint;
911
import fr.adrienbrault.idea.symfony2plugin.dic.container.util.ServiceContainerUtil;
12+
import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver;
1013
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
1114
import org.jetbrains.annotations.NotNull;
15+
import org.jetbrains.yaml.psi.YAMLScalar;
1216

1317
import java.io.File;
1418
import java.util.Arrays;
@@ -32,6 +36,8 @@ public void setUp() throws Exception {
3236

3337
myFixture.configureByFile("usage.services.xml");
3438
myFixture.configureByFile("usage1.services.xml");
39+
40+
myFixture.configureByFile("classes.php");
3541
}
3642

3743
public String getTestDataPath() {
@@ -199,6 +205,53 @@ public void testXmlFileScopeDefaultsForSymfony33() {
199205
assertTrue(defaultsOverwrite.isPublic());
200206
}
201207

208+
/**
209+
* @see fr.adrienbrault.idea.symfony2plugin.dic.container.util.ServiceContainerUtil#getYamlConstructorTypeHint
210+
*/
211+
public void testGetYamlConstructorTypeHint() {
212+
myFixture.configureByText("test.yml", "" +
213+
"services:\n" +
214+
" NamedArgument\\Foobar:\n" +
215+
" arguments: ['<caret>']\n"
216+
);
217+
218+
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
219+
220+
YAMLScalar parent = (YAMLScalar) psiElement.getParent();
221+
222+
ServiceTypeHint typeHint = ServiceContainerUtil.getYamlConstructorTypeHint(
223+
parent,
224+
new ContainerCollectionResolver.LazyServiceCollector(getProject())
225+
);
226+
227+
assertEquals(0, typeHint.getIndex());
228+
assertEquals("__construct", typeHint.getMethod().getName());
229+
}
230+
231+
/**
232+
* @see fr.adrienbrault.idea.symfony2plugin.dic.container.util.ServiceContainerUtil#getYamlConstructorTypeHint
233+
*/
234+
public void testGetYamlConstructorTypeHintForNamedArgument() {
235+
myFixture.configureByText("test.yml", "" +
236+
"services:\n" +
237+
" NamedArgument\\Foobar:\n" +
238+
" arguments:\n" +
239+
" - $foobar: '<caret>'\n"
240+
);
241+
242+
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
243+
244+
YAMLScalar parent = (YAMLScalar) psiElement.getParent();
245+
246+
ServiceTypeHint typeHint = ServiceContainerUtil.getYamlConstructorTypeHint(
247+
parent,
248+
new ContainerCollectionResolver.LazyServiceCollector(getProject())
249+
);
250+
251+
assertEquals(0, typeHint.getIndex());
252+
assertEquals("__construct", typeHint.getMethod().getName());
253+
}
254+
202255
private static class MyStringServiceInterfaceCondition implements Condition<ServiceInterface> {
203256

204257
@NotNull
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace NamedArgument
4+
{
5+
class Foobar
6+
{
7+
public function __construct(Foobar $foobar)
8+
{
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)