Skip to content

Commit a8bc032

Browse files
committed
provide completion for yaml arguments in _defaults -> bind
1 parent 05256a2 commit a8bc032

File tree

5 files changed

+100
-18
lines changed

5 files changed

+100
-18
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlCompletionContributor.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import fr.adrienbrault.idea.symfony2plugin.dic.ContainerParameter;
2424
import fr.adrienbrault.idea.symfony2plugin.dic.ServiceCompletionProvider;
2525
import fr.adrienbrault.idea.symfony2plugin.dic.container.util.DotEnvUtil;
26+
import fr.adrienbrault.idea.symfony2plugin.dic.container.util.ServiceContainerUtil;
2627
import fr.adrienbrault.idea.symfony2plugin.doctrine.DoctrineYamlAnnotationLookupBuilder;
2728
import fr.adrienbrault.idea.symfony2plugin.doctrine.EntityHelper;
2829
import fr.adrienbrault.idea.symfony2plugin.doctrine.component.PhpEntityClassCompletionProvider;
@@ -40,6 +41,7 @@
4041
import fr.adrienbrault.idea.symfony2plugin.util.controller.ControllerCompletionProvider;
4142
import fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil;
4243
import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper;
44+
import org.apache.commons.lang.StringUtils;
4345
import org.jetbrains.annotations.NotNull;
4446
import org.jetbrains.annotations.Nullable;
4547
import org.jetbrains.yaml.psi.YAMLCompoundValue;
@@ -48,6 +50,7 @@
4850

4951
import java.util.Collections;
5052
import java.util.HashMap;
53+
import java.util.HashSet;
5154
import java.util.Map;
5255
import java.util.regex.Matcher;
5356
import java.util.regex.Pattern;
@@ -244,6 +247,16 @@ public void addCompletions(@NotNull CompletionParameters parameters,
244247
YamlElementPatternHelper.getParentKeyName("services"),
245248
new MyServiceKeyAsClassCompletionParametersCompletionProvider()
246249
);
250+
251+
// services:
252+
// _defaults:
253+
// bind:
254+
// $<caret>: ''
255+
extend(
256+
CompletionType.BASIC,
257+
YamlElementPatternHelper.getNamedDefaultBindPattern(),
258+
new NamedArgumentCompletionProvider()
259+
);
247260
}
248261

249262
/**
@@ -377,6 +390,35 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
377390
}
378391
}
379392

393+
/**
394+
* services:
395+
* _defaults:
396+
* bind:
397+
* $projectDir: '%kernel.project_dir%'
398+
*/
399+
private static class NamedArgumentCompletionProvider extends CompletionProvider<CompletionParameters> {
400+
@Override
401+
protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) {
402+
HashSet<String> uniqueParameters = new HashSet<>();
403+
404+
ServiceContainerUtil.visitNamedArguments(parameters.getPosition().getContainingFile(), parameter -> {
405+
String name = parameter.getName();
406+
if (uniqueParameters.contains(name)) {
407+
return;
408+
}
409+
410+
uniqueParameters.add(name);
411+
412+
// create argument for yaml: $parameter
413+
result.addElement(
414+
LookupElementBuilder.create("$" + name)
415+
.withIcon(parameter.getIcon())
416+
.withTypeText(StringUtils.stripStart(parameter.getType().toString(), "\\"), true)
417+
);
418+
});
419+
}
420+
}
421+
380422
/**
381423
* tags:
382424
* - { method: 'foobar' }

src/main/java/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlElementPatternHelper.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,28 @@ public static ElementPattern<PsiElement> getTaggedServicePattern() {
711711
);
712712
}
713713

714+
/**
715+
* services:
716+
* _defaults:
717+
* bind:
718+
* $<caret>: ''
719+
*/
720+
static PsiElementPattern.Capture<PsiElement> getNamedDefaultBindPattern() {
721+
return PlatformPatterns.psiElement(YAMLTokenTypes.SCALAR_KEY).withText(PlatformPatterns.string().startsWith("$")).withParent(
722+
PlatformPatterns.psiElement(YAMLKeyValue.class).withParent(PlatformPatterns.psiElement(YAMLMapping.class).withParent(PlatformPatterns.psiElement(YAMLKeyValue.class).with(new PatternCondition<YAMLKeyValue>("KeyText") {
723+
@Override
724+
public boolean accepts(@NotNull YAMLKeyValue yamlKeyValue, ProcessingContext context) {
725+
return "bind".equals(yamlKeyValue.getKeyText());
726+
}
727+
}).withParent(PlatformPatterns.psiElement(YAMLMapping.class).withParent(PlatformPatterns.psiElement(YAMLKeyValue.class).with(new PatternCondition<YAMLKeyValue>("KeyText") {
728+
@Override
729+
public boolean accepts(@NotNull YAMLKeyValue yamlKeyValue, ProcessingContext context) {
730+
return "_defaults".equals(yamlKeyValue.getKeyText());
731+
}
732+
})))))
733+
);
734+
}
735+
714736
/**
715737
* Match elements types
716738
*/

