docs: function makeAstFromTopLevelDefine(load, options, ast) {
  	var slimAst;
  
  	types.visit(ast, {
  		visitCallExpression: function(path) {
  			if (this.isAmd(path)) {
  				var args = this.getAmdDefineArguments(
  					path.getValueProperty("arguments")
  				);
  
  				if (needsNormalize(args.dependencies, options)) {
  					args.dependencies = normalizeDependencies(
  						load,
  						options,
  						args.dependencies
  					);
  				}
  
  				args.id = load.uniqueId || load.name || args.id;
  				args.name = load.name;
  
  				slimAst = args.isCjsWrapper
  					? slimBuilder.makeAstFromCjsWrapper(args)
  					: slimBuilder.makeAst(args);
  
  				this.abort();
  			}
  
  			this.traverse(path);
  		},
  
  		// checks if `define` is invoked at the top-level.
  		isAmd: function(path) {
  			return (
  				this.isDefineExpression(path.node) &&
  				n.Program.check(path.parent.parent.node) &&
  				n.ExpressionStatement.check(path.parent.node)
  			);
  		},
  
  		// whether a `define(` call is found in the AST
  		isDefineExpression: function(node) {
  			return n.Identifier.check(node.callee) && node.callee.name === "define";
  		},
  
  		isNamed: function(defineArguments) {
  			return n.Literal.check(defineArguments[0]);
  		},
  
  		isAnonymous: function(defineArguments) {
  			return !n.Literal.check(defineArguments[0]);
  		},
  
  		/**
  		 * Whether CJS require/exports are required by `define`
  		 * See https://github.com/amdjs/amdjs-api/blob/master/AMD.md#using-require-and-exports
  		 * @param {Object} dependenciesNode - The AST node of the `define` dependencies array
  		 * @return {boolean} `true` if CJS keywords used, `false` otherwise.
  		 */
  		usesCjsRequireExports: function(dependenciesNode) {
  			var keywords = ["require", "exports", "module"];
  			var intersection = require("lodash/intersection");
  			var deps = slimBuilder.getDependenciesIds(dependenciesNode);
  
  			return !!intersection(deps, keywords).length;
  		},
  
  		/**
  		 * Whether the factory matches the simplified CJS wrapper
  		 * See https://github.com/amdjs/amdjs-api/blob/master/AMD.md#simplified-commonjs-wrapping-
  		 * @param {Object} factoryNode - The ast node of the `define` factory function
  		 * @return {boolean} `true` if matches, `false` otherwise
  		 */
  		isCjsSimplifiedWrapper: function(factoryNode) {
  			var params = slimBuilder.getFactoryParamsNames(factoryNode);
  
  			return (
  				isEqual(params, ["require"]) ||
  				isEqual(params, ["require", "exports"]) ||
  				isEqual(params, ["require", "exports", "module"])
  			);
  		},
  
  		/**
  		 * The AMD define arguments AST nodes as an object
  		 * @typedef {Object} DefineArguments
  		 * @property {?string} id - The module if of the module being defined
  		 * @property {Array.<string>} dependencies - Array of modules ids dependencies
  		 * @property {!Function} factory - Module's factory function
  		 * @property {boolean} isCjsWrapper - Whether factory function is AMD's
  		 *                     simplified CommonJS wrapping.
  		 */
  
  		/**
  		 * Returns an object with the arguments of the define function
  		 * @param {Array} args - The AST node of the `define` call arguments
  		 * @return {DefineArguments} An object with AMD's define function arguments
  		 */
  		getAmdDefineArguments: function(args) {
  			var result = { id: null, factory: null, dependencies: [] };
  
  			switch (args.length) {
  				// define(factory);
  				case 1:
  					result.factory = getFactory(args[0]);
  					break;
  
  				// define(id || dependencies, factory);
  				case 2:
  					if (this.isNamed(args)) {
  						assign(result, {
  							id: args[0],
  							factory: getFactory(args[1])
  						});
  					} else {
  						assign(result, {
  							dependencies: args[0],
  							factory: getFactory(args[1])
  						});
  					}
  					break;
  
  				// define(id, dependencies, factory);
  				case 3:
  					assign(result, {
  						id: args[0],
  						dependencies: args[1],
  						factory: getFactory(args[2])
  					});
  					break;
  
  				default:
  					throw new Error("Invalid `define` function signature");
  			}
  
  			// set the `isCjsWrapper` flag
  			result.isCjsWrapper =
  				n.ArrayExpression.check(result.dependencies) &&
  				result.dependencies.elements.length
  					? this.usesCjsRequireExports(result.dependencies)
  					: this.isCjsSimplifiedWrapper(result.factory);
  
  			return result;
  		}
  	});
  
  	return slimAst;
  }