Skip to content

Commit 7f4facc

Browse files
authored
Merge pull request #18661 from asgerf/js/hoist-in-block
JS: Hoist function declarations to the top of a block statement
2 parents 83ccdb7 + 6ae06ae commit 7f4facc

File tree

72 files changed

+159
-135
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+159
-135
lines changed

javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java

+7-14
Original file line numberDiff line numberDiff line change
@@ -586,14 +586,6 @@ private static List<Identifier> of(List<Statement> body) {
586586
public static List<Identifier> of(Program p) {
587587
return of(p.getBody());
588588
}
589-
590-
public static List<Identifier> of(IFunction fn) {
591-
Node body = fn.getBody();
592-
if (body instanceof BlockStatement) return of(((BlockStatement) body).getBody());
593-
// if the body of the function is missing or is an expression, then there are
594-
// no hoisted functions
595-
return Collections.emptyList();
596-
}
597589
}
598590

599591
/**
@@ -1096,8 +1088,6 @@ private void buildFunctionBody(IFunction nd) {
10961088
if (nd.hasRest()) paramsAndDefaults.add((Expression) nd.getRest());
10971089

10981090
Node entry = getEntryNode(nd);
1099-
List<Identifier> fns = HoistedFunDecls.of(nd);
1100-
hoistedFns.addAll(fns);
11011091

11021092
// if this is the constructor of a class without a superclass, we need to
11031093
// initialise all fields before running the body of the constructor
@@ -1117,7 +1107,7 @@ private void buildFunctionBody(IFunction nd) {
11171107
if (firstField != null) fst = Collections.singleton(First.of(firstField));
11181108
fst =
11191109
visitSequence(
1120-
nd instanceof FunctionDeclaration ? null : nd.getId(), paramsAndDefaults, fns, fst);
1110+
nd instanceof FunctionDeclaration ? null : nd.getId(), paramsAndDefaults, fst);
11211111
writeSuccessors(entry, fst);
11221112

11231113
this.ctxt.pop();
@@ -1255,9 +1245,12 @@ public Void visit(Literal nd, SuccessorInfo i) {
12551245

12561246
@Override
12571247
public Void visit(BlockStatement nd, SuccessorInfo i) {
1258-
if (nd.getBody().isEmpty()) writeSuccessors(nd, i.getAllSuccessors());
1259-
else writeSuccessor(nd, First.of(nd.getBody().get(0)));
1260-
visitSequence(nd.getBody(), i.getAllSuccessors());
1248+
// Hoist function declarations in a block statement to the top of the block.
1249+
// This reflects non-standard behaviour implemented by most engines.
1250+
// See also: ECMAScript "B.3.2 Block-Level Function Declarations Web Legacy Compatibility Semantics".
1251+
List<Identifier> hoisted = HoistedFunDecls.of(nd.getBody());
1252+
hoistedFns.addAll(hoisted);
1253+
writeSuccessors(nd, visitSequence(hoisted, nd.getBody(), i.getAllSuccessors()));
12611254
return null;
12621255
}
12631256

javascript/extractor/src/com/semmle/js/extractor/Main.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class Main {
4242
* A version identifier that should be updated every time the extractor changes in such a way that
4343
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
4444
*/
45-
public static final String EXTRACTOR_VERSION = "2025-01-21";
45+
public static final String EXTRACTOR_VERSION = "2025-02-03";
4646

4747
public static final Pattern NEWLINE = Pattern.compile("\n");
4848

