14
14
use Symfony \Component \DependencyInjection \Argument \ArgumentInterface ;
15
15
use Symfony \Component \DependencyInjection \ContainerInterface ;
16
16
use Symfony \Component \DependencyInjection \Definition ;
17
- use Symfony \Component \DependencyInjection \Exception \RuntimeException ;
18
- use Symfony \Component \DependencyInjection \ExpressionLanguage ;
19
17
use Symfony \Component \DependencyInjection \Reference ;
20
18
use Symfony \Component \DependencyInjection \ContainerBuilder ;
21
- use Symfony \Component \ExpressionLanguage \Expression ;
22
19
23
20
/**
24
21
* Run this pass before passes that need to know more about the relation of
28
25
* retrieve the graph in other passes from the compiler.
29
26
*
30
27
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
28
+ * @author Nicolas Grekas <p@tchwork.com>
31
29
*/
32
30
class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements RepeatablePassInterface
33
31
{
34
32
private $ graph ;
35
33
private $ currentDefinition ;
36
34
private $ onlyConstructorArguments ;
37
35
private $ lazy ;
38
- private $ expressionLanguage ;
36
+ private $ definitions ;
37
+ private $ aliases ;
39
38
40
39
/**
41
40
* @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
42
41
*/
43
42
public function __construct (bool $ onlyConstructorArguments = false )
44
43
{
45
44
$ this ->onlyConstructorArguments = $ onlyConstructorArguments ;
45
+ $ this ->enableExpressionProcessing ();
46
46
}
47
47
48
48
/**
49
49
* {@inheritdoc}
50
50
*/
51
51
public function setRepeatedPass (RepeatedPass $ repeatedPass )
52
52
{
53
- // no-op for BC
53
+ @ trigger_error ( sprintf ( ' The "%s" method is deprecated since Symfony 4.2. ' , __METHOD__ ), E_USER_DEPRECATED );
54
54
}
55
55
56
56
/**
@@ -62,16 +62,22 @@ public function process(ContainerBuilder $container)
62
62
$ this ->graph = $ container ->getCompiler ()->getServiceReferenceGraph ();
63
63
$ this ->graph ->clear ();
64
64
$ this ->lazy = false ;
65
+ $ this ->definitions = $ container ->getDefinitions ();
66
+ $ this ->aliases = $ container ->getAliases ();
65
67
66
- foreach ($ container -> getAliases () as $ id => $ alias ) {
68
+ foreach ($ this -> aliases as $ id => $ alias ) {
67
69
$ targetId = $ this ->getDefinitionId ((string ) $ alias );
68
- $ this ->graph ->connect ($ id , $ alias , $ targetId , $ this ->getDefinition ($ targetId ), null );
70
+ $ this ->graph ->connect ($ id , $ alias , $ targetId , null !== $ targetId ? $ this ->container -> getDefinition ($ targetId ) : null , null );
69
71
}
70
72
71
- parent ::process ($ container );
73
+ try {
74
+ parent ::process ($ container );
75
+ } finally {
76
+ $ this ->aliases = $ this ->definitions = array ();
77
+ }
72
78
}
73
79
74
- protected function processValue ($ value , $ isRoot = false )
80
+ protected function processValue ($ value , $ isRoot = false , bool $ inExpression = false )
75
81
{
76
82
$ lazy = $ this ->lazy ;
77
83
@@ -82,14 +88,9 @@ protected function processValue($value, $isRoot = false)
82
88
83
89
return $ value ;
84
90
}
85
- if ($ value instanceof Expression) {
86
- $ this ->getExpressionLanguage ()->compile ((string ) $ value , array ('this ' => 'container ' ));
87
-
88
- return $ value ;
89
- }
90
91
if ($ value instanceof Reference) {
91
92
$ targetId = $ this ->getDefinitionId ((string ) $ value );
92
- $ targetDefinition = $ this ->getDefinition ($ targetId );
93
+ $ targetDefinition = null !== $ targetId ? $ this ->container -> getDefinition ($ targetId ) : null ;
93
94
94
95
$ this ->graph ->connect (
95
96
$ this ->currentId ,
@@ -101,6 +102,18 @@ protected function processValue($value, $isRoot = false)
101
102
ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $ value ->getInvalidBehavior ()
102
103
);
103
104
105
+ if ($ inExpression ) {
106
+ $ this ->graph ->connect (
107
+ '.internal.reference_in_expression ' ,
108
+ null ,
109
+ $ targetId ,
110
+ $ targetDefinition ,
111
+ $ value ,
112
+ $ this ->lazy || ($ targetDefinition && $ targetDefinition ->isLazy ()),
113
+ true
114
+ );
115
+ }
116
+
104
117
return $ value ;
105
118
}
106
119
if (!$ value instanceof Definition) {
@@ -127,49 +140,12 @@ protected function processValue($value, $isRoot = false)
127
140
return $ value ;
128
141
}
129
142
130
- private function getDefinition (?string $ id ): ?Definition
131
- {
132
- return null === $ id ? null : $ this ->container ->getDefinition ($ id );
133
- }
134
-
135
143
private function getDefinitionId (string $ id ): ?string
136
144
{
137
- while ($ this ->container ->hasAlias ($ id )) {
138
- $ id = (string ) $ this ->container ->getAlias ($ id );
139
- }
140
-
141
- if (!$ this ->container ->hasDefinition ($ id )) {
142
- return null ;
143
- }
144
-
145
- return $ id ;
146
- }
147
-
148
- private function getExpressionLanguage ()
149
- {
150
- if (null === $ this ->expressionLanguage ) {
151
- if (!class_exists (ExpressionLanguage::class)) {
152
- throw new RuntimeException ('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. ' );
153
- }
154
-
155
- $ providers = $ this ->container ->getExpressionLanguageProviders ();
156
- $ this ->expressionLanguage = new ExpressionLanguage (null , $ providers , function ($ arg ) {
157
- if ('"" ' === substr_replace ($ arg , '' , 1 , -1 )) {
158
- $ id = stripcslashes (substr ($ arg , 1 , -1 ));
159
- $ id = $ this ->getDefinitionId ($ id );
160
-
161
- $ this ->graph ->connect (
162
- $ this ->currentId ,
163
- $ this ->currentDefinition ,
164
- $ id ,
165
- $ this ->getDefinition ($ id )
166
- );
167
- }
168
-
169
- return sprintf ('$this->get(%s) ' , $ arg );
170
- });
145
+ while (isset ($ this ->aliases [$ id ])) {
146
+ $ id = (string ) $ this ->aliases [$ id ];
171
147
}
172
148
173
- return $ this ->expressionLanguage ;
149
+ return isset ( $ this ->definitions [ $ id ]) ? $ id : null ;
3C87
tr>174
150
}
175
151
}
0 commit comments