'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();var _fs = require('fs');var _fs2 = _interopRequireDefault(_fs);

var _doctrine = require('doctrine');var _doctrine2 = _interopRequireDefault(_doctrine);

var _debug = require('debug');var _debug2 = _interopRequireDefault(_debug);

var _parse2 = require('eslint-module-utils/parse');var _parse3 = _interopRequireDefault(_parse2);
var _visit = require('eslint-module-utils/visit');var _visit2 = _interopRequireDefault(_visit);
var _resolve = require('eslint-module-utils/resolve');var _resolve2 = _interopRequireDefault(_resolve);
var _ignore = require('eslint-module-utils/ignore');var _ignore2 = _interopRequireDefault(_ignore);

var _hash = require('eslint-module-utils/hash');
var _unambiguous = require('eslint-module-utils/unambiguous');var unambiguous = _interopRequireWildcard(_unambiguous);

var _ = require('.');var _2 = _interopRequireDefault(_);
var _childContext = require('./childContext');var _childContext2 = _interopRequireDefault(_childContext);
var _typescript = require('./typescript');
var _remotePath = require('./remotePath');
var _visitor = require('./visitor');var _visitor2 = _interopRequireDefault(_visitor);function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];}}newObj['default'] = obj;return newObj;}}function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { 'default': obj };}function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}

var log = (0, _debug2['default'])('eslint-plugin-import:ExportMap');

var exportCache = new Map();

/**
                              * The creation of this closure is isolated from other scopes
                              * to avoid over-retention of unrelated variables, which has
                              * caused memory leaks. See #1266.
                              */
function thunkFor(p, context) {
  // eslint-disable-next-line no-use-before-define
  return function () {return ExportMapBuilder['for']((0, _childContext2['default'])(p, context));};
}var

ExportMapBuilder = function () {function ExportMapBuilder() {_classCallCheck(this, ExportMapBuilder);}_createClass(ExportMapBuilder, null, [{ key: 'get', value: function () {function get(
      source, context) {
        var path = (0, _resolve2['default'])(source, context);
        if (path == null) {return null;}

        return ExportMapBuilder['for']((0, _childContext2['default'])(path, context));
      }return get;}() }, { key: 'for', value: function () {function _for(

      context) {var
        path = context.path;

        var cacheKey = context.cacheKey || (0, _hash.hashObject)(context).digest('hex');
        var exportMap = exportCache.get(cacheKey);

        // return cached ignore
        if (exportMap === null) {return null;}

        var stats = _fs2['default'].statSync(path);
        if (exportMap != null) {
          // date equality check
          if (exportMap.mtime - stats.mtime === 0) {
            return exportMap;
          }
          // future: check content equality?
        }

        // check valid extensions first
        if (!(0, _ignore.hasValidExtension)(path, context)) {
          exportCache.set(cacheKey, null);
          return null;
        }

        // check for and cache ignore
        if ((0, _ignore2['default'])(path, context)) {
          log('ignored path due to ignore settings:', path);
          exportCache.set(cacheKey, null);
          return null;
        }

        var content = _fs2['default'].readFileSync(path, { encoding: 'utf8' });

        // check for and cache unambiguous modules
        if (!unambiguous.test(content)) {
          log('ignored path due to unambiguous regex:', path);
          exportCache.set(cacheKey, null);
          return null;
        }

        log('cache miss', cacheKey, 'for path', path);
        exportMap = ExportMapBuilder.parse(path, content, context);

        // ambiguous modules return null
        if (exportMap == null) {
          log('ignored path due to ambiguous parse:', path);
          exportCache.set(cacheKey, null);
          return null;
        }

        exportMap.mtime = stats.mtime;

        // If the visitor keys were not populated, then we shouldn't save anything to the cache,
        // since the parse results may not be reliable.
        if (exportMap.visitorKeys) {
          exportCache.set(cacheKey, exportMap);
        }
        return exportMap;
      }return _for;}() }, { key: 'parse', value: function () {function parse(

      path, content, context) {
        var exportMap = new _2['default'](path);
        var isEsModuleInteropTrue = (0, _typescript.isEsModuleInterop)(context);

        var ast = void 0;
        var visitorKeys = void 0;
        try {
          var result = (0, _parse3['default'])(path, content, context);
          ast = result.ast;
          visitorKeys = result.visitorKeys;
        } catch (err) {
          exportMap.errors.push(err);
          return exportMap; // can't continue
        }

        exportMap.visitorKeys = visitorKeys;

        var hasDynamicImports = false;

        var remotePathResolver = new _remotePath.RemotePath(path, context);

        function processDynamicImport(source) {
          hasDynamicImports = true;
          if (source.type !== 'Literal') {
            return null;
          }
          var p = remotePathResolver.resolve(source.value);
          if (p == null) {
            return null;
          }
          var importedSpecifiers = new Set();
          importedSpecifiers.add('ImportNamespaceSpecifier');
          var getter = thunkFor(p, context);
          exportMap.imports.set(p, {
            getter: getter,
            declarations: new Set([{
              source: {
                // capturing actual node reference holds full AST in memory!
                value: source.value,
                loc: source.loc },

              importedSpecifiers: importedSpecifiers,
              dynamic: true }]) });


        }

        (0, _visit2['default'])(ast, visitorKeys, {
          ImportExpression: function () {function ImportExpression(node) {
              processDynamicImport(node.source);
            }return ImportExpression;}(),
          CallExpression: function () {function CallExpression(node) {
              if (node.callee.type === 'Import') {
                processDynamicImport(node.arguments[0]);
              }
            }return CallExpression;}() });


        var unambiguouslyESM = unambiguous.isModule(ast);
        if (!unambiguouslyESM && !hasDynamicImports) {return null;}

        // attempt to collect module doc
        if (ast.comments) {
          ast.comments.some(function (c) {
            if (c.type !== 'Block') {return false;}
            try {
              var doc = _doctrine2['default'].parse(c.value, { unwrap: true });
              if (doc.tags.some(function (t) {return t.title === 'module';})) {
                exportMap.doc = doc;
                return true;
              }
            } catch (err) {/* ignore */}
            return false;
          });
        }

        var visitorBuilder = new _visitor2['default'](
        path,
        context,
        exportMap,
        ExportMapBuilder,
        content,
        ast,
        isEsModuleInteropTrue,
        thunkFor);

        ast.body.forEach(function (astNode) {
          var visitor = visitorBuilder.build(astNode);

          if (visitor[astNode.type]) {
            visitor[astNode.type].call(visitorBuilder);
          }
        });

        if (
        isEsModuleInteropTrue // esModuleInterop is on in tsconfig
        && exportMap.namespace.size > 0 // anything is exported
        && !exportMap.namespace.has('default') // and default isn't added already
        ) {
            exportMap.namespace.set('default', {}); // add default export
          }

        if (unambiguouslyESM) {
          exportMap.parseGoal = 'Module';
        }
        return exportMap;
      }return parse;}() }]);return ExportMapBuilder;}();exports['default'] = ExportMapBuilder;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,[encoded data, 15248 characters]