private boolean removeIIFEWrapper ( Node root ) { checkState ( root . isScript ( ) ) ; Node n = root . getFirstChild ( ) ; // Sometimes scripts start with a semicolon for easy concatenation. // Skip any empty statements from those while ( n != null && n . isEmpty ( ) ) { n = n . getNext ( ) ; } // An IIFE wrapper must be the only non-empty statement in the script, // and it must be an expression statement. if ( n == null || ! n . isExprResult ( ) || n . getNext ( ) != null ) { return false ; } // Function expression can be forced with !, just skip ! // TODO(ChadKillingsworth): // Expression could also be forced with: + - ~ void // ! ~ void can be repeated any number of times if ( n != null && n . getFirstChild ( ) != null && n . getFirstChild ( ) . isNot ( ) ) { n = n . getFirstChild ( ) ; } Node call = n . getFirstChild ( ) ; if ( call == null || ! call . isCall ( ) ) { return false ; } // Find the IIFE call and function nodes Node fnc ; if ( call . getFirstChild ( ) . isFunction ( ) ) { fnc = n . getFirstFirstChild ( ) ; } else if ( call . getFirstChild ( ) . isGetProp ( ) && call . getFirstFirstChild ( ) . isFunction ( ) && call . getFirstFirstChild ( ) . getNext ( ) . isString ( ) && call . getFirstFirstChild ( ) . getNext ( ) . getString ( ) . equals ( "call" ) ) { fnc = call . getFirstFirstChild ( ) ; // We only support explicitly binding "this" to the parent "this" or "exports" if ( ! ( call . getSecondChild ( ) != null && ( call . getSecondChild ( ) . isThis ( ) || call . getSecondChild ( ) . matchesQualifiedName ( EXPORTS ) ) ) ) { return false ; } } else { return false ; } if ( NodeUtil . doesFunctionReferenceOwnArgumentsObject ( fnc ) ) { return false ; } CompilerInput ci = compiler . getInput ( root . getInputId ( ) ) ; ModulePath modulePath = ci . getPath ( ) ; if ( modulePath == null ) { return false ; } String iifeLabel = getModuleName ( modulePath ) + "_iifeWrapper" ; FunctionToBlockMutator mutator = new FunctionToBlockMutator ( compiler , compiler . getUniqueNameIdSupplier ( ) ) ; Node block = mutator . mutateWithoutRenaming ( iifeLabel , fnc , call , null , false , false ) ; root . removeChildren ( ) ; root . addChildrenToFront ( block . removeChildren ( ) ) ; reportNestedScopesDeleted ( fnc ) ; compiler . reportChangeToEnclosingScope ( root ) ; return true ; }
UMD modules are often wrapped in an IIFE for cases where they are used as scripts instead of modules . Remove the wrapper .