in lib/semantic.js [1099:1185]
hasReturnStmt(ast) {
assert.equal(ast.type, 'stmts');
if (ast.stmts.length === 0) {
return false;
}
const stmt = ast.stmts[ast.stmts.length - 1];
if (stmt.type === 'return') {
return true;
}
if (stmt.type === 'throw') {
return true;
}
if (stmt.type === 'yield') {
return true;
}
if (stmt.type === 'if') {
if (!this.hasReturnStmt(stmt.stmts)) {
return false;
}
for (let index = 0; index < stmt.elseIfs.length; index++) {
const branch = stmt.elseIfs[index];
if (!this.hasReturnStmt(branch.stmts)) {
return false;
}
}
if (!stmt.elseStmts) {
return false;
}
if (!this.hasReturnStmt(stmt.elseStmts)) {
return false;
}
return true;
}
if (stmt.type === 'try') {
let tryReturn = true;
let catchReturn = true;
let finallyReturn = true;
if (!this.hasReturnStmt(stmt.tryBlock)) {
tryReturn = false;
}
if (stmt.catchBlock && !this.hasReturnStmt(stmt.catchBlock)) {
catchReturn = false;
}
if (!stmt.finallyBlock || !this.hasReturnStmt(stmt.finallyBlock)) {
finallyReturn = false;
}
if (finallyReturn) {
return true;
}
if (!tryReturn) {
return false;
}
if (!catchReturn) {
return false;
}
return true;
}
// TODO: while, for
if (stmt.type === 'while') {
return true;
}
if (stmt.type === 'for') {
return true;
}
return false;
}