javascript/extractor/tests/cfg/output/trap/classexpr3.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,12 @@ hasLocation(#20044,#20028)
163163
#20045=*
164164
exit_cfg_node(#20045,#20030)
165165
hasLocation(#20045,#20028)
166-
successor(#20035,#20036)
167166
successor(#20036,#20038)
168167
successor(#20040,#20039)
169168
successor(#20039,#20037)
170169
successor(#20038,#20040)
171170
successor(#20037,#20045)
171+
successor(#20035,#20036)
172172
successor(#20033,#20035)
173173
successor(#20044,#20033)
174174
successor(#20029,#20030)

javascript/extractor/tests/cfg/output/trap/classexpr4.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,12 @@ hasLocation(#20050,#20034)
184184
#20051=*
185185
exit_cfg_node(#20051,#20036)
186186
hasLocation(#20051,#20034)
187-
successor(#20041,#20042)
188187
successor(#20042,#20044)
189188
successor(#20046,#20045)
190189
successor(#20045,#20043)
191190
successor(#20044,#20046)
192191
successor(#20043,#20051)
192+
successor(#20041,#20042)
193193
successor(#20039,#20041)
194194
successor(#20050,#20039)
195195
successor(#20035,#20036)

javascript/extractor/tests/cfg/output/trap/fields.js.trap

+2-2
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,6 @@ exit_cfg_node(#20215,#20188)
671671
#20216=@"loc,{#10000},16,4,16,3"
672672
locations_default(#20216,#10000,16,4,16,3)
673673
hasLocation(#20215,#20216)
674-
successor(#20192,#20194)
675674
successor(#20203,#20205)
676675
successor(#20205,#20215)
677676
successor(#20198,#20202)
@@ -680,6 +679,7 @@ successor(#20207,#20203)
680679
successor(#20200,#20209)
681680
successor(#20194,#20196)
682681
successor(#20196,#20198)
682+
successor(#20192,#20194)
683683
successor(#20213,#20192)
684684
successor(#20187,#20188)
685685
successor(#20185,#20180)
@@ -729,9 +729,9 @@ exit_cfg_node(#20227,#20146)
729729
#20228=@"loc,{#10000},4,4,4,3"
730730
locations_default(#20228,#10000,4,4,4,3)
731731
hasLocation(#20227,#20228)
732-
successor(#20150,#20152)
733732
successor(#20152,#20154)
734733
successor(#20154,#20227)
734+
successor(#20150,#20152)
735735
successor(#20225,#20158)
736736
successor(#20145,#20146)
737737
successor(#20143,#20164)

javascript/extractor/tests/cfg/output/trap/tst.js.trap

+5-5
Original file line numberDiff line numberDiff line change
@@ -1425,30 +1425,30 @@ successor(#20455,#20457)
14251425
successor(#20457,#20461)
14261426
successor(#20432,#20434)
14271427
successor(#20434,#20436)
1428-
successor(#20436,#20438)
14291428
successor(#20438,#20442)
14301429
successor(#20442,#20440)
14311430
successor(#20440,#20443)
1431+
successor(#20436,#20438)
14321432
successor(#20414,#20416)
1433-
successor(#20416,#20420)
14341433
successor(#20420,#20418)
14351434
successor(#20418,#20422)
14361435
successor(#20418,#20432)
14371436
successor(#20424,#20418)
14381437
successor(#20422,#20424)
1438+
successor(#20416,#20420)
14391439
successor(#20425,#20429)
14401440
successor(#20430,#20432)
14411441
successor(#20429,#20430)
14421442
successor(#20392,#20394)
14431443
successor(#20394,#20412)
14441444
successor(#20396,#20400)
1445-
successor(#20401,#20403)
14461445
successor(#20403,#20409)
14471446
successor(#20411,#20407)
14481447
successor(#20409,#20411)
14491448
successor(#20407,#20412)
14501449
successor(#20407,#20405)
14511450
successor(#20405,#20412)
1451+
successor(#20401,#20403)
14521452
successor(#20400,#20401)
14531453
successor(#20412,#20414)
14541454
successor(#20371,#20392)
@@ -1462,7 +1462,6 @@ exit_cfg_node(#20468,#20371)
14621462
#20469=@"loc,{#10000},18,2,18,1"
14631463
locations_default(#20469,#10000,18,2,18,1)
14641464
hasLocation(#20468,#20469)
1465-
successor(#20379,#20383)
14661465
successor(#20383,#20381)
14671466
successor(#20381,#20384)
14681467
successor(#20381,#20468)
@@ -1481,6 +1480,7 @@ successor(#20391,#20381)
14811480
successor(#20384,#20387)
14821481
successor(#20387,#20386)
14831482
successor(#20386,#20388)
1483+
successor(#20379,#20383)
14841484
successor(#20377,#20379)
14851485
successor(#20466,#20377)
14861486
successor(#20365,#20367)
@@ -1504,7 +1504,6 @@ exit_cfg_node(#20475,#20322)
15041504
#20476=@"loc,{#10000},10,2,10,1"
15051505
locations_default(#20476,#10000,10,2,10,1)
15061506
hasLocation(#20475,#20476)
1507-
successor(#20328,#20330)
15081507
successor(#20356,#20358)
15091508
successor(#20358,#20359)
15101509
successor(#20359,#20361)
@@ -1539,6 +1538,7 @@ successor(#20330,#20334)
15391538
successor(#20335,#20332)
15401539
successor(#20334,#20335)
15411540
successor(#20332,#20336)
1541+
successor(#20328,#20330)
15421542
successor(#20474,#20328)
15431543
successor(#20373,#20322)
15441544
successor(#20324,#20373)

javascript/extractor/tests/es2015/output/trap/array_pattern_with_rest.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,14 @@ hasLocation(#20074,#20072)
235235
#20075=*
236236
exit_cfg_node(#20075,#20051)
237237
hasLocation(#20075,#20048)
238-
successor(#20058,#20060)
239238
successor(#20070,#20068)
240239
successor(#20068,#20075)
241240
successor(#20060,#20067)
242241
successor(#20064,#20066)
243242
successor(#20066,#20062)
244243
successor(#20067,#20064)
245244
successor(#20062,#20070)
245+
successor(#20058,#20060)
246246
successor(#20056,#20058)
247247
successor(#20074,#20056)
248248
successor(#20052,#20051)

javascript/extractor/tests/es2015/output/trap/arrowfn.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -509,11 +509,11 @@ exit_cfg_node(#20163,#20143)
509509
#20164=@"loc,{#10000},3,40,3,39"
510510
locations_default(#20164,#10000,3,40,3,39)
511511
hasLocation(#20163,#20164)
512-
successor(#20146,#20148)
513512
successor(#20148,#20152)
514513
successor(#20154,#20150)
515514
successor(#20152,#20154)
516515
successor(#20150,#20163)
516+
successor(#20146,#20148)
517517
successor(#20161,#20146)
518518
successor(#20141,#20143)
519519
successor(#20139,#20160)

javascript/extractor/tests/es2015/output/trap/class_accessors.js.trap

+2-2
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,14 @@ exit_cfg_node(#20134,#20101)
434434
#20135=@"loc,{#10000},7,4,7,3"
435435
locations_default(#20135,#10000,7,4,7,3)
436436
hasLocation(#20134,#20135)
437-
successor(#20107,#20109)
438437
successor(#20109,#20115)
439438
successor(#20119,#20117)
440439
successor(#20117,#20111)
441440
successor(#20116,#20113)
442441
successor(#20115,#20116)
443442
successor(#20113,#20119)
444443
successor(#20111,#20134)
444+
successor(#20107,#20109)
445445
successor(#20105,#20107)
446446
successor(#20132,#20105)
447447
successor(#20100,#20101)
@@ -457,11 +457,11 @@ exit_cfg_node(#20138,#20086)
457457
#20139=@"loc,{#10000},4,4,4,3"
458458
locations_default(#20139,#10000,4,4,4,3)
459459
hasLocation(#20138,#20139)
460-
successor(#20090,#20096)
461460
successor(#20097,#20094)
462461
successor(#20096,#20097)
463462
successor(#20094,#20092)
464463
successor(#20092,#20138)
464+
successor(#20090,#20096)
465465
successor(#20136,#20090)
466466
successor(#20085,#20086)
467467
successor(#20083,#20100)

javascript/extractor/tests/es2015/output/trap/class_ctor.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,13 @@ exit_cfg_node(#20076,#20054)
246246
#20077=@"loc,{#10000},4,4,4,3"
247247
locations_default(#20077,#10000,4,4,4,3)
248248
hasLocation(#20076,#20077)
249-
successor(#20060,#20062)
250249
successor(#20062,#20068)
251250
successor(#20070,#20064)
252251
successor(#20069,#20066)
253252
successor(#20068,#20069)
254253
successor(#20066,#20070)
255254
successor(#20064,#20076)
255+
successor(#20060,#20062)
256256
successor(#20058,#20060)
257257
successor(#20074,#20058)
258258
successor(#20053,#20054)

javascript/extractor/tests/es2015/output/trap/class_extends.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,12 @@ hasLocation(#20042,#20026)
159159
#20043=*
160160
exit_cfg_node(#20043,#20028)
161161
hasLocation(#20043,#20026)
162-
successor(#20033,#20034)
163162
successor(#20034,#20036)
164163
successor(#20038,#20037)
165164
successor(#20037,#20035)
166165
successor(#20036,#20038)
167166
successor(#20035,#20043)
167+
successor(#20033,#20034)
168168
successor(#20031,#20033)
169169
successor(#20042,#20031)
170170
successor(#20027,#20028)

javascript/extractor/tests/es2015/output/trap/class_extends2.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,12 @@ hasLocation(#20075,#20059)
261261
#20076=*
262262
exit_cfg_node(#20076,#20061)
263263
hasLocation(#20076,#20059)
264-
successor(#20066,#20067)
265264
successor(#20067,#20069)
266265
successor(#20071,#20070)
267266
successor(#20070,#20068)
268267
successor(#20069,#20071)
269268
successor(#20068,#20076)
269+
successor(#20066,#20067)
270270
successor(#20064,#20066)
271271
successor(#20075,#20064)
272272
successor(#20060,#20061)

javascript/extractor/tests/es2015/output/trap/class_method.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,11 @@ exit_cfg_node(#20076,#20050)
253253
#20077=@"loc,{#10000},4,4,4,3"
254254
locations_default(#20077,#10000,4,4,4,3)
255255
hasLocation(#20076,#20077)
256-
successor(#20054,#20060)
257256
successor(#20061,#20058)
258257
successor(#20060,#20061)
259258
successor(#20058,#20056)
260259
successor(#20056,#20076)
260+
successor(#20054,#20060)
261261
successor(#20074,#20054)
262262
successor(#20049,#20050)
263263
successor(#20047,#20064)

javascript/extractor/tests/es2015/output/trap/class_static.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@ exit_cfg_node(#20073,#20048)
243243
#20074=@"loc,{#10000},4,4,4,3"
244244
locations_default(#20074,#10000,4,4,4,3)
245245
hasLocation(#20073,#20074)
246-
successor(#20052,#20056)
247246
successor(#20056,#20054)
248247
successor(#20054,#20073)
248+
successor(#20052,#20056)
249249
successor(#20071,#20052)
250250
successor(#20047,#20048)
251251
successor(#20045,#20061)

javascript/extractor/tests/es2015/output/trap/delegating_yield.js.trap

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,11 @@ hasLocation(#20054,#20052)
171171
#20055=*
172172
exit_cfg_node(#20055,#20037)
173173
hasLocation(#20055,#20034)
174-
successor(#20041,#20043)
175174
successor(#20043,#20049)
176175
successor(#20049,#20047)
177176
successor(#20047,#20045)
178177
successor(#20045,#20055)
178+
successor(#20041,#20043)
179179
successor(#20054,#20041)
180180
successor(#20038,#20037)
181181
successor(#20051,#20038)

javascript/extractor/tests/es2015/output/trap/destructuring.js.trap

+4-4
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,6 @@ hasLocation(#20266,#20267)
822822
#20268=*
823823
exit_cfg_node(#20268,#20230)
824824
hasLocation(#20268,#20173)
825-
successor(#20247,#20249)
826825
successor(#20262,#20260)
827826
successor(#20260,#20268)
828827
successor(#20249,#20259)
@@ -832,6 +831,7 @@ successor(#20257,#20258)
832831
successor(#20255,#20251)
833832
successor(#20259,#20253)
834833
successor(#20251,#20262)
834+
successor(#20247,#20249)
835835
successor(#20237,#20240)
836836
successor(#20245,#20242)
837837
successor(#20244,#20245)
@@ -849,21 +849,20 @@ exit_cfg_node(#20270,#20177)
849849
#20271=@"loc,{#10000},8,2,8,1"
850850
locations_default(#20271,#10000,8,2,8,1)
851851
hasLocation(#20270,#20271)
852-
successor(#20190,#20192)
853852
successor(#20203,#20205)
854-
successor(#20205,#20209)
855853
successor(#20209,#20211)
856854
successor(#20212,#20207)
857855
successor(#20211,#20212)
858856
successor(#20207,#20213)
857+
successor(#20205,#20209)
859858
successor(#20213,#20217)
860-
successor(#20218,#20220)
861859
successor(#20220,#20226)
862860
successor(#20229,#20222)
863861
successor(#20228,#20224)
864862
successor(#20226,#20228)
865863
successor(#20224,#20229)
866864
successor(#20222,#20270)
865+
successor(#20218,#20220)
867866
successor(#20217,#20218)
868867
successor(#20192,#20202)
869868
successor(#20196,#20198)
@@ -872,6 +871,7 @@ successor(#20201,#20194)
872871
successor(#20198,#20199)
873872
successor(#20202,#20196)
874873
successor(#20194,#20203)
874+
successor(#20190,#20192)
875875
successor(#20185,#20187)
876876
successor(#20188,#20190)
877877
successor(#20187,#20188)

javascript/extractor/tests/es2015/output/trap/forof.js.trap

+2-2
Original file line numberDiff line numberDiff line change
@@ -436,28 +436,28 @@ exit_cfg_node(#20140,#20118)
436436
#20141=@"loc,{#10000},7,2,7,1"
437437
locations_default(#20141,#10000,7,2,7,1)
438438
hasLocation(#20140,#20141)
439-
successor(#20124,#20128)
440439
successor(#20128,#20126)
441440
successor(#20126,#20130)
442441
successor(#20126,#20140)
443442
successor(#20134,#20126)
444443
successor(#20130,#20133)
445444
successor(#20133,#20132)
446445
successor(#20132,#20134)
446+
successor(#20124,#20128)
447447
successor(#20138,#20124)
448448
successor(#20094,#20096)
449449
successor(#20098,#20092)
450450
successor(#20097,#20098)
451451
successor(#20096,#20097)
452452
successor(#20092,#20101)
453453
successor(#20092,#20118)
454-
successor(#20105,#20109)
455454
successor(#20109,#20113)
456455
successor(#20117,#20114)
457456
successor(#20116,#20117)
458457
successor(#20114,#20111)
459458
successor(#20113,#20116)
460459
successor(#20111,#20092)
460+
successor(#20105,#20109)
461461
successor(#20101,#20104)
462462
successor(#20104,#20103)
463463
successor(#20103,#20105)

0 commit comments

Comments
 (0)