From 0f2341bfa929d4d0d8a41519bb9d28b95e21bb60 Mon Sep 17 00:00:00 2001 From: Vadym Slizov Date: Sun, 27 Dec 2020 23:04:09 +0200 Subject: [PATCH] refactoring: update ast structure of "MethodCall" and "PropertyFetch" nodes --- internal/php5/php5.go | Bin 264502 -> 265114 bytes internal/php5/php5.y | 20 ++++++++--- internal/php7/php7.go | Bin 219091 -> 219920 bytes internal/php7/php7.y | 30 ++++++++++++++-- pkg/ast/node.go | 28 ++++++++------- pkg/ast/visitor/dumper.go | 4 +++ pkg/ast/visitor/formatter.go | 22 ++++++++++++ pkg/ast/visitor/formatter_test.go | 56 ++++++++++++++++++++++++++++++ pkg/ast/visitor/printer.go | 4 +++ 9 files changed, 144 insertions(+), 20 deletions(-) diff --git a/internal/php5/php5.go b/internal/php5/php5.go index 9cc409a8f4aa551c370ddaf821d5df6d8dd76199..a2bd33cfae51cbd291beebc187308c51052d3e7a 100644 GIT binary patch delta 1935 zcmZ8ic}!Gy5YGH&ut zv6cOzjS8*jVik$-ys!lmEk-M7lu*$?6O6WsXjF_^>AbfEk3U}We)F3*-#0Vg%&Y!B zU^40drKN=P^ju_)QNbqbL~9nDV^la674b4S4pAs&!G4Ga!db*N z#BSm^bQW@?Hu^gr;DyK^)F7m9Nk+T7Ukj->Se%dg&c?m7l)&`h==JQ-kzhNhxL$XE0mzRlNPgyeMmWM+N90An^d$z ze~BX~XlFO>tjQORUitKh8j&r4Q zF-&<9Gh=!gr)ulUc`@PfPn<#t$XKr|xNTxD)NkkecyBvTQwcV_zU6d_pTTf7blpK_zR=RtN8c-#-=c_!$U!W5_!nN2~t!H4g)Jd3hNKWxa zU*&ZDFsBB``1$&-k;gYXXLD6f{gE6OyXg3THK2!anuWofa>$X688O zFI||sa*TEPQtO0?Xq!Mo(9l7?!HK%Xh}9cR7k)@z8G)X!(0WpZMD<{eOYZ@F<}q%{ zhl{fo=wQ#H=z8_(4N;s!A#nc4!G`pFdV-<-2+vY>n=YmZoMBaipkq>#q|bOL)-T~M ztgMmFIZ&2K!!U1}^27BSZo%1K*&l1#sV}UVGFtbJbF+%EYxY=5C4|;WgrGW6+`2nz ztZOO_#c457Y;PY8@tH8GoG5KR(6Zxa6PTb?Pr*-@;qu^(0_wp7| z?Anw3HrgK0YY0BYsVZSSCJ&)d6h5M0&Af)+B%J?UnkDI^U*JTvrqN(@7K{A*H*ydv z=8_LaHu5a3tDg7D(8lO)@j3y!?%@sV2IZ{@m7RnGZW$AuJ}S=fDCB>nypZ3=WI;Mq zGz$OV%M_!lE~3}zmPqC$Tuq`TDT>!-Uf@h6@(TQtBVnDb95{N8Ezd>GU&zr~-X&&P zAvUd`iStO=u}ICmwf)VUL^8ETXJpfu5p~%ZV`Bvx`^V_l z>T!b9(adikDOd#{=}&#N{lx=dDWd_H(IhQR>c>84oumAb{XTgkr$x3*tUi{;OuaO3 zqppe|;yi0cx{?Rm6PoFXonKB)`HE2(6h0Q`L67)jlG{g0p@wiCL&OeyF*rHsq11e34H@gKw$sAd2F delta 1591 zcmZuxeN2^Q6yJHy%ZGw=S;|LTcQ1&}{*bsAE+2CXt>kKp^7e<(CtPsmW=&Wnt&*TG zYeQ|B{LGd>TA0_5E9re^#ubN6osyLMP-t(OEoO6EX z_dAY<7N?TuO>gQNZz{>Bv^SL>d=Zz|^8LDD9WRSUeSqD_+{g>zU#1?$S8`JM z1@L=S2AmF#hr5v%Q68q)xlH#p@=0YzXJDv-WAOe*oQAdQ*n=QA9iy8$s9bq^_s6`Q zl)Jz@8h1ibXmPlPm zSYNCXQ1q$XCg!jU2joN^J+zaT6IN_vFBPDE7Nw#4ZDnB4;Aj+n&VScy; z<-8@~uY0+eaxv7XQX&N}Z4;-x!~b=w%g*yXgd1O)Q2E9o5MxTCOFfFJnRExfo~FXs zwBKq+U`m3slM)aW5;%S9$8o3&$$d7eFVZv<{iQe-k~vtzD_fu@W2NSP<*}ygC+t2T zE#+AwmcP=2R;3V*0Wa=BfRVw@F}iqgaUBW54wcsQfRBB5F$6S}xWpYP>fQh6RT(Od)vg$U(kGN9~qiq&&Y z^Cgnn6W#TmB zX*ShTK{HIT+OgrR#g_?%>anvtkA#V?TIDcVx5^ao{7*z#qK?;)JxY)0jscV50}T;1 z8G8NCd|e5=Qgaa&w@N?VgKCyFc8Wln_i z9Hqe4BD_xcjkP6RfjJsgmxQ$C2gQDVI@|E~Sv3hK%jCByq@wk^zjIiPGbS1r!h8+S z3`&b03^Yl(b(!3TmxfG(4iE8jN|2t=li9A+`tq4ye4&PJP!6jx`aT*h~7p5l$iO-JzWNl~I8YPmGG6?H|+6b5qd}ON=fW<3yso zjXtAI<-4@YLkkHd$`D>gcHq&-+1fJQal)|qY?xcdl$%2ziZQl{f0W@xxsU8R7-bB~ dVD?b5Zf0W_p>mSp6_T2p(RAKISRQA%{{@4`I6?pb diff --git a/internal/php5/php5.y b/internal/php5/php5.y index ac247f2..ba55690 100644 --- a/internal/php5/php5.y +++ b/internal/php5/php5.y @@ -4709,7 +4709,9 @@ variable: ) $3 = append($3, $4[1:len($4)]...) case *ast.ExprPropertyFetch: + $4[0].(*ast.ExprMethodCall).OpenCurlyBracketTkn = l.OpenCurlyBracketTkn $4[0].(*ast.ExprMethodCall).Method = l.Property + $4[0].(*ast.ExprMethodCall).CloseCurlyBracketTkn = l.CloseCurlyBracketTkn $4[0].(*ast.ExprMethodCall).ObjectOperatorTkn = l.ObjectOperatorTkn $3 = append($3[:len($3)-1], $4...) } @@ -4801,7 +4803,9 @@ variable_property: ) $2 = append($2, $3[1:len($3)]...) case *ast.ExprPropertyFetch: + $3[0].(*ast.ExprMethodCall).OpenCurlyBracketTkn = l.OpenCurlyBracketTkn $3[0].(*ast.ExprMethodCall).Method = l.Property + $3[0].(*ast.ExprMethodCall).CloseCurlyBracketTkn = l.CloseCurlyBracketTkn $3[0].(*ast.ExprMethodCall).ObjectOperatorTkn = l.ObjectOperatorTkn $2 = append($2[:len($2)-1], $3...) } @@ -5078,12 +5082,18 @@ object_dim_list: } | variable_name { - $$ = []ast.Vertex{ - &ast.ExprPropertyFetch{ - Position: yylex.(*Parser).builder.NewNodePosition($1), - Property: $1, - }, + property := &ast.ExprPropertyFetch{ + Position: yylex.(*Parser).builder.NewNodePosition($1), + Property: $1, } + + if brackets, ok := $1.(*ast.ParserBrackets); ok { + property.OpenCurlyBracketTkn = brackets.OpenBracketTkn + property.Property = brackets.Child + property.CloseCurlyBracketTkn = brackets.CloseBracketTkn + } + + $$ = []ast.Vertex{ property } } ; diff --git a/internal/php7/php7.go b/internal/php7/php7.go index da378e52f82b1a5f6b914f0bf15a24ea0f49c5e7..bdd9dc602c500972979286197865b835c79bda2e 100644 GIT binary patch delta 1776 zcmds%T}+#06vuO(Gw9j@qrkupN?)8X46|!Xp)CYM#|DfD6vkwk8f1e7Qd|Mi#9)G` zafx0)qT|0Ui-IO5;s>&9zE>KUQ4`}wqtTi9HBI!w%*Z5J6oc`+EvzuP@Y=igIq&&; ze&>Il&u3D{-%5Qm*QR{lC+xNpb{pw-n~MCB@<8`cPo%4+v#(F9(7{}-GA(Aax%ZfM zWU%vSxO?cqU0NiJ(4CZvxeS$z=xfTHT`4wg*l;u_5;!sN3T3uvRX0MN&HdfS_r&wG zg^%Ct-x#aC*1x8wx3BAFH@IghYs(rpgkM)XEs4VTGKml1+G)x`buxG1l!>#AFFP(J zb1nHW`h{|%*~IlWU%6zDHQqlM>F*vKdZe~{=xC2tfrTVHMo5B<1!Dul%a5;_t!cZF5;$%8&x*UUq zfx~gwd1y-KI;0OP4U@&3bYYA&!euMhQ8}!`QZ->cmdSNCU+MpS0P|TQMhdZJkXwQ? zTUZ1z@RG2I8OCx1Wpq1#gTV>ft1sko9>Ka@jIDO|;u+)XBRgBr@GNB@w2$7#bS~G! zb%OE`y_b@)d{$kD#m@Cq7MJ#u@~z4O`X_ciM56aq@D_v|+-5AmRf=sy9xgeg9lw6% zqS{aBDUcii%tvLpC37=!Z{=F{x?H%{E(85~hX`hTQ5B+kM3o}@c5cN?A!k85s7y#7 zRaOk{SP6*TPiAeycqcjV&hHZMxs3-To7)iMnrsu_Qz6ctS7|6O@aDy|(n?l0m+ zw3KiFO`FtV{JfLTkk`0jHWr4IS(o&)%D8he`=MDRO#7RP^k@k$lk$}z7^ZCqof8k6 zQ-JsaaZ7qJne-7SSCb03Fu$9hQUNc5U#UM3baSt)K+B@ijAhwPSn_bKa=YX6GPHYg zOd#AS1}SFMBjsF0IArC=@m!hkERC%jKF*XUC+51~R%QAN@2M)%r+vJiq$ObxgB%-Q zK02;S`{EWrbV;S4qmu8z_-aFpb;{#53guz)CzXUN->En7;~v9Yu9wtsSSfF*erg}z z#nO=Rn5@t$Z4e*7TYt2H-&d=z&XGobm{e)3jzj;miA{165quzF1tHFnlRPalRXxkyewwX^3R DZ~Zn% delta 1187 zcma)6TWDNW6lL#iJDC|Xxn|lV)0xTKiAhas#JQR0H7$0)OcF`WGzo1}s#GksHK-{* ze#DaEM^&VbC|Lxgq!wB~M59;_iiLopeuxSZ6-C9LLQ1NYf=Ek>`_4FR@XNn*);(wM zwf0))Rz7I__MOK0XoRz==i-rL@d%lCgde|vE4#SGoD#`0?5{Y03u|SNvPeEk4)*(G z2pwf^ndy)ie)Y)!<#4hC&L~$uYeq7B^6qWnAh$a#ruJus} zQ(+0>fM3S2FQTg-1A6zjBW&Z|Z5%QqL3x-s?}FasL=}QU0Zb)$6mxG-lPNdKT0-+< zRPE+pb>?_TepjwX7rDhF;>U_5R{={()LX4*6etpCiCe2W4mWG>pDnSm&?RfmzAQFj zC9K%|g7Ue6y|7;OX7TQVQYyF-|DWP+MzBpva1tCt>Hy#5@wtM@h!)GE_^OWP2Kwa& zWm&-VGR08tr*l}2$^aMK>N!)6$vs4=`o!b-BCdtQQTYi=?NTzCm~0>n*$TcEmkd7f zR-twYm~c|cgu{EZ?7ns4$MYRBQ8zVws|<23Ws(yzL^$24!jr>l?>BpC1iQPWBxyH~ z2RF$UB)YZW^el%k)+3{6->jux+9-$gM4=|7T0M4~e5#PU$^)I^LwNmtz4=79TvQF$ z?J?7v#3D89WS8{ej}sil{71AEowv)ZqQ%oXpnBDHs9fgz@ZwnwfHLS~R5ptXJD@(< z*Jxuc8nHVy0IKelZfZgKJzec|RAM%Z;v}ty)lEM0u_N1vb2$&{fSs28oKKgrBq5)Z5~pfbc#M+&?Q7+wfmbCjX!HsE#gwjzog1e$PzyWF)D}5L zm@9ZD>mIsaK-uM1G|iG_+VA$vN|rS*_0J_(cSsXfzGDm9NAyYA=XI196XG*YQOCn;D{-&R$8*e!w3!)~rwKbQ tvu%2IN`q&zGsOurzDwG?dqh=#QoczwD9Te*lk0U0whH diff --git a/internal/php7/php7.y b/internal/php7/php7.y index ae5f176..078c6eb 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -3738,7 +3738,7 @@ callable_variable: } | dereferencable T_OBJECT_OPERATOR property_name argument_list { - $$ = &ast.ExprMethodCall{ + methodCall := &ast.ExprMethodCall{ Position: yylex.(*Parser).builder.NewNodesPosition($1, $4), Var: $1, ObjectOperatorTkn: $2, @@ -3748,6 +3748,14 @@ callable_variable: SeparatorTkns: $4.(*ast.ArgumentList).SeparatorTkns, CloseParenthesisTkn: $4.(*ast.ArgumentList).CloseParenthesisTkn, } + + if brackets, ok := $3.(*ast.ParserBrackets); ok { + methodCall.OpenCurlyBracketTkn = brackets.OpenBracketTkn + methodCall.Method = brackets.Child + methodCall.CloseCurlyBracketTkn = brackets.CloseBracketTkn + } + + $$ = methodCall } | function_call { @@ -3766,12 +3774,20 @@ variable: } | dereferencable T_OBJECT_OPERATOR property_name { - $$ = &ast.ExprPropertyFetch{ + propertyFetch := &ast.ExprPropertyFetch{ Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), Var: $1, ObjectOperatorTkn: $2, Property: $3, } + + if brackets, ok := $3.(*ast.ParserBrackets); ok { + propertyFetch.OpenCurlyBracketTkn = brackets.OpenBracketTkn + propertyFetch.Property = brackets.Child + propertyFetch.CloseCurlyBracketTkn = brackets.CloseBracketTkn + } + + $$ = propertyFetch } ; @@ -3855,12 +3871,20 @@ new_variable: } | new_variable T_OBJECT_OPERATOR property_name { - $$ = &ast.ExprPropertyFetch{ + propertyFetch := &ast.ExprPropertyFetch{ Position: yylex.(*Parser).builder.NewNodesPosition($1, $3), Var: $1, ObjectOperatorTkn: $2, Property: $3, } + + if brackets, ok := $3.(*ast.ParserBrackets); ok { + propertyFetch.OpenCurlyBracketTkn = brackets.OpenBracketTkn + propertyFetch.Property = brackets.Child + propertyFetch.CloseCurlyBracketTkn = brackets.CloseBracketTkn + } + + $$ = propertyFetch } | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { diff --git a/pkg/ast/node.go b/pkg/ast/node.go index 400537f..7a89a90 100644 --- a/pkg/ast/node.go +++ b/pkg/ast/node.go @@ -1501,14 +1501,16 @@ func (n *ExprList) GetPosition() *position.Position { // ExprMethodCall node type ExprMethodCall struct { - Position *position.Position - Var Vertex - ObjectOperatorTkn *token.Token - Method Vertex - OpenParenthesisTkn *token.Token - Arguments []Vertex - SeparatorTkns []*token.Token - CloseParenthesisTkn *token.Token + Position *position.Position + Var Vertex + ObjectOperatorTkn *token.Token + OpenCurlyBracketTkn *token.Token + Method Vertex + CloseCurlyBracketTkn *token.Token + OpenParenthesisTkn *token.Token + Arguments []Vertex + SeparatorTkns []*token.Token + CloseParenthesisTkn *token.Token } func (n *ExprMethodCall) Accept(v NodeVisitor) { @@ -1615,10 +1617,12 @@ func (n *ExprPrint) GetPosition() *position.Position { // ExprPropertyFetch node type ExprPropertyFetch struct { - Position *position.Position - Var Vertex - ObjectOperatorTkn *token.Token - Property Vertex + Position *position.Position + Var Vertex + ObjectOperatorTkn *token.Token + OpenCurlyBracketTkn *token.Token + Property Vertex + CloseCurlyBracketTkn *token.Token } func (n *ExprPropertyFetch) Accept(v NodeVisitor) { diff --git a/pkg/ast/visitor/dumper.go b/pkg/ast/visitor/dumper.go index 9778215..11f3159 100644 --- a/pkg/ast/visitor/dumper.go +++ b/pkg/ast/visitor/dumper.go @@ -1326,7 +1326,9 @@ func (v *Dumper) ExprMethodCall(n *ast.ExprMethodCall) { v.dumpPosition(n.Position) v.dumpVertex("Var", n.Var) v.dumpToken("ObjectOperatorTkn", n.ObjectOperatorTkn) + v.dumpToken("OpenCurlyBracketTkn", n.OpenCurlyBracketTkn) v.dumpVertex("Method", n.Method) + v.dumpToken("CloseCurlyBracketTkn", n.CloseCurlyBracketTkn) v.dumpToken("OpenParenthesisTkn", n.OpenParenthesisTkn) v.dumpVertexList("Arguments", n.Arguments) v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) @@ -1419,7 +1421,9 @@ func (v *Dumper) ExprPropertyFetch(n *ast.ExprPropertyFetch) { v.dumpPosition(n.Position) v.dumpVertex("Var", n.Var) v.dumpToken("ObjectOperatorTkn", n.ObjectOperatorTkn) + v.dumpToken("OpenCurlyBracketTkn", n.OpenCurlyBracketTkn) v.dumpVertex("Property", n.Property) + v.dumpToken("CloseCurlyBracketTkn", n.CloseCurlyBracketTkn) v.indent-- v.print(v.indent, "},\n") diff --git a/pkg/ast/visitor/formatter.go b/pkg/ast/visitor/formatter.go index 7fde3cb..9dd5d00 100644 --- a/pkg/ast/visitor/formatter.go +++ b/pkg/ast/visitor/formatter.go @@ -1290,6 +1290,17 @@ func (f *formatter) ExprList(n *ast.ExprList) { func (f *formatter) ExprMethodCall(n *ast.ExprMethodCall) { n.Var.Accept(f) n.ObjectOperatorTkn = f.newToken(token.T_OBJECT_OPERATOR, []byte("->")) + + n.OpenCurlyBracketTkn = nil + n.CloseCurlyBracketTkn = nil + switch n.Method.(type) { + case *ast.Identifier: + case *ast.ExprVariable: + default: + n.OpenCurlyBracketTkn = f.newToken('{', []byte("{")) + n.CloseCurlyBracketTkn = f.newToken('}', []byte("}")) + } + n.Method.Accept(f) n.OpenParenthesisTkn = f.newToken('(', []byte("(")) @@ -1346,6 +1357,17 @@ func (f *formatter) ExprPrint(n *ast.ExprPrint) { func (f *formatter) ExprPropertyFetch(n *ast.ExprPropertyFetch) { n.Var.Accept(f) n.ObjectOperatorTkn = f.newToken(token.T_OBJECT_OPERATOR, []byte("->")) + + n.OpenCurlyBracketTkn = nil + n.CloseCurlyBracketTkn = nil + switch n.Property.(type) { + case *ast.Identifier: + case *ast.ExprVariable: + default: + n.OpenCurlyBracketTkn = f.newToken('{', []byte("{")) + n.CloseCurlyBracketTkn = f.newToken('}', []byte("}")) + } + n.Property.Accept(f) } diff --git a/pkg/ast/visitor/formatter_test.go b/pkg/ast/visitor/formatter_test.go index 62580e7..bc08e81 100644 --- a/pkg/ast/visitor/formatter_test.go +++ b/pkg/ast/visitor/formatter_test.go @@ -4216,6 +4216,34 @@ func TestFormatter_ExprMethodCall(t *testing.T) { } } +func TestFormatter_ExprMethodCall_Expr(t *testing.T) { + o := bytes.NewBufferString("") + + n := &ast.ExprMethodCall{ + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{ + Value: []byte("$foo"), + }, + }, + Method: &ast.ScalarString{ + Value: []byte("'bar'"), + }, + } + + f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) + n.Accept(f) + + p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) + n.Accept(p) + + expected := `$foo->{'bar'}()` + actual := o.String() + + if expected != actual { + t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) + } +} + func TestFormatter_ExprMethodCall_Arguments(t *testing.T) { o := bytes.NewBufferString("") @@ -4483,6 +4511,34 @@ func TestFormatter_ExprPropertyFetch(t *testing.T) { } } +func TestFormatter_ExprPropertyFetch_Expr(t *testing.T) { + o := bytes.NewBufferString("") + + n := &ast.ExprPropertyFetch{ + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{ + Value: []byte("$foo"), + }, + }, + Property: &ast.ScalarString{ + Value: []byte("'bar'"), + }, + } + + f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) + n.Accept(f) + + p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) + n.Accept(p) + + expected := `$foo->{'bar'}` + actual := o.String() + + if expected != actual { + t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) + } +} + func TestFormatter_ExprRequire(t *testing.T) { o := bytes.NewBufferString("") diff --git a/pkg/ast/visitor/printer.go b/pkg/ast/visitor/printer.go index 99db93a..d4ac78a 100644 --- a/pkg/ast/visitor/printer.go +++ b/pkg/ast/visitor/printer.go @@ -772,7 +772,9 @@ func (p *printer) ExprList(n *ast.ExprList) { func (p *printer) ExprMethodCall(n *ast.ExprMethodCall) { p.printNode(n.Var) p.printToken(n.ObjectOperatorTkn, []byte("->")) + p.printToken(n.OpenCurlyBracketTkn, nil) p.printNode(n.Method) + p.printToken(n.CloseCurlyBracketTkn, nil) p.printToken(n.OpenParenthesisTkn, []byte("(")) p.printSeparatedList(n.Arguments, n.SeparatorTkns, []byte(",")) p.printToken(n.CloseParenthesisTkn, []byte(")")) @@ -814,7 +816,9 @@ func (p *printer) ExprPrint(n *ast.ExprPrint) { func (p *printer) ExprPropertyFetch(n *ast.ExprPropertyFetch) { p.printNode(n.Var) p.printToken(n.ObjectOperatorTkn, []byte("->")) + p.printToken(n.OpenCurlyBracketTkn, nil) p.printNode(n.Property) + p.printToken(n.CloseCurlyBracketTkn, nil) } func (p *printer) ExprRequire(n *ast.ExprRequire) {