detectSourceType()

in src/scanners/javascript.js [263:311]


  detectSourceType() {
    /*
     * Analyze the source-code by naively parsing the source code manually and
     * checking for module syntax errors and/or some features in the source code
     * in order to determine the source type of the file.
  
     * This function returns an object with the source type (`script` or
     * `module`) and a non-null parsing error object when parsing has failed with
     * the default source type. The parsing error object contains the `error`
     * message and the source `type`.
    */
    // Default options taken from eslint/lib/linter:parse
    const parserOptions = {
      filePath: this.filename,
      sourceType: 'module',
      ecmaVersion: ECMA_VERSION,
    };

    const detected = {
      sourceType: 'module',
      parsingError: null,
    };

    try {
      const ast = espree.parse(this.code, parserOptions);
      detected.sourceType =
        this.filename.endsWith('.mjs') || this.code.includes('import.meta')
          ? 'module'
          : this._getSourceType(ast, true);
    } catch (exc) {
      const line = exc.lineNumber || '(unknown)';
      const column = exc.column || '(unknown)';
      let error = `${exc.message} at line: ${line} and column: ${column}`;

      // When there is no line/column, it likely means something went wrong in
      // our code (`_getSourceType()`) and we should know about it so we append
      // a comment to hopefully get new bug reports.
      if (!exc.lineNumber || !exc.column) {
        error = oneLine`${error}. This looks like a bug in addons-linter,
          please open a new issue:
          https://github.com/mozilla/addons-linter/issues`;
      }

      detected.sourceType = 'script';
      detected.parsingError = { type: parserOptions.sourceType, error };
    }

    return detected;
  }