code: function astFromFile(options, file, cb) {
    function convertSourceFile(file, packageName, packagePath) {
      fs.readFile(file, 'utf-8', function (err, source) {
        if (err) {
          return cb(err);
        }
        var extension = path.extname(file);
        if (extension[0] === '.') {
          extension = extension.substr(1);
        }
        astFromSource(options, source, extension, function (err, ast) {
          if (err) {
            err.file = file;
            return cb(err);
          }
          if (packageName) {
            ast.package = {name: packageName, path: packagePath};
            if (packagePath[0] !== '/') {
              ast.package.path = path.join(process.cwd(), packagePath);
            }
            ast.package.originalPath = packagePath;
          }
          ast.originalPath = file;
          if (file[0] === '/') {
            ast.path = file;
          } else {
            ast.path = path.join(process.cwd(), file);
          }
          return cb(null, ast);
        });
      });
    }
  
    function convertPackage() {
      if (path.basename(file) === 'package.json') {
        fs.readFile(file, 'utf-8', function (err, pkgString) {
          try {
            var pkg = JSON.parse(pkgString);
            if (!pkg.main) {
              return cb(new Error(file + " has no main modules."));
            }
            var main = path.join(path.dirname(file), pkg.main);
            if (!main.match(/\.js$/)) {
              main = main + '.js';
            }
            convertSourceFile(main, pkg.name, file);
          } catch (packageParseError) {
            packageParseError.message = 'Error parsing ' + file + ' - ' + packageParseError.message;
            return cb(packageParseError);
          }
        });
      } else {
        convertSourceFile(file, null);
      }
    }
  
    convertPackage();
  }
docs: /*
  Convert file to AST.
  @param {Object} options Doctor options.
  @param {String} file File name.
  @param {function} cb Function to call with AST.