From d3ae2954ff75391b7726fe4824d7d8c9ecdacc2f Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Tue, 29 Jan 2019 15:53:11 +0000 Subject: [PATCH] JavaScript: Add support for parsing postfix generator comprehensions. --- .../src/com/semmle/jcorn/CustomParser.java | 24 +- .../mozilla/input/generator_expressions.js | 3 +- .../output/trap/generator_expressions.js.trap | 1147 +++++++++-------- 3 files changed, 667 insertions(+), 507 deletions(-) diff --git a/javascript/extractor/src/com/semmle/jcorn/CustomParser.java b/javascript/extractor/src/com/semmle/jcorn/CustomParser.java index f62d1881d3e..15914ab3f1f 100644 --- a/javascript/extractor/src/com/semmle/jcorn/CustomParser.java +++ b/javascript/extractor/src/com/semmle/jcorn/CustomParser.java @@ -314,7 +314,29 @@ public class CustomParser extends FlowParser { } } - return super.parseParenAndDistinguishExpression(canBeArrow); + Expression res = super.parseParenAndDistinguishExpression(canBeArrow); + if (res instanceof ParenthesizedExpression) { + ParenthesizedExpression p = (ParenthesizedExpression) res; + if (p.getExpression() instanceof ComprehensionExpression) { + ComprehensionExpression c = (ComprehensionExpression) p.getExpression(); + if (c.isGenerator()) + return new ComprehensionExpression(p.getLoc(), c.getBody(), c.getBlocks(), c.getFilter(), c.isGenerator()); + } + } + return res; + } + + @Override + protected boolean parseParenthesisedExpression(DestructuringErrors refDestructuringErrors, + boolean allowTrailingComma, ParenthesisedExpressions parenExprs, boolean first) { + boolean cont = super.parseParenthesisedExpression(refDestructuringErrors, allowTrailingComma, parenExprs, first); + if (options.mozExtensions() && parenExprs.exprList.size() == 1 && this.type == TokenType._for) { + Expression body = parenExprs.exprList.remove(0); + ComprehensionExpression c = parseComprehension(body.getLoc().getStart(), true, body); + parenExprs.exprList.add(this.finishNode(c)); + return false; + } + return cont; } // add parsing of for-each loops diff --git a/javascript/extractor/tests/mozilla/input/generator_expressions.js b/javascript/extractor/tests/mozilla/input/generator_expressions.js index 18a7d69ab8a..10fa676f5ef 100644 --- a/javascript/extractor/tests/mozilla/input/generator_expressions.js +++ b/javascript/extractor/tests/mozilla/input/generator_expressions.js @@ -1,4 +1,5 @@ (for (year of years) if (year > 2000) year); year; (for (i of numbers) for (j of letters) i+j); -(for (i of numbers) for (j of letters) if (i") -#20031=@"loc,{#10000},1,31,1,31" -locations_default(#20031,#10000,1,31,1,31) +tokeninfo(#20030,6,#20001,9,"year") +#20031=@"loc,{#10000},1,26,1,29" +locations_default(#20031,#10000,1,26,1,29) hasLocation(#20030,#20031) #20032=* -tokeninfo(#20032,3,#20001,11,"2000") -#20033=@"loc,{#10000},1,33,1,36" -locations_default(#20033,#10000,1,33,1,36) +tokeninfo(#20032,8,#20001,10,">") +#20033=@"loc,{#10000},1,31,1,31" +locations_default(#20033,#10000,1,31,1,31) hasLocation(#20032,#20033) #20034=* -tokeninfo(#20034,8,#20001,12,")") -#20035=@"loc,{#10000},1,37,1,37" -locations_default(#20035,#10000,1,37,1,37) +tokeninfo(#20034,3,#20001,11,"2000") +#20035=@"loc,{#10000},1,33,1,36" +locations_default(#20035,#10000,1,33,1,36) hasLocation(#20034,#20035) #20036=* -tokeninfo(#20036,6,#20001,13,"year") -#20037=@"loc,{#10000},1,39,1,42" -locations_default(#20037,#10000,1,39,1,42) +tokeninfo(#20036,8,#20001,12,")") +#20037=@"loc,{#10000},1,37,1,37" +locations_default(#20037,#10000,1,37,1,37) hasLocation(#20036,#20037) #20038=* -tokeninfo(#20038,8,#20001,14,")") -#20039=@"loc,{#10000},1,43,1,43" -locations_default(#20039,#10000,1,43,1,43) +tokeninfo(#20038,6,#20001,13,"year") +#20039=@"loc,{#10000},1,39,1,42" +locations_default(#20039,#10000,1,39,1,42) hasLocation(#20038,#20039) #20040=* -tokeninfo(#20040,8,#20001,15,";") -#20041=@"loc,{#10000},1,44,1,44" -locations_default(#20041,#10000,1,44,1,44) +tokeninfo(#20040,8,#20001,14,")") +#20041=@"loc,{#10000},1,43,1,43" +locations_default(#20041,#10000,1,43,1,43) hasLocation(#20040,#20041) #20042=* -tokeninfo(#20042,6,#20001,16,"year") -#20043=@"loc,{#10000},2,1,2,4" -locations_default(#20043,#10000,2,1,2,4) +tokeninfo(#20042,8,#20001,15,";") +#20043=@"loc,{#10000},1,44,1,44" +locations_default(#20043,#10000,1,44,1,44) hasLocation(#20042,#20043) #20044=* -tokeninfo(#20044,8,#20001,17,";") -#20045=@"loc,{#10000},2,5,2,5" -locations_default(#20045,#10000,2,5,2,5) +tokeninfo(#20044,6,#20001,16,"year") +#20045=@"loc,{#10000},2,1,2,4" +locations_default(#20045,#10000,2,1,2,4) hasLocation(#20044,#20045) #20046=* -tokeninfo(#20046,8,#20001,18,"(") -#20047=@"loc,{#10000},3,1,3,1" -locations_default(#20047,#10000,3,1,3,1) +tokeninfo(#20046,8,#20001,17,";") +#20047=@"loc,{#10000},2,5,2,5" +locations_default(#20047,#10000,2,5,2,5) hasLocation(#20046,#20047) #20048=* -tokeninfo(#20048,7,#20001,19,"for") -#20049=@"loc,{#10000},3,2,3,4" -locations_default(#20049,#10000,3,2,3,4) +tokeninfo(#20048,8,#20001,18,"(") +#20049=@"loc,{#10000},3,1,3,1" +locations_default(#20049,#10000,3,1,3,1) hasLocation(#20048,#20049) #20050=* -tokeninfo(#20050,8,#20001,20,"(") -#20051=@"loc,{#10000},3,6,3,6" -locations_default(#20051,#10000,3,6,3,6) +tokeninfo(#20050,7,#20001,19,"for") +#20051=@"loc,{#10000},3,2,3,4" +locations_default(#20051,#10000,3,2,3,4) hasLocation(#20050,#20051) #20052=* -tokeninfo(#20052,6,#20001,21,"i") -#20053=@"loc,{#10000},3,7,3,7" -locations_default(#20053,#10000,3,7,3,7) +tokeninfo(#20052,8,#20001,20,"(") +#20053=@"loc,{#10000},3,6,3,6" +locations_default(#20053,#10000,3,6,3,6) hasLocation(#20052,#20053) #20054=* -tokeninfo(#20054,6,#20001,22,"of") -#20055=@"loc,{#10000},3,9,3,10" -locations_default(#20055,#10000,3,9,3,10) +tokeninfo(#20054,6,#20001,21,"i") +#20055=@"loc,{#10000},3,7,3,7" +locations_default(#20055,#10000,3,7,3,7) hasLocation(#20054,#20055) #20056=* -tokeninfo(#20056,6,#20001,23,"numbers") -#20057=@"loc,{#10000},3,12,3,18" -locations_default(#20057,#10000,3,12,3,18) +tokeninfo(#20056,6,#20001,22,"of") +#20057=@"loc,{#10000},3,9,3,10" +locations_default(#20057,#10000,3,9,3,10) hasLocation(#20056,#20057) #20058=* -tokeninfo(#20058,8,#20001,24,")") -#20059=@"loc,{#10000},3,19,3,19" -locations_default(#20059,#10000,3,19,3,19) +tokeninfo(#20058,6,#20001,23,"numbers") +#20059=@"loc,{#10000},3,12,3,18" +locations_default(#20059,#10000,3,12,3,18) hasLocation(#20058,#20059) #20060=* -tokeninfo(#20060,7,#20001,25,"for") -#20061=@"loc,{#10000},3,21,3,23" -locations_default(#20061,#10000,3,21,3,23) +tokeninfo(#20060,8,#20001,24,")") +#20061=@"loc,{#10000},3,19,3,19" +locations_default(#20061,#10000,3,19,3,19) hasLocation(#20060,#20061) #20062=* -tokeninfo(#20062,8,#20001,26,"(") -#20063=@"loc,{#10000},3,25,3,25" -locations_default(#20063,#10000,3,25,3,25) +tokeninfo(#20062,7,#20001,25,"for") +#20063=@"loc,{#10000},3,21,3,23" +locations_default(#20063,#10000,3,21,3,23) hasLocation(#20062,#20063) #20064=* -tokeninfo(#20064,6,#20001,27,"j") -#20065=@"loc,{#10000},3,26,3,26" -locations_default(#20065,#10000,3,26,3,26) +tokeninfo(#20064,8,#20001,26,"(") +#20065=@"loc,{#10000},3,25,3,25" +locations_default(#20065,#10000,3,25,3,25) hasLocation(#20064,#20065) #20066=* -tokeninfo(#20066,6,#20001,28,"of") -#20067=@"loc,{#10000},3,28,3,29" -locations_default(#20067,#10000,3,28,3,29) +tokeninfo(#20066,6,#20001,27,"j") +#20067=@"loc,{#10000},3,26,3,26" +locations_default(#20067,#10000,3,26,3,26) hasLocation(#20066,#20067) #20068=* -tokeninfo(#20068,6,#20001,29,"letters") -#20069=@"loc,{#10000},3,31,3,37" -locations_default(#20069,#10000,3,31,3,37) +tokeninfo(#20068,6,#20001,28,"of") +#20069=@"loc,{#10000},3,28,3,29" +locations_default(#20069,#10000,3,28,3,29) hasLocation(#20068,#20069) #20070=* -tokeninfo(#20070,8,#20001,30,")") -#20071=@"loc,{#10000},3,38,3,38" -locations_default(#20071,#10000,3,38,3,38) +tokeninfo(#20070,6,#20001,29,"letters") +#20071=@"loc,{#10000},3,31,3,37" +locations_default(#20071,#10000,3,31,3,37) hasLocation(#20070,#20071) #20072=* -tokeninfo(#20072,6,#20001,31,"i") -#20073=@"loc,{#10000},3,40,3,40" -locations_default(#20073,#10000,3,40,3,40) +tokeninfo(#20072,8,#20001,30,")") +#20073=@"loc,{#10000},3,38,3,38" +locations_default(#20073,#10000,3,38,3,38) hasLocation(#20072,#20073) #20074=* -tokeninfo(#20074,8,#20001,32,"+") -#20075=@"loc,{#10000},3,41,3,41" -locations_default(#20075,#10000,3,41,3,41) +tokeninfo(#20074,6,#20001,31,"i") +#20075=@"loc,{#10000},3,40,3,40" +locations_default(#20075,#10000,3,40,3,40) hasLocation(#20074,#20075) #20076=* -tokeninfo(#20076,6,#20001,33,"j") -#20077=@"loc,{#10000},3,42,3,42" -locations_default(#20077,#10000,3,42,3,42) +tokeninfo(#20076,8,#20001,32,"+") +#20077=@"loc,{#10000},3,41,3,41" +locations_default(#20077,#10000,3,41,3,41) hasLocation(#20076,#20077) #20078=* -tokeninfo(#20078,8,#20001,34,")") -#20079=@"loc,{#10000},3,43,3,43" -locations_default(#20079,#10000,3,43,3,43) +tokeninfo(#20078,6,#20001,33,"j") +#20079=@"loc,{#10000},3,42,3,42" +locations_default(#20079,#10000,3,42,3,42) hasLocation(#20078,#20079) #20080=* -tokeninfo(#20080,8,#20001,35,";") -#20081=@"loc,{#10000},3,44,3,44" -locations_default(#20081,#10000,3,44,3,44) +tokeninfo(#20080,8,#20001,34,")") +#20081=@"loc,{#10000},3,43,3,43" +locations_default(#20081,#10000,3,43,3,43) hasLocation(#20080,#20081) #20082=* -tokeninfo(#20082,8,#20001,36,"(") -#20083=@"loc,{#10000},4,1,4,1" -locations_default(#20083,#10000,4,1,4,1) +tokeninfo(#20082,8,#20001,35,";") +#20083=@"loc,{#10000},3,44,3,44" +locations_default(#20083,#10000,3,44,3,44) hasLocation(#20082,#20083) #20084=* -tokeninfo(#20084,7,#20001,37,"for") -#20085=@"loc,{#10000},4,2,4,4" -locations_default(#20085,#10000,4,2,4,4) +tokeninfo(#20084,8,#20001,36,"(") +#20085=@"loc,{#10000},4,1,4,1" +locations_default(#20085,#10000,4,1,4,1) hasLocation(#20084,#20085) #20086=* -tokeninfo(#20086,8,#20001,38,"(") -#20087=@"loc,{#10000},4,6,4,6" -locations_default(#20087,#10000,4,6,4,6) +tokeninfo(#20086,7,#20001,37,"for") +#20087=@"loc,{#10000},4,2,4,4" +locations_default(#20087,#10000,4,2,4,4) hasLocation(#20086,#20087) #20088=* -tokeninfo(#20088,6,#20001,39,"i") -#20089=@"loc,{#10000},4,7,4,7" -locations_default(#20089,#10000,4,7,4,7) +tokeninfo(#20088,8,#20001,38,"(") +#20089=@"loc,{#10000},4,6,4,6" +locations_default(#20089,#10000,4,6,4,6) hasLocation(#20088,#20089) #20090=* -tokeninfo(#20090,6,#20001,40,"of") -#20091=@"loc,{#10000},4,9,4,10" -locations_default(#20091,#10000,4,9,4,10) +tokeninfo(#20090,6,#20001,39,"i") +#20091=@"loc,{#10000},4,7,4,7" +locations_default(#20091,#10000,4,7,4,7) hasLocation(#20090,#20091) #20092=* -tokeninfo(#20092,6,#20001,41,"numbers") -#20093=@"loc,{#10000},4,12,4,18" -locations_default(#20093,#10000,4,12,4,18) +tokeninfo(#20092,6,#20001,40,"of") +#20093=@"loc,{#10000},4,9,4,10" +locations_default(#20093,#10000,4,9,4,10) hasLocation(#20092,#20093) #20094=* -tokeninfo(#20094,8,#20001,42,")") -#20095=@"loc,{#10000},4,19,4,19" -locations_default(#20095,#10000,4,19,4,19) +tokeninfo(#20094,6,#20001,41,"numbers") +#20095=@"loc,{#10000},4,12,4,18" +locations_default(#20095,#10000,4,12,4,18) hasLocation(#20094,#20095) #20096=* -tokeninfo(#20096,7,#20001,43,"for") -#20097=@"loc,{#10000},4,21,4,23" -locations_default(#20097,#10000,4,21,4,23) +tokeninfo(#20096,8,#20001,42,")") +#20097=@"loc,{#10000},4,19,4,19" +locations_default(#20097,#10000,4,19,4,19) hasLocation(#20096,#20097) #20098=* -tokeninfo(#20098,8,#20001,44,"(") -#20099=@"loc,{#10000},4,25,4,25" -locations_default(#20099,#10000,4,25,4,25) +tokeninfo(#20098,7,#20001,43,"for") +#20099=@"loc,{#10000},4,21,4,23" +locations_default(#20099,#10000,4,21,4,23) hasLocation(#20098,#20099) #20100=* -tokeninfo(#20100,6,#20001,45,"j") -#20101=@"loc,{#10000},4,26,4,26" -locations_default(#20101,#10000,4,26,4,26) +tokeninfo(#20100,8,#20001,44,"(") +#20101=@"loc,{#10000},4,25,4,25" +locations_default(#20101,#10000,4,25,4,25) hasLocation(#20100,#20101) #20102=* -tokeninfo(#20102,6,#20001,46,"of") -#20103=@"loc,{#10000},4,28,4,29" -locations_default(#20103,#10000,4,28,4,29) +tokeninfo(#20102,6,#20001,45,"j") +#20103=@"loc,{#10000},4,26,4,26" +locations_default(#20103,#10000,4,26,4,26) hasLocation(#20102,#20103) #20104=* -tokeninfo(#20104,6,#20001,47,"letters") -#20105=@"loc,{#10000},4,31,4,37" -locations_default(#20105,#10000,4,31,4,37) +tokeninfo(#20104,6,#20001,46,"of") +#20105=@"loc,{#10000},4,28,4,29" +locations_default(#20105,#10000,4,28,4,29) hasLocation(#20104,#20105) #20106=* -tokeninfo(#20106,8,#20001,48,")") -#20107=@"loc,{#10000},4,38,4,38" -locations_default(#20107,#10000,4,38,4,38) +tokeninfo(#20106,6,#20001,47,"letters") +#20107=@"loc,{#10000},4,31,4,37" +locations_default(#20107,#10000,4,31,4,37) hasLocation(#20106,#20107) #20108=* -tokeninfo(#20108,7,#20001,49,"if") -#20109=@"loc,{#10000},4,40,4,41" -locations_default(#20109,#10000,4,40,4,41) +tokeninfo(#20108,8,#20001,48,")") +#20109=@"loc,{#10000},4,38,4,38" +locations_default(#20109,#10000,4,38,4,38) hasLocation(#20108,#20109) #20110=* -tokeninfo(#20110,8,#20001,50,"(") -#20111=@"loc,{#10000},4,43,4,43" -locations_default(#20111,#10000,4,43,4,43) +tokeninfo(#20110,7,#20001,49,"if") +#20111=@"loc,{#10000},4,40,4,41" +locations_default(#20111,#10000,4,40,4,41) hasLocation(#20110,#20111) #20112=* -tokeninfo(#20112,6,#20001,51,"i") -#20113=@"loc,{#10000},4,44,4,44" -locations_default(#20113,#10000,4,44,4,44) +tokeninfo(#20112,8,#20001,50,"(") +#20113=@"loc,{#10000},4,43,4,43" +locations_default(#20113,#10000,4,43,4,43) hasLocation(#20112,#20113) #20114=* -tokeninfo(#20114,8,#20001,52,"<") -#20115=@"loc,{#10000},4,45,4,45" -locations_default(#20115,#10000,4,45,4,45) +tokeninfo(#20114,6,#20001,51,"i") +#20115=@"loc,{#10000},4,44,4,44" +locations_default(#20115,#10000,4,44,4,44) hasLocation(#20114,#20115) #20116=* -tokeninfo(#20116,6,#20001,53,"j") -#20117=@"loc,{#10000},4,46,4,46" -locations_default(#20117,#10000,4,46,4,46) +tokeninfo(#20116,8,#20001,52,"<") +#20117=@"loc,{#10000},4,45,4,45" +locations_default(#20117,#10000,4,45,4,45) hasLocation(#20116,#20117) #20118=* -tokeninfo(#20118,8,#20001,54,")") -#20119=@"loc,{#10000},4,47,4,47" -locations_default(#20119,#10000,4,47,4,47) +tokeninfo(#20118,6,#20001,53,"j") +#20119=@"loc,{#10000},4,46,4,46" +locations_default(#20119,#10000,4,46,4,46) hasLocation(#20118,#20119) #20120=* -tokeninfo(#20120,6,#20001,55,"i") -#20121=@"loc,{#10000},4,49,4,49" -locations_default(#20121,#10000,4,49,4,49) +tokeninfo(#20120,8,#20001,54,")") +#20121=@"loc,{#10000},4,47,4,47" +locations_default(#20121,#10000,4,47,4,47) hasLocation(#20120,#20121) #20122=* -tokeninfo(#20122,8,#20001,56,"+") -#20123=@"loc,{#10000},4,50,4,50" -locations_default(#20123,#10000,4,50,4,50) +tokeninfo(#20122,6,#20001,55,"i") +#20123=@"loc,{#10000},4,49,4,49" +locations_default(#20123,#10000,4,49,4,49) hasLocation(#20122,#20123) #20124=* -tokeninfo(#20124,6,#20001,57,"j") -#20125=@"loc,{#10000},4,51,4,51" -locations_default(#20125,#10000,4,51,4,51) +tokeninfo(#20124,8,#20001,56,"+") +#20125=@"loc,{#10000},4,50,4,50" +locations_default(#20125,#10000,4,50,4,50) hasLocation(#20124,#20125) #20126=* -tokeninfo(#20126,8,#20001,58,")") -#20127=@"loc,{#10000},4,52,4,52" -locations_default(#20127,#10000,4,52,4,52) +tokeninfo(#20126,6,#20001,57,"j") +#20127=@"loc,{#10000},4,51,4,51" +locations_default(#20127,#10000,4,51,4,51) hasLocation(#20126,#20127) #20128=* -tokeninfo(#20128,8,#20001,59,";") -#20129=@"loc,{#10000},4,53,4,53" -locations_default(#20129,#10000,4,53,4,53) +tokeninfo(#20128,8,#20001,58,")") +#20129=@"loc,{#10000},4,52,4,52" +locations_default(#20129,#10000,4,52,4,52) hasLocation(#20128,#20129) #20130=* -tokeninfo(#20130,0,#20001,60,"") -#20131=@"loc,{#10000},4,54,4,53" -locations_default(#20131,#10000,4,54,4,53) +tokeninfo(#20130,8,#20001,59,";") +#20131=@"loc,{#10000},4,53,4,53" +locations_default(#20131,#10000,4,53,4,53) hasLocation(#20130,#20131) -toplevels(#20001,0) -#20132=@"loc,{#10000},1,1,4,53" -locations_default(#20132,#10000,1,1,4,53) -hasLocation(#20001,#20132) -#20133=* -stmts(#20133,2,#20001,0,"(for (y ... year);") -hasLocation(#20133,#20003) -stmtContainers(#20133,#20001) +#20132=* +tokeninfo(#20132,8,#20001,60,"(") +#20133=@"loc,{#10000},5,1,5,1" +locations_default(#20133,#10000,5,1,5,1) +hasLocation(#20132,#20133) #20134=* -exprs(#20134,74,#20133,0,"(for (y ... ) year)") -#20135=@"loc,{#10000},1,1,1,43" -locations_default(#20135,#10000,1,1,1,43) +tokeninfo(#20134,6,#20001,61,"x") +#20135=@"loc,{#10000},5,2,5,2" +locations_default(#20135,#10000,5,2,5,2) hasLocation(#20134,#20135) -enclosingStmt(#20134,#20133) -exprContainers(#20134,#20001) #20136=* -exprs(#20136,76,#20134,1,"for (year of years)") -#20137=@"loc,{#10000},1,2,1,20" -locations_default(#20137,#10000,1,2,1,20) +tokeninfo(#20136,8,#20001,62,".") +#20137=@"loc,{#10000},5,3,5,3" +locations_default(#20137,#10000,5,3,5,3) hasLocation(#20136,#20137) -enclosingStmt(#20136,#20133) -exprContainers(#20136,#20001) #20138=* -scopes(#20138,7) -scopenodes(#20136,#20138) -scopenesting(#20138,#20000) -#20139=@"var;{year};{#20138}" -variables(#20139,"year",#20138) +tokeninfo(#20138,6,#20001,63,"p") +#20139=@"loc,{#10000},5,4,5,4" +locations_default(#20139,#10000,5,4,5,4) +hasLocation(#20138,#20139) #20140=* -exprs(#20140,78,#20136,0,"year") -hasLocation(#20140,#20017) -enclosingStmt(#20140,#20133) -exprContainers(#20140,#20001) -literals("year","year",#20140) -decl(#20140,#20139) -#20141=* -exprs(#20141,79,#20136,1,"years") -hasLocation(#20141,#20021) -enclosingStmt(#20141,#20133) -exprContainers(#20141,#20001) -literals("years","years",#20141) -#20142=@"var;{years};{#20000}" -variables(#20142,"years",#20000) -bind(#20141,#20142) -#20143=* -exprs(#20143,29,#20134,-1,"year > 2000") -#20144=@"loc,{#10000},1,26,1,36" -locations_default(#20144,#10000,1,26,1,36) -hasLocation(#20143,#20144) -enclosingStmt(#20143,#20133) -exprContainers(#20143,#20001) -#20145=* -exprs(#20145,79,#20143,0,"year") -hasLocation(#20145,#20029) -enclosingStmt(#20145,#20133) -exprContainers(#20145,#20001) -literals("year","year",#20145) -bind(#20145,#20139) +tokeninfo(#20140,7,#20001,64,"for") +#20141=@"loc,{#10000},5,6,5,8" +locations_default(#20141,#10000,5,6,5,8) +hasLocation(#20140,#20141) +#20142=* +tokeninfo(#20142,8,#20001,65,"(") +#20143=@"loc,{#10000},5,10,5,10" +locations_default(#20143,#10000,5,10,5,10) +hasLocation(#20142,#20143) +#20144=* +tokeninfo(#20144,6,#20001,66,"x") +#20145=@"loc,{#10000},5,11,5,11" +locations_default(#20145,#10000,5,11,5,11) +hasLocation(#20144,#20145) #20146=* -exprs(#20146,3,#20143,1,"2000") -hasLocation(#20146,#20033) -enclosingStmt(#20146,#20133) -exprContainers(#20146,#20001) -literals("2000","2000",#20146) -#20147=* -exprs(#20147,79,#20134,0,"year") -hasLocation(#20147,#20037) -enclosingStmt(#20147,#20133) -exprContainers(#20147,#20001) -literals("year","year",#20147) -bind(#20147,#20139) +tokeninfo(#20146,7,#20001,67,"in") +#20147=@"loc,{#10000},5,13,5,14" +locations_default(#20147,#10000,5,13,5,14) +hasLocation(#20146,#20147) #20148=* -stmts(#20148,2,#20001,1,"year;") -hasLocation(#20148,#20005) -stmtContainers(#20148,#20001) -#20149=* -exprs(#20149,79,#20148,0,"year") -hasLocation(#20149,#20043) -enclosingStmt(#20149,#20148) -exprContainers(#20149,#20001) -literals("year","year",#20149) -#20150=@"var;{year};{#20000}" -variables(#20150,"year",#20000) -bind(#20149,#20150) -#20151=* -stmts(#20151,2,#20001,2,"(for (i ... ) i+j);") -hasLocation(#20151,#20007) -stmtContainers(#20151,#20001) +tokeninfo(#20148,6,#20001,68,"xs") +#20149=@"loc,{#10000},5,16,5,17" +locations_default(#20149,#10000,5,16,5,17) +hasLocation(#20148,#20149) +#20150=* +tokeninfo(#20150,8,#20001,69,")") +#20151=@"loc,{#10000},5,18,5,18" +locations_default(#20151,#10000,5,18,5,18) +hasLocation(#20150,#20151) #20152=* -exprs(#20152,74,#20151,0,"(for (i ... s) i+j)") -#20153=@"loc,{#10000},3,1,3,43" -locations_default(#20153,#10000,3,1,3,43) +tokeninfo(#20152,8,#20001,70,")") +#20153=@"loc,{#10000},5,19,5,19" +locations_default(#20153,#10000,5,19,5,19) hasLocation(#20152,#20153) -enclosingStmt(#20152,#20151) -exprContainers(#20152,#20001) #20154=* -exprs(#20154,76,#20152,1,"for (i of numbers)") -#20155=@"loc,{#10000},3,2,3,19" -locations_default(#20155,#10000,3,2,3,19) +tokeninfo(#20154,8,#20001,71,";") +#20155=@"loc,{#10000},5,20,5,20" +locations_default(#20155,#10000,5,20,5,20) hasLocation(#20154,#20155) -enclosingStmt(#20154,#20151) -exprContainers(#20154,#20001) #20156=* -scopes(#20156,7) -scopenodes(#20154,#20156) -scopenesting(#20156,#20000) -#20157=@"var;{i};{#20156}" -variables(#20157,"i",#20156) -#20158=* -exprs(#20158,78,#20154,0,"i") -hasLocation(#20158,#20053) -enclosingStmt(#20158,#20151) -exprContainers(#20158,#20001) -literals("i","i",#20158) -decl(#20158,#20157) +tokeninfo(#20156,0,#20001,72,"") +#20157=@"loc,{#10000},6,1,6,0" +locations_default(#20157,#10000,6,1,6,0) +hasLocation(#20156,#20157) +toplevels(#20001,0) +#20158=@"loc,{#10000},1,1,6,0" +locations_default(#20158,#10000,1,1,6,0) +hasLocation(#20001,#20158) #20159=* -exprs(#20159,79,#20154,1,"numbers") -hasLocation(#20159,#20057) -enclosingStmt(#20159,#20151) -exprContainers(#20159,#20001) -literals("numbers","numbers",#20159) -#20160=@"var;{numbers};{#20000}" -variables(#20160,"numbers",#20000) -bind(#20159,#20160) -#20161=* -exprs(#20161,76,#20152,2,"for (j of letters)") -#20162=@"loc,{#10000},3,21,3,38" -locations_default(#20162,#10000,3,21,3,38) -hasLocation(#20161,#20162) -enclosingStmt(#20161,#20151) -exprContainers(#20161,#20001) -#20163=* -scopes(#20163,7) -scopenodes(#20161,#20163) -scopenesting(#20163,#20156) -#20164=@"var;{j};{#20163}" -variables(#20164,"j",#20163) -#20165=* -exprs(#20165,78,#20161,0,"j") -hasLocation(#20165,#20065) -enclosingStmt(#20165,#20151) -exprContainers(#20165,#20001) -literals("j","j",#20165) -decl(#20165,#20164) +stmts(#20159,2,#20001,0,"(for (y ... year);") +hasLocation(#20159,#20003) +stmtContainers(#20159,#20001) +#20160=* +exprs(#20160,74,#20159,0,"(for (y ... ) year)") +#20161=@"loc,{#10000},1,1,1,43" +locations_default(#20161,#10000,1,1,1,43) +hasLocation(#20160,#20161) +enclosingStmt(#20160,#20159) +exprContainers(#20160,#20001) +#20162=* +exprs(#20162,76,#20160,1,"for (year of years)") +#20163=@"loc,{#10000},1,2,1,20" +locations_default(#20163,#10000,1,2,1,20) +hasLocation(#20162,#20163) +enclosingStmt(#20162,#20159) +exprContainers(#20162,#20001) +#20164=* +scopes(#20164,7) +scopenodes(#20162,#20164) +scopenesting(#20164,#20000) +#20165=@"var;{year};{#20164}" +variables(#20165,"year",#20164) #20166=* -exprs(#20166,79,#20161,1,"letters") -hasLocation(#20166,#20069) -enclosingStmt(#20166,#20151) +exprs(#20166,78,#20162,0,"year") +hasLocation(#20166,#20019) +enclosingStmt(#20166,#20159) exprContainers(#20166,#20001) -literals("letters","letters",#20166) -#20167=@"var;{letters};{#20000}" -variables(#20167,"letters",#20000) -bind(#20166,#20167) -#20168=* -exprs(#20168,34,#20152,0,"i+j") -#20169=@"loc,{#10000},3,40,3,42" -locations_default(#20169,#10000,3,40,3,42) -hasLocation(#20168,#20169) -enclosingStmt(#20168,#20151) -exprContainers(#20168,#20001) -#20170=* -exprs(#20170,79,#20168,0,"i") -hasLocation(#20170,#20073) -enclosingStmt(#20170,#20151) -exprContainers(#20170,#20001) -literals("i","i",#20170) -bind(#20170,#20157) +literals("year","year",#20166) +decl(#20166,#20165) +#20167=* +exprs(#20167,79,#20162,1,"years") +hasLocation(#20167,#20023) +enclosingStmt(#20167,#20159) +exprContainers(#20167,#20001) +literals("years","years",#20167) +#20168=@"var;{years};{#20000}" +variables(#20168,"years",#20000) +bind(#20167,#20168) +#20169=* +exprs(#20169,29,#20160,-1,"year > 2000") +#20170=@"loc,{#10000},1,26,1,36" +locations_default(#20170,#10000,1,26,1,36) +hasLocation(#20169,#20170) +enclosingStmt(#20169,#20159) +exprContainers(#20169,#20001) #20171=* -exprs(#20171,79,#20168,1,"j") -hasLocation(#20171,#20077) -enclosingStmt(#20171,#20151) +exprs(#20171,79,#20169,0,"year") +hasLocation(#20171,#20031) +enclosingStmt(#20171,#20159) exprContainers(#20171,#20001) -literals("j","j",#20171) -bind(#20171,#20164) +literals("year","year",#20171) +bind(#20171,#20165) #20172=* -stmts(#20172,2,#20001,3,"(for (i ... ) i+j);") -hasLocation(#20172,#20009) -stmtContainers(#20172,#20001) +exprs(#20172,3,#20169,1,"2000") +hasLocation(#20172,#20035) +enclosingStmt(#20172,#20159) +exprContainers(#20172,#20001) +literals("2000","2000",#20172) #20173=* -exprs(#20173,74,#20172,0,"(for (i ... j) i+j)") -#20174=@"loc,{#10000},4,1,4,52" -locations_default(#20174,#10000,4,1,4,52) -hasLocation(#20173,#20174) -enclosingStmt(#20173,#20172) +exprs(#20173,79,#20160,0,"year") +hasLocation(#20173,#20039) +enclosingStmt(#20173,#20159) exprContainers(#20173,#20001) +literals("year","year",#20173) +bind(#20173,#20165) +#20174=* +stmts(#20174,2,#20001,1,"year;") +hasLocation(#20174,#20005) +stmtContainers(#20174,#20001) #20175=* -exprs(#20175,76,#20173,1,"for (i of numbers)") -#20176=@"loc,{#10000},4,2,4,19" -locations_default(#20176,#10000,4,2,4,19) -hasLocation(#20175,#20176) -enclosingStmt(#20175,#20172) +exprs(#20175,79,#20174,0,"year") +hasLocation(#20175,#20045) +enclosingStmt(#20175,#20174) exprContainers(#20175,#20001) +literals("year","year",#20175) +#20176=@"var;{year};{#20000}" +variables(#20176,"year",#20000) +bind(#20175,#20176) #20177=* -scopes(#20177,7) -scopenodes(#20175,#20177) -scopenesting(#20177,#20000) -#20178=@"var;{i};{#20177}" -variables(#20178,"i",#20177) -#20179=* -exprs(#20179,78,#20175,0,"i") -hasLocation(#20179,#20089) -enclosingStmt(#20179,#20172) -exprContainers(#20179,#20001) -literals("i","i",#20179) -decl(#20179,#20178) +stmts(#20177,2,#20001,2,"(for (i ... ) i+j);") +hasLocation(#20177,#20007) +stmtContainers(#20177,#20001) +#20178=* +exprs(#20178,74,#20177,0,"(for (i ... s) i+j)") +#20179=@"loc,{#10000},3,1,3,43" +locations_default(#20179,#10000,3,1,3,43) +hasLocation(#20178,#20179) +enclosingStmt(#20178,#20177) +exprContainers(#20178,#20001) #20180=* -exprs(#20180,79,#20175,1,"numbers") -hasLocation(#20180,#20093) -enclosingStmt(#20180,#20172) +exprs(#20180,76,#20178,1,"for (i of numbers)") +#20181=@"loc,{#10000},3,2,3,19" +locations_default(#20181,#10000,3,2,3,19) +hasLocation(#20180,#20181) +enclosingStmt(#20180,#20177) exprContainers(#20180,#20001) -literals("numbers","numbers",#20180) -bind(#20180,#20160) -#20181=* -exprs(#20181,76,#20173,2,"for (j of letters)") -#20182=@"loc,{#10000},4,21,4,38" -locations_default(#20182,#10000,4,21,4,38) -hasLocation(#20181,#20182) -enclosingStmt(#20181,#20172) -exprContainers(#20181,#20001) -#20183=* -scopes(#20183,7) -scopenodes(#20181,#20183) -scopenesting(#20183,#20177) -#20184=@"var;{j};{#20183}" -variables(#20184,"j",#20183) +#20182=* +scopes(#20182,7) +scopenodes(#20180,#20182) +scopenesting(#20182,#20000) +#20183=@"var;{i};{#20182}" +variables(#20183,"i",#20182) +#20184=* +exprs(#20184,78,#20180,0,"i") +hasLocation(#20184,#20055) +enclosingStmt(#20184,#20177) +exprContainers(#20184,#20001) +literals("i","i",#20184) +decl(#20184,#20183) #20185=* -exprs(#20185,78,#20181,0,"j") -hasLocation(#20185,#20101) -enclosingStmt(#20185,#20172) +exprs(#20185,79,#20180,1,"numbers") +hasLocation(#20185,#20059) +enclosingStmt(#20185,#20177) exprContainers(#20185,#20001) -literals("j","j",#20185) -decl(#20185,#20184) -#20186=* -exprs(#20186,79,#20181,1,"letters") -hasLocation(#20186,#20105) -enclosingStmt(#20186,#20172) -exprContainers(#20186,#20001) -literals("letters","letters",#20186) -bind(#20186,#20167) +literals("numbers","numbers",#20185) +#20186=@"var;{numbers};{#20000}" +variables(#20186,"numbers",#20000) +bind(#20185,#20186) #20187=* -exprs(#20187,27,#20173,-1,"i