Keep short strings inline
[hiphop-php.git] / hphp / hack / src / hackc / test / infer / class.hack
blob8d51929b6ba5077ece2eaa9e3a9a555ad47006e4
1 // RUN: %hackc compile-infer %s | FileCheck %s
3 // TEST-CHECK-BAL: type C$static
4 // CHECK: type C$static = .kind="class" .static {
5 // CHECK:   prop3: .public *HackFloat;
6 // CHECK:   prop4: .public .SomeAttribute *HackMixed
7 // CHECK: }
9 // TEST-CHECK-BAL: "type C "
10 // CHECK: type C = .kind="class" {
11 // CHECK:   prop1: .public *HackInt;
12 // CHECK:   prop2: .public *HackString;
13 // CHECK:   type_: .public *HackInt
14 // CHECK: }
16 // TEST-CHECK-BAL: define C$static.$init_static
17 // CHECK: define C$static.$init_static() : void {
18 // CHECK: #b0:
19 // CHECK:   n0 = $builtins.alloc_words(0)
20 // CHECK:   store &C$static::static_singleton <- n0: *C$static
21 // CHECK:   store &C$static::MY_CONSTANT <- $builtins.hack_int(7): *HackMixed
22 // CHECK:   ret 0
23 // CHECK: }
25 <<__ConsistentConstruct>>
26 class C {
27   public int $prop1 = 42;
28   public string $prop2 = "hello";
29   public static float $prop3 = 3.14;
30   <<SomeAttribute>>
31   public static mixed $prop4 = null;
33   const int MY_CONSTANT = 7;
35   // Test reserved token.
36   public int $type = 2;
38   // TEST-CHECK-BAL: define C$static.__factory
39   // CHECK: define C$static.__factory($this: *C$static, $a: *HackInt, $b: *HackString, $c: *HackInt) : *C {
40   // CHECK: #b0:
41   // CHECK:   n0: *HackInt = load &$a
42   // CHECK:   n1: *HackString = load &$b
43   // CHECK:   n2: *HackInt = load &$c
44   // CHECK:   n3 = __sil_allocate(<C>)
45   // CHECK:   n4 = C.__construct(n3, n0, n1, n2)
46   // CHECK:   ret n3
47   // CHECK: }
49   // TEST-CHECK-BAL: define C.__construct
50   // CHECK: define C.__construct($this: *C, $a: *HackInt, $b: *HackString, $c: *HackInt) : *HackMixed {
51   // CHECK: #b0:
52   // CHECK:   ret null
53   // CHECK: }
55   public function __construct(int $a, string $b, int $c) {
56   }
58   // TEST-CHECK-BAL: define C.cons_static
59   // CHECK: define C.cons_static($this: *C) : *void {
60   // CHECK: local $a: *void, $0: *void, $1: *void, $2: *void
61   // CHECK: #b0:
62   // CHECK:   jmp b1
63   // CHECK: #b1:
64   // CHECK:   n0: *C = load &$this
65   // CHECK:   n1 = $builtins.hack_get_static_class(n0)
66   // CHECK:   store &$0 <- n1: *HackMixed
67   // CHECK:   n2: *C = load &$this
68   // CHECK:   n3 = $builtins.hack_get_static_class(n2)
69   // CHECK:   n4 = n3.HackMixed.__factory()
70   // CHECK:   store &$2 <- n4: *HackMixed
71   // CHECK:   n5: *HackMixed = load &$0
72   // CHECK:   n6 = $builtins.hhbc_class_has_reified_generics(n5)
73   // CHECK:   jmp b2, b3
74   // CHECK:   .handlers b17
75   // CHECK: #b2:
76   // CHECK:   prune ! $builtins.hack_is_true(n6)
77   // CHECK:   jmp b7
78   // CHECK: #b3:
79   // CHECK:   prune $builtins.hack_is_true(n6)
80   // CHECK:   n7: *HackMixed = load &$0
81   // CHECK:   n8 = $builtins.hhbc_get_cls_rg_prop(n7)
82   // CHECK:   store &$1 <- n8: *HackMixed
83   // CHECK:   n9 = $builtins.hhbc_is_type_null(n8)
84   // CHECK:   jmp b4, b5
85   // CHECK:   .handlers b17
86   // CHECK: #b4:
87   // CHECK:   prune $builtins.hack_is_true(n9)
88   // CHECK:   jmp b7
89   // CHECK: #b5:
90   // CHECK:   prune ! $builtins.hack_is_true(n9)
91   // CHECK:   n10: *HackMixed = load &$1
92   // CHECK:   n11 = $root.count(null, n10)
93   // CHECK:   n12 = $builtins.hhbc_cmp_eq(n11, $builtins.hack_int(0))
94   // CHECK:   jmp b6, b10
95   // CHECK:   .handlers b17
96   // CHECK: #b6:
97   // CHECK:   prune $builtins.hack_is_true(n12)
98   // CHECK:   jmp b7
99   // CHECK: #b7:
100   // CHECK:   n13: *HackMixed = load &$0
101   // CHECK:   n14 = $builtins.hhbc_class_has_reified_generics(n13)
102   // CHECK:   jmp b8, b9
103   // CHECK:   .handlers b17
104   // CHECK: #b8:
105   // CHECK:   prune ! $builtins.hack_is_true(n14)
106   // CHECK:   jmp b12
107   // CHECK: #b9:
108   // CHECK:   prune $builtins.hack_is_true(n14)
109   // CHECK:   n15: *HackMixed = load &$0
110   // CHECK:   n16 = $builtins.hhbc_class_get_c(n15)
111   // CHECK:   jmp b16
112   // CHECK:   .handlers b17
113   // CHECK: #b10:
114   // CHECK:   prune ! $builtins.hack_is_true(n12)
115   // CHECK:   n17: *HackMixed = load &$0
116   // CHECK:   n18 = $builtins.hhbc_class_has_reified_generics(n17)
117   // CHECK:   jmp b11, b15
118   // CHECK:   .handlers b17
119   // CHECK: #b11:
120   // CHECK:   prune ! $builtins.hack_is_true(n18)
121   // CHECK:   jmp b12
122   // CHECK: #b12:
123   // CHECK:   n19: *HackMixed = load &$0
124   // CHECK:   n20 = $builtins.hhbc_has_reified_parent(n19)
125   // CHECK:   jmp b13, b14
126   // CHECK:   .handlers b17
127   // CHECK: #b13:
128   // CHECK:   prune ! $builtins.hack_is_true(n20)
129   // CHECK:   jmp b16
130   // CHECK: #b14:
131   // CHECK:   prune $builtins.hack_is_true(n20)
132   // CHECK:   n21: *HackMixed = load &$2
133   // CHECK:   n22 = $builtins.hhbc_cast_vec($builtins.hhbc_new_col_vector())
134   // CHECK:   n23 = n21.HackMixed._86reifiedinit(n22)
135   // CHECK:   jmp b16
136   // CHECK:   .handlers b17
137   // CHECK: #b15:
138   // CHECK:   prune $builtins.hack_is_true(n18)
139   // CHECK:   n24: *HackMixed = load &$2
140   // CHECK:   n25: *HackMixed = load &$1
141   // CHECK:   n26 = n24.HackMixed._86reifiedinit(n25)
142   // CHECK:   jmp b16
143   // CHECK:   .handlers b17
144   // CHECK: #b16:
145   // CHECK:   n27: *HackMixed = load &$2
146   // CHECK:   jmp b18
147   // CHECK:   .handlers b17
148   // CHECK: #b17(n28: *HackMixed):
149   // CHECK:   store &$0 <- null: *HackMixed
150   // CHECK:   store &$1 <- null: *HackMixed
151   // CHECK:   store &$2 <- null: *HackMixed
152   // CHECK:   n29 = $builtins.hhbc_throw(n28)
153   // CHECK:   unreachable
154   // CHECK: #b18:
155   // CHECK:   store &$0 <- null: *HackMixed
156   // CHECK:   store &$1 <- null: *HackMixed
157   // CHECK:   store &$2 <- null: *HackMixed
158   // CHECK:   n30 = n27.HackMixed.__construct($builtins.hack_int(1), $builtins.hack_string("x"), $builtins.hack_int(3))
159   // CHECK:   n31 = $builtins.hhbc_lock_obj(n27)
160   // CHECK:   store &$a <- n27: *HackMixed
161   // CHECK:   ret null
162   // CHECK: }
163   public function cons_static(): void {
164     $a = new static(1, "x", 3);
165   }
167   // TEST-CHECK-BAL: define C.cons_self
168   // CHECK: define C.cons_self($this: *C) : *void {
169   // CHECK: local $a: *void, $0: *void, $1: *void, $2: *void
170   // CHECK: #b0:
171   // CHECK:   jmp b1
172   // CHECK: #b1:
173   // CHECK:   n0: *C$static = load &C$static::static_singleton
174   // CHECK:   n1 = $builtins.lazy_initialize(n0)
175   // CHECK:   store &$0 <- n0: *HackMixed
176   // CHECK:   n2: *C$static = load &C$static::static_singleton
177   // CHECK:   n3 = $builtins.lazy_initialize(n2)
178   // CHECK:   n4 = n2.HackMixed.__factory()
179   // CHECK:   store &$2 <- n4: *HackMixed
180   // CHECK:   n5: *HackMixed = load &$0
181   // CHECK:   n6 = $builtins.hhbc_class_has_reified_generics(n5)
182   // CHECK:   jmp b2, b5
183   // CHECK:   .handlers b7
184   // CHECK: #b2:
185   // CHECK:   prune ! $builtins.hack_is_true(n6)
186   // CHECK:   n7: *HackMixed = load &$0
187   // CHECK:   n8 = $builtins.hhbc_has_reified_parent(n7)
188   // CHECK:   jmp b3, b4
189   // CHECK:   .handlers b7
190   // CHECK: #b3:
191   // CHECK:   prune ! $builtins.hack_is_true(n8)
192   // CHECK:   jmp b6
193   // CHECK: #b4:
194   // CHECK:   prune $builtins.hack_is_true(n8)
195   // CHECK:   n9: *HackMixed = load &$2
196   // CHECK:   n10 = $builtins.hhbc_cast_vec($builtins.hhbc_new_col_vector())
197   // CHECK:   n11 = n9.HackMixed._86reifiedinit(n10)
198   // CHECK:   jmp b6
199   // CHECK:   .handlers b7
200   // CHECK: #b5:
201   // CHECK:   prune $builtins.hack_is_true(n6)
202   // CHECK:   n12: *HackMixed = load &$0
203   // CHECK:   n13 = $builtins.hhbc_class_get_c(n12)
204   // CHECK:   jmp b6
205   // CHECK:   .handlers b7
206   // CHECK: #b6:
207   // CHECK:   n14: *HackMixed = load &$2
208   // CHECK:   jmp b8
209   // CHECK:   .handlers b7
210   // CHECK: #b7(n15: *HackMixed):
211   // CHECK:   store &$0 <- null: *HackMixed
212   // CHECK:   store &$1 <- null: *HackMixed
213   // CHECK:   store &$2 <- null: *HackMixed
214   // CHECK:   n16 = $builtins.hhbc_throw(n15)
215   // CHECK:   unreachable
216   // CHECK: #b8:
217   // CHECK:   store &$0 <- null: *HackMixed
218   // CHECK:   store &$1 <- null: *HackMixed
219   // CHECK:   store &$2 <- null: *HackMixed
220   // CHECK:   n17 = n14.HackMixed.__construct($builtins.hack_int(1), $builtins.hack_string("x"), $builtins.hack_int(3))
221   // CHECK:   n18 = $builtins.hhbc_lock_obj(n14)
222   // CHECK:   store &$a <- n14: *HackMixed
223   // CHECK:   ret null
224   // CHECK: }
225   public function cons_self(): void {
226     $a = new self(1, "x", 3);
227   }
229   // TEST-CHECK-BAL: define C.cons_inst
230   // CHECK: define C.cons_inst($this: *C) : *void {
231   // CHECK: local $a: *void, $0: *void, $1: *void, $2: *void
232   // CHECK: #b0:
233   // CHECK:   jmp b1
234   // CHECK: #b1:
235   // CHECK:   n0: *C$static = load &C$static::static_singleton
236   // CHECK:   n1 = $builtins.lazy_initialize(n0)
237   // CHECK:   store &$0 <- n0: *HackMixed
238   // CHECK:   n2: *C$static = load &C$static::static_singleton
239   // CHECK:   n3 = $builtins.lazy_initialize(n2)
240   // CHECK:   n4 = n2.HackMixed.__factory()
241   // CHECK:   store &$2 <- n4: *HackMixed
242   // CHECK:   n5: *HackMixed = load &$0
243   // CHECK:   n6 = $builtins.hhbc_class_has_reified_generics(n5)
244   // CHECK:   jmp b2, b5
245   // CHECK:   .handlers b7
246   // CHECK: #b2:
247   // CHECK:   prune ! $builtins.hack_is_true(n6)
248   // CHECK:   n7: *HackMixed = load &$0
249   // CHECK:   n8 = $builtins.hhbc_has_reified_parent(n7)
250   // CHECK:   jmp b3, b4
251   // CHECK:   .handlers b7
252   // CHECK: #b3:
253   // CHECK:   prune ! $builtins.hack_is_true(n8)
254   // CHECK:   jmp b6
255   // CHECK: #b4:
256   // CHECK:   prune $builtins.hack_is_true(n8)
257   // CHECK:   n9: *HackMixed = load &$2
258   // CHECK:   n10 = $builtins.hhbc_cast_vec($builtins.hhbc_new_col_vector())
259   // CHECK:   n11 = n9.HackMixed._86reifiedinit(n10)
260   // CHECK:   jmp b6
261   // CHECK:   .handlers b7
262   // CHECK: #b5:
263   // CHECK:   prune $builtins.hack_is_true(n6)
264   // CHECK:   n12: *HackMixed = load &$0
265   // CHECK:   n13 = $builtins.hhbc_class_get_c(n12)
266   // CHECK:   jmp b6
267   // CHECK:   .handlers b7
268   // CHECK: #b6:
269   // CHECK:   n14: *HackMixed = load &$2
270   // CHECK:   jmp b8
271   // CHECK:   .handlers b7
272   // CHECK: #b7(n15: *HackMixed):
273   // CHECK:   store &$0 <- null: *HackMixed
274   // CHECK:   store &$1 <- null: *HackMixed
275   // CHECK:   store &$2 <- null: *HackMixed
276   // CHECK:   n16 = $builtins.hhbc_throw(n15)
277   // CHECK:   unreachable
278   // CHECK: #b8:
279   // CHECK:   store &$0 <- null: *HackMixed
280   // CHECK:   store &$1 <- null: *HackMixed
281   // CHECK:   store &$2 <- null: *HackMixed
282   // CHECK:   n17 = n14.HackMixed.__construct($builtins.hack_int(1), $builtins.hack_string("x"), $builtins.hack_int(3))
283   // CHECK:   n18 = $builtins.hhbc_lock_obj(n14)
284   // CHECK:   store &$a <- n14: *HackMixed
285   // CHECK:   ret null
286   // CHECK: }
287   public function cons_inst(): void {
288     $a = new C(1, "x", 3);
289   }
291   // TEST-CHECK-BAL: define C$static.static_signature
292   // CHECK: define C$static.static_signature($this: *C$static, $a: *HackMixed, $b: *HackMixed) : *void {
293   // CHECK: #b0:
294   // CHECK:   n0: *HackMixed = load &$b
295   // CHECK:   n1: *HackMixed = load &$a
296   // CHECK:   n2 = $builtins.hhbc_cmp_eq(n1, n0)
297   // CHECK:   jmp b1, b2
298   // CHECK: #b1:
299   // CHECK:   prune ! $builtins.hack_is_true(n2)
300   // CHECK:   n3 = $builtins.hhbc_print($builtins.hack_string("unequal"))
301   // CHECK:   jmp b3
302   // CHECK: #b2:
303   // CHECK:   prune $builtins.hack_is_true(n2)
304   // CHECK:   n4 = $builtins.hhbc_print($builtins.hack_string("equal"))
305   // CHECK:   jmp b3
306   // CHECK: #b3:
307   // CHECK:   ret null
308   // CHECK: }
310   // TEST-CHECK-BAL: define C.static_signature
311   // CHECK: define C.static_signature($this: *C, $a: *HackMixed, $b: *HackMixed) : *void {
312   // CHECK: #b0:
313   // CHECK: // forward to the static method
314   // CHECK:   n0: *C = load &$this
315   // CHECK:   n1 = $builtins.hack_get_static_class(n0)
316   // CHECK:   n2: *HackMixed = load &$a
317   // CHECK:   n3: *HackMixed = load &$b
318   // CHECK:   n4 = C$static.static_signature(n1, n2, n3)
319   // CHECK:   ret n4
320   // CHECK: }
321   public static function static_signature(mixed $a, mixed $b): void {
322     if ($a == $b) {
323       echo "equal";
324     } else {
325       echo "unequal";
326     }
327   }
329   // TEST-CHECK-BAL: define C.test_const
330   // CHECK: define C.test_const($this: *C) : *void {
331   // CHECK: local $x: *void
332   // CHECK: #b0:
333   // CHECK:   n0: *HackMixed = load &C$static::MY_CONSTANT
334   // CHECK:   store &$x <- n0: *HackMixed
335   // CHECK:   ret null
336   // CHECK: }
337   public function test_const(): void {
338     $x = C::MY_CONSTANT;
339   }
342 trait T0 {
343   // TEST-CHECK-BAL: define T0.trait_parent_caller
344   // CHECK: define T0.trait_parent_caller($this: *T0) : *void {
345   // CHECK: #b0:
346   // CHECK:   n0: *T0 = load &$this
347   // CHECK:   n1 = __parent__.test_const(n0)
348   // CHECK:   ret null
349   // CHECK: }
350   public function trait_parent_caller(): void {
351     /* HH_FIXME[4074] This isn't valid Hack but actually occurs in www */
352     parent::test_const();
353   }
356 trait T1 {
357   require extends C;
359   // TEST-CHECK-BAL: define T1.trait_parent_caller
360   // CHECK: define T1.trait_parent_caller($this: *T1) : *void {
361   // CHECK: #b0:
362   // CHECK:   n0: *T1 = load &$this
363   // CHECK:   n1 = __parent__.test_const(n0)
364   // CHECK:   ret null
365   // CHECK: }
366   public function trait_parent_caller(): void {
367     parent::test_const();
368   }
371 // TEST-CHECK-BAL: define $root.dynamic_const
372 // CHECK: define $root.dynamic_const($this: *void, $c: *C) : *void {
373 // CHECK: #b0:
374 // CHECK:   n0: *HackMixed = load &$c
375 // CHECK:   n1 = $builtins.hhbc_class_get_c(n0)
376 // CHECK:   n2 = $builtins.hhbc_cls_cns(n1, $builtins.hack_string("MY_CONSTANT"))
377 // CHECK:   n3 = $builtins.hhbc_print(n2)
378 // CHECK:   ret null
379 // CHECK: }
380 function dynamic_const(C $c): void {
381   echo $c::MY_CONSTANT;
384 // TEST-CHECK-BAL: global C$static::MY_CONSTANT
385 // CHECK: global C$static::MY_CONSTANT : *HackMixed
387 // TEST-CHECK-BAL: global C$static::static_singleton
388 // CHECK: global C$static::static_singleton : *C$static