function visitTopLevelStatement()

in src/googmodule.ts [880:1026]


      function visitTopLevelStatement(
          statements: ts.Statement[], sf: ts.SourceFile,
          node: ts.Statement): void {
        // Handle each particular case by adding node to statements, then
        // return. For unhandled cases, break to jump to the default handling
        // below.

        // In JS transpilation mode, always rewrite `require('tslib')` to
        // goog.require('tslib'), ignoring normal module resolution.
        if (host.isJsTranspilation) {
          const rewrittenTsLib = maybeRewriteRequireTslib(node);
          if (rewrittenTsLib) {
            statements.push(rewrittenTsLib);
            return;
          }
        }

        switch (node.kind) {
          case ts.SyntaxKind.ExpressionStatement: {
            const exprStmt = node as ts.ExpressionStatement;
            // Check for "use strict" and certain Object.defineProperty and skip
            // it if necessary.
            if (isUseStrict(exprStmt) || isEsModuleProperty(exprStmt)) {
              stmts.push(createNotEmittedStatementWithComments(sf, exprStmt));
              return;
            }

            // If we have not already seen the defaulted export assignment
            // initializing all exports to `void 0`, skip the statement and mark
            // that we have have now seen it.
            if (checkExportsVoid0Assignment(exprStmt.expression)) {
              stmts.push(createNotEmittedStatementWithComments(sf, exprStmt));
              return;
            }

            // Check for:
            //   module.exports = ...;
            const modExports = rewriteModuleExportsAssignment(exprStmt);
            if (modExports) {
              stmts.push(modExports);
              return;
            }
            // Check for use of the comma operator.
            // This occurs in code like
            //   exports.a = ..., exports.b = ...;
            // which we want to change into multiple statements.
            const commaExpanded = rewriteCommaExpressions(exprStmt.expression);
            if (commaExpanded) {
              stmts.push(...commaExpanded);
              return;
            }
            // Check for:
            //   exports.ns = require('...');
            // which is generated by the `export * as ns from` syntax.
            const exportStarAsNs = maybeRewriteExportStarAsNs(exprStmt);
            if (exportStarAsNs) {
              stmts.push(...exportStarAsNs);
              return;
            }

            // Checks for:
            //   Object.defineProperty(exports, 'a', {
            //     enumerable: true, get: { return ...; }
            //   })
            // which is a live binding generated when re-exporting from another
            // module.
            const exportFromObjDefProp =
                rewriteObjectDefinePropertyOnExports(exprStmt);
            if (exportFromObjDefProp) {
              stmts.push(exportFromObjDefProp);
              return;
            }

            // The rest of this block handles only some function call forms:
            //   goog.declareModuleId(...);
            //   require('foo');
            //   __exportStar(require('foo'), ...);
            const expr = exprStmt.expression;
            if (!ts.isCallExpression(expr)) break;
            let callExpr = expr;

            // Check for declareModuleId.
            const declaredModuleId =
                maybeRewriteDeclareModuleId(exprStmt, callExpr);
            if (declaredModuleId) {
              statements.push(declaredModuleId);
              return;
            }

            // Check for __exportStar, the commonjs version of 'export *'.
            // export * creates either a pure top-level '__export(require(...))'
            // or the imported version, 'tslib.__exportStar(require(...))'. The
            // imported version is only substituted later on though, so appears
            // as a plain "__exportStar" on the top level here.
            const isExportStar = ts.isIdentifier(expr.expression) &&
                (expr.expression.text === '__exportStar' ||
                 expr.expression.text === '__export');
            let newIdent: ts.Identifier|undefined;
            if (isExportStar) {
              // Extract the goog.require() from the call. (It will be verified
              // as a goog.require() below.)
              callExpr = expr.arguments[0] as ts.CallExpression;
              newIdent = ts.createIdentifier(nextModuleVar());
            }

            // Check whether the call is actually a require() and translate
            // as appropriate.
            const require =
                maybeCreateGoogRequire(exprStmt, callExpr, newIdent);
            if (!require) break;
            statements.push(require);

            // If this was an export star, split it up into the import (created
            // by the maybe call above), and the export operation. This avoids a
            // Closure complaint about non-top-level requires.
            if (isExportStar) {
              const args: ts.Expression[] = [newIdent!];
              if (expr.arguments.length > 1) args.push(expr.arguments[1]);
              statements.push(ts.createExpressionStatement(
                  ts.createCall(expr.expression, undefined, args)));
            }
            return;
          }
          case ts.SyntaxKind.VariableStatement: {
            // It's possibly of the form "var x = require(...);".
            const varStmt = node as ts.VariableStatement;
            // Verify it's a single decl (and not "var x = ..., y = ...;").
            if (varStmt.declarationList.declarations.length !== 1) break;
            const decl = varStmt.declarationList.declarations[0];

            // Grab the variable name (avoiding things like destructuring
            // binds).
            if (decl.name.kind !== ts.SyntaxKind.Identifier) break;
            if (!decl.initializer || !ts.isCallExpression(decl.initializer)) {
              break;
            }
            const require =
                maybeCreateGoogRequire(varStmt, decl.initializer, decl.name);
            if (!require) break;
            statements.push(require);
            return;
          }
          default:
            break;
        }
        statements.push(node);
      }