1
1
package fr .adrienbrault .idea .symfony2plugin .config .yaml ;
2
2
3
+ import com .intellij .patterns .PatternCondition ;
3
4
import com .intellij .patterns .PlatformPatterns ;
4
5
import com .intellij .patterns .StandardPatterns ;
5
6
import com .intellij .psi .*;
6
7
import com .intellij .util .ProcessingContext ;
7
8
import fr .adrienbrault .idea .symfony2plugin .Symfony2ProjectComponent ;
9
+ import fr .adrienbrault .idea .symfony2plugin .config .ServiceReference ;
8
10
import org .jetbrains .annotations .NotNull ;
9
- import org .jetbrains .yaml .psi .YAMLScalar ;
11
+ import org .jetbrains .yaml .psi .* ;
10
12
11
13
public class YamlReferenceContributor extends PsiReferenceContributor {
12
14
private static final String TAG_PHP_CONST = "!php/const" ;
@@ -26,7 +28,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar)
26
28
return PsiReference .EMPTY_ARRAY ;
27
29
}
28
30
29
- var scalar = (YAMLScalar )element ;
31
+ var scalar = (YAMLScalar ) element ;
30
32
if (scalar .getTextValue ().isEmpty ()) {
31
33
return PsiReference .EMPTY_ARRAY ;
32
34
}
@@ -37,5 +39,180 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar)
37
39
}
38
40
}
39
41
);
42
+
43
+ // services:
44
+ // app.service.foo:
45
+ // arguments:
46
+ // - '@app.service.bar<caret>'
47
+ registrar .registerReferenceProvider (
48
+ PlatformPatterns
49
+ .psiElement (YAMLScalar .class )
50
+ .withParent (
51
+ PlatformPatterns
52
+ .psiElement (YAMLSequenceItem .class )
53
+ .withParent (
54
+ PlatformPatterns
55
+ .psiElement (YAMLSequence .class )
56
+ .withParent (
57
+ PlatformPatterns .psiElement (YAMLKeyValue .class ).withName ("arguments" )
58
+ )
59
+ )
60
+ ),
61
+ new YAMLScalarServiceReferenceProvider ()
62
+ );
63
+
64
+ // services:
65
+ // app.service.foo:
66
+ // arguments:
67
+ // $bar: '@app.service.bar'
68
+
69
+ // services:
70
+ // app.service.foo:
71
+ // properties:
72
+ // bar: '@app.service.bar'
73
+
74
+ registrar .registerReferenceProvider (
75
+ PlatformPatterns
76
+ .psiElement (YAMLScalar .class )
77
+ .withParent (
78
+ PlatformPatterns
79
+ .psiElement (YAMLKeyValue .class )
80
+ .withParent (
81
+ PlatformPatterns
82
+ .psiElement (YAMLMapping .class )
83
+ .withParent (
84
+ PlatformPatterns
85
+ .psiElement (YAMLKeyValue .class )
86
+ .withName ("arguments" , "properties" )
87
+ )
88
+ )
89
+ ),
90
+ new YAMLScalarServiceReferenceProvider ()
91
+ );
92
+
93
+ // services:
94
+ // app.service.foo:
95
+ // alias: app.service.bar
96
+
97
+ // services:
98
+ // app.service.foo_decorator:
99
+ // decorates: app.service.foo
100
+
101
+ // services:
102
+ // app.service.foo:
103
+ // parent: app.service.foo_parent
104
+
105
+ registrar .registerReferenceProvider (
106
+ PlatformPatterns
107
+ .psiElement (YAMLScalar .class )
108
+ .withParent (
109
+ PlatformPatterns
110
+ .psiElement (YAMLKeyValue .class )
111
+ .withName ("alias" , "decorates" , "parent" )
112
+ ),
113
+ new YAMLScalarServiceReferenceProvider (false )
114
+ );
115
+
116
+ // services:
117
+ // app.service.foo:
118
+ // configurator: @app.service.foo_configurator
119
+
120
+ // services:
121
+ // app.service.foo:
122
+ // factory: @app.service.foo_factory
123
+
124
+ registrar .registerReferenceProvider (
125
+ PlatformPatterns
126
+ .psiElement (YAMLScalar .class )
127
+ .withParent (
128
+ PlatformPatterns
129
+ .psiElement (YAMLKeyValue .class )
130
+ .withName ("configurator" , "factory" )
131
+ ),
132
+ new YAMLScalarServiceReferenceProvider ()
133
+ );
134
+
135
+ // services:
136
+ // app.service.foo:
137
+ // factory: ['@app.service.foo_factory', 'create']
138
+
139
+ // services:
140
+ // app.service.foo:
141
+ // configurator: ['@app.service.foo_configurator', 'configure']
142
+
143
+ registrar .registerReferenceProvider (
144
+ PlatformPatterns
145
+ .psiElement (YAMLScalar .class )
146
+ .withParent (
147
+ PlatformPatterns
148
+ .psiElement (YAMLSequenceItem .class )
149
+ .with (new PatternCondition <>("is first sequence item" ) {
150
+ @ Override
151
+ public boolean accepts (@ NotNull YAMLSequenceItem element , ProcessingContext context ) {
152
+ return element .getItemIndex () == 0 ;
153
+ }
154
+ })
155
+ .withParent (
156
+ PlatformPatterns
157
+ .psiElement (YAMLSequence .class )
158
+ .withParent (
159
+ PlatformPatterns .psiElement (YAMLKeyValue .class ).withName ("factory" , "configurator" )
160
+ )
161
+ )
162
+ ),
163
+ new YAMLScalarServiceReferenceProvider ()
164
+ );
165
+ }
166
+
167
+ private static class YAMLScalarServiceReferenceProvider extends PsiReferenceProvider {
168
+
169
+ private static final String PREFIX = "@" ;
170
+ private static final String ESCAPED_PREFIX = "@@" ;
171
+
172
+ /**
173
+ * Flag indicating whenever YAMLScalar value start with `@` prefix
174
+ */
175
+ private boolean isPrefixed = true ;
176
+
177
+ public YAMLScalarServiceReferenceProvider () {
178
+ }
179
+
180
+ public YAMLScalarServiceReferenceProvider (boolean isPrefixed ) {
181
+ this .isPrefixed = isPrefixed ;
182
+ }
183
+
184
+ @ Override
185
+ public PsiReference @ NotNull [] getReferencesByElement (@ NotNull PsiElement element , @ NotNull ProcessingContext context ) {
186
+ if (!Symfony2ProjectComponent .isEnabled (element )) {
187
+ return PsiReference .EMPTY_ARRAY ;
188
+ }
189
+
190
+ if (element instanceof YAMLScalar ) {
191
+ var serviceName = ((YAMLScalar ) element ).getTextValue ();
192
+ if (serviceName .isEmpty ()) {
193
+ return PsiReference .EMPTY_ARRAY ;
194
+ }
195
+
196
+ if (isPrefixed ) {
197
+ if (isValidServiceNameWithPrefix (serviceName )) {
198
+ return new PsiReference []{
199
+ new ServiceReference (element , serviceName )
200
+ };
201
+ }
202
+
203
+ return PsiReference .EMPTY_ARRAY ;
204
+ }
205
+
206
+ return new PsiReference []{
207
+ new ServiceReference (element , serviceName )
208
+ };
209
+ }
210
+
211
+ return PsiReference .EMPTY_ARRAY ;
212
+ }
213
+
214
+ private boolean isValidServiceNameWithPrefix (@ NotNull String serviceName ) {
215
+ return serviceName .length () > 1 && serviceName .startsWith (PREFIX ) && !serviceName .startsWith (ESCAPED_PREFIX );
216
+ }
40
217
}
41
218
}
0 commit comments