6
6
use io \streams \StringWriter ;
7
7
8
8
abstract class Emitter {
9
+ const PROPERTY = 0 ;
10
+ const METHOD = 1 ;
11
+
9
12
protected $ out ;
13
+ protected $ meta = [];
10
14
11
15
/**
12
16
* Selects the correct emitter for a given runtime version
@@ -98,21 +102,6 @@ protected function arguments($list) {
98
102
}
99
103
}
100
104
101
- protected function annotations ($ list ) {
102
- $ s = sizeof ($ list ) - 1 ;
103
- $ this ->out ->write ('#[ ' );
104
- foreach ($ list as $ i => $ annotation ) {
105
- $ this ->out ->write ('@ ' .$ annotation [0 ]);
106
- if (isset ($ annotation [1 ])) {
107
- $ this ->out ->write ('( ' );
108
- $ this ->arguments ($ annotation [1 ]);
109
- $ this ->out ->write (') ' );
110
- }
111
- if ($ i < $ s ) $ this ->out ->write (', ' );
112
- }
113
- $ this ->out ->write ("] \n" );
114
- }
115
-
116
105
protected function emitStart ($ node ) {
117
106
$ this ->out ->write ('<?php ' );
118
107
}
@@ -195,6 +184,7 @@ protected function emitClosure($node) {
195
184
}
196
185
197
186
protected function emitClass ($ node ) {
187
+ array_unshift ($ this ->meta , []);
198
188
$ this ->out ->write (implode (' ' , $ node ->value [1 ]).' class ' .$ node ->value [0 ]);
199
189
$ node ->value [2 ] && $ this ->out ->write (' extends ' .$ node ->value [2 ]);
200
190
$ node ->value [3 ] && $ this ->out ->write (' implements ' .implode (', ' , $ node ->value [3 ]));
@@ -204,6 +194,27 @@ protected function emitClass($node) {
204
194
$ this ->out ->write ("\n" );
205
195
}
206
196
$ this ->out ->write ('} ' );
197
+
198
+ // Cache annotations
199
+ $ this ->out ->write ('\xp::$meta[ \'' .$ node ->value [0 ].'\']= [ ' );
200
+ foreach (array_shift ($ this ->meta ) as $ type => $ lookup ) {
201
+ $ this ->out ->write ($ type .' => [ ' );
202
+ foreach ($ lookup as $ key => $ annotations ) {
203
+ $ this ->out ->write ("' " .$ key ."' => [DETAIL_ANNOTATIONS => [ " );
204
+ foreach ($ annotations as $ annotation ) {
205
+ $ this ->out ->write ("' " .$ annotation [0 ]."' => " );
206
+ if (isset ($ annotation [1 ])) {
207
+ $ this ->emit ($ annotation [1 ]);
208
+ $ this ->out ->write ('null ' );
209
+ } else {
210
+ $ this ->out ->write ('null, ' );
211
+ }
212
+ }
213
+ $ this ->out ->write (']], ' );
214
+ }
215
+ $ this ->out ->write ('], ' );
216
+ }
217
+ $ this ->out ->write (']; ' );
207
218
}
208
219
209
220
protected function emitInterface ($ node ) {
@@ -238,8 +249,7 @@ protected function emitProperty($node) {
238
249
$ this ->out ->write ("\n/** @var " .$ node ->value [3 ]." */ \n" );
239
250
}
240
251
if (isset ($ node ->value [4 ])) {
241
- $ this ->out ->write ("\n" );
242
- $ this ->annotations ($ node ->value [4 ]);
252
+ $ this ->meta [0 ][self ::PROPERTY ][$ node ->value [0 ]]= $ node ->value [4 ];
243
253
}
244
254
$ this ->out ->write (implode (' ' , $ node ->value [1 ]).' $ ' .$ node ->value [0 ]);
245
255
if (isset ($ node ->value [2 ])) {
@@ -259,8 +269,7 @@ protected function emitMethod($node) {
259
269
}
260
270
$ this ->out ->write ($ declare );
261
271
if (isset ($ node ->value [6 ])) {
262
- $ this ->out ->write ("\n" );
263
- $ this ->annotations ($ node ->value [6 ]);
272
+ $ this ->meta [0 ][self ::METHOD ][$ node ->value [0 ]]= $ node ->value [6 ];
264
273
}
265
274
$ this ->out ->write (implode (' ' , $ node ->value [1 ]).' function ' .$ node ->value [0 ].'( ' );
266
275
$ this ->params ($ node ->value [2 ]);
0 commit comments