hasReturnStmt()

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;
  }