src/main/java/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlGoToDeclarationHandler.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,12 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit
184184
private Collection<? extends PsiElement> namedDefaultBindArgumentGoto(@NotNull PsiElement psiElement, @NotNull String parameterName) {
185185
Collection<PsiElement> psiElements = new HashSet<>();
186186

187-
PsiFile containingFile = psiElement.getContainingFile();
188-
if (containingFile instanceof YAMLFile) {
189-
for (PhpClass phpClass : YamlHelper.getPhpClassesInYamlFile((YAMLFile) containingFile, new ContainerCollectionResolver.LazyServiceCollector(psiElement.getProject()))) {
190-
Method constructor = phpClass.getConstructor();
191-
if (constructor == null) {
192-
continue;
193-
}
194-
195-
for (Parameter parameter : constructor.getParameters()) {
196-
if (parameter.getName().equals(parameterName.substring(1))) {
197-
psiElements.add(parameter);
198-
}
199-
}
187+
String argumentWithoutDollar = parameterName.substring(1);
188+
ServiceContainerUtil.visitNamedArguments(psiElement.getContainingFile(), parameter -> {
189+
if (parameter.getName().equals(argumentWithoutDollar)) {
190+
psiElements.add(parameter);
200191
}
201-
}
192+
});
202193

203194
return psiElements;
204195
}

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@
3737
import org.jetbrains.yaml.YAMLUtil;
3838
import org.jetbrains.yaml.psi.*;
3939

40-
import java.util.ArrayList;
41-
import java.util.Collection;
42-
import java.util.Comparator;
43-
import java.util.List;
40+
import java.util.*;
4441

4542
/**
4643
* @author Daniel Espendiller <daniel@espendiller.net>
@@ -403,6 +400,25 @@ public static Parameter getYamlNamedArgument(@NotNull PsiElement psiElement, @No
403400
return null;
404401
}
405402

403+
/**
404+
* services:
405+
* _defaults:
406+
* bind:
407+
* $<caret>: ''
408+
*/
409+
public static void visitNamedArguments(@NotNull PsiFile psiFile, @NotNull Consumer<Parameter> processor) {
410+
if (psiFile instanceof YAMLFile) {
411+
for (PhpClass phpClass : YamlHelper.getPhpClassesInYamlFile((YAMLFile) psiFile, new ContainerCollectionResolver.LazyServiceCollector(psiFile.getProject()))) {
412+
Method constructor = phpClass.getConstructor();
413+
if (constructor == null) {
414+
continue;
415+
}
416+
417+
Arrays.stream(constructor.getParameters()).forEach(processor::consume);
418+
}
419+
}
420+
}
421+
406422
/**
407423
* Symfony 3.3: "class" is optional; use service name for its it
408424
*

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/YamlCompletionContributorTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,15 @@ public void testCompletionForServiceKeyAsClassMustNotBeFiredNonShortcutDefinitio
302302
"Bar"
303303
);
304304
}
305+
306+
public void testNamedArgumentCompletionForDefaultsBinding() {
307+
assertCompletionContains(YAMLFileType.YML, "" +
308+
"services:\n" +
309+
" _defaults:\n" +
310+
" bind:\n" +
311+
" $<caret>: ~\n" +
312+
" Foo\\Bar: ~",
313+
"$i"
314+
);
315+
}
305316
}

0 commit comments

Comments
 (0)