The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
"use strict";

exports.register = function (linter) {
  // Check for properties named __proto__. This special property was
  // deprecated and then re-introduced for ES6.

  linter.on("Identifier", function style_scanProto(data) {
    if (linter.getOption("proto")) {
      return;
    }

    if (data.name === "__proto__") {
      linter.warn("W103", {
        line: data.line,
        char: data.char,
        data: [ data.name ]
      });
    }
  });

  // Check for properties named __iterator__. This is a special property
  // available only in browsers with JavaScript 1.7 implementation.

  linter.on("Identifier", function style_scanIterator(data) {
    if (linter.getOption("iterator")) {
      return;
    }

    if (data.name === "__iterator__") {
      linter.warn("W104", {
        line: data.line,
        char: data.char,
        data: [ data.name ]
      });
    }
  });

  // Check that all identifiers are using camelCase notation.
  // Exceptions: names like MY_VAR and _myVar.

  linter.on("Identifier", function style_scanCamelCase(data) {
    if (!linter.getOption("camelcase")) {
      return;
    }

    if (data.name.replace(/^_+|_+$/g, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
      linter.warn("W106", {
        line: data.line,
        char: data.from,
        data: [ data.name ]
      });
    }
  });

  // Enforce consistency in style of quoting.

  linter.on("String", function style_scanQuotes(data) {
    var quotmark = linter.getOption("quotmark");
    var esnext = linter.getOption("esnext");
    var code;

    if (!quotmark) {
      return;
    }

    // If quotmark is enabled, return if this is a template literal.
    if (esnext && data.quote === "`") {
      return;
    }

    // If quotmark is set to 'single' warn about all double-quotes.

    if (quotmark === "single" && data.quote !== "'") {
      code = "W109";
    }

    // If quotmark is set to 'double' warn about all single-quotes.

    if (quotmark === "double" && data.quote !== "\"") {
      code = "W108";
    }

    // If quotmark is set to true, remember the first quotation style
    // and then warn about all others.

    if (quotmark === true) {
      if (!linter.getCache("quotmark")) {
        linter.setCache("quotmark", data.quote);
      }

      if (linter.getCache("quotmark") !== data.quote) {
        code = "W110";
      }
    }

    if (code) {
      linter.warn(code, {
        line: data.line,
        char: data.char,
      });
    }
  });

  linter.on("Number", function style_scanNumbers(data) {
    if (data.value.charAt(0) === ".") {
      // Warn about a leading decimal point.
      linter.warn("W008", {
        line: data.line,
        char: data.char,
        data: [ data.value ]
      });
    }

    if (data.value.substr(data.value.length - 1) === ".") {
      // Warn about a trailing decimal point.
      linter.warn("W047", {
        line: data.line,
        char: data.char,
        data: [ data.value ]
      });
    }

    if (/^00+/.test(data.value)) {
      // Multiple leading zeroes.
      linter.warn("W046", {
        line: data.line,
        char: data.char,
        data: [ data.value ]
      });
    }
  });

  // Warn about script URLs.

  linter.on("String", function style_scanJavaScriptURLs(data) {
    var re = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;

    if (linter.getOption("scripturl")) {
      return;
    }

    if (re.test(data.value)) {
      linter.warn("W107", {
        line: data.line,
        char: data.char
      });
    }
  });
};