Best Syzkaller code snippet using prog.analyze
ctrlflow_test.go
Source:ctrlflow_test.go
1package analysis2import (3 "testing"4 "github.com/hsiaosiyuan0/mole/ecma/parser"5 "github.com/hsiaosiyuan0/mole/span"6 . "github.com/hsiaosiyuan0/mole/util"7)8func newParser(code string, opts *parser.ParserOpts) *parser.Parser {9 if opts == nil {10 opts = parser.NewParserOpts()11 }12 s := span.NewSource("", code)13 return parser.NewParser(s, opts)14}15func compile(code string, opts *parser.ParserOpts) (*parser.Parser, parser.Node, *parser.SymTab, error) {16 p := newParser(code, opts)17 ast, err := p.Prog()18 if err != nil {19 return nil, nil, nil, err20 }21 return p, ast, p.Symtab(), nil22}23func TestCtrlflow_Basic(t *testing.T) {24 p, ast, symtab, err := compile(`25a26 `, nil)27 AssertEqual(t, nil, err, "should be prog ok")28 ana := NewAnalysis(ast, symtab, p.Source())29 ana.Analyze()30 AssertEqualString(t, `31digraph G {32node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];33edge[fontname="Consolas",fontsize=10]34initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];35final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];36b0[label="Prog:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nProg:exit\n"];37b0->final [xlabel="",color="black"];38initial->b0 [xlabel="",color="black"];39}40`, ana.Graph().Dot(), "should be ok")41}42func TestCtrlflow_Logic(t *testing.T) {43 p, ast, symtab, err := compile(`44 a && b45 `, nil)46 AssertEqual(t, nil, err, "should be prog ok")47 ana := NewAnalysis(ast, symtab, p.Source())48 ana.Analyze()49 AssertEqualString(t, `50digraph G {51node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];52edge[fontname="Consolas",fontsize=10]53initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];54final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];55b0[label="Prog:enter\nExprStmt:enter\nBinExpr(&&):enter\nIdent(a)\n"];56b6[label="Ident(b)\n"];57b9[label="BinExpr(&&):exit\nExprStmt:exit\nProg:exit\n"];58b0->b6 [xlabel="",color="black"];59b0->b9 [xlabel="F",color="orange"];60b6->b9 [xlabel="",color="black"];61b9->final [xlabel="",color="black"];62initial->b0 [xlabel="",color="black"];63}64`, ana.Graph().Dot(), "should be ok")65}66func TestCtrlflow_LogicMix(t *testing.T) {67 p, ast, symtab, err := compile(`68 a && b || c69 `, nil)70 AssertEqual(t, nil, err, "should be prog ok")71 ana := NewAnalysis(ast, symtab, p.Source())72 ana.Analyze()73 AssertEqualString(t, `74digraph G {75node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];76edge[fontname="Consolas",fontsize=10]77initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];78final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];79b0[label="Prog:enter\nExprStmt:enter\nBinExpr(||):enter\nBinExpr(&&):enter\nIdent(a)\n"];80b11[label="Ident(c)\n"];81b14[label="BinExpr(||):exit\nExprStmt:exit\nProg:exit\n"];82b7[label="Ident(b)\nBinExpr(&&):exit\n"];83b0->b11 [xlabel="F",color="orange"];84b0->b7 [xlabel="",color="black"];85b11->b14 [xlabel="",color="black"];86b14->final [xlabel="",color="black"];87b7->b11 [xlabel="",color="black"];88b7->b14 [xlabel="T",color="orange"];89initial->b0 [xlabel="",color="black"];90}91`, ana.Graph().Dot(), "should be ok")92}93func TestCtrlflow_IfStmt(t *testing.T) {94 p, ast, symtab, err := compile(`95 a;96 if (b) c;97 else d;98 e;99 `, nil)100 AssertEqual(t, nil, err, "should be prog ok")101 ana := NewAnalysis(ast, symtab, p.Source())102 ana.Analyze()103 AssertEqualString(t, `104digraph G {105node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];106edge[fontname="Consolas",fontsize=10]107initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];108final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];109b0[label="Prog:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nIfStmt:enter\nIdent(b)\n"];110b13[label="ExprStmt:enter\nIdent(d)\nExprStmt:exit\n"];111b19[label="IfStmt:exit\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nProg:exit\n"];112b8[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\n"];113b0->b13 [xlabel="F",color="orange"];114b0->b8 [xlabel="",color="black"];115b13->b19 [xlabel="",color="black"];116b19->final [xlabel="",color="black"];117b8->b19 [xlabel="",color="black"];118initial->b0 [xlabel="",color="black"];119}120`, ana.Graph().Dot(), "should be ok")121}122func TestCtrlflow_IfBlkStmt(t *testing.T) {123 p, ast, symtab, err := compile(`124 a;125 if (b) {126 c;127 d;128 }129 else e130 f;131 `, nil)132 AssertEqual(t, nil, err, "should be prog ok")133 ana := NewAnalysis(ast, symtab, p.Source())134 ana.Analyze()135 AssertEqualString(t, `136digraph G {137node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];138edge[fontname="Consolas",fontsize=10]139initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];140final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];141b0[label="Prog:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nIfStmt:enter\nIdent(b)\n"];142b17[label="ExprStmt:enter\nIdent(e)\nExprStmt:exit\n"];143b23[label="IfStmt:exit\nExprStmt:enter\nIdent(f)\nExprStmt:exit\nProg:exit\n"];144b8[label="BlockStmt:enter\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];145b0->b17 [xlabel="F",color="orange"];146b0->b8 [xlabel="",color="black"];147b17->b23 [xlabel="",color="black"];148b23->final [xlabel="",color="black"];149b8->b23 [xlabel="",color="black"];150initial->b0 [xlabel="",color="black"];151}152`, ana.Graph().Dot(), "should be ok")153}154func TestCtrlflow_IfBlk2Stmt(t *testing.T) {155 p, ast, symtab, err := compile(`156 a;157 if (b) {158 c;159 d;160 }161 else {162 e;163 }164 f;165 `, nil)166 AssertEqual(t, nil, err, "should be prog ok")167 ana := NewAnalysis(ast, symtab, p.Source())168 ana.Analyze()169 AssertEqualString(t, `170digraph G {171node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];172edge[fontname="Consolas",fontsize=10]173initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];174final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];175b0[label="Prog:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nIfStmt:enter\nIdent(b)\n"];176b17[label="BlockStmt:enter\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nBlockStmt:exit\n"];177b24[label="IfStmt:exit\nExprStmt:enter\nIdent(f)\nExprStmt:exit\nProg:exit\n"];178b8[label="BlockStmt:enter\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];179b0->b17 [xlabel="F",color="orange"];180b0->b8 [xlabel="",color="black"];181b17->b24 [xlabel="",color="black"];182b24->final [xlabel="",color="black"];183b8->b24 [xlabel="",color="black"];184initial->b0 [xlabel="",color="black"];185}186`, ana.Graph().Dot(), "should be ok")187}188func TestCtrlflow_IfLogic(t *testing.T) {189 p, ast, symtab, err := compile(`190 if (a && b) c191 else d192 `, nil)193 AssertEqual(t, nil, err, "should be prog ok")194 ana := NewAnalysis(ast, symtab, p.Source())195 ana.Analyze()196 AssertEqualString(t, `197digraph G {198node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];199edge[fontname="Consolas",fontsize=10]200initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];201final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];202b0[label="Prog:enter\nIfStmt:enter\nBinExpr(&&):enter\nIdent(a)\n"];203b10[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\n"];204b15[label="ExprStmt:enter\nIdent(d)\nExprStmt:exit\n"];205b21[label="IfStmt:exit\nProg:exit\n"];206b6[label="Ident(b)\nBinExpr(&&):exit\n"];207b0->b15 [xlabel="F",color="orange"];208b0->b6 [xlabel="",color="black"];209b10->b21 [xlabel="",color="black"];210b15->b21 [xlabel="",color="black"];211b21->final [xlabel="",color="black"];212b6->b10 [xlabel="",color="black"];213b6->b15 [xlabel="F",color="orange"];214initial->b0 [xlabel="",color="black"];215}216`, ana.Graph().Dot(), "should be ok")217}218func TestCtrlflow_IfLogicMix(t *testing.T) {219 p, ast, symtab, err := compile(`220 a221 if (b || c && d) e222 else f223 `, nil)224 AssertEqual(t, nil, err, "should be prog ok")225 ana := NewAnalysis(ast, symtab, p.Source())226 ana.Analyze()227 AssertEqualString(t, `228digraph G {229node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];230edge[fontname="Consolas",fontsize=10]231initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];232final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];233b0[label="Prog:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nIfStmt:enter\nBinExpr(||):enter\nIdent(b)\n"];234b11[label="Ident(d)\nBinExpr(&&):exit\nBinExpr(||):exit\n"];235b18[label="ExprStmt:enter\nIdent(e)\nExprStmt:exit\n"];236b23[label="ExprStmt:enter\nIdent(f)\nExprStmt:exit\n"];237b29[label="IfStmt:exit\nProg:exit\n"];238b9[label="BinExpr(&&):enter\nIdent(c)\n"];239b0->b18 [xlabel="T",color="orange"];240b0->b9 [xlabel="",color="black"];241b11->b18 [xlabel="",color="black"];242b11->b23 [xlabel="F",color="orange"];243b18->b29 [xlabel="",color="black"];244b23->b29 [xlabel="",color="black"];245b29->final [xlabel="",color="black"];246b9->b11 [xlabel="",color="black"];247b9->b23 [xlabel="F",color="orange"];248initial->b0 [xlabel="",color="black"];249}250`, ana.Graph().Dot(), "should be ok")251}252func TestCtrlflow_UpdateExpr(t *testing.T) {253 p, ast, symtab, err := compile(`254 a++255 `, nil)256 AssertEqual(t, nil, err, "should be prog ok")257 ana := NewAnalysis(ast, symtab, p.Source())258 ana.Analyze()259 AssertEqualString(t, `260digraph G {261node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];262edge[fontname="Consolas",fontsize=10]263initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];264final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];265b0[label="Prog:enter\nExprStmt:enter\nUpdateExpr(++):enter\nIdent(a)\nUpdateExpr(++):exit\nExprStmt:exit\nProg:exit\n"];266b0->final [xlabel="",color="black"];267initial->b0 [xlabel="",color="black"];268}269`, ana.Graph().Dot(), "should be ok")270}271func TestCtrlflow_VarDecStmt(t *testing.T) {272 p, ast, symtab, err := compile(`273 let a = 1, c = d274 `, nil)275 AssertEqual(t, nil, err, "should be prog ok")276 ana := NewAnalysis(ast, symtab, p.Source())277 ana.Analyze()278 AssertEqualString(t, `279digraph G {280node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];281edge[fontname="Consolas",fontsize=10]282initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];283final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];284b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nNumLit(1)\nVarDec:exit\nVarDec:enter\nIdent(c)\nIdent(d)\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];285b0->final [xlabel="",color="black"];286initial->b0 [xlabel="",color="black"];287}288`, ana.Graph().Dot(), "should be ok")289}290func TestCtrlflow_ForStmt(t *testing.T) {291 p, ast, symtab, err := compile(`292 for (let b = 1; b < c; b++) {293 d;294 }295 e;296 `, nil)297 AssertEqual(t, nil, err, "should be prog ok")298 ana := NewAnalysis(ast, symtab, p.Source())299 ana.Analyze()300 AssertEqualString(t, `301digraph G {302node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];303edge[fontname="Consolas",fontsize=10]304initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];305final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];306b0[label="Prog:enter\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(b)\nNumLit(1)\nVarDec:exit\nVarDecStmt:exit\n"];307b12[label="BinExpr(<):enter\nIdent(b)\nIdent(c)\nBinExpr(<):exit\n"];308b22[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\nUpdateExpr(++):enter\nIdent(b)\nUpdateExpr(++):exit\n"];309b29[label="ForStmt:exit\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nProg:exit\n"];310b0->b12 [xlabel="",color="black"];311b12->b22 [xlabel="",color="black"];312b12->b29 [xlabel="F",color="orange"];313b22:s->b12:ne [xlabel="L",color="orange"];314b29->final [xlabel="",color="black"];315initial->b0 [xlabel="",color="black"];316}317`, ana.Graph().Dot(), "should be ok")318}319func TestCtrlflow_ForStmtOmitInit(t *testing.T) {320 p, ast, symtab, err := compile(`321 for (; b < c; b++) {322 d;323 }324 e;325 `, nil)326 AssertEqual(t, nil, err, "should be prog ok")327 ana := NewAnalysis(ast, symtab, p.Source())328 ana.Analyze()329 AssertEqualString(t, `330digraph G {331node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];332edge[fontname="Consolas",fontsize=10]333initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];334final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];335b0[label="Prog:enter\nForStmt:enter\n"];336b14[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\nUpdateExpr(++):enter\nIdent(b)\nUpdateExpr(++):exit\n"];337b21[label="ForStmt:exit\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nProg:exit\n"];338b4[label="BinExpr(<):enter\nIdent(b)\nIdent(c)\nBinExpr(<):exit\n"];339b0->b4 [xlabel="",color="black"];340b14:s->b4:ne [xlabel="L",color="orange"];341b21->final [xlabel="",color="black"];342b4->b14 [xlabel="",color="black"];343b4->b21 [xlabel="F",color="orange"];344initial->b0 [xlabel="",color="black"];345}346`, ana.Graph().Dot(), "should be ok")347}348func TestCtrlflow_ForStmtOmitInitUpdate(t *testing.T) {349 p, ast, symtab, err := compile(`350 for (; b < c;) {351 d;352 }353 e;354 `, nil)355 AssertEqual(t, nil, err, "should be prog ok")356 ana := NewAnalysis(ast, symtab, p.Source())357 ana.Analyze()358 AssertEqualString(t, `359digraph G {360node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];361edge[fontname="Consolas",fontsize=10]362initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];363final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];364b0[label="Prog:enter\nForStmt:enter\n"];365b10[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];366b17[label="ForStmt:exit\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nProg:exit\n"];367b4[label="BinExpr(<):enter\nIdent(b)\nIdent(c)\nBinExpr(<):exit\n"];368b0->b4 [xlabel="",color="black"];369b10:s->b4:ne [xlabel="L",color="orange"];370b17->final [xlabel="",color="black"];371b4->b10 [xlabel="",color="black"];372b4->b17 [xlabel="F",color="orange"];373initial->b0 [xlabel="",color="black"];374}375 `, ana.Graph().Dot(), "should be ok")376}377func TestCtrlflow_ForStmtOmitInitUpdate_TestLogic(t *testing.T) {378 p, ast, symtab, err := compile(`379 for (; b && c;) {380 d;381 }382 e;383 `, nil)384 AssertEqual(t, nil, err, "should be prog ok")385 ana := NewAnalysis(ast, symtab, p.Source())386 ana.Analyze()387 AssertEqualString(t, `388digraph G {389node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];390edge[fontname="Consolas",fontsize=10]391initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];392final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];393b0[label="Prog:enter\nForStmt:enter\n"];394b10[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];395b17[label="ForStmt:exit\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nProg:exit\n"];396b4[label="BinExpr(&&):enter\nIdent(b)\n"];397b6[label="Ident(c)\nBinExpr(&&):exit\n"];398b0->b4 [xlabel="",color="black"];399b10:s->b4:ne [xlabel="L",color="orange"];400b17->final [xlabel="",color="black"];401b4->b17 [xlabel="F",color="orange"];402b4->b6 [xlabel="",color="black"];403b6->b10 [xlabel="",color="black"];404b6->b17 [xlabel="F",color="orange"];405initial->b0 [xlabel="",color="black"];406}407`, ana.Graph().Dot(), "should be ok")408}409func TestCtrlflow_ForStmtOmitAll(t *testing.T) {410 p, ast, symtab, err := compile(`411 for (; ;) {412 d;413 }414 e;415 `, nil)416 AssertEqual(t, nil, err, "should be prog ok")417 ana := NewAnalysis(ast, symtab, p.Source())418 ana.Analyze()419 AssertEqualString(t, `420digraph G {421node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];422edge[fontname="Consolas",fontsize=10]423initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];424final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];425b0[label="Prog:enter\nForStmt:enter\n"];426b11[label="ForStmt:exit\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nProg:exit\n"];427b4[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];428b0->b4 [xlabel="",color="black"];429b11->final [xlabel="",color="red"];430b4->b11 [xlabel="",color="red"];431b4:s->b4:ne [xlabel="L",color="orange"];432initial->b0 [xlabel="",color="black"];433}434`, ana.Graph().Dot(), "should be ok")435}436func TestCtrlflow_ForStmtLitTest(t *testing.T) {437 p, ast, symtab, err := compile(`438 for (; 1 ;) {439 d;440 }441 e;442 `, nil)443 AssertEqual(t, nil, err, "should be prog ok")444 ana := NewAnalysis(ast, symtab, p.Source())445 ana.Analyze()446 AssertEqualString(t, `447digraph G {448node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];449edge[fontname="Consolas",fontsize=10]450initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];451final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];452b0[label="Prog:enter\nForStmt:enter\n"];453b12[label="ForStmt:exit\nExprStmt:enter\nIdent(e)\nExprStmt:exit\nProg:exit\n"];454b4[label="NumLit(1)\n"];455b5[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];456b0->b4 [xlabel="",color="black"];457b12->final [xlabel="",color="black"];458b4->b12 [xlabel="",color="red"];459b4->b5 [xlabel="",color="black"];460b5:s->b4:ne [xlabel="L",color="orange"];461initial->b0 [xlabel="",color="black"];462}463`, ana.Graph().Dot(), "should be ok")464}465func TestCtrlflow_While(t *testing.T) {466 p, ast, symtab, err := compile(`467 while(a) b;468 `, nil)469 AssertEqual(t, nil, err, "should be prog ok")470 ana := NewAnalysis(ast, symtab, p.Source())471 ana.Analyze()472 AssertEqualString(t, `473digraph G {474node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];475edge[fontname="Consolas",fontsize=10]476initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];477final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];478b0[label="Prog:enter\nWhileStmt:enter\n"];479b11[label="WhileStmt:exit\nProg:exit\n"];480b4[label="Ident(a)\n"];481b5[label="ExprStmt:enter\nIdent(b)\nExprStmt:exit\n"];482b0->b4 [xlabel="",color="black"];483b11->final [xlabel="",color="black"];484b4->b11 [xlabel="F",color="orange"];485b4->b5 [xlabel="",color="black"];486b5:s->b4:ne [xlabel="L",color="orange"];487initial->b0 [xlabel="",color="black"];488}489`, ana.Graph().Dot(), "should be ok")490}491func TestCtrlflow_WhileBodyBlk(t *testing.T) {492 p, ast, symtab, err := compile(`493 while(a) {494 b;495 }496 `, nil)497 AssertEqual(t, nil, err, "should be prog ok")498 ana := NewAnalysis(ast, symtab, p.Source())499 ana.Analyze()500 AssertEqualString(t, `501digraph G {502node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];503edge[fontname="Consolas",fontsize=10]504initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];505final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];506b0[label="Prog:enter\nWhileStmt:enter\n"];507b12[label="WhileStmt:exit\nProg:exit\n"];508b4[label="Ident(a)\n"];509b5[label="BlockStmt:enter\nExprStmt:enter\nIdent(b)\nExprStmt:exit\nBlockStmt:exit\n"];510b0->b4 [xlabel="",color="black"];511b12->final [xlabel="",color="black"];512b4->b12 [xlabel="F",color="orange"];513b4->b5 [xlabel="",color="black"];514b5:s->b4:ne [xlabel="L",color="orange"];515initial->b0 [xlabel="",color="black"];516}517`, ana.Graph().Dot(), "should be ok")518}519func TestCtrlflow_WhileLogicOr(t *testing.T) {520 p, ast, symtab, err := compile(`521 while((a + b) || c) {522 d;523 }524 `, nil)525 AssertEqual(t, nil, err, "should be prog ok")526 ana := NewAnalysis(ast, symtab, p.Source())527 ana.Analyze()528 AssertEqualString(t, `529digraph G {530node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];531edge[fontname="Consolas",fontsize=10]532initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];533final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];534b0[label="Prog:enter\nWhileStmt:enter\n"];535b14[label="Ident(c)\nBinExpr(||):exit\n"];536b18[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];537b25[label="WhileStmt:exit\nProg:exit\n"];538b4[label="BinExpr(||):enter\nParenExpr:enter\nBinExpr(+):enter\nIdent(a)\nIdent(b)\nBinExpr(+):exit\nParenExpr:exit\n"];539b0->b4 [xlabel="",color="black"];540b14->b18 [xlabel="",color="black"];541b14->b25 [xlabel="F",color="orange"];542b18:s->b4:ne [xlabel="L",color="orange"];543b25->final [xlabel="",color="black"];544b4->b14 [xlabel="",color="black"];545b4->b18 [xlabel="T",color="orange"];546initial->b0 [xlabel="",color="black"];547}548`, ana.Graph().Dot(), "should be ok")549}550func TestCtrlflow_WhileTestLit(t *testing.T) {551 p, ast, symtab, err := compile(`552 while(1) {553 d;554 }555 `, nil)556 AssertEqual(t, nil, err, "should be prog ok")557 ana := NewAnalysis(ast, symtab, p.Source())558 ana.Analyze()559 AssertEqualString(t, `560digraph G {561node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];562edge[fontname="Consolas",fontsize=10]563initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];564final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];565b0[label="Prog:enter\nWhileStmt:enter\n"];566b12[label="WhileStmt:exit\nProg:exit\n"];567b4[label="NumLit(1)\nBlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];568b0->b4 [xlabel="",color="black"];569b12->final [xlabel="",color="red"];570b4->b12 [xlabel="",color="red"];571b4:s->b4:ne [xlabel="L",color="orange"];572initial->b0 [xlabel="",color="black"];573}574`, ana.Graph().Dot(), "should be ok")575}576func TestCtrlflow_WhileLogicMix(t *testing.T) {577 p, ast, symtab, err := compile(`578 while(a || b && c) {579 d580 }581 `, nil)582 AssertEqual(t, nil, err, "should be prog ok")583 ana := NewAnalysis(ast, symtab, p.Source())584 ana.Analyze()585 AssertEqualString(t, `586digraph G {587node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];588edge[fontname="Consolas",fontsize=10]589initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];590final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];591b0[label="Prog:enter\nWhileStmt:enter\n"];592b15[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];593b22[label="WhileStmt:exit\nProg:exit\n"];594b4[label="BinExpr(||):enter\nIdent(a)\n"];595b6[label="BinExpr(&&):enter\nIdent(b)\n"];596b8[label="Ident(c)\nBinExpr(&&):exit\nBinExpr(||):exit\n"];597b0->b4 [xlabel="",color="black"];598b15:s->b4:ne [xlabel="L",color="orange"];599b22->final [xlabel="",color="black"];600b4->b15 [xlabel="T",color="orange"];601b4->b6 [xlabel="",color="black"];602b6->b22 [xlabel="F",color="orange"];603b6->b8 [xlabel="",color="black"];604b8->b15 [xlabel="",color="black"];605b8->b22 [xlabel="F",color="orange"];606initial->b0 [xlabel="",color="black"];607}608`, ana.Graph().Dot(), "should be ok")609}610func TestCtrlflow_WhileCont(t *testing.T) {611 p, ast, symtab, err := compile(`612while (a) {613 continue614 c615}616 `, nil)617 AssertEqual(t, nil, err, "should be prog ok")618 ana := NewAnalysis(ast, symtab, p.Source())619 ana.Analyze()620 AssertEqualString(t, `621digraph G {622node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];623edge[fontname="Consolas",fontsize=10]624initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];625final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];626b0[label="Prog:enter\nWhileStmt:enter\n"];627b10[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];628b15[label="WhileStmt:exit\nProg:exit\n"];629b4[label="Ident(a)\n"];630b5[label="BlockStmt:enter\nContStmt:enter\nContStmt:exit\n"];631b0->b4 [xlabel="",color="black"];632b10:s->b4:ne [xlabel="L",color="red"];633b15->final [xlabel="",color="black"];634b4->b15 [xlabel="F",color="orange"];635b4->b5 [xlabel="",color="black"];636b5->b10 [xlabel="",color="red"];637b5:s->b4:ne [xlabel="L",color="orange"];638initial->b0 [xlabel="",color="black"];639}640`, ana.Graph().Dot(), "should be ok")641}642func TestCtrlflow_WhileLitCont(t *testing.T) {643 p, ast, symtab, err := compile(`644while (1) {645 continue646 c647}648 `, nil)649 AssertEqual(t, nil, err, "should be prog ok")650 ana := NewAnalysis(ast, symtab, p.Source())651 ana.Analyze()652 AssertEqualString(t, `653digraph G {654node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];655edge[fontname="Consolas",fontsize=10]656initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];657final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];658b0[label="Prog:enter\nWhileStmt:enter\n"];659b10[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];660b15[label="WhileStmt:exit\nProg:exit\n"];661b4[label="NumLit(1)\nBlockStmt:enter\nContStmt:enter\nContStmt:exit\n"];662b0->b4 [xlabel="",color="black"];663b10->b15 [xlabel="",color="red"];664b10:s->b4:ne [xlabel="L",color="red"];665b15->final [xlabel="",color="red"];666b4->b10 [xlabel="",color="red"];667b4:s->b4:ne [xlabel="L",color="orange"];668initial->b0 [xlabel="",color="black"];669}670`, ana.Graph().Dot(), "should be ok")671}672func TestCtrlflow_ParenExpr(t *testing.T) {673 p, ast, symtab, err := compile(`674 (a + b)675 `, nil)676 AssertEqual(t, nil, err, "should be prog ok")677 ana := NewAnalysis(ast, symtab, p.Source())678 ana.Analyze()679 AssertEqualString(t, `680digraph G {681node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];682edge[fontname="Consolas",fontsize=10]683initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];684final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];685b0[label="Prog:enter\nExprStmt:enter\nParenExpr:enter\nBinExpr(+):enter\nIdent(a)\nIdent(b)\nBinExpr(+):exit\nParenExpr:exit\nExprStmt:exit\nProg:exit\n"];686b0->final [xlabel="",color="black"];687initial->b0 [xlabel="",color="black"];688}689`, ana.Graph().Dot(), "should be ok")690}691func TestCtrlflow_ParenExprLogic(t *testing.T) {692 p, ast, symtab, err := compile(`693 (a && b)694 `, nil)695 AssertEqual(t, nil, err, "should be prog ok")696 ana := NewAnalysis(ast, symtab, p.Source())697 ana.Analyze()698 AssertEqualString(t, `699digraph G {700node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];701edge[fontname="Consolas",fontsize=10]702initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];703final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];704b0[label="Prog:enter\nExprStmt:enter\nParenExpr:enter\nBinExpr(&&):enter\nIdent(a)\n"];705b11[label="ParenExpr:exit\nExprStmt:exit\nProg:exit\n"];706b7[label="Ident(b)\nBinExpr(&&):exit\n"];707b0->b11 [xlabel="F",color="orange"];708b0->b7 [xlabel="",color="black"];709b11->final [xlabel="",color="black"];710b7->b11 [xlabel="",color="black"];711initial->b0 [xlabel="",color="black"];712}713`, ana.Graph().Dot(), "should be ok")714}715func TestCtrlflow_DoWhile(t *testing.T) {716 p, ast, symtab, err := compile(`717 do { a } while(b)718 `, nil)719 AssertEqual(t, nil, err, "should be prog ok")720 ana := NewAnalysis(ast, symtab, p.Source())721 ana.Analyze()722 AssertEqualString(t, `723digraph G {724node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];725edge[fontname="Consolas",fontsize=10]726initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];727final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];728b0[label="Prog:enter\nDoWhileStmt:enter\n"];729b12[label="DoWhileStmt:exit\nProg:exit\n"];730b4[label="BlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\nIdent(b)\n"];731b0->b4 [xlabel="",color="black"];732b12->final [xlabel="",color="black"];733b4->b12 [xlabel="F",color="orange"];734b4:s->b4:ne [xlabel="L",color="orange"];735initial->b0 [xlabel="",color="black"];736}737`, ana.Graph().Dot(), "should be ok")738}739func TestCtrlflow_DoWhileLogicOr(t *testing.T) {740 p, ast, symtab, err := compile(`741 do { a } while(b || c)742 `, nil)743 AssertEqual(t, nil, err, "should be prog ok")744 ana := NewAnalysis(ast, symtab, p.Source())745 ana.Analyze()746 AssertEqualString(t, `747digraph G {748node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];749edge[fontname="Consolas",fontsize=10]750initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];751final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];752b0[label="Prog:enter\nDoWhileStmt:enter\n"];753b12[label="Ident(c)\nBinExpr(||):exit\n"];754b17[label="DoWhileStmt:exit\nProg:exit\n"];755b4[label="BlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\nBinExpr(||):enter\nIdent(b)\n"];756b0->b4 [xlabel="",color="black"];757b12->b17 [xlabel="F",color="orange"];758b12:s->b4:ne [xlabel="L",color="orange"];759b17->final [xlabel="",color="black"];760b4->b12 [xlabel="",color="black"];761b4:s->b4:ne [xlabel="T,L",color="orange"];762initial->b0 [xlabel="",color="black"];763}764`, ana.Graph().Dot(), "should be ok")765}766func TestCtrlflow_DoWhileLogicAnd(t *testing.T) {767 p, ast, symtab, err := compile(`768 do { a } while(b && c)769 `, nil)770 AssertEqual(t, nil, err, "should be prog ok")771 ana := NewAnalysis(ast, symtab, p.Source())772 ana.Analyze()773 AssertEqualString(t, `774digraph G {775node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];776edge[fontname="Consolas",fontsize=10]777initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];778final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];779b0[label="Prog:enter\nDoWhileStmt:enter\n"];780b12[label="Ident(c)\nBinExpr(&&):exit\n"];781b17[label="DoWhileStmt:exit\nProg:exit\n"];782b4[label="BlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\nBinExpr(&&):enter\nIdent(b)\n"];783b0->b4 [xlabel="",color="black"];784b12->b17 [xlabel="F",color="orange"];785b12:s->b4:ne [xlabel="L",color="orange"];786b17->final [xlabel="",color="black"];787b4->b12 [xlabel="",color="black"];788b4->b17 [xlabel="F",color="orange"];789initial->b0 [xlabel="",color="black"];790}791`, ana.Graph().Dot(), "should be ok")792}793func TestCtrlflow_DoWhileLit(t *testing.T) {794 p, ast, symtab, err := compile(`795 do {796 d;797 } while(1)798 `, nil)799 AssertEqual(t, nil, err, "should be prog ok")800 ana := NewAnalysis(ast, symtab, p.Source())801 ana.Analyze()802 AssertEqualString(t, `803digraph G {804node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];805edge[fontname="Consolas",fontsize=10]806initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];807final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];808b0[label="Prog:enter\nDoWhileStmt:enter\n"];809b12[label="DoWhileStmt:exit\nProg:exit\n"];810b4[label="BlockStmt:enter\nExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\nNumLit(1)\n"];811b0->b4 [xlabel="",color="black"];812b12->final [xlabel="",color="black"];813b4->b12 [xlabel="",color="red"];814b4:s->b4:ne [xlabel="L",color="orange"];815initial->b0 [xlabel="",color="black"];816}817`, ana.Graph().Dot(), "should be ok")818}819func TestCtrlflow_DoWhileCont(t *testing.T) {820 p, ast, symtab, err := compile(`821do {822 continue823 c824} while(a)825 `, nil)826 AssertEqual(t, nil, err, "should be prog ok")827 ana := NewAnalysis(ast, symtab, p.Source())828 ana.Analyze()829 AssertEqualString(t, `830digraph G {831node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];832edge[fontname="Consolas",fontsize=10]833initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];834final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];835b0[label="Prog:enter\nDoWhileStmt:enter\n"];836b13[label="Ident(a)\n"];837b15[label="DoWhileStmt:exit\nProg:exit\n"];838b4[label="BlockStmt:enter\nContStmt:enter\nContStmt:exit\n"];839b9[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];840b0->b4 [xlabel="",color="black"];841b13->b15 [xlabel="F",color="orange"];842b13:s->b4:ne [xlabel="L",color="orange"];843b15->final [xlabel="",color="black"];844b4:s->b13:ne [xlabel="L",color="orange"];845b4->b9 [xlabel="",color="red"];846b9->b13 [xlabel="",color="red"];847initial->b0 [xlabel="",color="black"];848}849`, ana.Graph().Dot(), "should be ok")850}851func TestCtrlflow_DoWhileLitCont(t *testing.T) {852 p, ast, symtab, err := compile(`853do {854 continue855 c856} while(1)857 `, nil)858 AssertEqual(t, nil, err, "should be prog ok")859 ana := NewAnalysis(ast, symtab, p.Source())860 ana.Analyze()861 AssertEqualString(t, `862digraph G {863node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];864edge[fontname="Consolas",fontsize=10]865initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];866final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];867b0[label="Prog:enter\nDoWhileStmt:enter\n"];868b13[label="NumLit(1)\n"];869b15[label="DoWhileStmt:exit\nProg:exit\n"];870b4[label="BlockStmt:enter\nContStmt:enter\nContStmt:exit\n"];871b9[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];872b0->b4 [xlabel="",color="black"];873b13->b15 [xlabel="",color="red"];874b13:s->b4:ne [xlabel="L",color="orange"];875b15->final [xlabel="",color="black"];876b4:s->b13:ne [xlabel="L",color="orange"];877b4->b9 [xlabel="",color="red"];878b9->b13 [xlabel="",color="red"];879initial->b0 [xlabel="",color="black"];880}881`, ana.Graph().Dot(), "should be ok")882}883func TestCtrlflow_ContinueBasicEntry(t *testing.T) {884 p, ast, symtab, err := compile(`885 LabelA: while(a) {886 continue LabelA887 d888 }889 `, nil)890 AssertEqual(t, nil, err, "should be prog ok")891 ana := NewAnalysis(ast, symtab, p.Source())892 ana.Analyze()893 AssertEqualString(t, `894digraph G {895node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];896edge[fontname="Consolas",fontsize=10]897initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];898final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];899b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nWhileStmt:enter\n"];900b13[label="ExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];901b18[label="WhileStmt:exit\nLabelStmt:exit\nProg:exit\n"];902b6[label="Ident(a)\n"];903b7[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];904b0->b6 [xlabel="",color="black"];905b13:s->b6:ne [xlabel="L",color="red"];906b18->final [xlabel="",color="black"];907b6->b18 [xlabel="F",color="orange"];908b6->b7 [xlabel="",color="black"];909b7->b13 [xlabel="",color="red"];910b7:s->b6:ne [xlabel="L",color="orange"];911initial->b0 [xlabel="",color="black"];912}913 `, ana.Graph().Dot(), "should be ok")914}915func TestCtrlflow_Continue(t *testing.T) {916 p, ast, symtab, err := compile(`917 LabelA: while(a || b && c) {918 continue LabelA919 d920 }921 `, nil)922 AssertEqual(t, nil, err, "should be prog ok")923 ana := NewAnalysis(ast, symtab, p.Source())924 ana.Analyze()925 AssertEqualString(t, `926digraph G {927node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];928edge[fontname="Consolas",fontsize=10]929initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];930final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];931b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nWhileStmt:enter\n"];932b10[label="Ident(c)\nBinExpr(&&):exit\nBinExpr(||):exit\n"];933b17[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];934b23[label="ExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\n"];935b28[label="WhileStmt:exit\nLabelStmt:exit\nProg:exit\n"];936b6[label="BinExpr(||):enter\nIdent(a)\n"];937b8[label="BinExpr(&&):enter\nIdent(b)\n"];938b0->b6 [xlabel="",color="black"];939b10->b17 [xlabel="",color="black"];940b10->b28 [xlabel="F",color="orange"];941b17->b23 [xlabel="",color="red"];942b17:s->b6:ne [xlabel="L",color="orange"];943b23:s->b6:ne [xlabel="L",color="red"];944b28->final [xlabel="",color="black"];945b6->b17 [xlabel="T",color="orange"];946b6->b8 [xlabel="",color="black"];947b8->b10 [xlabel="",color="black"];948b8->b28 [xlabel="F",color="orange"];949initial->b0 [xlabel="",color="black"];950}951`, ana.Graph().Dot(), "should be ok")952}953func TestCtrlflow_ContinueOuter(t *testing.T) {954 p, ast, symtab, err := compile(`955 LabelA: while(a) {956 while(b) {957 continue LabelA958 c959 }960 }961 `, nil)962 AssertEqual(t, nil, err, "should be prog ok")963 ana := NewAnalysis(ast, symtab, p.Source())964 ana.Analyze()965 AssertEqualString(t, `966digraph G {967node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];968edge[fontname="Consolas",fontsize=10]969initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];970final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];971b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nWhileStmt:enter\n"];972b10[label="Ident(b)\n"];973b11[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];974b17[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];975b22[label="WhileStmt:exit\nBlockStmt:exit\n"];976b25[label="WhileStmt:exit\nLabelStmt:exit\nProg:exit\n"];977b6[label="Ident(a)\n"];978b7[label="BlockStmt:enter\nWhileStmt:enter\n"];979b0->b6 [xlabel="",color="black"];980b10->b11 [xlabel="",color="black"];981b10->b22 [xlabel="F",color="orange"];982b11->b17 [xlabel="",color="red"];983b11:s->b6:ne [xlabel="L",color="orange"];984b17:s->b10:ne [xlabel="L",color="red"];985b22:s->b6:ne [xlabel="L",color="orange"];986b25->final [xlabel="",color="black"];987b6->b25 [xlabel="F",color="orange"];988b6->b7 [xlabel="",color="black"];989b7->b10 [xlabel="",color="black"];990initial->b0 [xlabel="",color="black"];991}992`, ana.Graph().Dot(), "should be ok")993}994func TestCtrlflow_ContinueDoWhile(t *testing.T) {995 p, ast, symtab, err := compile(`996LabelA: do {997 a;998 do {999 continue LabelA;1000 d;1001 } while (c);1002} while (b);1003 `, nil)1004 AssertEqual(t, nil, err, "should be prog ok")1005 ana := NewAnalysis(ast, symtab, p.Source())1006 ana.Analyze()1007 AssertEqualString(t, `1008digraph G {1009node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1010edge[fontname="Consolas",fontsize=10]1011initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1012final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1013b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nDoWhileStmt:enter\n"];1014b12[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];1015b18[label="ExprStmt:enter\nIdent(d)\nExprStmt:exit\nBlockStmt:exit\nIdent(c)\n"];1016b24[label="DoWhileStmt:exit\nBlockStmt:exit\n"];1017b26[label="Ident(b)\n"];1018b28[label="DoWhileStmt:exit\nLabelStmt:exit\nProg:exit\n"];1019b6[label="BlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nDoWhileStmt:enter\n"];1020b0->b6 [xlabel="",color="black"];1021b12->b18 [xlabel="",color="red"];1022b12:s->b26:ne [xlabel="L",color="orange"];1023b18:s->b12:ne [xlabel="L",color="red"];1024b18->b24 [xlabel="F",color="red"];1025b24->b26 [xlabel="",color="red"];1026b26->b28 [xlabel="F",color="orange"];1027b26:s->b6:ne [xlabel="L",color="orange"];1028b28->final [xlabel="",color="black"];1029b6->b12 [xlabel="",color="black"];1030initial->b0 [xlabel="",color="black"];1031}1032`, ana.Graph().Dot(), "should be ok")1033}1034func TestCtrlflow_ContinueForBasic(t *testing.T) {1035 p, ast, symtab, err := compile(`1036for (let a = 1; a < 10; a++) {1037 continue1038 c1039}1040 `, nil)1041 AssertEqual(t, nil, err, "should be prog ok")1042 ana := NewAnalysis(ast, symtab, p.Source())1043 ana.Analyze()1044 AssertEqualString(t, `1045digraph G {1046node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1047edge[fontname="Consolas",fontsize=10]1048initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1049final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1050b0[label="Prog:enter\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nNumLit(1)\nVarDec:exit\nVarDecStmt:exit\n"];1051b12[label="BinExpr(<):enter\nIdent(a)\nNumLit(10)\nBinExpr(<):exit\n"];1052b18[label="UpdateExpr(++):enter\nIdent(a)\nUpdateExpr(++):exit\n"];1053b22[label="BlockStmt:enter\nContStmt:enter\nContStmt:exit\n"];1054b27[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1055b32[label="ForStmt:exit\nProg:exit\n"];1056b0->b12 [xlabel="",color="black"];1057b12->b22 [xlabel="",color="black"];1058b12->b32 [xlabel="F",color="orange"];1059b18:s->b12:ne [xlabel="L",color="orange"];1060b22:s->b18:ne [xlabel="L",color="orange"];1061b22->b27 [xlabel="",color="red"];1062b27->b18 [xlabel="",color="red"];1063b32->final [xlabel="",color="black"];1064initial->b0 [xlabel="",color="black"];1065}1066`, ana.Graph().Dot(), "should be ok")1067}1068func TestCtrlflow_ContinueForListTestLabel(t *testing.T) {1069 p, ast, symtab, err := compile(`1070LabelA: for (let a = 1; 1; a++) {1071 continue LabelA1072 c1073}1074 `, nil)1075 AssertEqual(t, nil, err, "should be prog ok")1076 ana := NewAnalysis(ast, symtab, p.Source())1077 ana.Analyze()1078 AssertEqualString(t, `1079digraph G {1080node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1081edge[fontname="Consolas",fontsize=10]1082initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1083final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1084b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nNumLit(1)\nVarDec:exit\nVarDecStmt:exit\n"];1085b14[label="NumLit(1)\n"];1086b15[label="UpdateExpr(++):enter\nIdent(a)\nUpdateExpr(++):exit\n"];1087b19[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];1088b25[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1089b30[label="ForStmt:exit\nLabelStmt:exit\nProg:exit\n"];1090b0->b14 [xlabel="",color="black"];1091b14->b19 [xlabel="",color="black"];1092b14->b30 [xlabel="",color="red"];1093b15:s->b14:ne [xlabel="L",color="orange"];1094b19:s->b15:ne [xlabel="L",color="orange"];1095b19->b25 [xlabel="",color="red"];1096b25->b15 [xlabel="",color="red"];1097b30->final [xlabel="",color="black"];1098initial->b0 [xlabel="",color="black"];1099}1100`, ana.Graph().Dot(), "should be ok")1101}1102func TestCtrlflow_ContinueForBasicLabel(t *testing.T) {1103 p, ast, symtab, err := compile(`1104LabelA: for (let a = 1; a < 10; a++) {1105 continue LabelA1106 c1107}1108 `, nil)1109 AssertEqual(t, nil, err, "should be prog ok")1110 ana := NewAnalysis(ast, symtab, p.Source())1111 ana.Analyze()1112 AssertEqualString(t, `1113digraph G {1114node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1115edge[fontname="Consolas",fontsize=10]1116initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1117final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1118b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nNumLit(1)\nVarDec:exit\nVarDecStmt:exit\n"];1119b14[label="BinExpr(<):enter\nIdent(a)\nNumLit(10)\nBinExpr(<):exit\n"];1120b20[label="UpdateExpr(++):enter\nIdent(a)\nUpdateExpr(++):exit\n"];1121b24[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];1122b30[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1123b35[label="ForStmt:exit\nLabelStmt:exit\nProg:exit\n"];1124b0->b14 [xlabel="",color="black"];1125b14->b24 [xlabel="",color="black"];1126b14->b35 [xlabel="F",color="orange"];1127b20:s->b14:ne [xlabel="L",color="orange"];1128b24:s->b20:ne [xlabel="L",color="orange"];1129b24->b30 [xlabel="",color="red"];1130b30->b20 [xlabel="",color="red"];1131b35->final [xlabel="",color="black"];1132initial->b0 [xlabel="",color="black"];1133}1134`, ana.Graph().Dot(), "should be ok")1135}1136func TestCtrlflow_ContinueFor(t *testing.T) {1137 p, ast, symtab, err := compile(`1138LabelA: for (let a = 1; a < 10; a++) {1139 for (let b = a; b < 10; b++) {1140 continue LabelA1141 c1142 }1143}1144 `, nil)1145 AssertEqual(t, nil, err, "should be prog ok")1146 ana := NewAnalysis(ast, symtab, p.Source())1147 ana.Analyze()1148 AssertEqualString(t, `1149digraph G {1150node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1151edge[fontname="Consolas",fontsize=10]1152initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1153final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1154b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nNumLit(1)\nVarDec:exit\nVarDecStmt:exit\n"];1155b14[label="BinExpr(<):enter\nIdent(a)\nNumLit(10)\nBinExpr(<):exit\n"];1156b20[label="UpdateExpr(++):enter\nIdent(a)\nUpdateExpr(++):exit\n"];1157b24[label="BlockStmt:enter\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(b)\nIdent(a)\nVarDec:exit\nVarDecStmt:exit\n"];1158b35[label="BinExpr(<):enter\nIdent(b)\nNumLit(10)\nBinExpr(<):exit\n"];1159b45[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];1160b51[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\nUpdateExpr(++):enter\nIdent(b)\nUpdateExpr(++):exit\n"];1161b56[label="ForStmt:exit\nBlockStmt:exit\n"];1162b59[label="ForStmt:exit\nLabelStmt:exit\nProg:exit\n"];1163b0->b14 [xlabel="",color="black"];1164b14->b24 [xlabel="",color="black"];1165b14->b59 [xlabel="F",color="orange"];1166b20:s->b14:ne [xlabel="L",color="orange"];1167b24->b35 [xlabel="",color="black"];1168b35->b45 [xlabel="",color="black"];1169b35->b56 [xlabel="F",color="orange"];1170b45:s->b20:ne [xlabel="L",color="orange"];1171b45->b51 [xlabel="",color="red"];1172b51:s->b35:ne [xlabel="L",color="red"];1173b56->b20 [xlabel="",color="black"];1174b59->final [xlabel="",color="black"];1175initial->b0 [xlabel="",color="black"];1176}1177`, ana.Graph().Dot(), "should be ok")1178}1179func TestCtrlflow_ContinueForNoUpdate(t *testing.T) {1180 p, ast, symtab, err := compile(`1181LabelA: for (let a = 1; a < 10; ) {1182 for (let b = a; b < 10; b++) {1183 continue LabelA1184 c1185 }1186}1187 `, nil)1188 AssertEqual(t, nil, err, "should be prog ok")1189 ana := NewAnalysis(ast, symtab, p.Source())1190 ana.Analyze()1191 AssertEqualString(t, `1192digraph G {1193node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1194edge[fontname="Consolas",fontsize=10]1195initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1196final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1197b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nNumLit(1)\nVarDec:exit\nVarDecStmt:exit\n"];1198b14[label="BinExpr(<):enter\nIdent(a)\nNumLit(10)\nBinExpr(<):exit\n"];1199b20[label="BlockStmt:enter\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(b)\nIdent(a)\nVarDec:exit\nVarDecStmt:exit\n"];1200b31[label="BinExpr(<):enter\nIdent(b)\nNumLit(10)\nBinExpr(<):exit\n"];1201b41[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];1202b47[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\nUpdateExpr(++):enter\nIdent(b)\nUpdateExpr(++):exit\n"];1203b52[label="ForStmt:exit\nBlockStmt:exit\n"];1204b55[label="ForStmt:exit\nLabelStmt:exit\nProg:exit\n"];1205b0->b14 [xlabel="",color="black"];1206b14->b20 [xlabel="",color="black"];1207b14->b55 [xlabel="F",color="orange"];1208b20->b31 [xlabel="",color="black"];1209b31->b41 [xlabel="",color="black"];1210b31->b52 [xlabel="F",color="orange"];1211b41:s->b14:ne [xlabel="L",color="orange"];1212b41->b47 [xlabel="",color="red"];1213b47:s->b31:ne [xlabel="L",color="red"];1214b52:s->b14:ne [xlabel="L",color="orange"];1215b55->final [xlabel="",color="black"];1216initial->b0 [xlabel="",color="black"];1217}1218`, ana.Graph().Dot(), "should be ok")1219}1220func TestCtrlflow_ContinueForNoTest(t *testing.T) {1221 p, ast, symtab, err := compile(`1222LabelA: for (let a = 1; ; ) {1223 for (let b = a; b < 10; b++) {1224 continue LabelA1225 c1226 }1227}1228 `, nil)1229 AssertEqual(t, nil, err, "should be prog ok")1230 ana := NewAnalysis(ast, symtab, p.Source())1231 ana.Analyze()1232 AssertEqualString(t, `1233digraph G {1234node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1235edge[fontname="Consolas",fontsize=10]1236initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1237final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1238b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nNumLit(1)\nVarDec:exit\nVarDecStmt:exit\n"];1239b14[label="BlockStmt:enter\nForStmt:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(b)\nIdent(a)\nVarDec:exit\nVarDecStmt:exit\n"];1240b25[label="BinExpr(<):enter\nIdent(b)\nNumLit(10)\nBinExpr(<):exit\n"];1241b35[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];1242b41[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\nUpdateExpr(++):enter\nIdent(b)\nUpdateExpr(++):exit\n"];1243b46[label="ForStmt:exit\nBlockStmt:exit\n"];1244b49[label="ForStmt:exit\nLabelStmt:exit\nProg:exit\n"];1245b0->b14 [xlabel="",color="black"];1246b14->b25 [xlabel="",color="black"];1247b25->b35 [xlabel="",color="black"];1248b25->b46 [xlabel="F",color="orange"];1249b35:s->b14:ne [xlabel="L",color="orange"];1250b35->b41 [xlabel="",color="red"];1251b41:s->b25:ne [xlabel="L",color="red"];1252b46:s->b14:ne [xlabel="L",color="orange"];1253b46->b49 [xlabel="",color="red"];1254b49->final [xlabel="",color="red"];1255initial->b0 [xlabel="",color="black"];1256}1257`, ana.Graph().Dot(), "should be ok")1258}1259func TestCtrlflow_ForIn(t *testing.T) {1260 p, ast, symtab, err := compile(`1261for (a in b) {1262 c1263}1264 `, nil)1265 AssertEqual(t, nil, err, "should be prog ok")1266 ana := NewAnalysis(ast, symtab, p.Source())1267 ana.Analyze()1268 AssertEqualString(t, `1269digraph G {1270node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1271edge[fontname="Consolas",fontsize=10]1272initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1273final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1274b0[label="Prog:enter\nForInOfStmt:enter\n"];1275b12[label="ForInOfStmt:exit\nProg:exit\n"];1276b4[label="Ident(a)\nIdent(b)\n"];1277b6[label="BlockStmt:enter\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1278b0->b4 [xlabel="",color="black"];1279b12->final [xlabel="",color="black"];1280b4->b12 [xlabel="F",color="orange"];1281b4->b6 [xlabel="",color="black"];1282b6:s->b4:ne [xlabel="L",color="orange"];1283initial->b0 [xlabel="",color="black"];1284}1285`, ana.Graph().Dot(), "should be ok")1286}1287func TestCtrlflow_ForInLet(t *testing.T) {1288 p, ast, symtab, err := compile(`1289for (let a in b) {1290 c1291}1292 `, nil)1293 AssertEqual(t, nil, err, "should be prog ok")1294 ana := NewAnalysis(ast, symtab, p.Source())1295 ana.Analyze()1296 AssertEqualString(t, `1297digraph G {1298node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1299edge[fontname="Consolas",fontsize=10]1300initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1301final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1302b0[label="Prog:enter\nForInOfStmt:enter\n"];1303b12[label="BlockStmt:enter\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1304b18[label="ForInOfStmt:exit\nProg:exit\n"];1305b4[label="VarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDecStmt:exit\nIdent(b)\n"];1306b0->b4 [xlabel="",color="black"];1307b12:s->b4:ne [xlabel="L",color="orange"];1308b18->final [xlabel="",color="black"];1309b4->b12 [xlabel="",color="black"];1310b4->b18 [xlabel="F",color="orange"];1311initial->b0 [xlabel="",color="black"];1312}1313`, ana.Graph().Dot(), "should be ok")1314}1315func TestCtrlflow_ContinueForIn(t *testing.T) {1316 p, ast, symtab, err := compile(`1317s1318LabelA: for(a in b) {1319 for(c in d) {1320 if (e && f) {1321 continue LabelA1322 }1323 g1324 }1325 h1326}1327 `, nil)1328 AssertEqual(t, nil, err, "should be prog ok")1329 ana := NewAnalysis(ast, symtab, p.Source())1330 ana.Analyze()1331 AssertEqualString(t, `1332digraph G {1333node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1334edge[fontname="Consolas",fontsize=10]1335initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1336final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1337b0[label="Prog:enter\nExprStmt:enter\nIdent(s)\nExprStmt:exit\nLabelStmt:enter\nIdent(LabelA)\nForInOfStmt:enter\n"];1338b11[label="BlockStmt:enter\nForInOfStmt:enter\n"];1339b14[label="Ident(c)\nIdent(d)\n"];1340b16[label="BlockStmt:enter\nIfStmt:enter\nBinExpr(&&):enter\nIdent(e)\n"];1341b21[label="Ident(f)\nBinExpr(&&):exit\n"];1342b25[label="BlockStmt:enter\nContStmt:enter\nIdent(LabelA)\nContStmt:exit\n"];1343b31[label="BlockStmt:exit\n"];1344b33[label="IfStmt:exit\nExprStmt:enter\nIdent(g)\nExprStmt:exit\nBlockStmt:exit\n"];1345b38[label="ForInOfStmt:exit\nExprStmt:enter\nIdent(h)\nExprStmt:exit\nBlockStmt:exit\n"];1346b43[label="ForInOfStmt:exit\nLabelStmt:exit\nProg:exit\n"];1347b9[label="Ident(a)\nIdent(b)\n"];1348b0->b9 [xlabel="",color="black"];1349b11->b14 [xlabel="",color="black"];1350b14->b16 [xlabel="",color="black"];1351b14->b38 [xlabel="F",color="orange"];1352b16->b21 [xlabel="",color="black"];1353b16->b33 [xlabel="F",color="orange"];1354b21->b25 [xlabel="",color="black"];1355b21->b33 [xlabel="F",color="orange"];1356b25->b31 [xlabel="",color="red"];1357b25:s->b9:ne [xlabel="L",color="orange"];1358b31->b33 [xlabel="",color="red"];1359b33:s->b14:ne [xlabel="L",color="orange"];1360b38:s->b9:ne [xlabel="L",color="orange"];1361b43->final [xlabel="",color="black"];1362b9->b11 [xlabel="",color="black"];1363b9->b43 [xlabel="F",color="orange"];1364initial->b0 [xlabel="",color="black"];1365}1366`, ana.Graph().Dot(), "should be ok")1367}1368func TestCtrlflow_ContinueNoLabel(t *testing.T) {1369 p, ast, symtab, err := compile(`1370while(a) {1371 if (a > 10) {1372 continue;1373 b1374 }1375 a--1376}1377 `, nil)1378 AssertEqual(t, nil, err, "should be prog ok")1379 ana := NewAnalysis(ast, symtab, p.Source())1380 ana.Analyze()1381 AssertEqualString(t, `1382digraph G {1383node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1384edge[fontname="Consolas",fontsize=10]1385initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1386final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1387b0[label="Prog:enter\nWhileStmt:enter\n"];1388b14[label="BlockStmt:enter\nContStmt:enter\nContStmt:exit\n"];1389b19[label="ExprStmt:enter\nIdent(b)\nExprStmt:exit\nBlockStmt:exit\n"];1390b24[label="IfStmt:exit\nExprStmt:enter\nUpdateExpr(--):enter\nIdent(a)\nUpdateExpr(--):exit\nExprStmt:exit\nBlockStmt:exit\n"];1391b33[label="WhileStmt:exit\nProg:exit\n"];1392b4[label="Ident(a)\n"];1393b5[label="BlockStmt:enter\nIfStmt:enter\nBinExpr(>):enter\nIdent(a)\nNumLit(10)\nBinExpr(>):exit\n"];1394b0->b4 [xlabel="",color="black"];1395b14->b19 [xlabel="",color="red"];1396b14:s->b4:ne [xlabel="L",color="orange"];1397b19->b24 [xlabel="",color="red"];1398b24:s->b4:ne [xlabel="L",color="orange"];1399b33->final [xlabel="",color="black"];1400b4->b33 [xlabel="F",color="orange"];1401b4->b5 [xlabel="",color="black"];1402b5->b14 [xlabel="",color="black"];1403b5->b24 [xlabel="F",color="orange"];1404initial->b0 [xlabel="",color="black"];1405}1406`, ana.Graph().Dot(), "should be ok")1407}1408func TestCtrlflow_BreakNoLabelForNest(t *testing.T) {1409 p, ast, symtab, err := compile(`1410while(a) {1411 if (a > 10) break;1412 a--1413}1414 `, nil)1415 AssertEqual(t, nil, err, "should be prog ok")1416 ana := NewAnalysis(ast, symtab, p.Source())1417 ana.Analyze()1418 AssertEqualString(t, `1419digraph G {1420node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1421edge[fontname="Consolas",fontsize=10]1422initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1423final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1424b0[label="Prog:enter\nWhileStmt:enter\n"];1425b14[label="BrkStmt:enter\nBrkStmt:exit\n"];1426b18[label="IfStmt:exit\nExprStmt:enter\nUpdateExpr(--):enter\nIdent(a)\nUpdateExpr(--):exit\nExprStmt:exit\nBlockStmt:exit\n"];1427b27[label="WhileStmt:exit\nProg:exit\n"];1428b4[label="Ident(a)\n"];1429b5[label="BlockStmt:enter\nIfStmt:enter\nBinExpr(>):enter\nIdent(a)\nNumLit(10)\nBinExpr(>):exit\n"];1430b0->b4 [xlabel="",color="black"];1431b14->b18 [xlabel="",color="red"];1432b14->b27 [xlabel="U",color="orange"];1433b18:s->b4:ne [xlabel="L",color="orange"];1434b27->final [xlabel="",color="black"];1435b4->b27 [xlabel="F",color="orange"];1436b4->b5 [xlabel="",color="black"];1437b5->b14 [xlabel="",color="black"];1438b5->b18 [xlabel="F",color="orange"];1439initial->b0 [xlabel="",color="black"];1440}1441`, ana.Graph().Dot(), "should be ok")1442}1443func TestCtrlflow_BreakNoLabelFor(t *testing.T) {1444 p, ast, symtab, err := compile(`1445for (; a; ) {1446 if (a > 10) {1447 break;1448 c1449 }1450 a--1451}1452 `, nil)1453 AssertEqual(t, nil, err, "should be prog ok")1454 ana := NewAnalysis(ast, symtab, p.Source())1455 ana.Analyze()1456 AssertEqualString(t, `1457digraph G {1458node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1459edge[fontname="Consolas",fontsize=10]1460initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1461final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1462b0[label="Prog:enter\nForStmt:enter\n"];1463b14[label="BlockStmt:enter\nBrkStmt:enter\nBrkStmt:exit\n"];1464b18[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1465b23[label="IfStmt:exit\nExprStmt:enter\nUpdateExpr(--):enter\nIdent(a)\nUpdateExpr(--):exit\nExprStmt:exit\nBlockStmt:exit\n"];1466b32[label="ForStmt:exit\nProg:exit\n"];1467b4[label="Ident(a)\n"];1468b5[label="BlockStmt:enter\nIfStmt:enter\nBinExpr(>):enter\nIdent(a)\nNumLit(10)\nBinExpr(>):exit\n"];1469b0->b4 [xlabel="",color="black"];1470b14->b18 [xlabel="",color="red"];1471b14->b32 [xlabel="U",color="orange"];1472b18->b23 [xlabel="",color="red"];1473b23:s->b4:ne [xlabel="L",color="orange"];1474b32->final [xlabel="",color="black"];1475b4->b32 [xlabel="F",color="orange"];1476b4->b5 [xlabel="",color="black"];1477b5->b14 [xlabel="",color="black"];1478b5->b23 [xlabel="F",color="orange"];1479initial->b0 [xlabel="",color="black"];1480}1481`, ana.Graph().Dot(), "should be ok")1482}1483func TestCtrlflow_BreakLabelWhile(t *testing.T) {1484 p, ast, symtab, err := compile(`1485 LabelA: while(a) {1486 for( ; b; ) {1487 break LabelA1488 c1489 }1490 }1491 `, nil)1492 AssertEqual(t, nil, err, "should be prog ok")1493 ana := NewAnalysis(ast, symtab, p.Source())1494 ana.Analyze()1495 AssertEqualString(t, `1496digraph G {1497node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1498edge[fontname="Consolas",fontsize=10]1499initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1500final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1501b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nWhileStmt:enter\n"];1502b10[label="Ident(b)\n"];1503b11[label="BlockStmt:enter\nBrkStmt:enter\nIdent(LabelA)\nBrkStmt:exit\n"];1504b16[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1505b21[label="ForStmt:exit\nBlockStmt:exit\n"];1506b24[label="WhileStmt:exit\nLabelStmt:exit\nProg:exit\n"];1507b6[label="Ident(a)\n"];1508b7[label="BlockStmt:enter\nForStmt:enter\n"];1509b0->b6 [xlabel="",color="black"];1510b10->b11 [xlabel="",color="black"];1511b10->b21 [xlabel="F",color="orange"];1512b11->b16 [xlabel="",color="red"];1513b11->b24 [xlabel="U",color="orange"];1514b16:s->b10:ne [xlabel="L",color="red"];1515b21:s->b6:ne [xlabel="L",color="orange"];1516b24->final [xlabel="",color="black"];1517b6->b24 [xlabel="F",color="orange"];1518b6->b7 [xlabel="",color="black"];1519b7->b10 [xlabel="",color="black"];1520initial->b0 [xlabel="",color="black"];1521}1522`, ana.Graph().Dot(), "should be ok")1523}1524func TestCtrlflow_BreakNoLabelWhile(t *testing.T) {1525 p, ast, symtab, err := compile(`1526 LabelA: while(a) {1527 for(;b;) {1528 break1529 c1530 }1531 }1532 `, nil)1533 AssertEqual(t, nil, err, "should be prog ok")1534 ana := NewAnalysis(ast, symtab, p.Source())1535 ana.Analyze()1536 AssertEqualString(t, `1537digraph G {1538node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1539edge[fontname="Consolas",fontsize=10]1540initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1541final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1542b0[label="Prog:enter\nLabelStmt:enter\nIdent(LabelA)\nWhileStmt:enter\n"];1543b10[label="Ident(b)\n"];1544b11[label="BlockStmt:enter\nBrkStmt:enter\nBrkStmt:exit\n"];1545b15[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1546b20[label="ForStmt:exit\nBlockStmt:exit\n"];1547b23[label="WhileStmt:exit\nLabelStmt:exit\nProg:exit\n"];1548b6[label="Ident(a)\n"];1549b7[label="BlockStmt:enter\nForStmt:enter\n"];1550b0->b6 [xlabel="",color="black"];1551b10->b11 [xlabel="",color="black"];1552b10->b20 [xlabel="F",color="orange"];1553b11->b15 [xlabel="",color="red"];1554b11->b20 [xlabel="U",color="orange"];1555b15:s->b10:ne [xlabel="L",color="red"];1556b20:s->b6:ne [xlabel="L",color="orange"];1557b23->final [xlabel="",color="black"];1558b6->b23 [xlabel="F",color="orange"];1559b6->b7 [xlabel="",color="black"];1560b7->b10 [xlabel="",color="black"];1561initial->b0 [xlabel="",color="black"];1562}1563`, ana.Graph().Dot(), "should be ok")1564}1565func TestCtrlflow_CallExpr(t *testing.T) {1566 p, ast, symtab, err := compile(`1567 fn()1568 `, nil)1569 AssertEqual(t, nil, err, "should be prog ok")1570 ana := NewAnalysis(ast, symtab, p.Source())1571 ana.Analyze()1572 AssertEqualString(t, `1573digraph G {1574node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1575edge[fontname="Consolas",fontsize=10]1576initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1577final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1578b0[label="Prog:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fn)\nCallExpr:exit\nExprStmt:exit\nProg:exit\n"];1579b0->final [xlabel="",color="black"];1580initial->b0 [xlabel="",color="black"];1581}1582`, ana.Graph().Dot(), "should be ok")1583}1584func TestCtrlflow_CallExprArgs(t *testing.T) {1585 p, ast, symtab, err := compile(`1586 fn(1, 2, a && b)1587 `, nil)1588 AssertEqual(t, nil, err, "should be prog ok")1589 ana := NewAnalysis(ast, symtab, p.Source())1590 ana.Analyze()1591 AssertEqualString(t, `1592digraph G {1593node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1594edge[fontname="Consolas",fontsize=10]1595initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1596final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1597b0[label="Prog:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fn)\nNumLit(1)\nNumLit(2)\nBinExpr(&&):enter\nIdent(a)\n"];1598b10[label="Ident(b)\nBinExpr(&&):exit\n"];1599b14[label="CallExpr:exit\nExprStmt:exit\nProg:exit\n"];1600b0->b10 [xlabel="",color="black"];1601b0->b14 [xlabel="F",color="orange"];1602b10->b14 [xlabel="",color="black"];1603b14->final [xlabel="",color="black"];1604initial->b0 [xlabel="",color="black"];1605}1606`, ana.Graph().Dot(), "should be ok")1607}1608func TestCtrlflow_CallExprArgsBin(t *testing.T) {1609 p, ast, symtab, err := compile(`1610 fn(1, a || b && c, d && e)1611 `, nil)1612 AssertEqual(t, nil, err, "should be prog ok")1613 ana := NewAnalysis(ast, symtab, p.Source())1614 ana.Analyze()1615 AssertEqualString(t, `1616digraph G {1617node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1618edge[fontname="Consolas",fontsize=10]1619initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1620final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1621b0[label="Prog:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fn)\nNumLit(1)\nBinExpr(||):enter\nIdent(a)\n"];1622b11[label="Ident(c)\nBinExpr(&&):exit\nBinExpr(||):exit\n"];1623b18[label="BinExpr(&&):enter\nIdent(d)\n"];1624b20[label="Ident(e)\nBinExpr(&&):exit\n"];1625b24[label="CallExpr:exit\nExprStmt:exit\nProg:exit\n"];1626b9[label="BinExpr(&&):enter\nIdent(b)\n"];1627b0->b18 [xlabel="T",color="orange"];1628b0->b9 [xlabel="",color="black"];1629b11->b18 [xlabel="",color="black"];1630b18->b20 [xlabel="",color="black"];1631b18->b24 [xlabel="F",color="orange"];1632b20->b24 [xlabel="",color="black"];1633b24->final [xlabel="",color="black"];1634b9->b11 [xlabel="",color="black"];1635b9->b18 [xlabel="F",color="orange"];1636initial->b0 [xlabel="",color="black"];1637}1638`, ana.Graph().Dot(), "should be ok")1639}1640func TestCtrlflow_Nullish(t *testing.T) {1641 p, ast, symtab, err := compile(`1642 const foo = null ?? 'default string';1643 `, nil)1644 AssertEqual(t, nil, err, "should be prog ok")1645 ana := NewAnalysis(ast, symtab, p.Source())1646 ana.Analyze()1647 AssertEqualString(t, `1648digraph G {1649node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1650edge[fontname="Consolas",fontsize=10]1651initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1652final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1653b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(foo)\nBinExpr(??):enter\nNullLit\n"];1654b12[label="VarDec:exit\nVarDecStmt:exit\nProg:exit\n"];1655b8[label="StrLit\nBinExpr(??):exit\n"];1656b0->b12 [xlabel="T",color="orange"];1657b0->b8 [xlabel="",color="black"];1658b12->final [xlabel="",color="black"];1659b8->b12 [xlabel="",color="black"];1660initial->b0 [xlabel="",color="black"];1661}1662`, ana.Graph().Dot(), "should be ok")1663}1664func TestCtrlflow_FnDecOuter(t *testing.T) {1665 p, ast, symtab, err := compile(`1666function f() {1667}1668 `, nil)1669 AssertEqual(t, nil, err, "should be prog ok")1670 ana := NewAnalysis(ast, symtab, p.Source())1671 ana.Analyze()1672 AssertEqualString(t, `1673digraph G {1674node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1675edge[fontname="Consolas",fontsize=10]1676initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1677final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1678b0[label="Prog:enter\nFnDec\nProg:exit\n"];1679b0->final [xlabel="",color="black"];1680initial->b0 [xlabel="",color="black"];1681}1682`, ana.Graph().Dot(), "should be ok")1683}1684func TestCtrlflow_FnDecBody(t *testing.T) {1685 p, ast, symtab, err := compile(`1686function f() {1687 a1688}1689 `, nil)1690 AssertEqual(t, nil, err, "should be prog ok")1691 ana := NewAnalysis(ast, symtab, p.Source())1692 ana.Analyze()1693 fn := ast.(*parser.Prog).Body()[0]1694 fnGraph := ana.AnalysisCtx().GraphOf(fn)1695 AssertEqualString(t, `1696digraph G {1697node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1698edge[fontname="Consolas",fontsize=10]1699initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1700final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1701b9[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];1702b9->final [xlabel="",color="black"];1703initial->b9 [xlabel="",color="black"];1704}1705`, fnGraph.Dot(), "should be ok")1706}1707func TestCtrlflow_ReturnNoArg(t *testing.T) {1708 p, ast, symtab, err := compile(`1709function f() {1710 a;1711 return;1712 b1713}1714 `, nil)1715 AssertEqual(t, nil, err, "should be prog ok")1716 ana := NewAnalysis(ast, symtab, p.Source())1717 ana.Analyze()1718 fn := ast.(*parser.Prog).Body()[0]1719 fnGraph := ana.AnalysisCtx().GraphOf(fn)1720 AssertEqualString(t, `1721digraph G {1722node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1723edge[fontname="Consolas",fontsize=10]1724initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1725final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1726b10[label="ExprStmt:enter\nIdent(b)\nExprStmt:exit\nBlockStmt:exit\n"];1727b14[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];1728b15[label="FnDec:exit\n"];1729b10->b15 [xlabel="",color="red"];1730b14->b10 [xlabel="",color="red"];1731b14->b15 [xlabel="U",color="orange"];1732b15->final [xlabel="",color="black"];1733initial->b14 [xlabel="",color="black"];1734}1735`, fnGraph.Dot(), "should be ok")1736}1737func TestCtrlflow_ReturnArg(t *testing.T) {1738 p, ast, symtab, err := compile(`1739function f() {1740 a;1741 return a ?? b;1742 c1743}1744 `, nil)1745 AssertEqual(t, nil, err, "should be prog ok")1746 ana := NewAnalysis(ast, symtab, p.Source())1747 ana.Analyze()1748 fn := ast.(*parser.Prog).Body()[0]1749 fnGraph := ana.AnalysisCtx().GraphOf(fn)1750 AssertEqualString(t, `1751digraph G {1752node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1753edge[fontname="Consolas",fontsize=10]1754initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1755final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1756b11[label="Ident(b)\nBinExpr(??):exit\n"];1757b15[label="RetStmt:exit\n"];1758b16[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1759b20[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nRetStmt:enter\nBinExpr(??):enter\nIdent(a)\n"];1760b21[label="FnDec:exit\n"];1761b11->b15 [xlabel="",color="black"];1762b15->b16 [xlabel="",color="red"];1763b15->b21 [xlabel="U",color="orange"];1764b16->b21 [xlabel="",color="red"];1765b20->b11 [xlabel="",color="black"];1766b20->b15 [xlabel="T",color="orange"];1767b21->final [xlabel="",color="black"];1768initial->b20 [xlabel="",color="black"];1769}1770`, fnGraph.Dot(), "should be ok")1771}1772func TestCtrlflow_ReturnArgBinNested(t *testing.T) {1773 p, ast, symtab, err := compile(`1774function f() {1775 a;1776 return a && b || c;1777 c1778}1779 `, nil)1780 AssertEqual(t, nil, err, "should be prog ok")1781 ana := NewAnalysis(ast, symtab, p.Source())1782 ana.Analyze()1783 fn := ast.(*parser.Prog).Body()[0]1784 fnGraph := ana.AnalysisCtx().GraphOf(fn)1785 AssertEqualString(t, `1786digraph G {1787node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1788edge[fontname="Consolas",fontsize=10]1789initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1790final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1791b12[label="Ident(b)\nBinExpr(&&):exit\n"];1792b16[label="Ident(c)\nBinExpr(||):exit\n"];1793b20[label="RetStmt:exit\n"];1794b21[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];1795b25[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nRetStmt:enter\nBinExpr(||):enter\nBinExpr(&&):enter\nIdent(a)\n"];1796b26[label="FnDec:exit\n"];1797b12->b16 [xlabel="",color="black"];1798b12->b20 [xlabel="T",color="orange"];1799b16->b20 [xlabel="",color="black"];1800b20->b21 [xlabel="",color="red"];1801b20->b26 [xlabel="U",color="orange"];1802b21->b26 [xlabel="",color="red"];1803b25->b12 [xlabel="",color="black"];1804b25->b16 [xlabel="F",color="orange"];1805b26->final [xlabel="",color="black"];1806initial->b25 [xlabel="",color="black"];1807}1808`, fnGraph.Dot(), "should be ok")1809}1810func TestCtrlflow_FnDecParam(t *testing.T) {1811 p, ast, symtab, err := compile(`1812function f(a, b) {}1813 `, nil)1814 AssertEqual(t, nil, err, "should be prog ok")1815 ana := NewAnalysis(ast, symtab, p.Source())1816 ana.Analyze()1817 fn := ast.(*parser.Prog).Body()[0]1818 fnGraph := ana.AnalysisCtx().GraphOf(fn)1819 AssertEqualString(t, `1820digraph G {1821node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1822edge[fontname="Consolas",fontsize=10]1823initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1824final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1825b8[label="FnDec:enter\nIdent(f)\nIdent(a)\nIdent(b)\nBlockStmt:enter\nBlockStmt:exit\nFnDec:exit\n"];1826b8->final [xlabel="",color="black"];1827initial->b8 [xlabel="",color="black"];1828}1829`, fnGraph.Dot(), "should be ok")1830}1831func TestCtrlflow_FnExpr(t *testing.T) {1832 p, ast, symtab, err := compile(`1833fn = function f(a, b) { c }1834 `, nil)1835 AssertEqual(t, nil, err, "should be prog ok")1836 ana := NewAnalysis(ast, symtab, p.Source())1837 ana.Analyze()1838 fn := ast.(*parser.Prog).Body()[0].(*parser.ExprStmt).Expr().(*parser.AssignExpr).Rhs()1839 fnGraph := ana.AnalysisCtx().GraphOf(fn)1840 AssertEqualString(t, `1841digraph G {1842node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1843edge[fontname="Consolas",fontsize=10]1844initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1845final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1846b11[label="FnDec:enter\nIdent(f)\nIdent(a)\nIdent(b)\nBlockStmt:enter\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];1847b11->final [xlabel="",color="black"];1848initial->b11 [xlabel="",color="black"];1849}1850 `, fnGraph.Dot(), "should be ok")1851}1852func TestCtrlflow_ArrLit(t *testing.T) {1853 p, ast, symtab, err := compile(`1854a = [b, c, d ?? e]1855 `, nil)1856 AssertEqual(t, nil, err, "should be prog ok")1857 ana := NewAnalysis(ast, symtab, p.Source())1858 ana.Analyze()1859 AssertEqualString(t, `1860digraph G {1861node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1862edge[fontname="Consolas",fontsize=10]1863initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1864final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1865b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nArrLit:enter\nIdent(b)\nIdent(c)\nBinExpr(??):enter\nIdent(d)\n"];1866b11[label="Ident(e)\nBinExpr(??):exit\n"];1867b15[label="ArrLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];1868b0->b11 [xlabel="",color="black"];1869b0->b15 [xlabel="T",color="orange"];1870b11->b15 [xlabel="",color="black"];1871b15->final [xlabel="",color="black"];1872initial->b0 [xlabel="",color="black"];1873}1874`, ana.Graph().Dot(), "should be ok")1875}1876func TestCtrlflow_ObjLit(t *testing.T) {1877 p, ast, symtab, err := compile(`1878a = { b: 1, c: d }1879 `, nil)1880 AssertEqual(t, nil, err, "should be prog ok")1881 ana := NewAnalysis(ast, symtab, p.Source())1882 ana.Analyze()1883 AssertEqualString(t, `1884digraph G {1885node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1886edge[fontname="Consolas",fontsize=10]1887initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1888final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1889b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nObjLit:enter\nProp:enter\nIdent(b)\nNumLit(1)\nProp:exit\nProp:enter\nIdent(c)\nIdent(d)\nProp:exit\nObjLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];1890b0->final [xlabel="",color="black"];1891initial->b0 [xlabel="",color="black"];1892}1893`, ana.Graph().Dot(), "should be ok")1894}1895func TestCtrlflow_ObjLitNest(t *testing.T) {1896 p, ast, symtab, err := compile(`1897a = { b: {c: 1} }1898 `, nil)1899 AssertEqual(t, nil, err, "should be prog ok")1900 ana := NewAnalysis(ast, symtab, p.Source())1901 ana.Analyze()1902 AssertEqualString(t, `1903digraph G {1904node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1905edge[fontname="Consolas",fontsize=10]1906initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1907final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1908b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nObjLit:enter\nProp:enter\nIdent(b)\nObjLit:enter\nProp:enter\nIdent(c)\nNumLit(1)\nProp:exit\nObjLit:exit\nProp:exit\nObjLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];1909b0->final [xlabel="",color="black"];1910initial->b0 [xlabel="",color="black"];1911}1912`, ana.Graph().Dot(), "should be ok")1913}1914func TestCtrlflow_ObjLitFn(t *testing.T) {1915 p, ast, symtab, err := compile(`1916a = { b: function (a, b) {} }1917 `, nil)1918 AssertEqual(t, nil, err, "should be prog ok")1919 ana := NewAnalysis(ast, symtab, p.Source())1920 ana.Analyze()1921 rhs := ast.(*parser.Prog).Body()[0].(*parser.ExprStmt).Expr().(*parser.AssignExpr).Rhs().(*parser.ObjLit)1922 fn := rhs.Props()[0].(*parser.Prop).Val()1923 fnGraph := ana.AnalysisCtx().GraphOf(fn)1924 AssertEqualString(t, `1925digraph G {1926node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1927edge[fontname="Consolas",fontsize=10]1928initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1929final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1930b7[label="FnDec:enter\nIdent(a)\nIdent(b)\nBlockStmt:enter\nBlockStmt:exit\nFnDec:exit\n"];1931b7->final [xlabel="",color="black"];1932initial->b7 [xlabel="",color="black"];1933}1934`, fnGraph.Dot(), "fn should be ok")1935}1936func TestCtrlflow_EmptyExpr(t *testing.T) {1937 p, ast, symtab, err := compile(`1938a;1939;1940 `, nil)1941 AssertEqual(t, nil, err, "should be prog ok")1942 ana := NewAnalysis(ast, symtab, p.Source())1943 ana.Analyze()1944 AssertEqualString(t, `1945digraph G {1946node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1947edge[fontname="Consolas",fontsize=10]1948initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1949final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1950b0[label="Prog:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nProg:exit\n"];1951b0->final [xlabel="",color="black"];1952initial->b0 [xlabel="",color="black"];1953}1954`, ana.Graph().Dot(), "should be ok")1955}1956func TestCtrlflow_DebugStmt(t *testing.T) {1957 p, ast, symtab, err := compile(`1958a1959debugger1960 `, nil)1961 AssertEqual(t, nil, err, "should be prog ok")1962 ana := NewAnalysis(ast, symtab, p.Source())1963 ana.Analyze()1964 AssertEqualString(t, `1965digraph G {1966node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1967edge[fontname="Consolas",fontsize=10]1968initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1969final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1970b0[label="Prog:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nDebugStmt\nProg:exit\n"];1971b0->final [xlabel="",color="black"];1972initial->b0 [xlabel="",color="black"];1973}1974`, ana.Graph().Dot(), "should be ok")1975}1976func TestCtrlflow_LitNull(t *testing.T) {1977 p, ast, symtab, err := compile(`1978a = null1979null1980 `, nil)1981 AssertEqual(t, nil, err, "should be prog ok")1982 ana := NewAnalysis(ast, symtab, p.Source())1983 ana.Analyze()1984 AssertEqualString(t, `1985digraph G {1986node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];1987edge[fontname="Consolas",fontsize=10]1988initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];1989final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];1990b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nNullLit\nAssignExpr:exit\nExprStmt:exit\nExprStmt:enter\nNullLit\nExprStmt:exit\nProg:exit\n"];1991b0->final [xlabel="",color="black"];1992initial->b0 [xlabel="",color="black"];1993}1994`, ana.Graph().Dot(), "should be ok")1995}1996func TestCtrlflow_LitBool(t *testing.T) {1997 p, ast, symtab, err := compile(`1998a = true1999false2000 `, nil)2001 AssertEqual(t, nil, err, "should be prog ok")2002 ana := NewAnalysis(ast, symtab, p.Source())2003 ana.Analyze()2004 AssertEqualString(t, `2005digraph G {2006node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2007edge[fontname="Consolas",fontsize=10]2008initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2009final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2010b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nBoolLit\nAssignExpr:exit\nExprStmt:exit\nExprStmt:enter\nBoolLit\nExprStmt:exit\nProg:exit\n"];2011b0->final [xlabel="",color="black"];2012initial->b0 [xlabel="",color="black"];2013}2014`, ana.Graph().Dot(), "should be ok")2015}2016func TestCtrlflow_LitNum(t *testing.T) {2017 p, ast, symtab, err := compile(`2018a = 120191.12020 `, nil)2021 AssertEqual(t, nil, err, "should be prog ok")2022 ana := NewAnalysis(ast, symtab, p.Source())2023 ana.Analyze()2024 AssertEqualString(t, `2025digraph G {2026node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2027edge[fontname="Consolas",fontsize=10]2028initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2029final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2030b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nNumLit(1)\nAssignExpr:exit\nExprStmt:exit\nExprStmt:enter\nNumLit(1.1)\nExprStmt:exit\nProg:exit\n"];2031b0->final [xlabel="",color="black"];2032initial->b0 [xlabel="",color="black"];2033}2034`, ana.Graph().Dot(), "should be ok")2035}2036func TestCtrlflow_LitStr(t *testing.T) {2037 p, ast, symtab, err := compile(`2038a = "str"2039'str'2040 `, nil)2041 AssertEqual(t, nil, err, "should be prog ok")2042 ana := NewAnalysis(ast, symtab, p.Source())2043 ana.Analyze()2044 AssertEqualString(t, `2045digraph G {2046node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2047edge[fontname="Consolas",fontsize=10]2048initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2049final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2050b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nStrLit\nAssignExpr:exit\nExprStmt:exit\nExprStmt:enter\nStrLit\nExprStmt:exit\nProg:exit\n"];2051b0->final [xlabel="",color="black"];2052initial->b0 [xlabel="",color="black"];2053}2054`, ana.Graph().Dot(), "should be ok")2055}2056func TestCtrlflow_LitArr(t *testing.T) {2057 p, ast, symtab, err := compile(`2058a = [1, 2, 3];2059[1, 2, 3]2060 `, nil)2061 AssertEqual(t, nil, err, "should be prog ok")2062 ana := NewAnalysis(ast, symtab, p.Source())2063 ana.Analyze()2064 AssertEqualString(t, `2065digraph G {2066node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2067edge[fontname="Consolas",fontsize=10]2068initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2069final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2070b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nArrLit:enter\nNumLit(1)\nNumLit(2)\nNumLit(3)\nArrLit:exit\nAssignExpr:exit\nExprStmt:exit\nExprStmt:enter\nArrLit:enter\nNumLit(1)\nNumLit(2)\nNumLit(3)\nArrLit:exit\nExprStmt:exit\nProg:exit\n"];2071b0->final [xlabel="",color="black"];2072initial->b0 [xlabel="",color="black"];2073}2074`, ana.Graph().Dot(), "should be ok")2075}2076func TestCtrlflow_LitArrNest(t *testing.T) {2077 p, ast, symtab, err := compile(`2078a = [1, 2, [4, 5, 6]];2079 `, nil)2080 AssertEqual(t, nil, err, "should be prog ok")2081 ana := NewAnalysis(ast, symtab, p.Source())2082 ana.Analyze()2083 AssertEqualString(t, `2084digraph G {2085node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2086edge[fontname="Consolas",fontsize=10]2087initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2088final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2089b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nArrLit:enter\nNumLit(1)\nNumLit(2)\nArrLit:enter\nNumLit(4)\nNumLit(5)\nNumLit(6)\nArrLit:exit\nArrLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];2090b0->final [xlabel="",color="black"];2091initial->b0 [xlabel="",color="black"];2092}2093`, ana.Graph().Dot(), "should be ok")2094}2095func TestCtrlflow_LitArrSpread(t *testing.T) {2096 p, ast, symtab, err := compile(`2097 a = [1, 2, ...d];2098 `, nil)2099 AssertEqual(t, nil, err, "should be prog ok")2100 ana := NewAnalysis(ast, symtab, p.Source())2101 ana.Analyze()2102 AssertEqualString(t, `2103digraph G {2104node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2105edge[fontname="Consolas",fontsize=10]2106initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2107final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2108b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nArrLit:enter\nNumLit(1)\nNumLit(2)\nSpread:enter\nIdent(d)\nSpread:exit\nArrLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];2109b0->final [xlabel="",color="black"];2110initial->b0 [xlabel="",color="black"];2111}2112`, ana.Graph().Dot(), "should be ok")2113}2114func TestCtrlflow_LitObj(t *testing.T) {2115 p, ast, symtab, err := compile(`2116a = { b: { c: 1 }, ...d };2117 `, nil)2118 AssertEqual(t, nil, err, "should be prog ok")2119 ana := NewAnalysis(ast, symtab, p.Source())2120 ana.Analyze()2121 AssertEqualString(t, `2122digraph G {2123node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2124edge[fontname="Consolas",fontsize=10]2125initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2126final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2127b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nObjLit:enter\nProp:enter\nIdent(b)\nObjLit:enter\nProp:enter\nIdent(c)\nNumLit(1)\nProp:exit\nObjLit:exit\nProp:exit\nSpread:enter\nIdent(d)\nSpread:exit\nObjLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];2128b0->final [xlabel="",color="black"];2129initial->b0 [xlabel="",color="black"];2130}2131`, ana.Graph().Dot(), "should be ok")2132}2133func TestCtrlflow_LitObjSpread(t *testing.T) {2134 p, ast, symtab, err := compile(`2135a = {b: { c: 1 } };2136({b: { c: 1 } })2137 `, nil)2138 AssertEqual(t, nil, err, "should be prog ok")2139 ana := NewAnalysis(ast, symtab, p.Source())2140 ana.Analyze()2141 AssertEqualString(t, `2142digraph G {2143node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2144edge[fontname="Consolas",fontsize=10]2145initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2146final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2147b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nObjLit:enter\nProp:enter\nIdent(b)\nObjLit:enter\nProp:enter\nIdent(c)\nNumLit(1)\nProp:exit\nObjLit:exit\nProp:exit\nObjLit:exit\nAssignExpr:exit\nExprStmt:exit\nExprStmt:enter\nParenExpr:enter\nObjLit:enter\nProp:enter\nIdent(b)\nObjLit:enter\nProp:enter\nIdent(c)\nNumLit(1)\nProp:exit\nObjLit:exit\nProp:exit\nObjLit:exit\nParenExpr:exit\nExprStmt:exit\nProg:exit\n"];2148b0->final [xlabel="",color="black"];2149initial->b0 [xlabel="",color="black"];2150}2151`, ana.Graph().Dot(), "should be ok")2152}2153func TestCtrlflow_LitObjNest(t *testing.T) {2154 p, ast, symtab, err := compile(`2155a = {b: { c: 1, d: [1, { f: 2}] } };2156 `, nil)2157 AssertEqual(t, nil, err, "should be prog ok")2158 ana := NewAnalysis(ast, symtab, p.Source())2159 ana.Analyze()2160 AssertEqualString(t, `2161digraph G {2162node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2163edge[fontname="Consolas",fontsize=10]2164initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2165final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2166b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nObjLit:enter\nProp:enter\nIdent(b)\nObjLit:enter\nProp:enter\nIdent(c)\nNumLit(1)\nProp:exit\nProp:enter\nIdent(d)\nArrLit:enter\nNumLit(1)\nObjLit:enter\nProp:enter\nIdent(f)\nNumLit(2)\nProp:exit\nObjLit:exit\nArrLit:exit\nProp:exit\nObjLit:exit\nProp:exit\nObjLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];2167b0->final [xlabel="",color="black"];2168initial->b0 [xlabel="",color="black"];2169}2170`, ana.Graph().Dot(), "should be ok")2171}2172func TestCtrlflow_LitRegexp(t *testing.T) {2173 p, ast, symtab, err := compile(`2174a = /reg/;2175 `, nil)2176 AssertEqual(t, nil, err, "should be prog ok")2177 ana := NewAnalysis(ast, symtab, p.Source())2178 ana.Analyze()2179 AssertEqualString(t, `2180digraph G {2181node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2182edge[fontname="Consolas",fontsize=10]2183initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2184final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2185b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nRegLit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];2186b0->final [xlabel="",color="black"];2187initial->b0 [xlabel="",color="black"];2188}2189`, ana.Graph().Dot(), "should be ok")2190}2191func TestCtrlflow_SwitchCase(t *testing.T) {2192 p, ast, symtab, err := compile(`2193switch(a) {2194 case 1: doSth1();2195 case 2: doSth2();2196 case 3: doSth3();2197 default: doSthDefault();2198}2199 `, nil)2200 AssertEqual(t, nil, err, "should be prog ok")2201 ana := NewAnalysis(ast, symtab, p.Source())2202 ana.Analyze()2203 AssertEqualString(t, `2204digraph G {2205node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2206edge[fontname="Consolas",fontsize=10]2207initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2208final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2209b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2210b19[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2211b28[label="SwitchCase:enter\nNumLit(2)\n"];2212b32[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2213b41[label="SwitchCase:enter\nNumLit(3)\n"];2214b45[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\nSwitchStmt:exit\nProg:exit\n"];2215b53[label="SwitchCase:enter\n"];2216b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2217b0->b28 [xlabel="F",color="orange"];2218b0->b6 [xlabel="",color="black"];2219b19->b32 [xlabel="",color="black"];2220b28->b19 [xlabel="",color="black"];2221b28->b41 [xlabel="F",color="orange"];2222b32->b45 [xlabel="",color="black"];2223b41->b32 [xlabel="",color="black"];2224b41->b53 [xlabel="F",color="orange"];2225b45->final [xlabel="",color="black"];2226b53->b45 [xlabel="",color="black"];2227b6->b19 [xlabel="",color="black"];2228initial->b0 [xlabel="",color="black"];2229}2230`, ana.Graph().Dot(), "should be ok")2231}2232func TestCtrlflow_SwitchCaseBlk(t *testing.T) {2233 p, ast, symtab, err := compile(`2234switch(a) {2235 case 1: doSth1();2236 case 2: {2237 doSth21();2238 doSth22();2239 }2240 case 3: doSth3();2241 default: doSthDefault();2242}2243 `, nil)2244 AssertEqual(t, nil, err, "should be prog ok")2245 ana := NewAnalysis(ast, symtab, p.Source())2246 ana.Analyze()2247 AssertEqualString(t, `2248digraph G {2249node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2250edge[fontname="Consolas",fontsize=10]2251initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2252final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2253b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2254b19[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth21)\nCallExpr:exit\nExprStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth22)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nSwitchCase:exit\n"];2255b36[label="SwitchCase:enter\nNumLit(2)\n"];2256b40[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2257b49[label="SwitchCase:enter\nNumLit(3)\n"];2258b53[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\nSwitchStmt:exit\nProg:exit\n"];2259b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2260b61[label="SwitchCase:enter\n"];2261b0->b36 [xlabel="F",color="orange"];2262b0->b6 [xlabel="",color="black"];2263b19->b40 [xlabel="",color="black"];2264b36->b19 [xlabel="",color="black"];2265b36->b49 [xlabel="F",color="orange"];2266b40->b53 [xlabel="",color="black"];2267b49->b40 [xlabel="",color="black"];2268b49->b61 [xlabel="F",color="orange"];2269b53->final [xlabel="",color="black"];2270b61->b53 [xlabel="",color="black"];2271b6->b19 [xlabel="",color="black"];2272initial->b0 [xlabel="",color="black"];2273}2274`, ana.Graph().Dot(), "should be ok")2275}2276func TestCtrlflow_SwitchCaseFallthrough(t *testing.T) {2277 p, ast, symtab, err := compile(`2278switch(a) {2279 case 1:2280 case 2: {2281 doSth21();2282 doSth22();2283 }2284 case 3: doSth3();2285 default: doSthDefault();2286}2287 `, nil)2288 AssertEqual(t, nil, err, "should be prog ok")2289 ana := NewAnalysis(ast, symtab, p.Source())2290 ana.Analyze()2291 AssertEqualString(t, `2292digraph G {2293node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2294edge[fontname="Consolas",fontsize=10]2295initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2296final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2297b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2298b12[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth21)\nCallExpr:exit\nExprStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth22)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nSwitchCase:exit\n"];2299b29[label="SwitchCase:enter\nNumLit(2)\n"];2300b33[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2301b42[label="SwitchCase:enter\nNumLit(3)\n"];2302b46[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\nSwitchStmt:exit\nProg:exit\n"];2303b54[label="SwitchCase:enter\n"];2304b9[label="SwitchCase:exit\n"];2305b0->b29 [xlabel="F",color="orange"];2306b0->b9 [xlabel="",color="black"];2307b12->b33 [xlabel="",color="black"];2308b29->b12 [xlabel="",color="black"];2309b29->b42 [xlabel="F",color="orange"];2310b33->b46 [xlabel="",color="black"];2311b42->b33 [xlabel="",color="black"];2312b42->b54 [xlabel="F",color="orange"];2313b46->final [xlabel="",color="black"];2314b54->b46 [xlabel="",color="black"];2315b9->b12 [xlabel="",color="black"];2316initial->b0 [xlabel="",color="black"];2317}2318`, ana.Graph().Dot(), "should be ok")2319}2320func TestCtrlflow_SwitchCaseDefaultFirst(t *testing.T) {2321 p, ast, symtab, err := compile(`2322switch(a) {2323 default: doSthDefault();2324 case 1: doSth1();2325 case 2: doSth2();2326}2327 `, nil)2328 AssertEqual(t, nil, err, "should be prog ok")2329 ana := NewAnalysis(ast, symtab, p.Source())2330 ana.Analyze()2331 AssertEqualString(t, `2332digraph G {2333node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2334edge[fontname="Consolas",fontsize=10]2335initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2336final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2337b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\n"];2338b18[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2339b27[label="SwitchCase:enter\nNumLit(1)\n"];2340b31[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2341b40[label="SwitchCase:enter\nNumLit(2)\n"];2342b43[label="SwitchStmt:exit\nProg:exit\n"];2343b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2344b0->b27 [xlabel="",color="black"];2345b18->b31 [xlabel="",color="black"];2346b27->b18 [xlabel="",color="black"];2347b27->b40 [xlabel="F",color="orange"];2348b31->b43 [xlabel="",color="black"];2349b40->b31 [xlabel="",color="black"];2350b40->b6 [xlabel="F",color="orange"];2351b43->final [xlabel="",color="black"];2352b6->b18 [xlabel="",color="black"];2353initial->b0 [xlabel="",color="black"];2354}2355`, ana.Graph().Dot(), "should be ok")2356}2357func TestCtrlflow_SwitchCaseDefaultInMiddle(t *testing.T) {2358 p, ast, symtab, err := compile(`2359switch(a) {2360 case 1: doSth1();2361 default: doSthDefault();2362 case 2: doSth2();2363 case 3: doSth3();2364}2365 `, nil)2366 AssertEqual(t, nil, err, "should be prog ok")2367 ana := NewAnalysis(ast, symtab, p.Source())2368 ana.Analyze()2369 AssertEqualString(t, `2370digraph G {2371node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2372edge[fontname="Consolas",fontsize=10]2373initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2374final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2375b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2376b19[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2377b27[label="SwitchCase:enter\n"];2378b31[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2379b40[label="SwitchCase:enter\nNumLit(2)\n"];2380b44[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2381b53[label="SwitchCase:enter\nNumLit(3)\n"];2382b56[label="SwitchStmt:exit\nProg:exit\n"];2383b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2384b0->b27 [xlabel="F",color="orange"];2385b0->b6 [xlabel="",color="black"];2386b19->b31 [xlabel="",color="black"];2387b27->b40 [xlabel="",color="black"];2388b31->b44 [xlabel="",color="black"];2389b40->b31 [xlabel="",color="black"];2390b40->b53 [xlabel="F",color="orange"];2391b44->b56 [xlabel="",color="black"];2392b53->b19 [xlabel="F",color="orange"];2393b53->b44 [xlabel="",color="black"];2394b56->final [xlabel="",color="black"];2395b6->b19 [xlabel="",color="black"];2396initial->b0 [xlabel="",color="black"];2397}2398`, ana.Graph().Dot(), "should be ok")2399}2400func TestCtrlflow_SwitchCaseDefaultInMiddleFallthrough(t *testing.T) {2401 p, ast, symtab, err := compile(`2402switch(a) {2403 case 1:2404 default: doSthDefault();2405 case 2: doSth2();2406 case 3: doSth3();2407}2408 `, nil)2409 AssertEqual(t, nil, err, "should be prog ok")2410 ana := NewAnalysis(ast, symtab, p.Source())2411 ana.Analyze()2412 AssertEqualString(t, `2413digraph G {2414node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2415edge[fontname="Consolas",fontsize=10]2416initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2417final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2418b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2419b12[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2420b20[label="SwitchCase:enter\n"];2421b24[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2422b33[label="SwitchCase:enter\nNumLit(2)\n"];2423b37[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2424b46[label="SwitchCase:enter\nNumLit(3)\n"];2425b49[label="SwitchStmt:exit\nProg:exit\n"];2426b9[label="SwitchCase:exit\n"];2427b0->b20 [xlabel="F",color="orange"];2428b0->b9 [xlabel="",color="black"];2429b12->b24 [xlabel="",color="black"];2430b20->b33 [xlabel="",color="black"];2431b24->b37 [xlabel="",color="black"];2432b33->b24 [xlabel="",color="black"];2433b33->b46 [xlabel="F",color="orange"];2434b37->b49 [xlabel="",color="black"];2435b46->b12 [xlabel="F",color="orange"];2436b46->b37 [xlabel="",color="black"];2437b49->final [xlabel="",color="black"];2438b9->b12 [xlabel="",color="black"];2439initial->b0 [xlabel="",color="black"];2440}2441`, ana.Graph().Dot(), "should be ok")2442}2443func TestCtrlflow_SwitchCaseBasic(t *testing.T) {2444 p, ast, symtab, err := compile(`2445switch(a) {2446 case 1: doSth1(); break;2447 case 2: doSth2();2448 case 3: doSth3();2449}2450 `, nil)2451 AssertEqual(t, nil, err, "should be prog ok")2452 ana := NewAnalysis(ast, symtab, p.Source())2453 ana.Analyze()2454 AssertEqualString(t, `2455digraph G {2456node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2457edge[fontname="Consolas",fontsize=10]2458initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2459final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2460b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2461b18[label="SwitchCase:exit\n"];2462b21[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2463b30[label="SwitchCase:enter\nNumLit(2)\n"];2464b34[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2465b43[label="SwitchCase:enter\nNumLit(3)\n"];2466b46[label="SwitchStmt:exit\n"];2467b47[label="Prog:exit\n"];2468b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nBrkStmt:enter\nBrkStmt:exit\n"];2469b0->b30 [xlabel="F",color="orange"];2470b0->b6 [xlabel="",color="black"];2471b18->b21 [xlabel="",color="red"];2472b21->b34 [xlabel="",color="black"];2473b30->b21 [xlabel="",color="black"];2474b30->b43 [xlabel="F",color="orange"];2475b34->b46 [xlabel="",color="black"];2476b43->b34 [xlabel="",color="black"];2477b43->b46 [xlabel="F",color="orange"];2478b46->b47 [xlabel="",color="black"];2479b47->final [xlabel="",color="black"];2480b6->b18 [xlabel="",color="red"];2481b6->b46 [xlabel="U",color="orange"];2482initial->b0 [xlabel="",color="black"];2483}2484`, ana.Graph().Dot(), "should be ok")2485}2486func TestCtrlflow_SwitchCaseBreak(t *testing.T) {2487 p, ast, symtab, err := compile(`2488switch(a) {2489 case 1: doSth1(); break;2490 default: doSthDefault();2491 case 2: doSth2();2492 case 3: doSth3();2493}2494 `, nil)2495 AssertEqual(t, nil, err, "should be prog ok")2496 ana := NewAnalysis(ast, symtab, p.Source())2497 ana.Analyze()2498 AssertEqualString(t, `2499digraph G {2500node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2501edge[fontname="Consolas",fontsize=10]2502initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2503final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2504b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2505b18[label="SwitchCase:exit\n"];2506b21[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2507b29[label="SwitchCase:enter\n"];2508b33[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2509b42[label="SwitchCase:enter\nNumLit(2)\n"];2510b46[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2511b55[label="SwitchCase:enter\nNumLit(3)\n"];2512b58[label="SwitchStmt:exit\n"];2513b59[label="Prog:exit\n"];2514b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nBrkStmt:enter\nBrkStmt:exit\n"];2515b0->b29 [xlabel="F",color="orange"];2516b0->b6 [xlabel="",color="black"];2517b18->b21 [xlabel="",color="red"];2518b21->b33 [xlabel="",color="black"];2519b29->b42 [xlabel="",color="black"];2520b33->b46 [xlabel="",color="black"];2521b42->b33 [xlabel="",color="black"];2522b42->b55 [xlabel="F",color="orange"];2523b46->b58 [xlabel="",color="black"];2524b55->b21 [xlabel="F",color="orange"];2525b55->b46 [xlabel="",color="black"];2526b58->b59 [xlabel="",color="black"];2527b59->final [xlabel="",color="black"];2528b6->b18 [xlabel="",color="red"];2529b6->b58 [xlabel="U",color="orange"];2530initial->b0 [xlabel="",color="black"];2531}2532`, ana.Graph().Dot(), "should be ok")2533}2534func TestCtrlflow_SwitchCaseBreakInBlock(t *testing.T) {2535 p, ast, symtab, err := compile(`2536switch(a) {2537 case 1: {2538 doSth1(); break;2539 }2540 default: doSthDefault();2541 case 2: doSth2();2542 case 3: doSth3();2543}2544 `, nil)2545 AssertEqual(t, nil, err, "should be prog ok")2546 ana := NewAnalysis(ast, symtab, p.Source())2547 ana.Analyze()2548 AssertEqualString(t, `2549digraph G {2550node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2551edge[fontname="Consolas",fontsize=10]2552initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2553final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2554b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2555b18[label="BlockStmt:exit\nSwitchCase:exit\n"];2556b23[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2557b31[label="SwitchCase:enter\n"];2558b35[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2559b44[label="SwitchCase:enter\nNumLit(2)\n"];2560b48[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2561b57[label="SwitchCase:enter\nNumLit(3)\n"];2562b6[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nBrkStmt:enter\nBrkStmt:exit\n"];2563b60[label="SwitchStmt:exit\n"];2564b61[label="Prog:exit\n"];2565b0->b31 [xlabel="F",color="orange"];2566b0->b6 [xlabel="",color="black"];2567b18->b23 [xlabel="",color="red"];2568b23->b35 [xlabel="",color="black"];2569b31->b44 [xlabel="",color="black"];2570b35->b48 [xlabel="",color="black"];2571b44->b35 [xlabel="",color="black"];2572b44->b57 [xlabel="F",color="orange"];2573b48->b60 [xlabel="",color="black"];2574b57->b23 [xlabel="F",color="orange"];2575b57->b48 [xlabel="",color="black"];2576b60->b61 [xlabel="",color="black"];2577b61->final [xlabel="",color="black"];2578b6->b18 [xlabel="",color="red"];2579b6->b60 [xlabel="U",color="orange"];2580initial->b0 [xlabel="",color="black"];2581}2582`, ana.Graph().Dot(), "should be ok")2583}2584func TestCtrlflow_SwitchCaseBreakSiblingBlock(t *testing.T) {2585 p, ast, symtab, err := compile(`2586switch(a) {2587 case 1: {2588 doSth1();2589 }2590 break;2591 default: doSthDefault();2592 case 2: doSth2();2593 case 3: doSth3();2594}2595 `, nil)2596 AssertEqual(t, nil, err, "should be prog ok")2597 ana := NewAnalysis(ast, symtab, p.Source())2598 ana.Analyze()2599 AssertEqualString(t, `2600digraph G {2601node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2602edge[fontname="Consolas",fontsize=10]2603initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2604final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2605b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2606b20[label="SwitchCase:exit\n"];2607b23[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2608b31[label="SwitchCase:enter\n"];2609b35[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2610b44[label="SwitchCase:enter\nNumLit(2)\n"];2611b48[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2612b57[label="SwitchCase:enter\nNumLit(3)\n"];2613b6[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nBrkStmt:enter\nBrkStmt:exit\n"];2614b60[label="SwitchStmt:exit\n"];2615b61[label="Prog:exit\n"];2616b0->b31 [xlabel="F",color="orange"];2617b0->b6 [xlabel="",color="black"];2618b20->b23 [xlabel="",color="red"];2619b23->b35 [xlabel="",color="black"];2620b31->b44 [xlabel="",color="black"];2621b35->b48 [xlabel="",color="black"];2622b44->b35 [xlabel="",color="black"];2623b44->b57 [xlabel="F",color="orange"];2624b48->b60 [xlabel="",color="black"];2625b57->b23 [xlabel="F",color="orange"];2626b57->b48 [xlabel="",color="black"];2627b60->b61 [xlabel="",color="black"];2628b61->final [xlabel="",color="black"];2629b6->b20 [xlabel="",color="red"];2630b6->b60 [xlabel="U",color="orange"];2631initial->b0 [xlabel="",color="black"];2632}2633`, ana.Graph().Dot(), "should be ok")2634}2635func TestCtrlflow_SwitchCaseBreakDefaultFirst(t *testing.T) {2636 p, ast, symtab, err := compile(`2637switch(a) {2638 default: doSthDefault(); break;2639 case 2: doSth2();2640 case 3: doSth3();2641}2642 `, nil)2643 AssertEqual(t, nil, err, "should be prog ok")2644 ana := NewAnalysis(ast, symtab, p.Source())2645 ana.Analyze()2646 AssertEqualString(t, `2647digraph G {2648node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2649edge[fontname="Consolas",fontsize=10]2650initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2651final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2652b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\n"];2653b17[label="SwitchCase:exit\n"];2654b20[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2655b29[label="SwitchCase:enter\nNumLit(2)\n"];2656b33[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2657b42[label="SwitchCase:enter\nNumLit(3)\n"];2658b45[label="SwitchStmt:exit\n"];2659b46[label="Prog:exit\n"];2660b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nBrkStmt:enter\nBrkStmt:exit\n"];2661b0->b29 [xlabel="",color="black"];2662b17->b20 [xlabel="",color="red"];2663b20->b33 [xlabel="",color="black"];2664b29->b20 [xlabel="",color="black"];2665b29->b42 [xlabel="F",color="orange"];2666b33->b45 [xlabel="",color="black"];2667b42->b33 [xlabel="",color="black"];2668b42->b6 [xlabel="F",color="orange"];2669b45->b46 [xlabel="",color="black"];2670b46->final [xlabel="",color="black"];2671b6->b17 [xlabel="",color="red"];2672b6->b45 [xlabel="U",color="orange"];2673initial->b0 [xlabel="",color="black"];2674}2675`, ana.Graph().Dot(), "should be ok")2676}2677func TestCtrlflow_SwitchCaseBreakDefaultMiddle(t *testing.T) {2678 p, ast, symtab, err := compile(`2679switch(a) {2680 case 1: doSth1();2681 default: doSthDefault(); break;2682 case 2: doSth2();2683 case 3: doSth3();2684}2685 `, nil)2686 AssertEqual(t, nil, err, "should be prog ok")2687 ana := NewAnalysis(ast, symtab, p.Source())2688 ana.Analyze()2689 AssertEqualString(t, `2690digraph G {2691node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2692edge[fontname="Consolas",fontsize=10]2693initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2694final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2695b0[label="Prog:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2696b19[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nBrkStmt:enter\nBrkStmt:exit\n"];2697b29[label="SwitchCase:enter\n"];2698b30[label="SwitchCase:exit\n"];2699b33[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2700b42[label="SwitchCase:enter\nNumLit(2)\n"];2701b46[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2702b55[label="SwitchCase:enter\nNumLit(3)\n"];2703b58[label="SwitchStmt:exit\n"];2704b59[label="Prog:exit\n"];2705b6[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2706b0->b29 [xlabel="F",color="orange"];2707b0->b6 [xlabel="",color="black"];2708b19->b30 [xlabel="",color="red"];2709b19->b58 [xlabel="U",color="orange"];2710b29->b42 [xlabel="",color="black"];2711b30->b33 [xlabel="",color="red"];2712b33->b46 [xlabel="",color="black"];2713b42->b33 [xlabel="",color="black"];2714b42->b55 [xlabel="F",color="orange"];2715b46->b58 [xlabel="",color="black"];2716b55->b19 [xlabel="F",color="orange"];2717b55->b46 [xlabel="",color="black"];2718b58->b59 [xlabel="",color="black"];2719b59->final [xlabel="",color="black"];2720b6->b19 [xlabel="",color="black"];2721initial->b0 [xlabel="",color="black"];2722}2723`, ana.Graph().Dot(), "should be ok")2724}2725func TestCtrlflow_SwitchCaseReturnDefaultMiddle(t *testing.T) {2726 p, ast, symtab, err := compile(`2727function f() {2728 switch(a) {2729 case 1: {2730 doSth1(); return;2731 }2732 default: doSthDefault();2733 case 2: doSth2();2734 }2735}2736 `, nil)2737 AssertEqual(t, nil, err, "should be prog ok")2738 ana := NewAnalysis(ast, symtab, p.Source())2739 ana.Analyze()2740 fn := ast.(*parser.Prog).Body()[0]2741 fnGraph := ana.AnalysisCtx().GraphOf(fn)2742 AssertEqualString(t, `2743digraph G {2744node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2745edge[fontname="Consolas",fontsize=10]2746initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2747final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2748b20[label="BlockStmt:exit\nSwitchCase:exit\n"];2749b25[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSthDefault)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2750b33[label="SwitchCase:enter\n"];2751b37[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nSwitchCase:exit\n"];2752b46[label="SwitchCase:enter\nNumLit(2)\n"];2753b49[label="SwitchStmt:exit\nBlockStmt:exit\n"];2754b51[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nSwitchStmt:enter\nIdent(a)\nSwitchCase:enter\nNumLit(1)\n"];2755b52[label="FnDec:exit\n"];2756b8[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];2757b20->b25 [xlabel="",color="red"];2758b25->b37 [xlabel="",color="black"];2759b33->b46 [xlabel="",color="black"];2760b37->b49 [xlabel="",color="black"];2761b46->b25 [xlabel="F",color="orange"];2762b46->b37 [xlabel="",color="black"];2763b49->b52 [xlabel="",color="black"];2764b51->b33 [xlabel="F",color="orange"];2765b51->b8 [xlabel="",color="black"];2766b52->final [xlabel="",color="black"];2767b8->b20 [xlabel="",color="red"];2768b8->b52 [xlabel="U",color="orange"];2769initial->b51 [xlabel="",color="black"];2770}2771`, fnGraph.Dot(), "should be ok")2772}2773func TestCtrlflow_TryCatchBasic(t *testing.T) {2774 p, ast, symtab, err := compile(`2775try {2776 doSth1();2777 doSth2();2778} catch (error) {2779 log(error);2780}2781 `, nil)2782 AssertEqual(t, nil, err, "should be prog ok")2783 ana := NewAnalysis(ast, symtab, p.Source())2784 ana.Analyze()2785 AssertEqualString(t, `2786digraph G {2787node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2788edge[fontname="Consolas",fontsize=10]2789initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2790final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2791b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2792b19[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];2793b33[label="TryStmt:exit\nProg:exit\n"];2794b0->b19 [xlabel="E",color="orange"];2795b0->b33 [xlabel="",color="black"];2796b19->b33 [xlabel="",color="black"];2797b33->final [xlabel="",color="black"];2798initial->b0 [xlabel="",color="black"];2799}2800`, ana.Graph().Dot(), "should be ok")2801}2802func TestCtrlflow_TryCatchIf(t *testing.T) {2803 p, ast, symtab, err := compile(`2804try {2805 if (a) {2806 doSth1();2807 }2808 doSth2();2809} catch (error) {2810 log(error);2811}2812 `, nil)2813 AssertEqual(t, nil, err, "should be prog ok")2814 ana := NewAnalysis(ast, symtab, p.Source())2815 ana.Analyze()2816 AssertEqualString(t, `2817digraph G {2818node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2819edge[fontname="Consolas",fontsize=10]2820initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2821final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2822b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\nIfStmt:enter\nIdent(a)\n"];2823b18[label="IfStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2824b26[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];2825b40[label="TryStmt:exit\nProg:exit\n"];2826b8[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2827b0->b18 [xlabel="F",color="orange"];2828b0->b26 [xlabel="E",color="orange"];2829b0->b8 [xlabel="",color="black"];2830b18->b26 [xlabel="E",color="orange"];2831b18->b40 [xlabel="",color="black"];2832b26->b40 [xlabel="",color="black"];2833b40->final [xlabel="",color="black"];2834b8->b18 [xlabel="",color="black"];2835b8->b26 [xlabel="E",color="orange"];2836initial->b0 [xlabel="",color="black"];2837}2838`, ana.Graph().Dot(), "should be ok")2839}2840func TestCtrlflow_TryCatchFin(t *testing.T) {2841 p, ast, symtab, err := compile(`2842try {2843 doSth1();2844 doSth2();2845} catch (error) {2846 log(error);2847} finally {2848 fin();2849}2850 `, nil)2851 AssertEqual(t, nil, err, "should be prog ok")2852 ana := NewAnalysis(ast, symtab, p.Source())2853 ana.Analyze()2854 AssertEqualString(t, `2855digraph G {2856node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2857edge[fontname="Consolas",fontsize=10]2858initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2859final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2860b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2861b19[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];2862b33[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nTryStmt:exit\nProg:exit\n"];2863b0->b19 [xlabel="E",color="orange"];2864b0->b33 [xlabel="",color="black"];2865b19->b33 [xlabel="",color="black"];2866b33->final [xlabel="",color="black"];2867initial->b0 [xlabel="",color="black"];2868}2869`, ana.Graph().Dot(), "should be ok")2870}2871func TestCtrlflow_TryReturn(t *testing.T) {2872 p, ast, symtab, err := compile(`2873function f() {2874 try {2875 doSth1();2876 return;2877 doSth2();2878 } catch (error) {2879 log(error);2880 }2881 afterFin()2882}2883 `, nil)2884 AssertEqual(t, nil, err, "should be prog ok")2885 ana := NewAnalysis(ast, symtab, p.Source())2886 ana.Analyze()2887 fn := ast.(*parser.Prog).Body()[0]2888 fnGraph := ana.AnalysisCtx().GraphOf(fn)2889 AssertEqualString(t, `2890digraph G {2891node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2892edge[fontname="Consolas",fontsize=10]2893initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2894final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2895b16[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2896b23[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];2897b37[label="TryStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(afterFin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2898b45[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];2899b46[label="FnDec:exit\n"];2900b16->b23 [xlabel="E",color="red"];2901b16->b37 [xlabel="",color="red"];2902b23->b37 [xlabel="",color="black"];2903b37->b46 [xlabel="",color="black"];2904b45->b16 [xlabel="",color="red"];2905b45->b23 [xlabel="E",color="orange"];2906b45->b46 [xlabel="U",color="orange"];2907b46->final [xlabel="",color="black"];2908initial->b45 [xlabel="",color="black"];2909}2910`, fnGraph.Dot(), "should be ok")2911}2912func TestCtrlflow_TryReturnFin(t *testing.T) {2913 p, ast, symtab, err := compile(`2914function f() {2915 try {2916 doSth1();2917 return;2918 doSth2();2919 } catch (error) {2920 log(error);2921 } finally {2922 fin()2923 }2924 afterFin()2925}2926 `, nil)2927 AssertEqual(t, nil, err, "should be prog ok")2928 ana := NewAnalysis(ast, symtab, p.Source())2929 ana.Analyze()2930 fn := ast.(*parser.Prog).Body()[0]2931 fnGraph := ana.AnalysisCtx().GraphOf(fn)2932 AssertEqualString(t, `2933digraph G {2934node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2935edge[fontname="Consolas",fontsize=10]2936initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2937final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2938b16[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2939b23[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];2940b37[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2941b46[label="TryStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(afterFin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2942b54[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];2943b55[label="FnDec:exit\n"];2944b16->b23 [xlabel="E",color="red"];2945b16->b37 [xlabel="",color="red"];2946b23->b37 [xlabel="",color="black"];2947b37->b46 [xlabel="",color="black"];2948b37->b55 [xlabel="P",color="orange"];2949b46->b55 [xlabel="",color="black"];2950b54->b16 [xlabel="",color="red"];2951b54->b23 [xlabel="E",color="orange"];2952b54->b37 [xlabel="U,P",color="orange"];2953b55->final [xlabel="",color="black"];2954initial->b54 [xlabel="",color="black"];2955}2956`, fnGraph.Dot(), "should be ok")2957}2958func TestCtrlflow_TryReturnFinIf(t *testing.T) {2959 p, ast, symtab, err := compile(`2960function f() {2961 try {2962 doSth1();2963 return;2964 doSth2();2965 } catch (error) {2966 log(error);2967 } finally {2968 if (a) {2969 fin1()2970 }2971 fin2()2972 }2973 afterFin()2974}2975 `, nil)2976 AssertEqual(t, nil, err, "should be prog ok")2977 ana := NewAnalysis(ast, symtab, p.Source())2978 ana.Analyze()2979 fn := ast.(*parser.Prog).Body()[0]2980 fnGraph := ana.AnalysisCtx().GraphOf(fn)2981 AssertEqualString(t, `2982digraph G {2983node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];2984edge[fontname="Consolas",fontsize=10]2985initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];2986final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];2987b16[label="ExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2988b23[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];2989b37[label="BlockStmt:enter\nIfStmt:enter\nIdent(a)\n"];2990b41[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin1)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2991b51[label="IfStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(fin2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2992b59[label="TryStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(afterFin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];2993b67[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];2994b68[label="FnDec:exit\n"];2995b16->b23 [xlabel="E",color="red"];2996b16->b37 [xlabel="",color="red"];2997b23->b37 [xlabel="",color="black"];2998b37->b41 [xlabel="",color="black"];2999b37->b51 [xlabel="F",color="orange"];3000b41->b51 [xlabel="",color="black"];3001b51->b59 [xlabel="",color="black"];3002b51->b68 [xlabel="P",color="orange"];3003b59->b68 [xlabel="",color="black"];3004b67->b16 [xlabel="",color="red"];3005b67->b23 [xlabel="E",color="orange"];3006b67->b37 [xlabel="U,P",color="orange"];3007b68->final [xlabel="",color="black"];3008initial->b67 [xlabel="",color="black"];3009}3010`, fnGraph.Dot(), "should be ok")3011}3012func TestCtrlflow_TryCatchReturn(t *testing.T) {3013 p, ast, symtab, err := compile(`3014function f() {3015 try {3016 doSth1();3017 doSth2();3018 } catch (error) {3019 return3020 log(error);3021 }3022 afterFin()3023}3024 `, nil)3025 AssertEqual(t, nil, err, "should be prog ok")3026 ana := NewAnalysis(ast, symtab, p.Source())3027 ana.Analyze()3028 fn := ast.(*parser.Prog).Body()[0]3029 fnGraph := ana.AnalysisCtx().GraphOf(fn)3030 AssertEqualString(t, `3031digraph G {3032node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3033edge[fontname="Consolas",fontsize=10]3034initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3035final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3036b21[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nRetStmt:enter\nRetStmt:exit\n"];3037b27[label="ExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3038b37[label="TryStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(afterFin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3039b45[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3040b46[label="FnDec:exit\n"];3041b21->b27 [xlabel="",color="red"];3042b21->b46 [xlabel="U",color="orange"];3043b27->b37 [xlabel="",color="red"];3044b37->b46 [xlabel="",color="black"];3045b45->b21 [xlabel="E",color="orange"];3046b45->b37 [xlabel="",color="black"];3047b46->final [xlabel="",color="black"];3048initial->b45 [xlabel="",color="black"];3049}3050`, fnGraph.Dot(), "should be ok")3051}3052func TestCtrlflow_TryCatchReturnFin(t *testing.T) {3053 p, ast, symtab, err := compile(`3054function f() {3055 try {3056 doSth1();3057 doSth2();3058 } catch (error) {3059 return3060 log(error);3061 } finally {3062 fin()3063 }3064 afterFin()3065}3066 `, nil)3067 AssertEqual(t, nil, err, "should be prog ok")3068 ana := NewAnalysis(ast, symtab, p.Source())3069 ana.Analyze()3070 fn := ast.(*parser.Prog).Body()[0]3071 fnGraph := ana.AnalysisCtx().GraphOf(fn)3072 AssertEqualString(t, `3073digraph G {3074node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3075edge[fontname="Consolas",fontsize=10]3076initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3077final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3078b21[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nRetStmt:enter\nRetStmt:exit\n"];3079b27[label="ExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3080b37[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3081b46[label="TryStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(afterFin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3082b54[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3083b55[label="FnDec:exit\n"];3084b21->b27 [xlabel="",color="red"];3085b21->b37 [xlabel="U,P",color="orange"];3086b27->b37 [xlabel="",color="red"];3087b37->b46 [xlabel="",color="black"];3088b37->b55 [xlabel="P",color="orange"];3089b46->b55 [xlabel="",color="black"];3090b54->b21 [xlabel="E",color="orange"];3091b54->b37 [xlabel="",color="black"];3092b55->final [xlabel="",color="black"];3093initial->b54 [xlabel="",color="black"];3094}3095`, fnGraph.Dot(), "should be ok")3096}3097func TestCtrlflow_TryFinReturn(t *testing.T) {3098 p, ast, symtab, err := compile(`3099function f() {3100 try {3101 doSth1();3102 doSth2();3103 } catch (error) {3104 return3105 log(error);3106 } finally {3107 fin()3108 return3109 }3110 afterFin()3111}3112 `, nil)3113 AssertEqual(t, nil, err, "should be prog ok")3114 ana := NewAnalysis(ast, symtab, p.Source())3115 ana.Analyze()3116 fn := ast.(*parser.Prog).Body()[0]3117 fnGraph := ana.AnalysisCtx().GraphOf(fn)3118 AssertEqualString(t, `3119digraph G {3120node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3121edge[fontname="Consolas",fontsize=10]3122initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3123final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3124b21[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nRetStmt:enter\nRetStmt:exit\n"];3125b27[label="ExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3126b37[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];3127b47[label="BlockStmt:exit\n"];3128b48[label="TryStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(afterFin)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3129b56[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3130b57[label="FnDec:exit\n"];3131b21->b27 [xlabel="",color="red"];3132b21->b37 [xlabel="U,P",color="orange"];3133b27->b37 [xlabel="",color="red"];3134b37->b47 [xlabel="",color="red"];3135b37->b57 [xlabel="U",color="orange"];3136b47->b48 [xlabel="",color="red"];3137b47->b57 [xlabel="P",color="red"];3138b48->b57 [xlabel="",color="red"];3139b56->b21 [xlabel="E",color="orange"];3140b56->b37 [xlabel="",color="black"];3141b57->final [xlabel="",color="black"];3142initial->b56 [xlabel="",color="black"];3143}3144`, fnGraph.Dot(), "should be ok")3145}3146func TestCtrlflow_TryNested(t *testing.T) {3147 p, ast, symtab, err := compile(`3148try {3149 doSth1()3150 try {3151 doSth2()3152 } catch (error) {3153 }3154} catch (error) {3155 log(error)3156}3157 `, nil)3158 AssertEqual(t, nil, err, "should be prog ok")3159 ana := NewAnalysis(ast, symtab, p.Source())3160 ana.Analyze()3161 AssertEqualString(t, `3162digraph G {3163node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3164edge[fontname="Consolas",fontsize=10]3165initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3166final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3167b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\n"];3168b12[label="TryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3169b22[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nBlockStmt:exit\nCatch:exit\n"];3170b29[label="TryStmt:exit\nBlockStmt:exit\n"];3171b31[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3172b45[label="TryStmt:exit\nProg:exit\n"];3173b0->b12 [xlabel="",color="black"];3174b0->b31 [xlabel="E",color="orange"];3175b12->b22 [xlabel="E",color="orange"];3176b12->b29 [xlabel="",color="black"];3177b22->b29 [xlabel="",color="black"];3178b22->b31 [xlabel="E",color="orange"];3179b29->b45 [xlabel="",color="black"];3180b31->b45 [xlabel="",color="black"];3181b45->final [xlabel="",color="black"];3182initial->b0 [xlabel="",color="black"];3183}3184`, ana.Graph().Dot(), "should be ok")3185}3186func TestCtrlflow_TryNestedTryReturn(t *testing.T) {3187 p, ast, symtab, err := compile(`3188function f() {3189 try {3190 doSth1()3191 3192 try {3193 doSth2()3194 return3195 } catch (error) {3196 3197 }3198 } catch (error) {3199 log(error)3200 }3201}3202 `, nil)3203 AssertEqual(t, nil, err, "should be prog ok")3204 ana := NewAnalysis(ast, symtab, p.Source())3205 ana.Analyze()3206 fn := ast.(*parser.Prog).Body()[0]3207 fnGraph := ana.AnalysisCtx().GraphOf(fn)3208 AssertEqualString(t, `3209digraph G {3210node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3211edge[fontname="Consolas",fontsize=10]3212initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3213final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3214b14[label="TryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];3215b25[label="BlockStmt:exit\n"];3216b26[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nBlockStmt:exit\nCatch:exit\n"];3217b33[label="TryStmt:exit\nBlockStmt:exit\n"];3218b35[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3219b49[label="TryStmt:exit\nBlockStmt:exit\n"];3220b51[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\n"];3221b52[label="FnDec:exit\n"];3222b14->b25 [xlabel="",color="red"];3223b14->b26 [xlabel="E",color="orange"];3224b14->b52 [xlabel="U",color="orange"];3225b25->b33 [xlabel="",color="red"];3226b26->b33 [xlabel="",color="black"];3227b26->b35 [xlabel="E",color="orange"];3228b33->b49 [xlabel="",color="black"];3229b35->b49 [xlabel="",color="black"];3230b49->b52 [xlabel="",color="black"];3231b51->b14 [xlabel="",color="black"];3232b51->b35 [xlabel="E",color="orange"];3233b52->final [xlabel="",color="black"];3234initial->b51 [xlabel="",color="black"];3235}3236`, fnGraph.Dot(), "should be ok")3237}3238func TestCtrlflow_TryNestedTryFinReturn(t *testing.T) {3239 p, ast, symtab, err := compile(`3240function f() {3241 try {3242 doSth1()3243 try {3244 doSth2()3245 return3246 } catch (error) {3247 } finally {3248 fin1()3249 }3250 } catch (error) {3251 log(error)3252 } finally {3253 fin2()3254 }3255}3256 `, nil)3257 AssertEqual(t, nil, err, "should be prog ok")3258 ana := NewAnalysis(ast, symtab, p.Source())3259 ana.Analyze()3260 fn := ast.(*parser.Prog).Body()[0]3261 fnGraph := ana.AnalysisCtx().GraphOf(fn)3262 AssertEqualString(t, `3263digraph G {3264node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3265edge[fontname="Consolas",fontsize=10]3266initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3267final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3268b14[label="TryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];3269b25[label="BlockStmt:exit\n"];3270b26[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nBlockStmt:exit\nCatch:exit\n"];3271b33[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin1)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3272b42[label="TryStmt:exit\nBlockStmt:exit\n"];3273b44[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3274b58[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nTryStmt:exit\nBlockStmt:exit\n"];3275b69[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\n"];3276b70[label="FnDec:exit\n"];3277b14->b25 [xlabel="",color="red"];3278b14->b26 [xlabel="E",color="orange"];3279b14->b33 [xlabel="U,P",color="orange"];3280b25->b33 [xlabel="",color="red"];3281b26->b33 [xlabel="",color="black"];3282b26->b44 [xlabel="E",color="orange"];3283b33->b42 [xlabel="",color="black"];3284b33->b44 [xlabel="E",color="orange"];3285b33->b58 [xlabel="P",color="orange"];3286b42->b58 [xlabel="",color="black"];3287b44->b58 [xlabel="",color="black"];3288b58->b70 [xlabel="",color="black"];3289b69->b14 [xlabel="",color="black"];3290b69->b44 [xlabel="E",color="orange"];3291b70->final [xlabel="",color="black"];3292initial->b69 [xlabel="",color="black"];3293}3294`, fnGraph.Dot(), "should be ok")3295}3296func TestCtrlflow_TryNestedNested(t *testing.T) {3297 p, ast, symtab, err := compile(`3298function f() {3299 try {3300 doSth1()3301 try {3302 doSth2()3303 try {3304 doSth3()3305 } catch (error) {3306 log1()3307 } finally {3308 fin1()3309 }3310 } catch (error) {3311 log2()3312 } finally {3313 fin2()3314 }3315 } catch (error) {3316 log3(error)3317 } finally {3318 fin3()3319 }3320}3321 `, nil)3322 AssertEqual(t, nil, err, "should be prog ok")3323 ana := NewAnalysis(ast, symtab, p.Source())3324 ana.Analyze()3325 fn := ast.(*parser.Prog).Body()[0]3326 fnGraph := ana.AnalysisCtx().GraphOf(fn)3327 AssertEqualString(t, `3328digraph G {3329node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3330edge[fontname="Consolas",fontsize=10]3331initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3332final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3333b106[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\n"];3334b14[label="TryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\n"];3335b23[label="TryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3336b33[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log1)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3337b46[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin1)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nTryStmt:exit\nBlockStmt:exit\n"];3338b57[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3339b70[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nTryStmt:exit\nBlockStmt:exit\n"];3340b81[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log3)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3341b95[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin3)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nTryStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];3342b106->b14 [xlabel="",color="black"];3343b106->b81 [xlabel="E",color="orange"];3344b14->b23 [xlabel="",color="black"];3345b14->b57 [xlabel="E",color="orange"];3346b23->b33 [xlabel="E",color="orange"];3347b23->b46 [xlabel="",color="black"];3348b33->b46 [xlabel="",color="black"];3349b33->b57 [xlabel="E",color="orange"];3350b46->b57 [xlabel="E",color="orange"];3351b46->b70 [xlabel="",color="black"];3352b57->b70 [xlabel="",color="black"];3353b57->b81 [xlabel="E",color="orange"];3354b70->b81 [xlabel="E",color="orange"];3355b70->b95 [xlabel="",color="black"];3356b81->b95 [xlabel="",color="black"];3357b95->final [xlabel="",color="black"];3358initial->b106 [xlabel="",color="black"];3359}3360`, fnGraph.Dot(), "should be ok")3361}3362func TestCtrlflow_TryNestedNestedTryFinReturn(t *testing.T) {3363 p, ast, symtab, err := compile(`3364function f() {3365 try {3366 doSth1()3367 try {3368 doSth2()3369 try {3370 doSth3()3371 return3372 } catch (error) {3373 3374 } finally {3375 fin1()3376 }3377 } catch (error) {3378 } finally {3379 fin2()3380 }3381 } catch (error) {3382 log(error)3383 } finally {3384 fin3()3385 }3386}3387 `, nil)3388 AssertEqual(t, nil, err, "should be prog ok")3389 ana := NewAnalysis(ast, symtab, p.Source())3390 ana.Analyze()3391 fn := ast.(*parser.Prog).Body()[0]3392 fnGraph := ana.AnalysisCtx().GraphOf(fn)3393 AssertEqualString(t, `3394digraph G {3395node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3396edge[fontname="Consolas",fontsize=10]3397initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3398final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3399b14[label="TryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth2)\nCallExpr:exit\nExprStmt:exit\n"];3400b23[label="TryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth3)\nCallExpr:exit\nExprStmt:exit\nRetStmt:enter\nRetStmt:exit\n"];3401b34[label="BlockStmt:exit\n"];3402b35[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nBlockStmt:exit\nCatch:exit\n"];3403b42[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin1)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3404b51[label="TryStmt:exit\nBlockStmt:exit\n"];3405b53[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nBlockStmt:exit\nCatch:exit\n"];3406b60[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin2)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nTryStmt:exit\nBlockStmt:exit\n"];3407b71[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3408b85[label="BlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(fin3)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nTryStmt:exit\nBlockStmt:exit\n"];3409b96[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(doSth1)\nCallExpr:exit\nExprStmt:exit\n"];3410b97[label="FnDec:exit\n"];3411b14->b23 [xlabel="",color="black"];3412b14->b53 [xlabel="E",color="orange"];3413b23->b34 [xlabel="",color="red"];3414b23->b35 [xlabel="E",color="orange"];3415b23->b42 [xlabel="U,P",color="orange"];3416b34->b42 [xlabel="",color="red"];3417b35->b42 [xlabel="",color="black"];3418b35->b53 [xlabel="E",color="orange"];3419b42->b51 [xlabel="",color="black"];3420b42->b53 [xlabel="E",color="orange"];3421b42->b60 [xlabel="P",color="orange"];3422b51->b60 [xlabel="",color="black"];3423b53->b60 [xlabel="",color="black"];3424b53->b71 [xlabel="E",color="orange"];3425b60->b71 [xlabel="E",color="orange"];3426b60->b85 [xlabel="",color="black"];3427b71->b85 [xlabel="",color="black"];3428b85->b97 [xlabel="",color="black"];3429b96->b14 [xlabel="",color="black"];3430b96->b71 [xlabel="E",color="orange"];3431b97->final [xlabel="",color="black"];3432initial->b96 [xlabel="",color="black"];3433}3434`, fnGraph.Dot(), "should be ok")3435}3436func TestCtrlflow_Throw(t *testing.T) {3437 p, ast, symtab, err := compile(`3438try {3439 throw a3440 a3441} catch (error) {3442 log(error)3443}3444 `, nil)3445 AssertEqual(t, nil, err, "should be prog ok")3446 ana := NewAnalysis(ast, symtab, p.Source())3447 ana.Analyze()3448 AssertEqualString(t, `3449digraph G {3450node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3451edge[fontname="Consolas",fontsize=10]3452initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3453final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3454b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\nThrowStmt:enter\nIdent(a)\n"];3455b13[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3456b27[label="TryStmt:exit\nProg:exit\n"];3457b8[label="ThrowStmt:exit\n"];3458b9[label="ExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\n"];3459b0->b13 [xlabel="E",color="orange"];3460b0->b8 [xlabel="",color="black"];3461b13->b27 [xlabel="",color="black"];3462b27->final [xlabel="",color="black"];3463b8->b13 [xlabel="U",color="orange"];3464b8->b9 [xlabel="",color="red"];3465b9->b13 [xlabel="E",color="red"];3466b9->b27 [xlabel="",color="red"];3467initial->b0 [xlabel="",color="black"];3468}3469`, ana.Graph().Dot(), "should be ok")3470}3471func TestCtrlflow_ThrowBin(t *testing.T) {3472 p, ast, symtab, err := compile(`3473try {3474 throw a && b || c3475 a3476} catch (error) {3477 log(error)3478}3479 `, nil)3480 AssertEqual(t, nil, err, "should be prog ok")3481 ana := NewAnalysis(ast, symtab, p.Source())3482 ana.Analyze()3483 AssertEqualString(t, `3484digraph G {3485node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3486edge[fontname="Consolas",fontsize=10]3487initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3488final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3489b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\nThrowStmt:enter\nBinExpr(||):enter\nBinExpr(&&):enter\nIdent(a)\n"];3490b10[label="Ident(b)\nBinExpr(&&):exit\n"];3491b14[label="Ident(c)\nBinExpr(||):exit\n"];3492b18[label="ThrowStmt:exit\n"];3493b19[label="ExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\n"];3494b23[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3495b37[label="TryStmt:exit\nProg:exit\n"];3496b0->b10 [xlabel="",color="black"];3497b0->b14 [xlabel="F",color="orange"];3498b0->b23 [xlabel="E",color="orange"];3499b10->b14 [xlabel="",color="black"];3500b10->b18 [xlabel="T",color="orange"];3501b10->b23 [xlabel="E",color="orange"];3502b14->b18 [xlabel="",color="black"];3503b14->b23 [xlabel="E",color="orange"];3504b18->b19 [xlabel="",color="red"];3505b18->b23 [xlabel="U",color="orange"];3506b19->b23 [xlabel="E",color="red"];3507b19->b37 [xlabel="",color="red"];3508b23->b37 [xlabel="",color="black"];3509b37->final [xlabel="",color="black"];3510initial->b0 [xlabel="",color="black"];3511}3512`, ana.Graph().Dot(), "should be ok")3513}3514func TestCtrlflow_ThrowNested(t *testing.T) {3515 p, ast, symtab, err := compile(`3516try {3517 try {3518 throw a3519 } catch (error) {3520 log1(error)3521 }3522} catch (error) {3523 log2(error)3524}3525 `, nil)3526 AssertEqual(t, nil, err, "should be prog ok")3527 ana := NewAnalysis(ast, symtab, p.Source())3528 ana.Analyze()3529 AssertEqualString(t, `3530digraph G {3531node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3532edge[fontname="Consolas",fontsize=10]3533initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3534final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3535b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\n"];3536b11[label="ThrowStmt:exit\n"];3537b12[label="BlockStmt:exit\n"];3538b13[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log1)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3539b27[label="TryStmt:exit\nBlockStmt:exit\n"];3540b29[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log2)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3541b43[label="TryStmt:exit\nProg:exit\n"];3542b5[label="TryStmt:enter\nBlockStmt:enter\nThrowStmt:enter\nIdent(a)\n"];3543b0->b5 [xlabel="",color="black"];3544b11->b12 [xlabel="",color="red"];3545b11->b13 [xlabel="U",color="orange"];3546b12->b27 [xlabel="",color="red"];3547b13->b27 [xlabel="",color="black"];3548b13->b29 [xlabel="E",color="orange"];3549b27->b43 [xlabel="",color="black"];3550b29->b43 [xlabel="",color="black"];3551b43->final [xlabel="",color="black"];3552b5->b11 [xlabel="",color="black"];3553b5->b13 [xlabel="E",color="orange"];3554initial->b0 [xlabel="",color="black"];3555}3556`, ana.Graph().Dot(), "should be ok")3557}3558func TestCtrlflow_ThrowNestedReturn(t *testing.T) {3559 p, ast, symtab, err := compile(`3560function f() {3561 try {3562 if (a) {3563 return a;3564 } else {3565 throw b;3566 }3567 } catch (err) {3568 // do nothing.3569 }3570 foo();3571}3572 `, nil)3573 AssertEqual(t, nil, err, "should be prog ok")3574 ana := NewAnalysis(ast, symtab, p.Source())3575 ana.Analyze()3576 fn := ast.(*parser.Prog).Body()[0]3577 fnGraph := ana.AnalysisCtx().GraphOf(fn)3578 AssertEqualString(t, `3579digraph G {3580node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3581edge[fontname="Consolas",fontsize=10]3582initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3583final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3584b10[label="BlockStmt:enter\nRetStmt:enter\nIdent(a)\nRetStmt:exit\n"];3585b15[label="BlockStmt:exit\n"];3586b16[label="BlockStmt:enter\nThrowStmt:enter\nIdent(b)\n"];3587b20[label="ThrowStmt:exit\n"];3588b21[label="BlockStmt:exit\n"];3589b23[label="IfStmt:exit\nBlockStmt:exit\n"];3590b25[label="Catch:enter\nIdent(err)\nBlockStmt:enter\nBlockStmt:exit\nCatch:exit\n"];3591b32[label="TryStmt:exit\nExprStmt:enter\nCallExpr:enter\nIdent(foo)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\n"];3592b40[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nTryStmt:enter\nBlockStmt:enter\nIfStmt:enter\nIdent(a)\n"];3593b41[label="FnDec:exit\n"];3594b10->b15 [xlabel="",color="red"];3595b10->b25 [xlabel="E",color="orange"];3596b10->b41 [xlabel="U",color="orange"];3597b15->b23 [xlabel="",color="red"];3598b16->b20 [xlabel="",color="black"];3599b16->b25 [xlabel="E",color="orange"];3600b20->b21 [xlabel="",color="red"];3601b20->b25 [xlabel="U",color="orange"];3602b21->b23 [xlabel="",color="red"];3603b23->b32 [xlabel="",color="red"];3604b25->b32 [xlabel="",color="black"];3605b32->b41 [xlabel="",color="black"];3606b40->b10 [xlabel="",color="black"];3607b40->b16 [xlabel="F",color="orange"];3608b40->b25 [xlabel="E",color="orange"];3609b41->final [xlabel="",color="black"];3610initial->b40 [xlabel="",color="black"];3611}3612`, fnGraph.Dot(), "should be ok")3613}3614func TestCtrlflow_ThrowCatch(t *testing.T) {3615 p, ast, symtab, err := compile(`3616try {3617 try {3618 throw 13619 a3620 } catch (error) {3621 throw error3622 b3623 }3624 c3625} catch (error) {3626 log2(error)3627}3628 `, nil)3629 AssertEqual(t, nil, err, "should be prog ok")3630 ana := NewAnalysis(ast, symtab, p.Source())3631 ana.Analyze()3632 AssertEqualString(t, `3633digraph G {3634node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3635edge[fontname="Consolas",fontsize=10]3636initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3637final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3638b0[label="Prog:enter\nTryStmt:enter\nBlockStmt:enter\n"];3639b12[label="ExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\n"];3640b16[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nThrowStmt:enter\nIdent(error)\n"];3641b22[label="ThrowStmt:exit\n"];3642b23[label="ExprStmt:enter\nIdent(b)\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3643b29[label="TryStmt:exit\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];3644b34[label="Catch:enter\nIdent(error)\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nIdent(log2)\nIdent(error)\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nCatch:exit\n"];3645b48[label="TryStmt:exit\nProg:exit\n"];3646b5[label="TryStmt:enter\nBlockStmt:enter\nThrowStmt:enter\nNumLit(1)\nThrowStmt:exit\n"];3647b0->b5 [xlabel="",color="black"];3648b12->b16 [xlabel="E",color="red"];3649b12->b29 [xlabel="",color="red"];3650b16->b22 [xlabel="",color="black"];3651b16->b34 [xlabel="E",color="orange"];3652b22->b23 [xlabel="",color="red"];3653b22->b34 [xlabel="U",color="orange"];3654b23->b29 [xlabel="",color="red"];3655b23->b34 [xlabel="E",color="red"];3656b29->b34 [xlabel="E",color="red"];3657b29->b48 [xlabel="",color="red"];3658b34->b48 [xlabel="",color="black"];3659b48->final [xlabel="",color="black"];3660b5->b12 [xlabel="",color="red"];3661b5->b16 [xlabel="U",color="orange"];3662initial->b0 [xlabel="",color="black"];3663}3664`, ana.Graph().Dot(), "should be ok")3665}3666func TestCtrlflow_ThrowBare(t *testing.T) {3667 p, ast, symtab, err := compile(`3668throw 13669a3670 `, nil)3671 AssertEqual(t, nil, err, "should be prog ok")3672 ana := NewAnalysis(ast, symtab, p.Source())3673 ana.Analyze()3674 AssertEqualString(t, `3675digraph G {3676node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3677edge[fontname="Consolas",fontsize=10]3678initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3679final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3680b0[label="Prog:enter\nThrowStmt:enter\nNumLit(1)\nThrowStmt:exit\n"];3681b6[label="ExprStmt:enter\nIdent(a)\nExprStmt:exit\n"];3682b9[label="Prog:exit\n"];3683b0->b6 [xlabel="",color="red"];3684b0->b9 [xlabel="U",color="orange"];3685b6->b9 [xlabel="",color="red"];3686b9->final [xlabel="",color="black"];3687initial->b0 [xlabel="",color="black"];3688}3689`, ana.Graph().Dot(), "should be ok")3690}3691func TestCtrlflow_NewExpr(t *testing.T) {3692 p, ast, symtab, err := compile(`3693 new fn()3694 `, nil)3695 AssertEqual(t, nil, err, "should be prog ok")3696 ana := NewAnalysis(ast, symtab, p.Source())3697 ana.Analyze()3698 AssertEqualString(t, `3699digraph G {3700node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3701edge[fontname="Consolas",fontsize=10]3702initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3703final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3704b0[label="Prog:enter\nExprStmt:enter\nNewExpr:enter\nIdent(fn)\nNewExpr:exit\nExprStmt:exit\nProg:exit\n"];3705b0->final [xlabel="",color="black"];3706initial->b0 [xlabel="",color="black"];3707}3708`, ana.Graph().Dot(), "should be ok")3709}3710func TestCtrlflow_NewExprArgs(t *testing.T) {3711 p, ast, symtab, err := compile(`3712 new fn(1, 2, a && b)3713 `, nil)3714 AssertEqual(t, nil, err, "should be prog ok")3715 ana := NewAnalysis(ast, symtab, p.Source())3716 ana.Analyze()3717 AssertEqualString(t, `3718digraph G {3719node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3720edge[fontname="Consolas",fontsize=10]3721initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3722final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3723b0[label="Prog:enter\nExprStmt:enter\nNewExpr:enter\nIdent(fn)\nNumLit(1)\nNumLit(2)\nBinExpr(&&):enter\nIdent(a)\n"];3724b10[label="Ident(b)\nBinExpr(&&):exit\n"];3725b14[label="NewExpr:exit\nExprStmt:exit\nProg:exit\n"];3726b0->b10 [xlabel="",color="black"];3727b0->b14 [xlabel="F",color="orange"];3728b10->b14 [xlabel="",color="black"];3729b14->final [xlabel="",color="black"];3730initial->b0 [xlabel="",color="black"];3731}3732`, ana.Graph().Dot(), "should be ok")3733}3734func TestCtrlflow_NewExprArgsBin(t *testing.T) {3735 p, ast, symtab, err := compile(`3736 new fn(1, a || b && c, d && e)3737 `, nil)3738 AssertEqual(t, nil, err, "should be prog ok")3739 ana := NewAnalysis(ast, symtab, p.Source())3740 ana.Analyze()3741 AssertEqualString(t, `3742digraph G {3743node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3744edge[fontname="Consolas",fontsize=10]3745initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3746final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3747b0[label="Prog:enter\nExprStmt:enter\nNewExpr:enter\nIdent(fn)\nNumLit(1)\nBinExpr(||):enter\nIdent(a)\n"];3748b11[label="Ident(c)\nBinExpr(&&):exit\nBinExpr(||):exit\n"];3749b18[label="BinExpr(&&):enter\nIdent(d)\n"];3750b20[label="Ident(e)\nBinExpr(&&):exit\n"];3751b24[label="NewExpr:exit\nExprStmt:exit\nProg:exit\n"];3752b9[label="BinExpr(&&):enter\nIdent(b)\n"];3753b0->b18 [xlabel="T",color="orange"];3754b0->b9 [xlabel="",color="black"];3755b11->b18 [xlabel="",color="black"];3756b18->b20 [xlabel="",color="black"];3757b18->b24 [xlabel="F",color="orange"];3758b20->b24 [xlabel="",color="black"];3759b24->final [xlabel="",color="black"];3760b9->b11 [xlabel="",color="black"];3761b9->b18 [xlabel="F",color="orange"];3762initial->b0 [xlabel="",color="black"];3763}3764`, ana.Graph().Dot(), "should be ok")3765}3766func TestCtrlflow_MemberExpr(t *testing.T) {3767 p, ast, symtab, err := compile(`3768 a.b3769 `, nil)3770 AssertEqual(t, nil, err, "should be prog ok")3771 ana := NewAnalysis(ast, symtab, p.Source())3772 ana.Analyze()3773 AssertEqualString(t, `3774digraph G {3775node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3776edge[fontname="Consolas",fontsize=10]3777initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3778final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3779b0[label="Prog:enter\nExprStmt:enter\nMemberExpr:enter\nIdent(a)\nIdent(b)\nMemberExpr:exit\nExprStmt:exit\nProg:exit\n"];3780b0->final [xlabel="",color="black"];3781initial->b0 [xlabel="",color="black"];3782}3783`, ana.Graph().Dot(), "should be ok")3784}3785func TestCtrlflow_MemberExprChain(t *testing.T) {3786 p, ast, symtab, err := compile(`3787 a.b.c3788 `, nil)3789 AssertEqual(t, nil, err, "should be prog ok")3790 ana := NewAnalysis(ast, symtab, p.Source())3791 ana.Analyze()3792 AssertEqualString(t, `3793digraph G {3794node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3795edge[fontname="Consolas",fontsize=10]3796initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3797final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3798b0[label="Prog:enter\nExprStmt:enter\nMemberExpr:enter\nMemberExpr:enter\nIdent(a)\nIdent(b)\nMemberExpr:exit\nIdent(c)\nMemberExpr:exit\nExprStmt:exit\nProg:exit\n"];3799b0->final [xlabel="",color="black"];3800initial->b0 [xlabel="",color="black"];3801}3802`, ana.Graph().Dot(), "should be ok")3803}3804func TestCtrlflow_MemberExprCompute(t *testing.T) {3805 p, ast, symtab, err := compile(`3806 (a && b).c3807 `, nil)3808 AssertEqual(t, nil, err, "should be prog ok")3809 ana := NewAnalysis(ast, symtab, p.Source())3810 ana.Analyze()3811 AssertEqualString(t, `3812digraph G {3813node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3814edge[fontname="Consolas",fontsize=10]3815initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3816final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3817b0[label="Prog:enter\nExprStmt:enter\nMemberExpr:enter\nParenExpr:enter\nBinExpr(&&):enter\nIdent(a)\n"];3818b12[label="ParenExpr:exit\nIdent(c)\nMemberExpr:exit\nExprStmt:exit\nProg:exit\n"];3819b8[label="Ident(b)\nBinExpr(&&):exit\n"];3820b0->b12 [xlabel="F",color="orange"];3821b0->b8 [xlabel="",color="black"];3822b12->final [xlabel="",color="black"];3823b8->b12 [xlabel="",color="black"];3824initial->b0 [xlabel="",color="black"];3825}3826`, ana.Graph().Dot(), "should be ok")3827}3828func TestCtrlflow_MemberExprSubscript(t *testing.T) {3829 p, ast, symtab, err := compile(`3830 a[b]3831 `, nil)3832 AssertEqual(t, nil, err, "should be prog ok")3833 ana := NewAnalysis(ast, symtab, p.Source())3834 ana.Analyze()3835 AssertEqualString(t, `3836digraph G {3837node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3838edge[fontname="Consolas",fontsize=10]3839initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3840final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3841b0[label="Prog:enter\nExprStmt:enter\nMemberExpr:enter\nIdent(a)\nIdent(b)\nMemberExpr:exit\nExprStmt:exit\nProg:exit\n"];3842b0->final [xlabel="",color="black"];3843initial->b0 [xlabel="",color="black"];3844}3845`, ana.Graph().Dot(), "should be ok")3846}3847func TestCtrlflow_MemberExprSubscriptBin(t *testing.T) {3848 p, ast, symtab, err := compile(`3849 a[b && c]3850 `, nil)3851 AssertEqual(t, nil, err, "should be prog ok")3852 ana := NewAnalysis(ast, symtab, p.Source())3853 ana.Analyze()3854 AssertEqualString(t, `3855digraph G {3856node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3857edge[fontname="Consolas",fontsize=10]3858initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3859final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3860b0[label="Prog:enter\nExprStmt:enter\nMemberExpr:enter\nIdent(a)\nBinExpr(&&):enter\nIdent(b)\n"];3861b12[label="MemberExpr:exit\nExprStmt:exit\nProg:exit\n"];3862b8[label="Ident(c)\nBinExpr(&&):exit\n"];3863b0->b12 [xlabel="F",color="orange"];3864b0->b8 [xlabel="",color="black"];3865b12->final [xlabel="",color="black"];3866b8->b12 [xlabel="",color="black"];3867initial->b0 [xlabel="",color="black"];3868}3869`, ana.Graph().Dot(), "should be ok")3870}3871func TestCtrlflow_MemberExprSubscriptBinBin(t *testing.T) {3872 p, ast, symtab, err := compile(`3873 a[b && c][e || f]3874 `, nil)3875 AssertEqual(t, nil, err, "should be prog ok")3876 ana := NewAnalysis(ast, symtab, p.Source())3877 ana.Analyze()3878 AssertEqualString(t, `3879digraph G {3880node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3881edge[fontname="Consolas",fontsize=10]3882initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3883final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3884b0[label="Prog:enter\nExprStmt:enter\nMemberExpr:enter\nMemberExpr:enter\nIdent(a)\nBinExpr(&&):enter\nIdent(b)\n"];3885b13[label="MemberExpr:exit\nBinExpr(||):enter\nIdent(e)\n"];3886b17[label="Ident(f)\nBinExpr(||):exit\n"];3887b21[label="MemberExpr:exit\nExprStmt:exit\nProg:exit\n"];3888b9[label="Ident(c)\nBinExpr(&&):exit\n"];3889b0->b13 [xlabel="F",color="orange"];3890b0->b9 [xlabel="",color="black"];3891b13->b17 [xlabel="",color="black"];3892b13->b21 [xlabel="T",color="orange"];3893b17->b21 [xlabel="",color="black"];3894b21->final [xlabel="",color="black"];3895b9->b13 [xlabel="",color="black"];3896initial->b0 [xlabel="",color="black"];3897}3898`, ana.Graph().Dot(), "should be ok")3899}3900func TestCtrlflow_MemberExprMixChain(t *testing.T) {3901 p, ast, symtab, err := compile(`3902 a.b[c && d].e3903 `, nil)3904 AssertEqual(t, nil, err, "should be prog ok")3905 ana := NewAnalysis(ast, symtab, p.Source())3906 ana.Analyze()3907 AssertEqualString(t, `3908digraph G {3909node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3910edge[fontname="Consolas",fontsize=10]3911initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3912final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3913b0[label="Prog:enter\nExprStmt:enter\nMemberExpr:enter\nMemberExpr:enter\nMemberExpr:enter\nIdent(a)\nIdent(b)\nMemberExpr:exit\nBinExpr(&&):enter\nIdent(c)\n"];3914b13[label="Ident(d)\nBinExpr(&&):exit\n"];3915b17[label="MemberExpr:exit\nIdent(e)\nMemberExpr:exit\nExprStmt:exit\nProg:exit\n"];3916b0->b13 [xlabel="",color="black"];3917b0->b17 [xlabel="F",color="orange"];3918b13->b17 [xlabel="",color="black"];3919b17->final [xlabel="",color="black"];3920initial->b0 [xlabel="",color="black"];3921}3922`, ana.Graph().Dot(), "should be ok")3923}3924func TestCtrlflow_SeqExpr(t *testing.T) {3925 p, ast, symtab, err := compile(`3926 a, b, c3927 `, nil)3928 AssertEqual(t, nil, err, "should be prog ok")3929 ana := NewAnalysis(ast, symtab, p.Source())3930 ana.Analyze()3931 AssertEqualString(t, `3932digraph G {3933node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3934edge[fontname="Consolas",fontsize=10]3935initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3936final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3937b0[label="Prog:enter\nExprStmt:enter\nSeqExpr:enter\nIdent(a)\nIdent(b)\nIdent(c)\nSeqExpr:exit\nExprStmt:exit\nProg:exit\n"];3938b0->final [xlabel="",color="black"];3939initial->b0 [xlabel="",color="black"];3940}3941`, ana.Graph().Dot(), "should be ok")3942}3943func TestCtrlflow_SeqExprBin(t *testing.T) {3944 p, ast, symtab, err := compile(`3945 a, b && c || d, e || f3946 `, nil)3947 AssertEqual(t, nil, err, "should be prog ok")3948 ana := NewAnalysis(ast, symtab, p.Source())3949 ana.Analyze()3950 AssertEqualString(t, `3951digraph G {3952node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3953edge[fontname="Consolas",fontsize=10]3954initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3955final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3956b0[label="Prog:enter\nExprStmt:enter\nSeqExpr:enter\nIdent(a)\nBinExpr(||):enter\nBinExpr(&&):enter\nIdent(b)\n"];3957b13[label="Ident(d)\nBinExpr(||):exit\n"];3958b17[label="BinExpr(||):enter\nIdent(e)\n"];3959b19[label="Ident(f)\nBinExpr(||):exit\n"];3960b23[label="SeqExpr:exit\nExprStmt:exit\nProg:exit\n"];3961b9[label="Ident(c)\nBinExpr(&&):exit\n"];3962b0->b13 [xlabel="F",color="orange"];3963b0->b9 [xlabel="",color="black"];3964b13->b17 [xlabel="",color="black"];3965b17->b19 [xlabel="",color="black"];3966b17->b23 [xlabel="T",color="orange"];3967b19->b23 [xlabel="",color="black"];3968b23->final [xlabel="",color="black"];3969b9->b13 [xlabel="",color="black"];3970b9->b17 [xlabel="T",color="orange"];3971initial->b0 [xlabel="",color="black"];3972}3973`, ana.Graph().Dot(), "should be ok")3974}3975func TestCtrlflow_SeqExprParen(t *testing.T) {3976 p, ast, symtab, err := compile(`3977 (a, b && c || d, e || f)3978 `, nil)3979 AssertEqual(t, nil, err, "should be prog ok")3980 ana := NewAnalysis(ast, symtab, p.Source())3981 ana.Analyze()3982 AssertEqualString(t, `3983digraph G {3984node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];3985edge[fontname="Consolas",fontsize=10]3986initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];3987final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];3988b0[label="Prog:enter\nExprStmt:enter\nParenExpr:enter\nSeqExpr:enter\nIdent(a)\nBinExpr(||):enter\nBinExpr(&&):enter\nIdent(b)\n"];3989b10[label="Ident(c)\nBinExpr(&&):exit\n"];3990b14[label="Ident(d)\nBinExpr(||):exit\n"];3991b18[label="BinExpr(||):enter\nIdent(e)\n"];3992b20[label="Ident(f)\nBinExpr(||):exit\n"];3993b24[label="SeqExpr:exit\nParenExpr:exit\nExprStmt:exit\nProg:exit\n"];3994b0->b10 [xlabel="",color="black"];3995b0->b14 [xlabel="F",color="orange"];3996b10->b14 [xlabel="",color="black"];3997b10->b18 [xlabel="T",color="orange"];3998b14->b18 [xlabel="",color="black"];3999b18->b20 [xlabel="",color="black"];4000b18->b24 [xlabel="T",color="orange"];4001b20->b24 [xlabel="",color="black"];4002b24->final [xlabel="",color="black"];4003initial->b0 [xlabel="",color="black"];4004}4005`, ana.Graph().Dot(), "should be ok")4006}4007func TestCtrlflow_ThisExpr(t *testing.T) {4008 p, ast, symtab, err := compile(`4009 function f() {4010 this4011 }4012 `, nil)4013 AssertEqual(t, nil, err, "should be prog ok")4014 ana := NewAnalysis(ast, symtab, p.Source())4015 ana.Analyze()4016 fn := ast.(*parser.Prog).Body()[0]4017 fnGraph := ana.AnalysisCtx().GraphOf(fn)4018 AssertEqualString(t, `4019digraph G {4020node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4021edge[fontname="Consolas",fontsize=10]4022initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4023final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4024b9[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nThisExpr\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];4025b9->final [xlabel="",color="black"];4026initial->b9 [xlabel="",color="black"];4027}4028`, fnGraph.Dot(), "should be ok")4029}4030func TestCtrlflow_Unary(t *testing.T) {4031 p, ast, symtab, err := compile(`4032 !a4033 `, nil)4034 AssertEqual(t, nil, err, "should be prog ok")4035 ana := NewAnalysis(ast, symtab, p.Source())4036 ana.Analyze()4037 AssertEqualString(t, `4038digraph G {4039node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4040edge[fontname="Consolas",fontsize=10]4041initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4042final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4043b0[label="Prog:enter\nExprStmt:enter\nUnaryExpr(!):enter\nIdent(a)\nUnaryExpr(!):exit\nExprStmt:exit\nProg:exit\n"];4044b0->final [xlabel="",color="black"];4045initial->b0 [xlabel="",color="black"];4046}4047`, ana.Graph().Dot(), "should be ok")4048}4049func TestCtrlflow_UnaryParen(t *testing.T) {4050 p, ast, symtab, err := compile(`4051 !(a || b && c)4052 `, nil)4053 AssertEqual(t, nil, err, "should be prog ok")4054 ana := NewAnalysis(ast, symtab, p.Source())4055 ana.Analyze()4056 AssertEqualString(t, `4057digraph G {4058node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4059edge[fontname="Consolas",fontsize=10]4060initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4061final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4062b0[label="Prog:enter\nExprStmt:enter\nUnaryExpr(!):enter\nParenExpr:enter\nBinExpr(||):enter\nIdent(a)\n"];4063b10[label="Ident(c)\nBinExpr(&&):exit\nBinExpr(||):exit\n"];4064b17[label="ParenExpr:exit\nUnaryExpr(!):exit\nExprStmt:exit\nProg:exit\n"];4065b8[label="BinExpr(&&):enter\nIdent(b)\n"];4066b0->b17 [xlabel="T",color="orange"];4067b0->b8 [xlabel="",color="black"];4068b10->b17 [xlabel="",color="black"];4069b17->final [xlabel="",color="black"];4070b8->b10 [xlabel="",color="black"];4071b8->b17 [xlabel="F",color="orange"];4072initial->b0 [xlabel="",color="black"];4073}4074`, ana.Graph().Dot(), "should be ok")4075}4076func TestCtrlflow_CondExpr(t *testing.T) {4077 p, ast, symtab, err := compile(`4078 a ? b : c4079 `, nil)4080 AssertEqual(t, nil, err, "should be prog ok")4081 ana := NewAnalysis(ast, symtab, p.Source())4082 ana.Analyze()4083 AssertEqualString(t, `4084digraph G {4085node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4086edge[fontname="Consolas",fontsize=10]4087initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4088final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4089b0[label="Prog:enter\nExprStmt:enter\nCondExpr:enter\nIdent(a)\n"];4090b6[label="Ident(b)\n"];4091b7[label="Ident(c)\n"];4092b8[label="CondExpr:exit\nExprStmt:exit\nProg:exit\n"];4093b0->b6 [xlabel="",color="black"];4094b0->b7 [xlabel="F",color="orange"];4095b6->b8 [xlabel="",color="black"];4096b7->b8 [xlabel="",color="black"];4097b8->final [xlabel="",color="black"];4098initial->b0 [xlabel="",color="black"];4099}4100`, ana.Graph().Dot(), "should be ok")4101}4102func TestCtrlflow_CondExprTestBin(t *testing.T) {4103 p, ast, symtab, err := compile(`4104 a && b ? c : d4105 `, nil)4106 AssertEqual(t, nil, err, "should be prog ok")4107 ana := NewAnalysis(ast, symtab, p.Source())4108 ana.Analyze()4109 AssertEqualString(t, `4110digraph G {4111node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4112edge[fontname="Consolas",fontsize=10]4113initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4114final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4115b0[label="Prog:enter\nExprStmt:enter\nCondExpr:enter\nBinExpr(&&):enter\nIdent(a)\n"];4116b11[label="Ident(c)\n"];4117b12[label="Ident(d)\n"];4118b13[label="CondExpr:exit\nExprStmt:exit\nProg:exit\n"];4119b7[label="Ident(b)\nBinExpr(&&):exit\n"];4120b0->b12 [xlabel="F",color="orange"];4121b0->b7 [xlabel="",color="black"];4122b11->b13 [xlabel="",color="black"];4123b12->b13 [xlabel="",color="black"];4124b13->final [xlabel="",color="black"];4125b7->b11 [xlabel="",color="black"];4126b7->b12 [xlabel="F",color="orange"];4127initial->b0 [xlabel="",color="black"];4128}4129`, ana.Graph().Dot(), "should be ok")4130}4131func TestCtrlflow_CondExprTestBinOr(t *testing.T) {4132 p, ast, symtab, err := compile(`4133 a || b ? c : d4134 `, nil)4135 AssertEqual(t, nil, err, "should be prog ok")4136 ana := NewAnalysis(ast, symtab, p.Source())4137 ana.Analyze()4138 AssertEqualString(t, `4139digraph G {4140node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4141edge[fontname="Consolas",fontsize=10]4142initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4143final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4144b0[label="Prog:enter\nExprStmt:enter\nCondExpr:enter\nBinExpr(||):enter\nIdent(a)\n"];4145b11[label="Ident(c)\n"];4146b12[label="Ident(d)\n"];4147b13[label="CondExpr:exit\nExprStmt:exit\nProg:exit\n"];4148b7[label="Ident(b)\nBinExpr(||):exit\n"];4149b0->b11 [xlabel="T",color="orange"];4150b0->b7 [xlabel="",color="black"];4151b11->b13 [xlabel="",color="black"];4152b12->b13 [xlabel="",color="black"];4153b13->final [xlabel="",color="black"];4154b7->b11 [xlabel="",color="black"];4155b7->b12 [xlabel="F",color="orange"];4156initial->b0 [xlabel="",color="black"];4157}4158`, ana.Graph().Dot(), "should be ok")4159}4160func TestCtrlflow_CondExprTestBinMix(t *testing.T) {4161 p, ast, symtab, err := compile(`4162 a || b && c ? d : e4163 `, nil)4164 AssertEqual(t, nil, err, "should be prog ok")4165 ana := NewAnalysis(ast, symtab, p.Source())4166 ana.Analyze()4167 AssertEqualString(t, `4168digraph G {4169node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4170edge[fontname="Consolas",fontsize=10]4171initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4172final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4173b0[label="Prog:enter\nExprStmt:enter\nCondExpr:enter\nBinExpr(||):enter\nIdent(a)\n"];4174b16[label="Ident(d)\n"];4175b17[label="Ident(e)\n"];4176b18[label="CondExpr:exit\nExprStmt:exit\nProg:exit\n"];4177b7[label="BinExpr(&&):enter\nIdent(b)\n"];4178b9[label="Ident(c)\nBinExpr(&&):exit\nBinExpr(||):exit\n"];4179b0->b16 [xlabel="T",color="orange"];4180b0->b7 [xlabel="",color="black"];4181b16->b18 [xlabel="",color="black"];4182b17->b18 [xlabel="",color="black"];4183b18->final [xlabel="",color="black"];4184b7->b17 [xlabel="F",color="orange"];4185b7->b9 [xlabel="",color="black"];4186b9->b16 [xlabel="",color="black"];4187b9->b17 [xlabel="F",color="orange"];4188initial->b0 [xlabel="",color="black"];4189}4190`, ana.Graph().Dot(), "should be ok")4191}4192func TestCtrlflow_CondExprTestBinMixAnd(t *testing.T) {4193 p, ast, symtab, err := compile(`4194 a && b || c ? d : e4195 `, nil)4196 AssertEqual(t, nil, err, "should be prog ok")4197 ana := NewAnalysis(ast, symtab, p.Source())4198 ana.Analyze()4199 AssertEqualString(t, `4200digraph G {4201node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4202edge[fontname="Consolas",fontsize=10]4203initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4204final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4205b0[label="Prog:enter\nExprStmt:enter\nCondExpr:enter\nBinExpr(||):enter\nBinExpr(&&):enter\nIdent(a)\n"];4206b12[label="Ident(c)\nBinExpr(||):exit\n"];4207b16[label="Ident(d)\n"];4208b17[label="Ident(e)\n"];4209b18[label="CondExpr:exit\nExprStmt:exit\nProg:exit\n"];4210b8[label="Ident(b)\nBinExpr(&&):exit\n"];4211b0->b12 [xlabel="F",color="orange"];4212b0->b8 [xlabel="",color="black"];4213b12->b16 [xlabel="",color="black"];4214b12->b17 [xlabel="F",color="orange"];4215b16->b18 [xlabel="",color="black"];4216b17->b18 [xlabel="",color="black"];4217b18->final [xlabel="",color="black"];4218b8->b12 [xlabel="",color="black"];4219b8->b16 [xlabel="T",color="orange"];4220initial->b0 [xlabel="",color="black"];4221}4222`, ana.Graph().Dot(), "should be ok")4223}4224func TestCtrlflow_CondExprNestedLeft(t *testing.T) {4225 p, ast, symtab, err := compile(`4226 a ? b ? c : d : c4227 `, nil)4228 AssertEqual(t, nil, err, "should be prog ok")4229 ana := NewAnalysis(ast, symtab, p.Source())4230 ana.Analyze()4231 AssertEqualString(t, `4232digraph G {4233node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4234edge[fontname="Consolas",fontsize=10]4235initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4236final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4237b0[label="Prog:enter\nExprStmt:enter\nCondExpr:enter\nIdent(a)\n"];4238b10[label="CondExpr:exit\n"];4239b12[label="Ident(c)\n"];4240b13[label="CondExpr:exit\nExprStmt:exit\nProg:exit\n"];4241b6[label="CondExpr:enter\nIdent(b)\n"];4242b8[label="Ident(c)\n"];4243b9[label="Ident(d)\n"];4244b0->b12 [xlabel="F",color="orange"];4245b0->b6 [xlabel="",color="black"];4246b10->b13 [xlabel="",color="black"];4247b12->b13 [xlabel="",color="black"];4248b13->final [xlabel="",color="black"];4249b6->b8 [xlabel="",color="black"];4250b6->b9 [xlabel="F",color="orange"];4251b8->b10 [xlabel="",color="black"];4252b9->b10 [xlabel="",color="black"];4253initial->b0 [xlabel="",color="black"];4254}4255`, ana.Graph().Dot(), "should be ok")4256}4257func TestCtrlflow_CondExprNestedRight(t *testing.T) {4258 p, ast, symtab, err := compile(`4259 a ? b : c ? d : e4260 `, nil)4261 AssertEqual(t, nil, err, "should be prog ok")4262 ana := NewAnalysis(ast, symtab, p.Source())4263 ana.Analyze()4264 AssertEqualString(t, `4265digraph G {4266node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4267edge[fontname="Consolas",fontsize=10]4268initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4269final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4270b0[label="Prog:enter\nExprStmt:enter\nCondExpr:enter\nIdent(a)\n"];4271b10[label="Ident(e)\n"];4272b11[label="CondExpr:exit\n"];4273b13[label="CondExpr:exit\nExprStmt:exit\nProg:exit\n"];4274b6[label="Ident(b)\n"];4275b7[label="CondExpr:enter\nIdent(c)\n"];4276b9[label="Ident(d)\n"];4277b0->b6 [xlabel="",color="black"];4278b0->b7 [xlabel="F",color="orange"];4279b10->b11 [xlabel="",color="black"];4280b11->b13 [xlabel="",color="black"];4281b13->final [xlabel="",color="black"];4282b6->b13 [xlabel="",color="black"];4283b7->b10 [xlabel="F",color="orange"];4284b7->b9 [xlabel="",color="black"];4285b9->b11 [xlabel="",color="black"];4286initial->b0 [xlabel="",color="black"];4287}4288`, ana.Graph().Dot(), "should be ok")4289}4290func TestCtrlflow_AssignExpr(t *testing.T) {4291 p, ast, symtab, err := compile(`4292 a = 14293 `, nil)4294 AssertEqual(t, nil, err, "should be prog ok")4295 ana := NewAnalysis(ast, symtab, p.Source())4296 ana.Analyze()4297 AssertEqualString(t, `4298digraph G {4299node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4300edge[fontname="Consolas",fontsize=10]4301initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4302final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4303b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nNumLit(1)\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];4304b0->final [xlabel="",color="black"];4305initial->b0 [xlabel="",color="black"];4306}4307`, ana.Graph().Dot(), "should be ok")4308}4309func TestCtrlflow_AssignExprBin(t *testing.T) {4310 p, ast, symtab, err := compile(`4311 a = b && c4312 `, nil)4313 AssertEqual(t, nil, err, "should be prog ok")4314 ana := NewAnalysis(ast, symtab, p.Source())4315 ana.Analyze()4316 AssertEqualString(t, `4317digraph G {4318node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4319edge[fontname="Consolas",fontsize=10]4320initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4321final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4322b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nIdent(a)\nBinExpr(&&):enter\nIdent(b)\n"];4323b12[label="AssignExpr:exit\nExprStmt:exit\nProg:exit\n"];4324b8[label="Ident(c)\nBinExpr(&&):exit\n"];4325b0->b12 [xlabel="F",color="orange"];4326b0->b8 [xlabel="",color="black"];4327b12->final [xlabel="",color="black"];4328b8->b12 [xlabel="",color="black"];4329initial->b0 [xlabel="",color="black"];4330}4331`, ana.Graph().Dot(), "should be ok")4332}4333func TestCtrlflow_ImportCall(t *testing.T) {4334 p, ast, symtab, err := compile(`4335 import("a")4336 `, nil)4337 AssertEqual(t, nil, err, "should be prog ok")4338 ana := NewAnalysis(ast, symtab, p.Source())4339 ana.Analyze()4340 AssertEqualString(t, `4341digraph G {4342node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4343edge[fontname="Consolas",fontsize=10]4344initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4345final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4346b0[label="Prog:enter\nExprStmt:enter\nImportCall:enter\nStrLit\nImportCall:exit\nExprStmt:exit\nProg:exit\n"];4347b0->final [xlabel="",color="black"];4348initial->b0 [xlabel="",color="black"];4349}4350`, ana.Graph().Dot(), "should be ok")4351}4352func TestCtrlflow_AwaitImportExpr(t *testing.T) {4353 p, ast, symtab, err := compile(`4354 await import("a")4355 `, nil)4356 AssertEqual(t, nil, err, "should be prog ok")4357 ana := NewAnalysis(ast, symtab, p.Source())4358 ana.Analyze()4359 AssertEqualString(t, `4360digraph G {4361node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4362edge[fontname="Consolas",fontsize=10]4363initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4364final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4365b0[label="Prog:enter\nExprStmt:enter\nUnaryExpr(await):enter\nImportCall:enter\nStrLit\nImportCall:exit\nUnaryExpr(await):exit\nExprStmt:exit\nProg:exit\n"];4366b0->final [xlabel="",color="black"];4367initial->b0 [xlabel="",color="black"];4368}4369`, ana.Graph().Dot(), "should be ok")4370}4371func TestCtrlflow_WithStmt(t *testing.T) {4372 opts := parser.NewParserOpts()4373 opts.Feature = opts.Feature.Off(parser.FEAT_STRICT)4374 p, ast, symtab, err := compile(`4375 with (a) {4376 b4377 }4378 `, opts)4379 AssertEqual(t, nil, err, "should be prog ok")4380 ana := NewAnalysis(ast, symtab, p.Source())4381 ana.Analyze()4382 AssertEqualString(t, `4383digraph G {4384node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4385edge[fontname="Consolas",fontsize=10]4386initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4387final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4388b0[label="Prog:enter\nWithStmt:enter\nIdent(a)\nBlockStmt:enter\nExprStmt:enter\nIdent(b)\nExprStmt:exit\nBlockStmt:exit\nWithStmt:exit\nProg:exit\n"];4389b0->final [xlabel="",color="black"];4390initial->b0 [xlabel="",color="black"];4391}4392`, ana.Graph().Dot(), "should be ok")4393}4394func TestCtrlflow_WithStmtBin(t *testing.T) {4395 opts := parser.NewParserOpts()4396 opts.Feature = opts.Feature.Off(parser.FEAT_STRICT)4397 p, ast, symtab, err := compile(`4398 with (a || b) {4399 c4400 }4401 `, opts)4402 AssertEqual(t, nil, err, "should be prog ok")4403 ana := NewAnalysis(ast, symtab, p.Source())4404 ana.Analyze()4405 AssertEqualString(t, `4406digraph G {4407node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4408edge[fontname="Consolas",fontsize=10]4409initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4410final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4411b0[label="Prog:enter\nWithStmt:enter\nBinExpr(||):enter\nIdent(a)\n"];4412b10[label="BlockStmt:enter\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\nWithStmt:exit\nProg:exit\n"];4413b6[label="Ident(b)\nBinExpr(||):exit\n"];4414b0->b10 [xlabel="T",color="orange"];4415b0->b6 [xlabel="",color="black"];4416b10->final [xlabel="",color="black"];4417b6->b10 [xlabel="",color="black"];4418initial->b0 [xlabel="",color="black"];4419}4420`, ana.Graph().Dot(), "should be ok")4421}4422func TestCtrlflow_ImportEffect(t *testing.T) {4423 p, ast, symtab, err := compile(`4424 import "a";4425 `, nil)4426 AssertEqual(t, nil, err, "should be prog ok")4427 ana := NewAnalysis(ast, symtab, p.Source())4428 ana.Analyze()4429 AssertEqualString(t, `4430digraph G {4431node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4432edge[fontname="Consolas",fontsize=10]4433initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4434final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4435b0[label="Prog:enter\nImportDec:enter\nStrLit\nImportDec:exit\nProg:exit\n"];4436b0->final [xlabel="",color="black"];4437initial->b0 [xlabel="",color="black"];4438}4439`, ana.Graph().Dot(), "should be ok")4440}4441func TestCtrlflow_ImportNs(t *testing.T) {4442 p, ast, symtab, err := compile(`4443 import * as a from "a";4444 `, nil)4445 AssertEqual(t, nil, err, "should be prog ok")4446 ana := NewAnalysis(ast, symtab, p.Source())4447 ana.Analyze()4448 AssertEqualString(t, `4449digraph G {4450node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4451edge[fontname="Consolas",fontsize=10]4452initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4453final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4454b0[label="Prog:enter\nImportDec:enter\nImportSpec(Namespace):enter\nIdent(a)\nImportSpec(Namespace):exit\nStrLit\nImportDec:exit\nProg:exit\n"];4455b0->final [xlabel="",color="black"];4456initial->b0 [xlabel="",color="black"];4457}4458`, ana.Graph().Dot(), "should be ok")4459}4460func TestCtrlflow_ImportDefault(t *testing.T) {4461 p, ast, symtab, err := compile(`4462 import a from "a";4463 `, nil)4464 AssertEqual(t, nil, err, "should be prog ok")4465 ana := NewAnalysis(ast, symtab, p.Source())4466 ana.Analyze()4467 AssertEqualString(t, `4468digraph G {4469node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4470edge[fontname="Consolas",fontsize=10]4471initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4472final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4473b0[label="Prog:enter\nImportDec:enter\nImportSpec(Default):enter\nIdent(a)\nImportSpec(Default):exit\nStrLit\nImportDec:exit\nProg:exit\n"];4474b0->final [xlabel="",color="black"];4475initial->b0 [xlabel="",color="black"];4476}4477`, ana.Graph().Dot(), "should be ok")4478}4479func TestCtrlflow_ImportDefaultMix(t *testing.T) {4480 p, ast, symtab, err := compile(`4481 import a, * as b from "a";4482 `, nil)4483 AssertEqual(t, nil, err, "should be prog ok")4484 ana := NewAnalysis(ast, symtab, p.Source())4485 ana.Analyze()4486 AssertEqualString(t, `4487digraph G {4488node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4489edge[fontname="Consolas",fontsize=10]4490initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4491final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4492b0[label="Prog:enter\nImportDec:enter\nImportSpec(Default):enter\nIdent(a)\nImportSpec(Default):exit\nImportSpec(Namespace):enter\nIdent(b)\nImportSpec(Namespace):exit\nStrLit\nImportDec:exit\nProg:exit\n"];4493b0->final [xlabel="",color="black"];4494initial->b0 [xlabel="",color="black"];4495}4496`, ana.Graph().Dot(), "should be ok")4497}4498func TestCtrlflow_ImportNamed(t *testing.T) {4499 p, ast, symtab, err := compile(`4500 import { a } from "a";4501 `, nil)4502 AssertEqual(t, nil, err, "should be prog ok")4503 ana := NewAnalysis(ast, symtab, p.Source())4504 ana.Analyze()4505 AssertEqualString(t, `4506digraph G {4507node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4508edge[fontname="Consolas",fontsize=10]4509initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4510final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4511b0[label="Prog:enter\nImportDec:enter\nImportSpec:enter\nIdent(a)\nIdent(a)\nImportSpec:exit\nStrLit\nImportDec:exit\nProg:exit\n"];4512b0->final [xlabel="",color="black"];4513initial->b0 [xlabel="",color="black"];4514}4515`, ana.Graph().Dot(), "should be ok")4516}4517func TestCtrlflow_ImportDefaultMixNamed(t *testing.T) {4518 p, ast, symtab, err := compile(`4519 import a, { b } from "a";4520 `, nil)4521 AssertEqual(t, nil, err, "should be prog ok")4522 ana := NewAnalysis(ast, symtab, p.Source())4523 ana.Analyze()4524 AssertEqualString(t, `4525digraph G {4526node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4527edge[fontname="Consolas",fontsize=10]4528initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4529final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4530b0[label="Prog:enter\nImportDec:enter\nImportSpec(Default):enter\nIdent(a)\nImportSpec(Default):exit\nImportSpec:enter\nIdent(b)\nIdent(b)\nImportSpec:exit\nStrLit\nImportDec:exit\nProg:exit\n"];4531b0->final [xlabel="",color="black"];4532initial->b0 [xlabel="",color="black"];4533}4534`, ana.Graph().Dot(), "should be ok")4535}4536func TestCtrlflow_ImportNamedAs(t *testing.T) {4537 p, ast, symtab, err := compile(`4538 import { a as b } from "a";4539 `, nil)4540 AssertEqual(t, nil, err, "should be prog ok")4541 ana := NewAnalysis(ast, symtab, p.Source())4542 ana.Analyze()4543 AssertEqualString(t, `4544digraph G {4545node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4546edge[fontname="Consolas",fontsize=10]4547initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4548final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4549b0[label="Prog:enter\nImportDec:enter\nImportSpec:enter\nIdent(a)\nIdent(b)\nImportSpec:exit\nStrLit\nImportDec:exit\nProg:exit\n"];4550b0->final [xlabel="",color="black"];4551initial->b0 [xlabel="",color="black"];4552}4553`, ana.Graph().Dot(), "should be ok")4554}4555func TestCtrlflow_ExportIndividual(t *testing.T) {4556 p, ast, symtab, err := compile(`4557 export let a, b, c;4558 `, nil)4559 AssertEqual(t, nil, err, "should be prog ok")4560 ana := NewAnalysis(ast, symtab, p.Source())4561 ana.Analyze()4562 AssertEqualString(t, `4563digraph G {4564node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4565edge[fontname="Consolas",fontsize=10]4566initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4567final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4568b0[label="Prog:enter\nExportDec:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDec:enter\nIdent(b)\nVarDec:exit\nVarDec:enter\nIdent(c)\nVarDec:exit\nVarDecStmt:exit\nExportDec:exit\nProg:exit\n"];4569b0->final [xlabel="",color="black"];4570initial->b0 [xlabel="",color="black"];4571}4572`, ana.Graph().Dot(), "should be ok")4573}4574func TestCtrlflow_ExportFn(t *testing.T) {4575 p, ast, symtab, err := compile(`4576 export function f() {}4577 `, nil)4578 AssertEqual(t, nil, err, "should be prog ok")4579 ana := NewAnalysis(ast, symtab, p.Source())4580 ana.Analyze()4581 AssertEqualString(t, `4582digraph G {4583node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4584edge[fontname="Consolas",fontsize=10]4585initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4586final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4587b0[label="Prog:enter\nExportDec:enter\nFnDec\nExportDec:exit\nProg:exit\n"];4588b0->final [xlabel="",color="black"];4589initial->b0 [xlabel="",color="black"];4590}4591`, ana.Graph().Dot(), "should be ok")4592}4593func TestCtrlflow_ExportClass(t *testing.T) {4594 p, ast, symtab, err := compile(`4595 export class A {}4596 `, nil)4597 AssertEqual(t, nil, err, "should be prog ok")4598 ana := NewAnalysis(ast, symtab, p.Source())4599 ana.Analyze()4600 AssertEqualString(t, `4601digraph G {4602node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4603edge[fontname="Consolas",fontsize=10]4604initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4605final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4606b0[label="Prog:enter\nExportDec:enter\nClassDec:enter\nIdent(A)\nClassBody:enter\nClassBody:exit\nClassDec:exit\nExportDec:exit\nProg:exit\n"];4607b0->final [xlabel="",color="black"];4608initial->b0 [xlabel="",color="black"];4609}4610`, ana.Graph().Dot(), "should be ok")4611}4612func TestCtrlflow_ExportList(t *testing.T) {4613 p, ast, symtab, err := compile(`4614 let a, b, c;4615 export { a, b, c }4616 `, nil)4617 AssertEqual(t, nil, err, "should be prog ok")4618 ana := NewAnalysis(ast, symtab, p.Source())4619 ana.Analyze()4620 AssertEqualString(t, `4621digraph G {4622node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4623edge[fontname="Consolas",fontsize=10]4624initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4625final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4626b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDec:enter\nIdent(b)\nVarDec:exit\nVarDec:enter\nIdent(c)\nVarDec:exit\nVarDecStmt:exit\nExportDec:enter\nExportSpec:enter\nIdent(a)\nIdent(a)\nExportSpec:exit\nExportSpec:enter\nIdent(b)\nIdent(b)\nExportSpec:exit\nExportSpec:enter\nIdent(c)\nIdent(c)\nExportSpec:exit\nExportDec:exit\nProg:exit\n"];4627b0->final [xlabel="",color="black"];4628initial->b0 [xlabel="",color="black"];4629}4630`, ana.Graph().Dot(), "should be ok")4631}4632func TestCtrlflow_ExportRename(t *testing.T) {4633 p, ast, symtab, err := compile(`4634 let a, b, c;4635 export { a as aa, b as bb, c as cc }4636 `, nil)4637 AssertEqual(t, nil, err, "should be prog ok")4638 ana := NewAnalysis(ast, symtab, p.Source())4639 ana.Analyze()4640 AssertEqualString(t, `4641digraph G {4642node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4643edge[fontname="Consolas",fontsize=10]4644initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4645final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4646b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDec:enter\nIdent(b)\nVarDec:exit\nVarDec:enter\nIdent(c)\nVarDec:exit\nVarDecStmt:exit\nExportDec:enter\nExportSpec:enter\nIdent(aa)\nIdent(a)\nExportSpec:exit\nExportSpec:enter\nIdent(bb)\nIdent(b)\nExportSpec:exit\nExportSpec:enter\nIdent(cc)\nIdent(c)\nExportSpec:exit\nExportDec:exit\nProg:exit\n"];4647b0->final [xlabel="",color="black"];4648initial->b0 [xlabel="",color="black"];4649}4650`, ana.Graph().Dot(), "should be ok")4651}4652func TestCtrlflow_ExportDestructArr(t *testing.T) {4653 p, ast, symtab, err := compile(`4654 export const [ a ] = arr4655 `, nil)4656 AssertEqual(t, nil, err, "should be prog ok")4657 ana := NewAnalysis(ast, symtab, p.Source())4658 ana.Analyze()4659 AssertEqualString(t, `4660digraph G {4661node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4662edge[fontname="Consolas",fontsize=10]4663initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4664final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4665b0[label="Prog:enter\nExportDec:enter\nVarDecStmt:enter\nVarDec:enter\nArrPat:enter\nIdent(a)\nArrPat:exit\nIdent(arr)\nVarDec:exit\nVarDecStmt:exit\nExportDec:exit\nProg:exit\n"];4666b0->final [xlabel="",color="black"];4667initial->b0 [xlabel="",color="black"];4668}4669`, ana.Graph().Dot(), "should be ok")4670}4671func TestCtrlflow_ExportDestructObj(t *testing.T) {4672 p, ast, symtab, err := compile(`4673 export const { a, b: c } = obj4674 `, nil)4675 AssertEqual(t, nil, err, "should be prog ok")4676 ana := NewAnalysis(ast, symtab, p.Source())4677 ana.Analyze()4678 AssertEqualString(t, `4679digraph G {4680node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4681edge[fontname="Consolas",fontsize=10]4682initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4683final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4684b0[label="Prog:enter\nExportDec:enter\nVarDecStmt:enter\nVarDec:enter\nObjPat:enter\nProp:enter\nIdent(a)\nIdent(a)\nProp:exit\nProp:enter\nIdent(b)\nIdent(c)\nProp:exit\nObjPat:exit\nIdent(obj)\nVarDec:exit\nVarDecStmt:exit\nExportDec:exit\nProg:exit\n"];4685b0->final [xlabel="",color="black"];4686initial->b0 [xlabel="",color="black"];4687}4688`, ana.Graph().Dot(), "should be ok")4689}4690func TestCtrlflow_ExportDefault(t *testing.T) {4691 p, ast, symtab, err := compile(`4692 export default a4693 `, nil)4694 AssertEqual(t, nil, err, "should be prog ok")4695 ana := NewAnalysis(ast, symtab, p.Source())4696 ana.Analyze()4697 AssertEqualString(t, `4698digraph G {4699node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4700edge[fontname="Consolas",fontsize=10]4701initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4702final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4703b0[label="Prog:enter\nExportDec(Default):enter\nIdent(a)\nExportDec(Default):exit\nProg:exit\n"];4704b0->final [xlabel="",color="black"];4705initial->b0 [xlabel="",color="black"];4706}4707`, ana.Graph().Dot(), "should be ok")4708}4709func TestCtrlflow_ExportDefaultFn(t *testing.T) {4710 p, ast, symtab, err := compile(`4711 export default function f() {}4712 `, nil)4713 AssertEqual(t, nil, err, "should be prog ok")4714 ana := NewAnalysis(ast, symtab, p.Source())4715 ana.Analyze()4716 AssertEqualString(t, `4717digraph G {4718node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4719edge[fontname="Consolas",fontsize=10]4720initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4721final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4722b0[label="Prog:enter\nExportDec(Default):enter\nFnDec\nExportDec(Default):exit\nProg:exit\n"];4723b0->final [xlabel="",color="black"];4724initial->b0 [xlabel="",color="black"];4725}4726`, ana.Graph().Dot(), "should be ok")4727}4728func TestCtrlflow_ExportAsDefault(t *testing.T) {4729 p, ast, symtab, err := compile(`4730 let a;4731 export { a as default }4732 `, nil)4733 AssertEqual(t, nil, err, "should be prog ok")4734 ana := NewAnalysis(ast, symtab, p.Source())4735 ana.Analyze()4736 AssertEqualString(t, `4737digraph G {4738node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4739edge[fontname="Consolas",fontsize=10]4740initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4741final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4742b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDecStmt:exit\nExportDec:enter\nExportSpec:enter\nIdent(default)\nIdent(a)\nExportSpec:exit\nExportDec:exit\nProg:exit\n"];4743b0->final [xlabel="",color="black"];4744initial->b0 [xlabel="",color="black"];4745}4746`, ana.Graph().Dot(), "should be ok")4747}4748func TestCtrlflow_ExportNs(t *testing.T) {4749 p, ast, symtab, err := compile(`4750 export * from "a"4751 `, nil)4752 AssertEqual(t, nil, err, "should be prog ok")4753 ana := NewAnalysis(ast, symtab, p.Source())4754 ana.Analyze()4755 AssertEqualString(t, `4756digraph G {4757node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4758edge[fontname="Consolas",fontsize=10]4759initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4760final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4761b0[label="Prog:enter\nExportDec(All):enter\nStrLit\nExportDec(All):exit\nProg:exit\n"];4762b0->final [xlabel="",color="black"];4763initial->b0 [xlabel="",color="black"];4764}4765`, ana.Graph().Dot(), "should be ok")4766}4767func TestCtrlflow_ExportNsAs(t *testing.T) {4768 p, ast, symtab, err := compile(`4769 export * as a from "a"4770 `, nil)4771 AssertEqual(t, nil, err, "should be prog ok")4772 ana := NewAnalysis(ast, symtab, p.Source())4773 ana.Analyze()4774 AssertEqualString(t, `4775digraph G {4776node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4777edge[fontname="Consolas",fontsize=10]4778initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4779final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4780b0[label="Prog:enter\nExportDec(All):enter\nExportSpec(Namespace):enter\nIdent(a)\nExportSpec(Namespace):exit\nStrLit\nExportDec(All):exit\nProg:exit\n"];4781b0->final [xlabel="",color="black"];4782initial->b0 [xlabel="",color="black"];4783}4784`, ana.Graph().Dot(), "should be ok")4785}4786func TestCtrlflow_ExportNamed(t *testing.T) {4787 p, ast, symtab, err := compile(`4788 export { a, b, c as cc, default, default as d } from "a"4789 `, nil)4790 AssertEqual(t, nil, err, "should be prog ok")4791 ana := NewAnalysis(ast, symtab, p.Source())4792 ana.Analyze()4793 AssertEqualString(t, `4794digraph G {4795node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4796edge[fontname="Consolas",fontsize=10]4797initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4798final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4799b0[label="Prog:enter\nExportDec:enter\nExportSpec:enter\nIdent(a)\nIdent(a)\nExportSpec:exit\nExportSpec:enter\nIdent(b)\nIdent(b)\nExportSpec:exit\nExportSpec:enter\nIdent(cc)\nIdent(c)\nExportSpec:exit\nExportSpec:enter\nIdent(default)\nIdent(default)\nExportSpec:exit\nExportSpec:enter\nIdent(d)\nIdent(default)\nExportSpec:exit\nStrLit\nExportDec:exit\nProg:exit\n"];4800b0->final [xlabel="",color="black"];4801initial->b0 [xlabel="",color="black"];4802}4803`, ana.Graph().Dot(), "should be ok")4804}4805func TestCtrlflow_PatArr(t *testing.T) {4806 p, ast, symtab, err := compile(`4807 let [a, b] = [1, 2]4808 `, nil)4809 AssertEqual(t, nil, err, "should be prog ok")4810 ana := NewAnalysis(ast, symtab, p.Source())4811 ana.Analyze()4812 AssertEqualString(t, `4813digraph G {4814node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4815edge[fontname="Consolas",fontsize=10]4816initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4817final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4818b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nArrPat:enter\nIdent(a)\nIdent(b)\nArrPat:exit\nArrLit:enter\nNumLit(1)\nNumLit(2)\nArrLit:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];4819b0->final [xlabel="",color="black"];4820initial->b0 [xlabel="",color="black"];4821}4822`, ana.Graph().Dot(), "should be ok")4823}4824func TestCtrlflow_PatArrAssign(t *testing.T) {4825 p, ast, symtab, err := compile(`4826 let a, b;4827 [a, b] = [1, 2]4828 `, nil)4829 AssertEqual(t, nil, err, "should be prog ok")4830 ana := NewAnalysis(ast, symtab, p.Source())4831 ana.Analyze()4832 AssertEqualString(t, `4833digraph G {4834node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4835edge[fontname="Consolas",fontsize=10]4836initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4837final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4838b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDec:enter\nIdent(b)\nVarDec:exit\nVarDecStmt:exit\nExprStmt:enter\nAssignExpr:enter\nArrPat:enter\nIdent(a)\nIdent(b)\nArrPat:exit\nArrLit:enter\nNumLit(1)\nNumLit(2)\nArrLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];4839b0->final [xlabel="",color="black"];4840initial->b0 [xlabel="",color="black"];4841}4842`, ana.Graph().Dot(), "should be ok")4843}4844func TestCtrlflow_PatArrDefault(t *testing.T) {4845 p, ast, symtab, err := compile(`4846 let [a = 3, b = 4] = [1, 2]4847 `, nil)4848 AssertEqual(t, nil, err, "should be prog ok")4849 ana := NewAnalysis(ast, symtab, p.Source())4850 ana.Analyze()4851 AssertEqualString(t, `4852digraph G {4853node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4854edge[fontname="Consolas",fontsize=10]4855initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4856final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4857b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nArrPat:enter\nAssignPat:enter\nIdent(a)\n"];4858b13[label="NumLit(4)\n"];4859b14[label="AssignPat:exit\nArrPat:exit\nArrLit:enter\nNumLit(1)\nNumLit(2)\nArrLit:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];4860b8[label="NumLit(3)\n"];4861b9[label="AssignPat:exit\nAssignPat:enter\nIdent(b)\n"];4862b0->b8 [xlabel="F",color="orange"];4863b0->b9 [xlabel="",color="black"];4864b13->b14 [xlabel="",color="black"];4865b14->final [xlabel="",color="black"];4866b8->b9 [xlabel="",color="black"];4867b9->b13 [xlabel="F",color="orange"];4868b9->b14 [xlabel="",color="black"];4869initial->b0 [xlabel="",color="black"];4870}4871`, ana.Graph().Dot(), "should be ok")4872}4873func TestCtrlflow_PatArrNested(t *testing.T) {4874 p, ast, symtab, err := compile(`4875 let [a = e && f, [ b, c = 2 ]] = arr4876 `, nil)4877 AssertEqual(t, nil, err, "should be prog ok")4878 ana := NewAnalysis(ast, symtab, p.Source())4879 ana.Analyze()4880 AssertEqualString(t, `4881digraph G {4882node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4883edge[fontname="Consolas",fontsize=10]4884initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4885final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4886b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nArrPat:enter\nAssignPat:enter\nIdent(a)\n"];4887b10[label="Ident(f)\nBinExpr(&&):exit\n"];4888b14[label="AssignPat:exit\nArrPat:enter\nIdent(b)\nAssignPat:enter\nIdent(c)\n"];4889b20[label="NumLit(2)\n"];4890b21[label="AssignPat:exit\nArrPat:exit\nArrPat:exit\nIdent(arr)\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];4891b8[label="BinExpr(&&):enter\nIdent(e)\n"];4892b0->b14 [xlabel="",color="black"];4893b0->b8 [xlabel="F",color="orange"];4894b10->b14 [xlabel="",color="black"];4895b14->b20 [xlabel="F",color="orange"];4896b14->b21 [xlabel="",color="black"];4897b20->b21 [xlabel="",color="black"];4898b21->final [xlabel="",color="black"];4899b8->b10 [xlabel="",color="black"];4900b8->b14 [xlabel="F",color="orange"];4901initial->b0 [xlabel="",color="black"];4902}4903`, ana.Graph().Dot(), "should be ok")4904}4905func TestCtrlflow_PatArrRest(t *testing.T) {4906 p, ast, symtab, err := compile(`4907 let [a, b, ...rest] = arr4908 `, nil)4909 AssertEqual(t, nil, err, "should be prog ok")4910 ana := NewAnalysis(ast, symtab, p.Source())4911 ana.Analyze()4912 AssertEqualString(t, `4913digraph G {4914node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4915edge[fontname="Consolas",fontsize=10]4916initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4917final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4918b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nArrPat:enter\nIdent(a)\nIdent(b)\nRestPat:enter\nIdent(rest)\nRestPat:exit\nArrPat:exit\nIdent(arr)\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];4919b0->final [xlabel="",color="black"];4920initial->b0 [xlabel="",color="black"];4921}4922`, ana.Graph().Dot(), "should be ok")4923}4924func TestCtrlflow_PatArrDiscardMiddle(t *testing.T) {4925 p, ast, symtab, err := compile(`4926 [a,,b] = [1, 2]4927 `, nil)4928 AssertEqual(t, nil, err, "should be prog ok")4929 ana := NewAnalysis(ast, symtab, p.Source())4930 ana.Analyze()4931 AssertEqualString(t, `4932digraph G {4933node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4934edge[fontname="Consolas",fontsize=10]4935initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4936final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4937b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nArrPat:enter\nIdent(a)\nIdent(b)\nArrPat:exit\nArrLit:enter\nNumLit(1)\nNumLit(2)\nArrLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];4938b0->final [xlabel="",color="black"];4939initial->b0 [xlabel="",color="black"];4940}4941`, ana.Graph().Dot(), "should be ok")4942}4943func TestCtrlflow_PatArrDiscardAll(t *testing.T) {4944 p, ast, symtab, err := compile(`4945 [,,] = [1, 2]4946 `, nil)4947 AssertEqual(t, nil, err, "should be prog ok")4948 ana := NewAnalysis(ast, symtab, p.Source())4949 ana.Analyze()4950 AssertEqualString(t, `4951digraph G {4952node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4953edge[fontname="Consolas",fontsize=10]4954initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4955final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4956b0[label="Prog:enter\nExprStmt:enter\nAssignExpr:enter\nArrPat:enter\nArrPat:exit\nArrLit:enter\nNumLit(1)\nNumLit(2)\nArrLit:exit\nAssignExpr:exit\nExprStmt:exit\nProg:exit\n"];4957b0->final [xlabel="",color="black"];4958initial->b0 [xlabel="",color="black"];4959}4960`, ana.Graph().Dot(), "should be ok")4961}4962func TestCtrlflow_PatObj(t *testing.T) {4963 p, ast, symtab, err := compile(`4964 let {a, b} = { a: 1, b: 2 }4965 `, nil)4966 AssertEqual(t, nil, err, "should be prog ok")4967 ana := NewAnalysis(ast, symtab, p.Source())4968 ana.Analyze()4969 AssertEqualString(t, `4970digraph G {4971node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4972edge[fontname="Consolas",fontsize=10]4973initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4974final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4975b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nObjPat:enter\nProp:enter\nIdent(a)\nIdent(a)\nProp:exit\nProp:enter\nIdent(b)\nIdent(b)\nProp:exit\nObjPat:exit\nObjLit:enter\nProp:enter\nIdent(a)\nNumLit(1)\nProp:exit\nProp:enter\nIdent(b)\nNumLit(2)\nProp:exit\nObjLit:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];4976b0->final [xlabel="",color="black"];4977initial->b0 [xlabel="",color="black"];4978}4979`, ana.Graph().Dot(), "should be ok")4980}4981func TestCtrlflow_PatObjAssign(t *testing.T) {4982 p, ast, symtab, err := compile(`4983 let a, b;4984 ({ a, b } = { a: 1, b: 2 })4985 `, nil)4986 AssertEqual(t, nil, err, "should be prog ok")4987 ana := NewAnalysis(ast, symtab, p.Source())4988 ana.Analyze()4989 AssertEqualString(t, `4990digraph G {4991node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];4992edge[fontname="Consolas",fontsize=10]4993initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];4994final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];4995b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDec:enter\nIdent(b)\nVarDec:exit\nVarDecStmt:exit\nExprStmt:enter\nParenExpr:enter\nAssignExpr:enter\nObjPat:enter\nProp:enter\nIdent(a)\nIdent(a)\nProp:exit\nProp:enter\nIdent(b)\nIdent(b)\nProp:exit\nObjPat:exit\nObjLit:enter\nProp:enter\nIdent(a)\nNumLit(1)\nProp:exit\nProp:enter\nIdent(b)\nNumLit(2)\nProp:exit\nObjLit:exit\nAssignExpr:exit\nParenExpr:exit\nExprStmt:exit\nProg:exit\n"];4996b0->final [xlabel="",color="black"];4997initial->b0 [xlabel="",color="black"];4998}4999`, ana.Graph().Dot(), "should be ok")5000}5001func TestCtrlflow_PatObjDefault(t *testing.T) {5002 p, ast, symtab, err := compile(`5003 let a, b;5004 ({ a = 3, b = 4 } = { a: 1, b: 2 })5005 `, nil)5006 AssertEqual(t, nil, err, "should be prog ok")5007 ana := NewAnalysis(ast, symtab, p.Source())5008 ana.Analyze()5009 AssertEqualString(t, `5010digraph G {5011node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5012edge[fontname="Consolas",fontsize=10]5013initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5014final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5015b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nVarDec:exit\nVarDec:enter\nIdent(b)\nVarDec:exit\nVarDecStmt:exit\nExprStmt:enter\nParenExpr:enter\nAssignExpr:enter\nObjPat:enter\nProp:enter\nIdent(a)\nAssignPat:enter\nIdent(a)\n"];5016b21[label="NumLit(3)\n"];5017b22[label="AssignPat:exit\nProp:exit\nProp:enter\nIdent(b)\nAssignPat:enter\nIdent(b)\n"];5018b30[label="NumLit(4)\n"];5019b31[label="AssignPat:exit\nProp:exit\nObjPat:exit\nObjLit:enter\nProp:enter\nIdent(a)\nNumLit(1)\nProp:exit\nProp:enter\nIdent(b)\nNumLit(2)\nProp:exit\nObjLit:exit\nAssignExpr:exit\nParenExpr:exit\nExprStmt:exit\nProg:exit\n"];5020b0->b21 [xlabel="F",color="orange"];5021b0->b22 [xlabel="",color="black"];5022b21->b22 [xlabel="",color="black"];5023b22->b30 [xlabel="F",color="orange"];5024b22->b31 [xlabel="",color="black"];5025b30->b31 [xlabel="",color="black"];5026b31->final [xlabel="",color="black"];5027initial->b0 [xlabel="",color="black"];5028}5029`, ana.Graph().Dot(), "should be ok")5030}5031func TestCtrlflow_PatObjRename(t *testing.T) {5032 p, ast, symtab, err := compile(`5033 let { a: b } = obj5034 `, nil)5035 AssertEqual(t, nil, err, "should be prog ok")5036 ana := NewAnalysis(ast, symtab, p.Source())5037 ana.Analyze()5038 AssertEqualString(t, `5039digraph G {5040node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5041edge[fontname="Consolas",fontsize=10]5042initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5043final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5044b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nObjPat:enter\nProp:enter\nIdent(a)\nIdent(b)\nProp:exit\nObjPat:exit\nIdent(obj)\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5045b0->final [xlabel="",color="black"];5046initial->b0 [xlabel="",color="black"];5047}5048`, ana.Graph().Dot(), "should be ok")5049}5050func TestCtrlflow_PatObjNested(t *testing.T) {5051 p, ast, symtab, err := compile(`5052 let { a: { b } } = obj5053 `, nil)5054 AssertEqual(t, nil, err, "should be prog ok")5055 ana := NewAnalysis(ast, symtab, p.Source())5056 ana.Analyze()5057 AssertEqualString(t, `5058digraph G {5059node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5060edge[fontname="Consolas",fontsize=10]5061initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5062final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5063b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nObjPat:enter\nProp:enter\nIdent(a)\nObjPat:enter\nProp:enter\nIdent(b)\nIdent(b)\nProp:exit\nObjPat:exit\nProp:exit\nObjPat:exit\nIdent(obj)\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5064b0->final [xlabel="",color="black"];5065initial->b0 [xlabel="",color="black"];5066}5067`, ana.Graph().Dot(), "should be ok")5068}5069func TestCtrlflow_PatObjCompute(t *testing.T) {5070 p, ast, symtab, err := compile(`5071 let key = "a"5072 let { [key]: foo } = obj5073 `, nil)5074 AssertEqual(t, nil, err, "should be prog ok")5075 ana := NewAnalysis(ast, symtab, p.Source())5076 ana.Analyze()5077 AssertEqualString(t, `5078digraph G {5079node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5080edge[fontname="Consolas",fontsize=10]5081initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5082final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5083b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(key)\nStrLit\nVarDec:exit\nVarDecStmt:exit\nVarDecStmt:enter\nVarDec:enter\nObjPat:enter\nProp:enter\nIdent(key)\nIdent(foo)\nProp:exit\nObjPat:exit\nIdent(obj)\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5084b0->final [xlabel="",color="black"];5085initial->b0 [xlabel="",color="black"];5086}5087`, ana.Graph().Dot(), "should be ok")5088}5089func TestCtrlflow_PatObjRest(t *testing.T) {5090 p, ast, symtab, err := compile(`5091 let { a, b, ...rest } = obj5092 `, nil)5093 AssertEqual(t, nil, err, "should be prog ok")5094 ana := NewAnalysis(ast, symtab, p.Source())5095 ana.Analyze()5096 AssertEqualString(t, `5097digraph G {5098node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5099edge[fontname="Consolas",fontsize=10]5100initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5101final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5102b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nObjPat:enter\nProp:enter\nIdent(a)\nIdent(a)\nProp:exit\nProp:enter\nIdent(b)\nIdent(b)\nProp:exit\nRestPat:enter\nIdent(rest)\nRestPat:exit\nObjPat:exit\nIdent(obj)\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5103b0->final [xlabel="",color="black"];5104initial->b0 [xlabel="",color="black"];5105}5106`, ana.Graph().Dot(), "should be ok")5107}5108func TestCtrlflow_ArrowFn(t *testing.T) {5109 p, ast, symtab, err := compile(`5110 let f = () => {}5111 `, nil)5112 AssertEqual(t, nil, err, "should be prog ok")5113 ana := NewAnalysis(ast, symtab, p.Source())5114 ana.Analyze()5115 AssertEqualString(t, `5116digraph G {5117node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5118edge[fontname="Consolas",fontsize=10]5119initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5120final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5121b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(f)\nArrowFn\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5122b0->final [xlabel="",color="black"];5123initial->b0 [xlabel="",color="black"];5124}5125`, ana.Graph().Dot(), "should be ok")5126}5127func TestCtrlflow_ArrowFnExpr(t *testing.T) {5128 p, ast, symtab, err := compile(`5129 let f = () => b5130 `, nil)5131 AssertEqual(t, nil, err, "should be prog ok")5132 ana := NewAnalysis(ast, symtab, p.Source())5133 ana.Analyze()5134 AssertEqualString(t, `5135digraph G {5136node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5137edge[fontname="Consolas",fontsize=10]5138initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5139final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5140b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(f)\nArrowFn\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5141b0->final [xlabel="",color="black"];5142initial->b0 [xlabel="",color="black"];5143}5144`, ana.Graph().Dot(), "should be ok")5145}5146func TestCtrlflow_ArrowFnExprBody(t *testing.T) {5147 p, ast, symtab, err := compile(`5148 let f = () => a && b || c5149 `, nil)5150 AssertEqual(t, nil, err, "should be prog ok")5151 ana := NewAnalysis(ast, symtab, p.Source())5152 ana.Analyze()5153 varDec := ast.(*parser.Prog).Body()[0].(*parser.VarDecStmt)5154 fn := varDec.DecList()[0].(*parser.VarDec).Init()5155 fnGraph := ana.AnalysisCtx().GraphOf(fn)5156 AssertEqualString(t, `5157digraph G {5158node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5159edge[fontname="Consolas",fontsize=10]5160initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5161final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5162b13[label="ArrowFn:enter\nBinExpr(||):enter\nBinExpr(&&):enter\nIdent(a)\n"];5163b14[label="ArrowFn:exit\n"];5164b5[label="Ident(b)\nBinExpr(&&):exit\n"];5165b9[label="Ident(c)\nBinExpr(||):exit\n"];5166b13->b5 [xlabel="",color="black"];5167b13->b9 [xlabel="F",color="orange"];5168b14->final [xlabel="",color="black"];5169b5->b14 [xlabel="T",color="orange"];5170b5->b9 [xlabel="",color="black"];5171b9->b14 [xlabel="",color="black"];5172initial->b13 [xlabel="",color="black"];5173}5174`, fnGraph.Dot(), "should be ok")5175}5176func TestCtrlflow_ArrowFnArgs(t *testing.T) {5177 p, ast, symtab, err := compile(`5178 let f = (a, b) => {5179 c5180 }5181 `, nil)5182 AssertEqual(t, nil, err, "should be prog ok")5183 ana := NewAnalysis(ast, symtab, p.Source())5184 ana.Analyze()5185 varDec := ast.(*parser.Prog).Body()[0].(*parser.VarDecStmt)5186 fn := varDec.DecList()[0].(*parser.VarDec).Init()5187 fnGraph := ana.AnalysisCtx().GraphOf(fn)5188 AssertEqualString(t, `5189digraph G {5190node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5191edge[fontname="Consolas",fontsize=10]5192initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5193final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5194b10[label="ArrowFn:enter\nIdent(a)\nIdent(b)\nBlockStmt:enter\nExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\nArrowFn:exit\n"];5195b10->final [xlabel="",color="black"];5196initial->b10 [xlabel="",color="black"];5197}5198`, fnGraph.Dot(), "should be ok")5199}5200func TestCtrlflow_ArrowFnRet(t *testing.T) {5201 p, ast, symtab, err := compile(`5202 let f = (a, b) => {5203 return5204 c5205 }5206 `, nil)5207 AssertEqual(t, nil, err, "should be prog ok")5208 ana := NewAnalysis(ast, symtab, p.Source())5209 ana.Analyze()5210 varDec := ast.(*parser.Prog).Body()[0].(*parser.VarDecStmt)5211 fn := varDec.DecList()[0].(*parser.VarDec).Init()5212 fnGraph := ana.AnalysisCtx().GraphOf(fn)5213 AssertEqualString(t, `5214digraph G {5215node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5216edge[fontname="Consolas",fontsize=10]5217initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5218final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5219b12[label="ArrowFn:enter\nIdent(a)\nIdent(b)\nBlockStmt:enter\nRetStmt:enter\nRetStmt:exit\n"];5220b13[label="ArrowFn:exit\n"];5221b8[label="ExprStmt:enter\nIdent(c)\nExprStmt:exit\nBlockStmt:exit\n"];5222b12->b13 [xlabel="U",color="orange"];5223b12->b8 [xlabel="",color="red"];5224b13->final [xlabel="",color="black"];5225b8->b13 [xlabel="",color="red"];5226initial->b12 [xlabel="",color="black"];5227}5228`, fnGraph.Dot(), "should be ok")5229}5230func TestCtrlflow_Yield(t *testing.T) {5231 p, ast, symtab, err := compile(`5232 function* f() {5233 yield 15234 }5235 `, nil)5236 AssertEqual(t, nil, err, "should be prog ok")5237 ana := NewAnalysis(ast, symtab, p.Source())5238 ana.Analyze()5239 fn := ast.(*parser.Prog).Body()[0]5240 fnGraph := ana.AnalysisCtx().GraphOf(fn)5241 AssertEqualString(t, `5242digraph G {5243node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5244edge[fontname="Consolas",fontsize=10]5245initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5246final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5247b13[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nYieldExpr:enter\nNumLit(1)\nYieldExpr:exit\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];5248b13->final [xlabel="",color="black"];5249initial->b13 [xlabel="",color="black"];5250}5251`, fnGraph.Dot(), "should be ok")5252}5253func TestCtrlflow_YieldStar(t *testing.T) {5254 p, ast, symtab, err := compile(`5255 function* f() {5256 yield* ff()5257 }5258 `, nil)5259 AssertEqual(t, nil, err, "should be prog ok")5260 ana := NewAnalysis(ast, symtab, p.Source())5261 ana.Analyze()5262 fn := ast.(*parser.Prog).Body()[0]5263 fnGraph := ana.AnalysisCtx().GraphOf(fn)5264 AssertEqualString(t, `5265digraph G {5266node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5267edge[fontname="Consolas",fontsize=10]5268initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5269final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5270b16[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nYieldExpr:enter\nCallExpr:enter\nIdent(ff)\nCallExpr:exit\nYieldExpr:exit\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];5271b16->final [xlabel="",color="black"];5272initial->b16 [xlabel="",color="black"];5273}5274`, fnGraph.Dot(), "should be ok")5275}5276func TestCtrlflow_OptChain(t *testing.T) {5277 p, ast, symtab, err := compile(`5278 obj?.prop5279 `, nil)5280 AssertEqual(t, nil, err, "should be prog ok")5281 ana := NewAnalysis(ast, symtab, p.Source())5282 ana.Analyze()5283 AssertEqualString(t, `5284digraph G {5285node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5286edge[fontname="Consolas",fontsize=10]5287initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5288final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5289b0[label="Prog:enter\nExprStmt:enter\nChainExpr:enter\nMemberExpr:enter\nIdent(obj)\n"];5290b10[label="ChainExpr:exit\nExprStmt:exit\nProg:exit\n"];5291b7[label="Ident(prop)\nMemberExpr:exit\n"];5292b0->b10 [xlabel="N",color="orange"];5293b0->b7 [xlabel="",color="black"];5294b10->final [xlabel="",color="black"];5295b7->b10 [xlabel="",color="black"];5296initial->b0 [xlabel="",color="black"];5297}5298`, ana.Graph().Dot(), "should be ok")5299}5300func TestCtrlflow_OptChainCompute(t *testing.T) {5301 p, ast, symtab, err := compile(`5302 (a || b)?.prop5303 `, nil)5304 AssertEqual(t, nil, err, "should be prog ok")5305 ana := NewAnalysis(ast, symtab, p.Source())5306 ana.Analyze()5307 AssertEqualString(t, `5308digraph G {5309node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5310edge[fontname="Consolas",fontsize=10]5311initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5312final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5313b0[label="Prog:enter\nExprStmt:enter\nChainExpr:enter\nMemberExpr:enter\nParenExpr:enter\nBinExpr(||):enter\nIdent(a)\n"];5314b13[label="ParenExpr:exit\n"];5315b15[label="Ident(prop)\nMemberExpr:exit\n"];5316b18[label="ChainExpr:exit\nExprStmt:exit\nProg:exit\n"];5317b9[label="Ident(b)\nBinExpr(||):exit\n"];5318b0->b13 [xlabel="T",color="orange"];5319b0->b9 [xlabel="",color="black"];5320b13->b15 [xlabel="",color="black"];5321b13->b18 [xlabel="N",color="orange"];5322b15->b18 [xlabel="",color="black"];5323b18->final [xlabel="",color="black"];5324b9->b13 [xlabel="",color="black"];5325initial->b0 [xlabel="",color="black"];5326}5327`, ana.Graph().Dot(), "should be ok")5328}5329func TestCtrlflow_OptChainMember(t *testing.T) {5330 p, ast, symtab, err := compile(`5331 obj.val?.prop5332 `, nil)5333 AssertEqual(t, nil, err, "should be prog ok")5334 ana := NewAnalysis(ast, symtab, p.Source())5335 ana.Analyze()5336 AssertEqualString(t, `5337digraph G {5338node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5339edge[fontname="Consolas",fontsize=10]5340initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5341final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5342b0[label="Prog:enter\nExprStmt:enter\nChainExpr:enter\nMemberExpr:enter\nMemberExpr:enter\nIdent(obj)\nIdent(val)\nMemberExpr:exit\n"];5343b11[label="Ident(prop)\nMemberExpr:exit\n"];5344b14[label="ChainExpr:exit\nExprStmt:exit\nProg:exit\n"];5345b0->b11 [xlabel="",color="black"];5346b0->b14 [xlabel="N",color="orange"];5347b11->b14 [xlabel="",color="black"];5348b14->final [xlabel="",color="black"];5349initial->b0 [xlabel="",color="black"];5350}5351`, ana.Graph().Dot(), "should be ok")5352}5353func TestCtrlflow_OptChainCallee(t *testing.T) {5354 p, ast, symtab, err := compile(`5355 obj.func?.()5356 `, nil)5357 AssertEqual(t, nil, err, "should be prog ok")5358 ana := NewAnalysis(ast, symtab, p.Source())5359 ana.Analyze()5360 AssertEqualString(t, `5361digraph G {5362node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5363edge[fontname="Consolas",fontsize=10]5364initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5365final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5366b0[label="Prog:enter\nExprStmt:enter\nChainExpr:enter\nCallExpr:enter\nMemberExpr:enter\nIdent(obj)\nIdent(func)\nMemberExpr:exit\n"];5367b11[label="CallExpr:exit\n"];5368b13[label="ChainExpr:exit\nExprStmt:exit\nProg:exit\n"];5369b0->b11 [xlabel="",color="black"];5370b0->b13 [xlabel="F",color="orange"];5371b11->b13 [xlabel="",color="black"];5372b13->final [xlabel="",color="black"];5373initial->b0 [xlabel="",color="black"];5374}5375`, ana.Graph().Dot(), "should be ok")5376}5377func TestCtrlflow_OptChainCalleeArgs(t *testing.T) {5378 p, ast, symtab, err := compile(`5379 obj.func?.(args)5380 `, nil)5381 AssertEqual(t, nil, err, "should be prog ok")5382 ana := NewAnalysis(ast, symtab, p.Source())5383 ana.Analyze()5384 AssertEqualString(t, `5385digraph G {5386node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5387edge[fontname="Consolas",fontsize=10]5388initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5389final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5390b0[label="Prog:enter\nExprStmt:enter\nChainExpr:enter\nCallExpr:enter\nMemberExpr:enter\nIdent(obj)\nIdent(func)\nMemberExpr:exit\n"];5391b11[label="Ident(args)\nCallExpr:exit\n"];5392b14[label="ChainExpr:exit\nExprStmt:exit\nProg:exit\n"];5393b0->b11 [xlabel="",color="black"];5394b0->b14 [xlabel="F",color="orange"];5395b11->b14 [xlabel="",color="black"];5396b14->final [xlabel="",color="black"];5397initial->b0 [xlabel="",color="black"];5398}5399`, ana.Graph().Dot(), "should be ok")5400}5401func TestCtrlflow_OptChainIdx(t *testing.T) {5402 p, ast, symtab, err := compile(`5403 obj.arr?.[index]5404 `, nil)5405 AssertEqual(t, nil, err, "should be prog ok")5406 ana := NewAnalysis(ast, symtab, p.Source())5407 ana.Analyze()5408 AssertEqualString(t, `5409digraph G {5410node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5411edge[fontname="Consolas",fontsize=10]5412initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5413final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5414b0[label="Prog:enter\nExprStmt:enter\nChainExpr:enter\nMemberExpr:enter\nMemberExpr:enter\nIdent(obj)\nIdent(arr)\nMemberExpr:exit\n"];5415b11[label="Ident(index)\nMemberExpr:exit\n"];5416b14[label="ChainExpr:exit\nExprStmt:exit\nProg:exit\n"];5417b0->b11 [xlabel="",color="black"];5418b0->b14 [xlabel="N",color="orange"];5419b11->b14 [xlabel="",color="black"];5420b14->final [xlabel="",color="black"];5421initial->b0 [xlabel="",color="black"];5422}5423`, ana.Graph().Dot(), "should be ok")5424}5425func TestCtrlflow_OptChainNested(t *testing.T) {5426 p, ast, symtab, err := compile(`5427 a?.b?.c()5428 `, nil)5429 AssertEqual(t, nil, err, "should be prog ok")5430 ana := NewAnalysis(ast, symtab, p.Source())5431 ana.Analyze()5432 AssertEqualString(t, `5433digraph G {5434node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5435edge[fontname="Consolas",fontsize=10]5436initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5437final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5438b0[label="Prog:enter\nExprStmt:enter\nChainExpr:enter\nCallExpr:enter\nMemberExpr:enter\nMemberExpr:enter\nIdent(a)\n"];5439b12[label="Ident(c)\nMemberExpr:exit\nCallExpr:exit\n"];5440b17[label="ChainExpr:exit\nExprStmt:exit\nProg:exit\n"];5441b9[label="Ident(b)\nMemberExpr:exit\n"];5442b0->b17 [xlabel="N",color="orange"];5443b0->b9 [xlabel="",color="black"];5444b12->b17 [xlabel="",color="black"];5445b17->final [xlabel="",color="black"];5446b9->b12 [xlabel="",color="black"];5447b9->b17 [xlabel="N",color="orange"];5448initial->b0 [xlabel="",color="black"];5449}5450`, ana.Graph().Dot(), "should be ok")5451}5452func TestCtrlflow_TplStr(t *testing.T) {5453 p, ast, symtab, err := compile("`string text`", nil)5454 AssertEqual(t, nil, err, "should be prog ok")5455 ana := NewAnalysis(ast, symtab, p.Source())5456 ana.Analyze()5457 AssertEqualString(t, `5458digraph G {5459node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5460edge[fontname="Consolas",fontsize=10]5461initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5462final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5463b0[label="Prog:enter\nExprStmt:enter\nTplExpr:enter\nStrLit\nTplExpr:exit\nExprStmt:exit\nProg:exit\n"];5464b0->final [xlabel="",color="black"];5465initial->b0 [xlabel="",color="black"];5466}5467`, ana.Graph().Dot(), "should be ok")5468}5469func TestCtrlflow_TplStrExpr(t *testing.T) {5470 p, ast, symtab, err := compile("`string text ${a && b} string ${c} text`", nil)5471 AssertEqual(t, nil, err, "should be prog ok")5472 ana := NewAnalysis(ast, symtab, p.Source())5473 ana.Analyze()5474 AssertEqualString(t, `5475digraph G {5476node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5477edge[fontname="Consolas",fontsize=10]5478initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5479final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5480b0[label="Prog:enter\nExprStmt:enter\nTplExpr:enter\nStrLit\nBinExpr(&&):enter\nIdent(a)\n"];5481b12[label="StrLit\nIdent(c)\nStrLit\nTplExpr:exit\nExprStmt:exit\nProg:exit\n"];5482b8[label="Ident(b)\nBinExpr(&&):exit\n"];5483b0->b12 [xlabel="F",color="orange"];5484b0->b8 [xlabel="",color="black"];5485b12->final [xlabel="",color="black"];5486b8->b12 [xlabel="",color="black"];5487initial->b0 [xlabel="",color="black"];5488}5489`, ana.Graph().Dot(), "should be ok")5490}5491func TestCtrlflow_TplStrExprLast(t *testing.T) {5492 p, ast, symtab, err := compile("`string text ${a} string ${b} text ${c && d}`", nil)5493 AssertEqual(t, nil, err, "should be prog ok")5494 ana := NewAnalysis(ast, symtab, p.Source())5495 ana.Analyze()5496 AssertEqualString(t, `5497digraph G {5498node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5499edge[fontname="Consolas",fontsize=10]5500initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5501final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5502b0[label="Prog:enter\nExprStmt:enter\nTplExpr:enter\nStrLit\nIdent(a)\nStrLit\nIdent(b)\nStrLit\nBinExpr(&&):enter\nIdent(c)\n"];5503b12[label="Ident(d)\nBinExpr(&&):exit\n"];5504b16[label="StrLit\nTplExpr:exit\nExprStmt:exit\nProg:exit\n"];5505b0->b12 [xlabel="",color="black"];5506b0->b16 [xlabel="F",color="orange"];5507b12->b16 [xlabel="",color="black"];5508b16->final [xlabel="",color="black"];5509initial->b0 [xlabel="",color="black"];5510}5511`, ana.Graph().Dot(), "should be ok")5512}5513func TestCtrlflow_TplStrFn(t *testing.T) {5514 p, ast, symtab, err := compile("tagFn`string text ${a} string text`", nil)5515 AssertEqual(t, nil, err, "should be prog ok")5516 ana := NewAnalysis(ast, symtab, p.Source())5517 ana.Analyze()5518 AssertEqualString(t, `5519digraph G {5520node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5521edge[fontname="Consolas",fontsize=10]5522initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5523final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5524b0[label="Prog:enter\nExprStmt:enter\nTplExpr:enter\nIdent(tagFn)\nStrLit\nIdent(a)\nStrLit\nTplExpr:exit\nExprStmt:exit\nProg:exit\n"];5525b0->final [xlabel="",color="black"];5526initial->b0 [xlabel="",color="black"];5527}5528`, ana.Graph().Dot(), "should be ok")5529}5530func TestCtrlflow_MetaProp(t *testing.T) {5531 p, ast, symtab, err := compile(`5532 function f() {5533 new.target5534 }5535 `, nil)5536 AssertEqual(t, nil, err, "should be prog ok")5537 ana := NewAnalysis(ast, symtab, p.Source())5538 ana.Analyze()5539 fn := ast.(*parser.Prog).Body()[0]5540 fnGraph := ana.AnalysisCtx().GraphOf(fn)5541 AssertEqualString(t, `5542digraph G {5543node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5544edge[fontname="Consolas",fontsize=10]5545initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5546final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5547b13[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nMetaProp:enter\nIdent(new)\nIdent(target)\nMetaProp:exit\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];5548b13->final [xlabel="",color="black"];5549initial->b13 [xlabel="",color="black"];5550}5551`, fnGraph.Dot(), "should be ok")5552}5553func TestCtrlflow_JsxBasic(t *testing.T) {5554 p, ast, symtab, err := compile(`5555 let a = <div></div>5556 `, nil)5557 AssertEqual(t, nil, err, "should be prog ok")5558 ana := NewAnalysis(ast, symtab, p.Source())5559 ana.Analyze()5560 AssertEqualString(t, `5561digraph G {5562node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5563edge[fontname="Consolas",fontsize=10]5564initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5565final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5566b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxOpen:exit\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5567b0->final [xlabel="",color="black"];5568initial->b0 [xlabel="",color="black"];5569}5570`, ana.Graph().Dot(), "should be ok")5571}5572func TestCtrlflow_JsxSelfClosed(t *testing.T) {5573 p, ast, symtab, err := compile(`5574 let a = <div/>5575 `, nil)5576 AssertEqual(t, nil, err, "should be prog ok")5577 ana := NewAnalysis(ast, symtab, p.Source())5578 ana.Analyze()5579 AssertEqualString(t, `5580digraph G {5581node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5582edge[fontname="Consolas",fontsize=10]5583initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5584final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5585b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen(Closed):enter\nJsxIdent(div)\nJsxOpen(Closed):exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5586b0->final [xlabel="",color="black"];5587initial->b0 [xlabel="",color="black"];5588}5589`, ana.Graph().Dot(), "should be ok")5590}5591func TestCtrlflow_JsxExpr(t *testing.T) {5592 p, ast, symtab, err := compile(`5593 let a = <div>a {b && c} d</div>5594 `, nil)5595 AssertEqual(t, nil, err, "should be prog ok")5596 ana := NewAnalysis(ast, symtab, p.Source())5597 ana.Analyze()5598 AssertEqualString(t, `5599digraph G {5600node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5601edge[fontname="Consolas",fontsize=10]5602initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5603final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5604b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxOpen:exit\nJsxText\nJsxExprSpan:enter\nBinExpr(&&):enter\nIdent(b)\n"];5605b15[label="Ident(c)\nBinExpr(&&):exit\n"];5606b19[label="JsxExprSpan:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5607b0->b15 [xlabel="",color="black"];5608b0->b19 [xlabel="F",color="orange"];5609b15->b19 [xlabel="",color="black"];5610b19->final [xlabel="",color="black"];5611initial->b0 [xlabel="",color="black"];5612}5613`, ana.Graph().Dot(), "should be ok")5614}5615func TestCtrlflow_JsxEmpty(t *testing.T) {5616 p, ast, symtab, err := compile(`5617 let a = <div>{/* empty */}</div>5618 `, nil)5619 AssertEqual(t, nil, err, "should be prog ok")5620 ana := NewAnalysis(ast, symtab, p.Source())5621 ana.Analyze()5622 AssertEqualString(t, `5623digraph G {5624node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5625edge[fontname="Consolas",fontsize=10]5626initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5627final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5628b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxOpen:exit\nJsxExprSpan:enter\nJsxEmpty\nJsxExprSpan:exit\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5629b0->final [xlabel="",color="black"];5630initial->b0 [xlabel="",color="black"];5631}5632`, ana.Graph().Dot(), "should be ok")5633}5634func TestCtrlflow_JsxMember(t *testing.T) {5635 p, ast, symtab, err := compile(`5636 let a = <A.b/>5637 `, nil)5638 AssertEqual(t, nil, err, "should be prog ok")5639 ana := NewAnalysis(ast, symtab, p.Source())5640 ana.Analyze()5641 AssertEqualString(t, `5642digraph G {5643node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5644edge[fontname="Consolas",fontsize=10]5645initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5646final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5647b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen(Closed):enter\nJsxMember:enter\nJsxIdent(A)\nIdent(b)\nJsxMember:exit\nJsxOpen(Closed):exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5648b0->final [xlabel="",color="black"];5649initial->b0 [xlabel="",color="black"];5650}5651`, ana.Graph().Dot(), "should be ok")5652}5653func TestCtrlflow_JsxNs(t *testing.T) {5654 opts := parser.NewParserOpts()5655 opts.Feature = opts.Feature.On(parser.FEAT_JSX_NS)5656 p, ast, symtab, err := compile(`5657 let a = <div:a>text</div:a>5658 `, opts)5659 AssertEqual(t, nil, err, "should be prog ok")5660 ana := NewAnalysis(ast, symtab, p.Source())5661 ana.Analyze()5662 AssertEqualString(t, `5663digraph G {5664node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5665edge[fontname="Consolas",fontsize=10]5666initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5667final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5668b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxNsName\nJsxOpen:exit\nJsxText\nJsxClose:enter\nJsxNsName\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5669b0->final [xlabel="",color="black"];5670initial->b0 [xlabel="",color="black"];5671}5672`, ana.Graph().Dot(), "should be ok")5673}5674func TestCtrlflow_JsxSpread(t *testing.T) {5675 p, ast, symtab, err := compile(`5676 let a = <div>5677 {...e}5678 </div>5679 `, nil)5680 AssertEqual(t, nil, err, "should be prog ok")5681 ana := NewAnalysis(ast, symtab, p.Source())5682 ana.Analyze()5683 AssertEqualString(t, `5684digraph G {5685node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5686edge[fontname="Consolas",fontsize=10]5687initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5688final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5689b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxOpen:exit\nJsxText\nJsxSpreadChild:enter\nIdent(e)\nJsxSpreadChild:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5690b0->final [xlabel="",color="black"];5691initial->b0 [xlabel="",color="black"];5692}5693`, ana.Graph().Dot(), "should be ok")5694}5695func TestCtrlflow_JsxAttr(t *testing.T) {5696 p, ast, symtab, err := compile(`5697 let a = <div attr="str">text</div>5698 `, nil)5699 AssertEqual(t, nil, err, "should be prog ok")5700 ana := NewAnalysis(ast, symtab, p.Source())5701 ana.Analyze()5702 AssertEqualString(t, `5703digraph G {5704node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5705edge[fontname="Consolas",fontsize=10]5706initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5707final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5708b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxAttr:enter\nJsxIdent(attr)\nStrLit\nJsxAttr:exit\nJsxOpen:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5709b0->final [xlabel="",color="black"];5710initial->b0 [xlabel="",color="black"];5711}5712`, ana.Graph().Dot(), "should be ok")5713}5714func TestCtrlflow_JsxAttrExpr(t *testing.T) {5715 p, ast, symtab, err := compile(`5716 let a = <div attr={1}>text</div>5717 `, nil)5718 AssertEqual(t, nil, err, "should be prog ok")5719 ana := NewAnalysis(ast, symtab, p.Source())5720 ana.Analyze()5721 AssertEqualString(t, `5722digraph G {5723node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5724edge[fontname="Consolas",fontsize=10]5725initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5726final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5727b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxAttr:enter\nJsxIdent(attr)\nJsxExprSpan:enter\nNumLit(1)\nJsxExprSpan:exit\nJsxAttr:exit\nJsxOpen:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5728b0->final [xlabel="",color="black"];5729initial->b0 [xlabel="",color="black"];5730}5731`, ana.Graph().Dot(), "should be ok")5732}5733func TestCtrlflow_JsxAttrExprBin(t *testing.T) {5734 p, ast, symtab, err := compile(`5735 let a = <div attr={a && b}>text</div>5736 `, nil)5737 AssertEqual(t, nil, err, "should be prog ok")5738 ana := NewAnalysis(ast, symtab, p.Source())5739 ana.Analyze()5740 AssertEqualString(t, `5741digraph G {5742node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5743edge[fontname="Consolas",fontsize=10]5744initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5745final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5746b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxAttr:enter\nJsxIdent(attr)\nJsxExprSpan:enter\nBinExpr(&&):enter\nIdent(a)\n"];5747b14[label="Ident(b)\nBinExpr(&&):exit\n"];5748b18[label="JsxExprSpan:exit\nJsxAttr:exit\nJsxOpen:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5749b0->b14 [xlabel="",color="black"];5750b0->b18 [xlabel="F",color="orange"];5751b14->b18 [xlabel="",color="black"];5752b18->final [xlabel="",color="black"];5753initial->b0 [xlabel="",color="black"];5754}5755`, ana.Graph().Dot(), "should be ok")5756}5757func TestCtrlflow_JsxAttrFlag(t *testing.T) {5758 p, ast, symtab, err := compile(`5759 let a = <div attr>text</div>5760 `, nil)5761 AssertEqual(t, nil, err, "should be prog ok")5762 ana := NewAnalysis(ast, symtab, p.Source())5763 ana.Analyze()5764 AssertEqualString(t, `5765digraph G {5766node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5767edge[fontname="Consolas",fontsize=10]5768initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5769final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5770b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxAttr:enter\nJsxIdent(attr)\nJsxAttr:exit\nJsxOpen:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5771b0->final [xlabel="",color="black"];5772initial->b0 [xlabel="",color="black"];5773}5774`, ana.Graph().Dot(), "should be ok")5775}5776func TestCtrlflow_JsxAttrSpread(t *testing.T) {5777 p, ast, symtab, err := compile(`5778 let a = <div {...props}>text</div>5779 `, nil)5780 AssertEqual(t, nil, err, "should be prog ok")5781 ana := NewAnalysis(ast, symtab, p.Source())5782 ana.Analyze()5783 AssertEqualString(t, `5784digraph G {5785node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5786edge[fontname="Consolas",fontsize=10]5787initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5788final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5789b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxSpreadAttr:enter\nSpread:enter\nIdent(props)\nSpread:exit\nJsxSpreadAttr:exit\nJsxOpen:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5790b0->final [xlabel="",color="black"];5791initial->b0 [xlabel="",color="black"];5792}5793`, ana.Graph().Dot(), "should be ok")5794}5795func TestCtrlflow_JsxAttrMixed(t *testing.T) {5796 p, ast, symtab, err := compile(`5797 let a = <div attr0 attr1={true} attr2="a" {...b}>text</div>5798 `, nil)5799 AssertEqual(t, nil, err, "should be prog ok")5800 ana := NewAnalysis(ast, symtab, p.Source())5801 ana.Analyze()5802 AssertEqualString(t, `5803digraph G {5804node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5805edge[fontname="Consolas",fontsize=10]5806initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5807final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5808b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nJsxElem:enter\nJsxOpen:enter\nJsxIdent(div)\nJsxAttr:enter\nJsxIdent(attr0)\nJsxAttr:exit\nJsxAttr:enter\nJsxIdent(attr1)\nJsxExprSpan:enter\nBoolLit\nJsxExprSpan:exit\nJsxAttr:exit\nJsxAttr:enter\nJsxIdent(attr2)\nStrLit\nJsxAttr:exit\nJsxSpreadAttr:enter\nSpread:enter\nIdent(b)\nSpread:exit\nJsxSpreadAttr:exit\nJsxOpen:exit\nJsxText\nJsxClose:enter\nJsxIdent(div)\nJsxClose:exit\nJsxElem:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5809b0->final [xlabel="",color="black"];5810initial->b0 [xlabel="",color="black"];5811}5812`, ana.Graph().Dot(), "should be ok")5813}5814func TestCtrlflow_ClassStmt(t *testing.T) {5815 p, ast, symtab, err := compile(`5816class A {}5817 `, nil)5818 AssertEqual(t, nil, err, "should be prog ok")5819 ana := NewAnalysis(ast, symtab, p.Source())5820 ana.Analyze()5821 AssertEqualString(t, `5822digraph G {5823node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5824edge[fontname="Consolas",fontsize=10]5825initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5826final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5827b0[label="Prog:enter\nClassDec:enter\nIdent(A)\nClassBody:enter\nClassBody:exit\nClassDec:exit\nProg:exit\n"];5828b0->final [xlabel="",color="black"];5829initial->b0 [xlabel="",color="black"];5830}5831`, ana.Graph().Dot(), "should be ok")5832}5833func TestCtrlflow_ClassField(t *testing.T) {5834 p, ast, symtab, err := compile(`5835class A {5836 a;5837 b = 15838 c = a && b5839 d = function f() {}5840 e = () => {}5841}5842 `, nil)5843 AssertEqual(t, nil, err, "should be prog ok")5844 ana := NewAnalysis(ast, symtab, p.Source())5845 ana.Analyze()5846 AssertEqualString(t, `5847digraph G {5848node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5849edge[fontname="Consolas",fontsize=10]5850initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5851final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5852b0[label="Prog:enter\nClassDec:enter\nIdent(A)\nClassBody:enter\nField:enter\nIdent(a)\nField:exit\nField:enter\nIdent(b)\nNumLit(1)\nField:exit\nField:enter\nIdent(c)\nBinExpr(&&):enter\nIdent(a)\n"];5853b19[label="Ident(b)\nBinExpr(&&):exit\n"];5854b23[label="Field:exit\nField:enter\nIdent(d)\nFnDec\nField:exit\nField:enter\nIdent(e)\nArrowFn\nField:exit\nClassBody:exit\nClassDec:exit\nProg:exit\n"];5855b0->b19 [xlabel="",color="black"];5856b0->b23 [xlabel="F",color="orange"];5857b19->b23 [xlabel="",color="black"];5858b23->final [xlabel="",color="black"];5859initial->b0 [xlabel="",color="black"];5860}5861`, ana.Graph().Dot(), "should be ok")5862}5863func TestCtrlflow_ClassFieldFn(t *testing.T) {5864 p, ast, symtab, err := compile(`5865class A {5866 a = function f() {5867 b5868 }5869}5870 `, nil)5871 AssertEqual(t, nil, err, "should be prog ok")5872 ana := NewAnalysis(ast, symtab, p.Source())5873 ana.Analyze()5874 fn := ast.(*parser.Prog).Body()[0].(*parser.ClassDec).Body().(*parser.ClassBody).Elems()[0].(*parser.Field).Val().(*parser.FnDec)5875 fnGraph := ana.AnalysisCtx().GraphOf(fn)5876 AssertEqualString(t, `5877digraph G {5878node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5879edge[fontname="Consolas",fontsize=10]5880initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5881final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5882b9[label="FnDec:enter\nIdent(f)\nBlockStmt:enter\nExprStmt:enter\nIdent(b)\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];5883b9->final [xlabel="",color="black"];5884initial->b9 [xlabel="",color="black"];5885}5886`, fnGraph.Dot(), "should be ok")5887}5888func TestCtrlflow_ClassFieldArrowFn(t *testing.T) {5889 p, ast, symtab, err := compile(`5890class A {5891 a = () => {5892 b5893 }5894}5895 `, nil)5896 AssertEqual(t, nil, err, "should be prog ok")5897 ana := NewAnalysis(ast, symtab, p.Source())5898 ana.Analyze()5899 fn := ast.(*parser.Prog).Body()[0].(*parser.ClassDec).Body().(*parser.ClassBody).Elems()[0].(*parser.Field).Val().(*parser.ArrowFn)5900 fnGraph := ana.AnalysisCtx().GraphOf(fn)5901 AssertEqualString(t, `5902digraph G {5903node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5904edge[fontname="Consolas",fontsize=10]5905initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5906final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5907b8[label="ArrowFn:enter\nBlockStmt:enter\nExprStmt:enter\nIdent(b)\nExprStmt:exit\nBlockStmt:exit\nArrowFn:exit\n"];5908b8->final [xlabel="",color="black"];5909initial->b8 [xlabel="",color="black"];5910}5911`, fnGraph.Dot(), "should be ok")5912}5913func TestCtrlflow_ClassFieldArrowFnExpr(t *testing.T) {5914 p, ast, symtab, err := compile(`5915class A {5916 a = () => a?.b()5917}5918 `, nil)5919 AssertEqual(t, nil, err, "should be prog ok")5920 ana := NewAnalysis(ast, symtab, p.Source())5921 ana.Analyze()5922 fn := ast.(*parser.Prog).Body()[0].(*parser.ClassDec).Body().(*parser.ClassBody).Elems()[0].(*parser.Field).Val().(*parser.ArrowFn)5923 fnGraph := ana.AnalysisCtx().GraphOf(fn)5924 AssertEqualString(t, `5925digraph G {5926node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5927edge[fontname="Consolas",fontsize=10]5928initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5929final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5930b11[label="ChainExpr:exit\nArrowFn:exit\n"];5931b14[label="ArrowFn:enter\nChainExpr:enter\nCallExpr:enter\nMemberExpr:enter\nIdent(a)\n"];5932b6[label="Ident(b)\nMemberExpr:exit\nCallExpr:exit\n"];5933b11->final [xlabel="",color="black"];5934b14->b11 [xlabel="N",color="orange"];5935b14->b6 [xlabel="",color="black"];5936b6->b11 [xlabel="",color="black"];5937initial->b14 [xlabel="",color="black"];5938}5939`, fnGraph.Dot(), "should be ok")5940}5941func TestCtrlflow_ClassExpr(t *testing.T) {5942 p, ast, symtab, err := compile(`5943 let a = class A {}5944 `, nil)5945 AssertEqual(t, nil, err, "should be prog ok")5946 ana := NewAnalysis(ast, symtab, p.Source())5947 ana.Analyze()5948 AssertEqualString(t, `5949digraph G {5950node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5951edge[fontname="Consolas",fontsize=10]5952initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5953final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5954b0[label="Prog:enter\nVarDecStmt:enter\nVarDec:enter\nIdent(a)\nClassDec:enter\nIdent(A)\nClassBody:enter\nClassBody:exit\nClassDec:exit\nVarDec:exit\nVarDecStmt:exit\nProg:exit\n"];5955b0->final [xlabel="",color="black"];5956initial->b0 [xlabel="",color="black"];5957}5958`, ana.Graph().Dot(), "should be ok")5959}5960func TestCtrlflow_ClassMethod(t *testing.T) {5961 p, ast, symtab, err := compile(`5962 class A {5963 f () {}5964 }5965 `, nil)5966 AssertEqual(t, nil, err, "should be prog ok")5967 ana := NewAnalysis(ast, symtab, p.Source())5968 ana.Analyze()5969 AssertEqualString(t, `5970digraph G {5971node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5972edge[fontname="Consolas",fontsize=10]5973initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5974final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];5975b0[label="Prog:enter\nClassDec:enter\nIdent(A)\nClassBody:enter\nMethod:enter\nIdent(f)\nFnDec\nMethod:exit\nClassBody:exit\nClassDec:exit\nProg:exit\n"];5976b0->final [xlabel="",color="black"];5977initial->b0 [xlabel="",color="black"];5978}5979`, ana.Graph().Dot(), "should be ok")5980}5981func TestCtrlflow_ClassMethodBdy(t *testing.T) {5982 p, ast, symtab, err := compile(`5983 class A {5984 f () {5985 a5986 }5987 }5988 `, nil)5989 AssertEqual(t, nil, err, "should be prog ok")5990 ana := NewAnalysis(ast, symtab, p.Source())5991 ana.Analyze()5992 fn := ast.(*parser.Prog).Body()[0].(*parser.ClassDec).Body().(*parser.ClassBody).Elems()[0].(*parser.Method).Val().(*parser.FnDec)5993 fnGraph := ana.AnalysisCtx().GraphOf(fn)5994 AssertEqualString(t, `5995digraph G {5996node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];5997edge[fontname="Consolas",fontsize=10]5998initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];5999final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];6000b8[label="FnDec:enter\nBlockStmt:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];6001b8->final [xlabel="",color="black"];6002initial->b8 [xlabel="",color="black"];6003}6004`, fnGraph.Dot(), "should be ok")6005}6006func TestCtrlflow_ClassCtor(t *testing.T) {6007 p, ast, symtab, err := compile(`6008 class A extends B {6009 constructor () {6010 super()6011 }6012 }6013 `, nil)6014 AssertEqual(t, nil, err, "should be prog ok")6015 ana := NewAnalysis(ast, symtab, p.Source())6016 ana.Analyze()6017 fn := ast.(*parser.Prog).Body()[0].(*parser.ClassDec).Body().(*parser.ClassBody).Elems()[0].(*parser.Method).Val().(*parser.FnDec)6018 fnGraph := ana.AnalysisCtx().GraphOf(fn)6019 AssertEqualString(t, `6020digraph G {6021node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];6022edge[fontname="Consolas",fontsize=10]6023initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];6024final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];6025b11[label="FnDec:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nSuper\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];6026b11->final [xlabel="",color="black"];6027initial->b11 [xlabel="",color="black"];6028}6029`, fnGraph.Dot(), "should be ok")6030}6031func TestCtrlflow_ClassSuper(t *testing.T) {6032 p, ast, symtab, err := compile(`6033 class A {6034 f () {6035 super.a()6036 }6037 }6038 `, nil)6039 AssertEqual(t, nil, err, "should be prog ok")6040 ana := NewAnalysis(ast, symtab, p.Source())6041 ana.Analyze()6042 fn := ast.(*parser.Prog).Body()[0].(*parser.ClassDec).Body().(*parser.ClassBody).Elems()[0].(*parser.Method).Val().(*parser.FnDec)6043 fnGraph := ana.AnalysisCtx().GraphOf(fn)6044 AssertEqualString(t, `6045digraph G {6046node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];6047edge[fontname="Consolas",fontsize=10]6048initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];6049final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];6050b15[label="FnDec:enter\nBlockStmt:enter\nExprStmt:enter\nCallExpr:enter\nMemberExpr:enter\nSuper\nIdent(a)\nMemberExpr:exit\nCallExpr:exit\nExprStmt:exit\nBlockStmt:exit\nFnDec:exit\n"];6051b15->final [xlabel="",color="black"];6052initial->b15 [xlabel="",color="black"];6053}6054`, fnGraph.Dot(), "should be ok")6055}6056func TestCtrlflow_StaticBlk(t *testing.T) {6057 p, ast, symtab, err := compile(`6058 class A {6059 static {6060 a6061 }6062 }6063 `, nil)6064 AssertEqual(t, nil, err, "should be prog ok")6065 ana := NewAnalysis(ast, symtab, p.Source())6066 ana.Analyze()6067 AssertEqualString(t, `6068digraph G {6069node[shape=box,style="rounded,filled",fillcolor=white,fontname="Consolas",fontsize=10];6070edge[fontname="Consolas",fontsize=10]6071initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];6072final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];6073b0[label="Prog:enter\nClassDec:enter\nClassBody:enter\nStaticBlock:enter\nExprStmt:enter\nIdent(a)\nExprStmt:exit\nStaticBlock:exit\nClassBody:exit\nClassDec:exit\nProg:exit\n"];6074b0->final [xlabel="",color="black"];6075initial->b0 [xlabel="",color="black"];6076}6077`, ana.Graph().Dot(), "should be ok")6078}6079// func TestCtrlflow_Demo(t *testing.T) {6080// ast, symtab, err := compile(`6081// var a = function f() { if (baz) { return true; } return 1 }6082// `, nil)6083// AssertEqual(t, nil, err, "should be prog ok")6084// ana := NewAnalysis(ast, symtab,p.Source())6085// ana.Analyze()6086// fn := ast.(*parser.Prog).Body()[0].(*parser.VarDecStmt).DecList()[0].(*parser.VarDec).Init()6087// fnGraph := ana.AnalysisCtx().GraphOf(fn)6088// AssertEqualString(t, `6089// `, fnGraph.Dot(), "should be ok")6090// // AssertEqualString(t, `6091// // `, ana.Graph().Dot(), "should be ok")6092// }...
init.go
Source:init.go
...11 target.PageSize = pageSize12 target.DataOffset = dataOffset13 target.MmapSyscall = arch.mmapSyscall14 target.MakeMmap = arch.makeMmap15 target.AnalyzeMmap = arch.analyzeMmap16}17const (18 pageSize = 4 << 1019 dataOffset = 512 << 2020)21type arch struct {22 mmapSyscall *prog.Syscall23}24func (arch *arch) makeMmap(start, npages uint64) *prog.Call {25 meta := arch.mmapSyscall26 return &prog.Call{27 Meta: meta,28 Args: []prog.Arg{29 prog.MakePointerArg(meta.Args[0], start, 0, npages, nil),30 prog.MakeConstArg(meta.Args[1], npages*pageSize),31 },32 Ret: prog.MakeReturnArg(meta.Ret),33 }34}35func (arch *arch) analyzeMmap(c *prog.Call) (start, npages uint64, mapped bool) {36 switch c.Meta.Name {37 case "syz_mmap":38 npages = c.Args[1].(*prog.ConstArg).Val / pageSize39 start = c.Args[0].(*prog.PointerArg).PageIndex40 mapped = true41 }42 return43}...
analyze
Using AI Code Generation
1import (2func main() { singlechecker.Main(prog.Analyzer) }3type prog struct{}4func (prog) Analyzer() *analysis.Analyzer {5 return &analysis.Analyzer{6 }7}8func run(pass *analysis.Pass) (interface{}, error) {9 for _, file := range pass.Files {10 ast.Inspect(file, func(n ast.Node) bool {11 f, ok := n.(*ast.FuncDecl)12 if !ok {13 }14 if f.Name.Name != "main" {15 }16 for _, stmt := range f.Body.List {17 call, ok := stmt.(*ast.CallExpr)18 if !ok {19 }20 ident, ok := call.Fun.(*ast.Ident)21 if !ok {22 }23 if ident.Name != "Println" {24 }25 if len(call.Args) != 2 {26 }27 lit, ok := call.Args[0].(*ast.BasicLit)28 if !ok {29 }30 if lit.Kind != token.STRING {31 }32 _, ok = call.Args[1].(*ast.BasicLit)33 if !ok {34 }35 pass.Reportf(call.Pos(), "should use Printf")36 }37 })38 }39}40import (
analyze
Using AI Code Generation
1import (2func main() {3 p.Analyze()4 fmt.Println(p)5}6type Prog struct {7}8func (p *Prog) Analyze() {9}10import (11func TestAnalyze(t *testing.T) {12 p.Analyze()13 if p.Name != "Analyze" {14 t.Error("Expected Name to be 'Analyze', got ", p.Name)15 }16}17type Prog struct {18}19func (p *Prog) Analyze() {20}21import (22func TestAnalyze(t *testing.T) {23 p.Analyze()24 if p.Name != "Analyze" {25 t.Error("Expected Name to be 'Analyze', got ", p.Name)26 }27}28type Prog struct {29}30func (p *Prog) Analyze() {31}32import (33func TestAnalyze(t *testing.T) {34 p.Analyze()35 if p.Name != "Analyze" {36 t.Error("Expected Name to be 'Analyze', got ", p.Name)37 }38}39type Prog struct {40}41func (p *Prog) Analyze() {42}43import (44func TestAnalyze(t *testing.T) {45 p.Analyze()46 if p.Name != "Analyze" {47 t.Error("Expected Name to be 'Analyze', got ", p.Name)48 }49}50type Prog struct {51}52func (p *Prog) Analyze() {53}
analyze
Using AI Code Generation
1import (2func main() {3 fmt.Println("Enter a string")4 fmt.Scan(&s)5 prog.Analyze(s)6}7import (8func Analyze(s string) {9 for _, c := range s {10 if strings.ContainsAny(string(c), "aeiouAEIOU") {11 } else if strings.ContainsAny(string(c), "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ") {12 } else if strings.ContainsAny(string(c), "0123456789") {13 } else if strings.ContainsAny(string(c), " ") {14 }15 }16 fmt.Println("Vowels:", vowels)17 fmt.Println("Consonants:", consonants)18 fmt.Println("Digits:", digits)19 fmt.Println("White Spaces:", spaces)20}
analyze
Using AI Code Generation
1import (2func main() {3 p.Analyze()4 fmt.Println("Done")5}6import (7type Prog struct {8}9func (p *Prog) Analyze() {10 fmt.Println("Analyzing ...")11 analysis.Analyze()12}13import (14func Analyze() {15 fmt.Println("Analyzing ...")16}17import (18func TestAnalyze(t *testing.T) {19 Analyze()20}
analyze
Using AI Code Generation
1import (2func main() {3 p := prog.Prog{0, 0, 0, 0, 0, 0, 0, 0, 0}4 p.Analyze()5 fmt.Println("Number of lines:", p.Lines)6 fmt.Println("Number of words:", p.Words)7 fmt.Println("Number of characters:", p.Characters)8 fmt.Println("Number of sentences:", p.Sentences)9 fmt.Println("Number of paragraphs:", p.Paragraphs)10 fmt.Println("Number of whitespaces:", p.Whitespaces)11 fmt.Println("Number of tabs:", p.Tabs)12 fmt.Println("Number of new lines:", p.Newlines)13}
analyze
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello, playground")4 p.Analyze()5}6import "fmt"7type Prog struct {8}9func (p *Prog) Analyze() {10 fmt.Println("Analyze called")11}12import (13func TestAnalyze(t *testing.T) {14 p.Analyze()15}16import "fmt"17type Prog struct {18}19func (p *Prog) Analyze() {20 fmt.Println("Analyze called")21}22import (23func TestAnalyze(t *testing.T) {24 p.Analyze()25}26import "fmt"27type Prog struct {28}29func (p *Prog) Analyze() {30 fmt.Println("Analyze called")31}32import (33func TestAnalyze(t *testing.T) {34 p.Analyze()35}36import "fmt"37type Prog struct {38}39func (p *Prog) Analyze() {40 fmt.Println("Analyze called")41}42import (43func TestAnalyze(t *testing.T) {44 p.Analyze()45}46import "fmt"47type Prog struct {48}49func (p *Prog) Analyze() {50 fmt.Println("Analyze called")51}52import (53func TestAnalyze(t *testing.T) {54 p.Analyze()55}56import "
analyze
Using AI Code Generation
1import (2func main() {3 file, err := os.Open(os.Args[1])4 if err != nil {5 fmt.Println(err)6 }7 defer file.Close()8 scanner := bufio.NewScanner(file)9 for scanner.Scan() {10 line := scanner.Text()11 fields := strings.Fields(line)12 for _, f := range fields {13 n, err := strconv.Atoi(f)14 if err != nil {15 fmt.Println(err)16 }17 nums = append(nums, n)18 }19 p.analyze(nums)20 }21 fmt.Println("Number of instructions:", p.inst)22 fmt.Println("Number of data:", p.data)23 fmt.Println("Number of jumps:", p.jumps)24 fmt.Println("Number of jumps to data:", p.jumpsToData)25 fmt.Println("Number of jumps to instructions:", p.jumpsToInst)26}27import (28func main() {29 file, err := os.Open(os.Args[1])30 if err != nil {31 fmt.Println(err)32 }33 defer file.Close()34 scanner := bufio.NewScanner(file)35 for scanner.Scan() {36 line := scanner.Text()37 fields := strings.Fields(line)38 for _, f := range fields {39 n, err := strconv.Atoi(f)40 if err != nil {41 fmt.Println(err)42 }
analyze
Using AI Code Generation
1import "fmt"2func main() {3 p.analyze()4 fmt.Println("p is", p)5}6type prog struct {7}8func (p prog) analyze() {9 fmt.Println("analyzing prog", p.name)10}11type prog struct {12}13func (p prog) analyze() {14 fmt.Println("analyzing prog", p.name)15}16type prog struct {17}18func (p prog) analyze() {19 fmt.Println("analyzing prog", p.name)20}21type prog struct {22}23func (p prog) analyze() {24 fmt.Println("analyzing prog", p.name)25}26type prog struct {27}28func (p prog) analyze() {29 fmt.Println("analyzing prog", p.name)30}31type prog struct {32}33func (p prog) analyze() {34 fmt.Println("analyzing prog", p.name)35}36type prog struct {37}38func (p prog) analyze() {39 fmt.Println("analyzing prog", p.name)40}41type prog struct {42}43func (p prog) analyze() {44 fmt.Println("analyzing prog", p.name)45}46type prog struct {47}48func (p prog) analyze() {49 fmt.Println("analyzing prog", p.name)50}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!