Skip to content

Commit be08257

Browse files
committed
JS: Hoist function decls in a block to the top of the block
1 parent 2987929 commit be08257

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,9 +1255,12 @@ public Void visit(Literal nd, SuccessorInfo i) {
12551255

12561256
@Override
12571257
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());
1258+
// Hoist function declarations in a block statement to the top of the block.
1259+
// This reflects non-standard behaviour implemented by most engines.
1260+
// See also: EcmaScript "B.3.2 Block-Level Function Declarations Web Legacy Compatibility Semantics".
1261+
List<Identifier> hoisted = HoistedFunDecls.of(nd.getBody());
1262+
hoistedFns.addAll(hoisted);
1263+
writeSuccessors(nd, visitSequence(hoisted, nd.getBody(), i.getAllSuccessors()));
12611264
return null;
12621265
}
12631266

javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/Test.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ spuriousCallee
22
missingCallee
33
| constructor-field.ts:40:5:40:14 | f3.build() | constructor-field.ts:13:3:13:12 | build() {} | -1 | calls |
44
| constructor-field.ts:71:1:71:11 | bf3.build() | constructor-field.ts:13:3:13:12 | build() {} | -1 | calls |
5-
| hoisted.js:20:9:20:11 | f() | hoisted.js:23:9:23:23 | function f() {} | -1 | calls |
65
badAnnotation
76
accessorCall
87
| accessors.js:12:1:12:5 | obj.f | accessors.js:5:8:5:12 | () {} |

0 commit comments

Comments
 (0)