77 BinaryExpression ,
88 Block ,
99 Comment ,
10+ Expression ,
1011 InstanceExpression ,
1112 Literal ,
1213 Property ,
@@ -104,8 +105,8 @@ protected function propertyType($type) {
104105 protected function enclose ($ result , $ node , $ signature , $ static , $ emit ) {
105106 $ capture = [];
106107 foreach ($ result ->codegen ->search ($ node , 'variable ' ) as $ var ) {
107- if (isset ($ result ->locals [$ var ->name ])) {
108- $ capture [$ var ->name ]= true ;
108+ if (isset ($ result ->locals [$ var ->pointer ])) {
109+ $ capture [$ var ->pointer ]= true ;
109110 }
110111 }
111112 unset($ capture ['this ' ]);
@@ -228,7 +229,18 @@ protected function emitStatic($result, $static) {
228229 }
229230
230231 protected function emitVariable ($ result , $ variable ) {
231- $ result ->out ->write ('$ ' .$ variable ->name );
232+ if ($ variable ->const ) {
233+ $ result ->out ->write ('$ ' .$ variable ->pointer );
234+ } else {
235+ $ result ->out ->write ('$ ' );
236+ $ this ->emitOne ($ result , $ variable ->pointer );
237+ }
238+ }
239+
240+ protected function emitExpression ($ result , $ expression ) {
241+ $ result ->out ->write ('{ ' );
242+ $ this ->emitOne ($ result , $ expression ->inline );
243+ $ result ->out ->write ('} ' );
232244 }
233245
234246 protected function emitCast ($ result , $ cast ) {
@@ -674,10 +686,10 @@ protected function emitOffset($result, $offset) {
674686 }
675687
676688 protected function emitAssign ($ result , $ target ) {
677- if (' variable ' === $ target ->kind ) {
678- $ result ->out ->write ('$ ' .$ target ->name );
679- $ result ->locals [$ target ->name ]= true ;
680- } else if (' array ' === $ target-> kind ) {
689+ if ($ target instanceof Variable && $ target ->const ) {
690+ $ result ->out ->write ('$ ' .$ target ->pointer );
691+ $ result ->locals [$ target ->pointer ]= true ;
692+ } else if ($ target instanceof ArrayLiteral ) {
681693 $ result ->out ->write ('list( ' );
682694 foreach ($ target ->values as $ pair ) {
683695 if ($ pair [0 ]) {
@@ -813,7 +825,8 @@ protected function emitForeach($result, $foreach) {
813825 $ result ->out ->write (' => ' );
814826 }
815827
816- if ('array ' === $ foreach ->value ->kind ) {
828+ // Support empty elements: `foreach (<expr> as [$a, , $b])`
829+ if ($ foreach ->value instanceof ArrayLiteral) {
817830 $ result ->out ->write ('[ ' );
818831 foreach ($ foreach ->value ->values as $ pair ) {
819832 if ($ pair [0 ]) {
@@ -960,6 +973,13 @@ protected function emitNewClass($result, $new) {
960973 }
961974
962975 protected function emitCallable ($ result , $ callable ) {
976+
977+ // Disambiguate the following:
978+ //
979+ // - `T::{$func}`, a dynamic class constant
980+ // - `T::{$func}(...)`, a dynamic first-class callable
981+ $ callable ->expression ->line = -1 ;
982+
963983 $ this ->emitOne ($ result , $ callable ->expression );
964984 $ result ->out ->write ('(...) ' );
965985 }
@@ -983,25 +1003,29 @@ protected function emitInvoke($result, $invoke) {
9831003 }
9841004
9851005 protected function emitScope ($ result , $ scope ) {
1006+
1007+ // $x::<expr> vs. e.g. invoke()::<expr> vs. T::<expr>
9861008 if ($ scope ->type instanceof Variable) {
9871009 $ this ->emitOne ($ result , $ scope ->type );
9881010 $ result ->out ->write (':: ' );
989- $ this ->emitOne ($ result , $ scope ->member );
9901011 } else if ($ scope ->type instanceof Node) {
9911012 $ t = $ result ->temp ();
992- $ result ->out ->write ('( ' .$ t .'= ' );
1013+ $ result ->out ->write ('(null=== ' .$ t .'= ' );
9931014 $ this ->emitOne ($ result , $ scope ->type );
994- $ result ->out ->write (')? ' .$ t .':: ' );
995- $ this ->emitOne ($ result , $ scope ->member );
996- $ result ->out ->write (':null ' );
997- } else if (
1015+ $ result ->out ->write (")?null: {$ t }:: " );
1016+ } else {
1017+ $ result ->out ->write ("{$ scope ->type }:: " );
1018+ }
1019+
1020+ // Rewrite T::member to T::$member for XP enums
1021+ if (
9981022 $ scope ->member instanceof Literal &&
1023+ is_string ($ scope ->type ) &&
9991024 'class ' !== $ scope ->member ->expression &&
10001025 $ result ->lookup ($ scope ->type )->rewriteEnumCase ($ scope ->member ->expression )
10011026 ) {
1002- $ result ->out ->write ($ scope -> type . ' :: $ ' .$ scope ->member ->expression );
1027+ $ result ->out ->write (' $ ' .$ scope ->member ->expression );
10031028 } else {
1004- $ result ->out ->write ($ scope ->type .':: ' );
10051029 $ this ->emitOne ($ result , $ scope ->member );
10061030 }
10071031 }
@@ -1016,26 +1040,13 @@ protected function emitInstance($result, $instance) {
10161040 $ result ->out ->write ('-> ' );
10171041 }
10181042
1019- if ('literal ' === $ instance ->member ->kind ) {
1020- $ result ->out ->write ($ instance ->member ->expression );
1021- } else {
1022- $ result ->out ->write ('{ ' );
1023- $ this ->emitOne ($ result , $ instance ->member );
1024- $ result ->out ->write ('} ' );
1025- }
1043+ $ this ->emitOne ($ result , $ instance ->member );
10261044 }
10271045
10281046 protected function emitNullsafeInstance ($ result , $ instance ) {
10291047 $ this ->emitOne ($ result , $ instance ->expression );
10301048 $ result ->out ->write ('?-> ' );
1031-
1032- if ('literal ' === $ instance ->member ->kind ) {
1033- $ result ->out ->write ($ instance ->member ->expression );
1034- } else {
1035- $ result ->out ->write ('{ ' );
1036- $ this ->emitOne ($ result , $ instance ->member );
1037- $ result ->out ->write ('} ' );
1038- }
1049+ $ this ->emitOne ($ result , $ instance ->member );
10391050 }
10401051
10411052 protected function emitUnpack ($ result , $ unpack ) {
0 commit comments