"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.selectorTypeToMessageString = void 0;
const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
const util = __importStar(require("../util"));
// #region Options Type Config
var PredefinedFormats;
(function (PredefinedFormats) {
    PredefinedFormats[PredefinedFormats["camelCase"] = 1] = "camelCase";
    PredefinedFormats[PredefinedFormats["strictCamelCase"] = 2] = "strictCamelCase";
    PredefinedFormats[PredefinedFormats["PascalCase"] = 4] = "PascalCase";
    PredefinedFormats[PredefinedFormats["StrictPascalCase"] = 8] = "StrictPascalCase";
    PredefinedFormats[PredefinedFormats["snake_case"] = 16] = "snake_case";
    PredefinedFormats[PredefinedFormats["UPPER_CASE"] = 32] = "UPPER_CASE";
})(PredefinedFormats || (PredefinedFormats = {}));
var UnderscoreOptions;
(function (UnderscoreOptions) {
    UnderscoreOptions[UnderscoreOptions["forbid"] = 1] = "forbid";
    UnderscoreOptions[UnderscoreOptions["allow"] = 2] = "allow";
    UnderscoreOptions[UnderscoreOptions["require"] = 4] = "require";
})(UnderscoreOptions || (UnderscoreOptions = {}));
var Selectors;
(function (Selectors) {
    // variableLike
    Selectors[Selectors["variable"] = 1] = "variable";
    Selectors[Selectors["function"] = 2] = "function";
    Selectors[Selectors["parameter"] = 4] = "parameter";
    // memberLike
    Selectors[Selectors["property"] = 8] = "property";
    Selectors[Selectors["parameterProperty"] = 16] = "parameterProperty";
    Selectors[Selectors["method"] = 32] = "method";
    Selectors[Selectors["accessor"] = 64] = "accessor";
    Selectors[Selectors["enumMember"] = 128] = "enumMember";
    // typeLike
    Selectors[Selectors["class"] = 256] = "class";
    Selectors[Selectors["interface"] = 512] = "interface";
    Selectors[Selectors["typeAlias"] = 1024] = "typeAlias";
    Selectors[Selectors["enum"] = 2048] = "enum";
    Selectors[Selectors["typeParameter"] = 4096] = "typeParameter";
})(Selectors || (Selectors = {}));
const SELECTOR_COUNT = util.getEnumNames(Selectors).length;
var MetaSelectors;
(function (MetaSelectors) {
    MetaSelectors[MetaSelectors["default"] = -1] = "default";
    MetaSelectors[MetaSelectors["variableLike"] = 7] = "variableLike";
    MetaSelectors[MetaSelectors["memberLike"] = 248] = "memberLike";
    MetaSelectors[MetaSelectors["typeLike"] = 7936] = "typeLike";
})(MetaSelectors || (MetaSelectors = {}));
var Modifiers;
(function (Modifiers) {
    Modifiers[Modifiers["const"] = 1] = "const";
    Modifiers[Modifiers["readonly"] = 2] = "readonly";
    Modifiers[Modifiers["static"] = 4] = "static";
    Modifiers[Modifiers["public"] = 8] = "public";
    Modifiers[Modifiers["protected"] = 16] = "protected";
    Modifiers[Modifiers["private"] = 32] = "private";
    Modifiers[Modifiers["abstract"] = 64] = "abstract";
})(Modifiers || (Modifiers = {}));
var TypeModifiers;
(function (TypeModifiers) {
    TypeModifiers[TypeModifiers["boolean"] = 1024] = "boolean";
    TypeModifiers[TypeModifiers["string"] = 2048] = "string";
    TypeModifiers[TypeModifiers["number"] = 4096] = "number";
    TypeModifiers[TypeModifiers["function"] = 8192] = "function";
    TypeModifiers[TypeModifiers["array"] = 16384] = "array";
})(TypeModifiers || (TypeModifiers = {}));
// #endregion Options Type Config
// #region Schema Config
const UNDERSCORE_SCHEMA = {
    type: 'string',
    enum: util.getEnumNames(UnderscoreOptions),
};
const PREFIX_SUFFIX_SCHEMA = {
    type: 'array',
    items: {
        type: 'string',
        minLength: 1,
    },
    additionalItems: false,
};
const MATCH_REGEX_SCHEMA = {
    type: 'object',
    properties: {
        match: { type: 'boolean' },
        regex: { type: 'string' },
    },
    required: ['match', 'regex'],
};
const FORMAT_OPTIONS_PROPERTIES = {
    format: {
        oneOf: [
            {
                type: 'array',
                items: {
                    type: 'string',
                    enum: util.getEnumNames(PredefinedFormats),
                },
                additionalItems: false,
            },
            {
                type: 'null',
            },
        ],
    },
    custom: MATCH_REGEX_SCHEMA,
    leadingUnderscore: UNDERSCORE_SCHEMA,
    trailingUnderscore: UNDERSCORE_SCHEMA,
    prefix: PREFIX_SUFFIX_SCHEMA,
    suffix: PREFIX_SUFFIX_SCHEMA,
};
function selectorSchema(selectorString, allowType, modifiers) {
    const selector = {
        filter: {
            oneOf: [
                {
                    type: 'string',
                    minLength: 1,
                },
                MATCH_REGEX_SCHEMA,
            ],
        },
        selector: {
            type: 'string',
            enum: [selectorString],
        },
    };
    if (modifiers && modifiers.length > 0) {
        selector.modifiers = {
            type: 'array',
            items: {
                type: 'string',
                enum: modifiers,
            },
            additionalItems: false,
        };
    }
    if (allowType) {
        selector.types = {
            type: 'array',
            items: {
                type: 'string',
                enum: util.getEnumNames(TypeModifiers),
            },
            additionalItems: false,
        };
    }
    return [
        {
            type: 'object',
            properties: Object.assign(Object.assign({}, FORMAT_OPTIONS_PROPERTIES), selector),
            required: ['selector', 'format'],
            additionalProperties: false,
        },
    ];
}
function selectorsSchema() {
    return {
        type: 'object',
        properties: Object.assign(Object.assign({}, FORMAT_OPTIONS_PROPERTIES), {
            filter: {
                oneOf: [
                    {
                        type: 'string',
                        minLength: 1,
                    },
                    MATCH_REGEX_SCHEMA,
                ],
            },
            selector: {
                type: 'array',
                items: {
                    type: 'string',
                    enum: [
                        ...util.getEnumNames(MetaSelectors),
                        ...util.getEnumNames(Selectors),
                    ],
                },
                additionalItems: false,
            },
            modifiers: {
                type: 'array',
                items: {
                    type: 'string',
                    enum: util.getEnumNames(Modifiers),
                },
                additionalItems: false,
            },
            types: {
                type: 'array',
                items: {
                    type: 'string',
                    enum: util.getEnumNames(TypeModifiers),
                },
                additionalItems: false,
            },
        }),
        required: ['selector', 'format'],
        additionalProperties: false,
    };
}
const SCHEMA = {
    type: 'array',
    items: {
        oneOf: [
            selectorsSchema(),
            ...selectorSchema('default', false, util.getEnumNames(Modifiers)),
            ...selectorSchema('variableLike', false),
            ...selectorSchema('variable', true, ['const']),
            ...selectorSchema('function', false),
            ...selectorSchema('parameter', true),
            ...selectorSchema('memberLike', false, [
                'private',
                'protected',
                'public',
                'static',
                'readonly',
                'abstract',
            ]),
            ...selectorSchema('property', true, [
                'private',
                'protected',
                'public',
                'static',
                'readonly',
                'abstract',
            ]),
            ...selectorSchema('parameterProperty', true, [
                'private',
                'protected',
                'public',
                'readonly',
            ]),
            ...selectorSchema('method', false, [
                'private',
                'protected',
                'public',
                'static',
                'abstract',
            ]),
            ...selectorSchema('accessor', true, [
                'private',
                'protected',
                'public',
                'static',
                'abstract',
            ]),
            ...selectorSchema('enumMember', false),
            ...selectorSchema('typeLike', false, ['abstract']),
            ...selectorSchema('class', false, ['abstract']),
            ...selectorSchema('interface', false),
            ...selectorSchema('typeAlias', false),
            ...selectorSchema('enum', false),
            ...selectorSchema('typeParameter', false),
        ],
    },
    additionalItems: false,
};
// #endregion Schema Config
// This essentially mirrors ESLint's `camelcase` rule
// note that that rule ignores leading and trailing underscores and only checks those in the middle of a variable name
const defaultCamelCaseAllTheThingsConfig = [
    {
        selector: 'default',
        format: ['camelCase'],
        leadingUnderscore: 'allow',
        trailingUnderscore: 'allow',
    },
    {
        selector: 'variable',
        format: ['camelCase', 'UPPER_CASE'],
        leadingUnderscore: 'allow',
        trailingUnderscore: 'allow',
    },
    {
        selector: 'typeLike',
        format: ['PascalCase'],
    },
];
exports.default = util.createRule({
    name: 'naming-convention',
    meta: {
        docs: {
            category: 'Variables',
            description: 'Enforces naming conventions for everything across a codebase',
            recommended: false,
            // technically only requires type checking if the user uses "type" modifiers
            requiresTypeChecking: true,
        },
        type: 'suggestion',
        messages: {
            unexpectedUnderscore: '{{type}} name `{{name}}` must not have a {{position}} underscore.',
            missingUnderscore: '{{type}} name `{{name}}` must have a {{position}} underscore.',
            missingAffix: '{{type}} name `{{name}}` must have one of the following {{position}}es: {{affixes}}',
            satisfyCustom: '{{type}} name `{{name}}` must {{regexMatch}} the RegExp: {{regex}}',
            doesNotMatchFormat: '{{type}} name `{{name}}` must match one of the following formats: {{formats}}',
            doesNotMatchFormatTrimmed: '{{type}} name `{{name}}` trimmed as `{{processedName}}` must match one of the following formats: {{formats}}',
        },
        schema: SCHEMA,
    },
    defaultOptions: defaultCamelCaseAllTheThingsConfig,
    create(contextWithoutDefaults) {
        const context = contextWithoutDefaults.options &&
            contextWithoutDefaults.options.length > 0
            ? contextWithoutDefaults
            : // only apply the defaults when the user provides no config
                Object.setPrototypeOf({
                    options: defaultCamelCaseAllTheThingsConfig,
                }, contextWithoutDefaults);
        const validators = parseOptions(context);
        function handleMember(validator, node, modifiers) {
            if (!validator) {
                return;
            }
            const key = node.key;
            validator(key, modifiers);
        }
        function getMemberModifiers(node) {
            const modifiers = new Set();
            if (node.accessibility) {
                modifiers.add(Modifiers[node.accessibility]);
            }
            else {
                modifiers.add(Modifiers.public);
            }
            if (node.static) {
                modifiers.add(Modifiers.static);
            }
            if ('readonly' in node && node.readonly) {
                modifiers.add(Modifiers.readonly);
            }
            if (node.type === experimental_utils_1.AST_NODE_TYPES.TSAbstractClassProperty ||
                node.type === experimental_utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition) {
                modifiers.add(Modifiers.abstract);
            }
            return modifiers;
        }
        return {
            // #region variable
            VariableDeclarator(node) {
                const validator = validators.variable;
                if (!validator) {
                    return;
                }
                const identifiers = [];
                getIdentifiersFromPattern(node.id, identifiers);
                const modifiers = new Set();
                const parent = node.parent;
                if (parent &&
                    parent.type === experimental_utils_1.AST_NODE_TYPES.VariableDeclaration &&
                    parent.kind === 'const') {
                    modifiers.add(Modifiers.const);
                }
                identifiers.forEach(i => {
                    validator(i, modifiers);
                });
            },
            // #endregion
            // #region function
            'FunctionDeclaration, TSDeclareFunction, FunctionExpression'(node) {
                const validator = validators.function;
                if (!validator || node.id === null) {
                    return;
                }
                validator(node.id);
            },
            // #endregion function
            // #region parameter
            'FunctionDeclaration, TSDeclareFunction, FunctionExpression, ArrowFunctionExpression'(node) {
                const validator = validators.parameter;
                if (!validator) {
                    return;
                }
                node.params.forEach(param => {
                    if (param.type === experimental_utils_1.AST_NODE_TYPES.TSParameterProperty) {
                        return;
                    }
                    const identifiers = [];
                    getIdentifiersFromPattern(param, identifiers);
                    identifiers.forEach(i => {
                        validator(i);
                    });
                });
            },
            // #endregion parameter
            // #region parameterProperty
            TSParameterProperty(node) {
                const validator = validators.parameterProperty;
                if (!validator) {
                    return;
                }
                const modifiers = getMemberModifiers(node);
                const identifiers = [];
                getIdentifiersFromPattern(node.parameter, identifiers);
                identifiers.forEach(i => {
                    validator(i, modifiers);
                });
            },
            // #endregion parameterProperty
            // #region property
            ':not(ObjectPattern) > Property[computed = false][kind = "init"][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'(node) {
                const modifiers = new Set([Modifiers.public]);
                handleMember(validators.property, node, modifiers);
            },
            ':matches(ClassProperty, TSAbstractClassProperty)[computed = false][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'(node) {
                const modifiers = getMemberModifiers(node);
                handleMember(validators.property, node, modifiers);
            },
            'TSPropertySignature[computed = false]'(node) {
                const modifiers = new Set([Modifiers.public]);
                if (node.readonly) {
                    modifiers.add(Modifiers.readonly);
                }
                handleMember(validators.property, node, modifiers);
            },
            // #endregion property
            // #region method
            [[
                'Property[computed = false][kind = "init"][value.type = "ArrowFunctionExpression"]',
                'Property[computed = false][kind = "init"][value.type = "FunctionExpression"]',
                'Property[computed = false][kind = "init"][value.type = "TSEmptyBodyFunctionExpression"]',
                'TSMethodSignature[computed = false]',
            ].join(', ')](node) {
                const modifiers = new Set([Modifiers.public]);
                handleMember(validators.method, node, modifiers);
            },
            [[
                ':matches(ClassProperty, TSAbstractClassProperty)[computed = false][value.type = "ArrowFunctionExpression"]',
                ':matches(ClassProperty, TSAbstractClassProperty)[computed = false][value.type = "FunctionExpression"]',
                ':matches(ClassProperty, TSAbstractClassProperty)[computed = false][value.type = "TSEmptyBodyFunctionExpression"]',
                ':matches(MethodDefinition, TSAbstractMethodDefinition)[computed = false][kind = "method"]',
            ].join(', ')](node) {
                const modifiers = getMemberModifiers(node);
                handleMember(validators.method, node, modifiers);
            },
            // #endregion method
            // #region accessor
            'Property[computed = false]:matches([kind = "get"], [kind = "set"])'(node) {
                const modifiers = new Set([Modifiers.public]);
                handleMember(validators.accessor, node, modifiers);
            },
            'MethodDefinition[computed = false]:matches([kind = "get"], [kind = "set"])'(node) {
                const modifiers = getMemberModifiers(node);
                handleMember(validators.accessor, node, modifiers);
            },
            // #endregion accessor
            // #region enumMember
            // computed is optional, so can't do [computed = false]
            'TSEnumMember[computed != true]'(node) {
                const validator = validators.enumMember;
                if (!validator) {
                    return;
                }
                const id = node.id;
                validator(id);
            },
            // #endregion enumMember
            // #region class
            'ClassDeclaration, ClassExpression'(node) {
                const validator = validators.class;
                if (!validator) {
                    return;
                }
                const id = node.id;
                if (id === null) {
                    return;
                }
                const modifiers = new Set();
                if (node.abstract) {
                    modifiers.add(Modifiers.abstract);
                }
                validator(id, modifiers);
            },
            // #endregion class
            // #region interface
            TSInterfaceDeclaration(node) {
                const validator = validators.interface;
                if (!validator) {
                    return;
                }
                validator(node.id);
            },
            // #endregion interface
            // #region typeAlias
            TSTypeAliasDeclaration(node) {
                const validator = validators.typeAlias;
                if (!validator) {
                    return;
                }
                validator(node.id);
            },
            // #endregion typeAlias
            // #region enum
            TSEnumDeclaration(node) {
                const validator = validators.enum;
                if (!validator) {
                    return;
                }
                validator(node.id);
            },
            // #endregion enum
            // #region typeParameter
            'TSTypeParameterDeclaration > TSTypeParameter'(node) {
                const validator = validators.typeParameter;
                if (!validator) {
                    return;
                }
                validator(node.name);
            },
        };
    },
});
function getIdentifiersFromPattern(pattern, identifiers) {
    switch (pattern.type) {
        case experimental_utils_1.AST_NODE_TYPES.Identifier:
            identifiers.push(pattern);
            break;
        case experimental_utils_1.AST_NODE_TYPES.ArrayPattern:
            pattern.elements.forEach(element => {
                if (element !== null) {
                    getIdentifiersFromPattern(element, identifiers);
                }
            });
            break;
        case experimental_utils_1.AST_NODE_TYPES.ObjectPattern:
            pattern.properties.forEach(property => {
                if (property.type === experimental_utils_1.AST_NODE_TYPES.RestElement) {
                    getIdentifiersFromPattern(property, identifiers);
                }
                else {
                    // this is a bit weird, but it's because ESTree doesn't have a new node type
                    // for object destructuring properties - it just reuses Property...
                    // https://github.com/estree/estree/blob/9ae284b71130d53226e7153b42f01bf819e6e657/es2015.md#L206-L211
                    // However, the parser guarantees this is safe (and there is error handling)
                    getIdentifiersFromPattern(property.value, identifiers);
                }
            });
            break;
        case experimental_utils_1.AST_NODE_TYPES.RestElement:
            getIdentifiersFromPattern(pattern.argument, identifiers);
            break;
        case experimental_utils_1.AST_NODE_TYPES.AssignmentPattern:
            getIdentifiersFromPattern(pattern.left, identifiers);
            break;
        case experimental_utils_1.AST_NODE_TYPES.MemberExpression:
            // ignore member expressions, as the everything must already be defined
            break;
        default:
            // https://github.com/typescript-eslint/typescript-eslint/issues/1282
            // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
            throw new Error(`Unexpected pattern type ${pattern.type}`);
    }
}
function parseOptions(context) {
    const normalizedOptions = context.options
        .map(opt => normalizeOption(opt))
        .reduce((acc, val) => acc.concat(val), []);
    return util.getEnumNames(Selectors).reduce((acc, k) => {
        acc[k] = createValidator(k, context, normalizedOptions);
        return acc;
    }, {});
}
function createValidator(type, context, allConfigs) {
    // make sure the "highest priority" configs are checked first
    const selectorType = Selectors[type];
    const configs = allConfigs
        // gather all of the applicable selectors
        .filter(c => (c.selector & selectorType) !== 0 ||
        c.selector === MetaSelectors.default)
        .sort((a, b) => {
        if (a.selector === b.selector) {
            // in the event of the same selector, order by modifier weight
            // sort descending - the type modifiers are "more important"
            return b.modifierWeight - a.modifierWeight;
        }
        /*
        meta selectors will always be larger numbers than the normal selectors they contain, as they are the sum of all
        of the selectors that they contain.
        to give normal selectors a higher priority, shift them all SELECTOR_COUNT bits to the left before comparison, so
        they are instead always guaranteed to be larger than the meta selectors.
        */
        const aSelector = isMetaSelector(a.selector)
            ? a.selector
            : a.selector << SELECTOR_COUNT;
        const bSelector = isMetaSelector(b.selector)
            ? b.selector
            : b.selector << SELECTOR_COUNT;
        // sort descending - the meta selectors are "least important"
        return bSelector - aSelector;
    });
    return (node, modifiers = new Set()) => {
        var _a, _b, _c;
        const originalName = node.type === experimental_utils_1.AST_NODE_TYPES.Identifier ? node.name : `${node.value}`;
        // return will break the loop and stop checking configs
        // it is only used when the name is known to have failed or succeeded a config.
        for (const config of configs) {
            if (((_a = config.filter) === null || _a === void 0 ? void 0 : _a.regex.test(originalName)) !== ((_b = config.filter) === null || _b === void 0 ? void 0 : _b.match)) {
                // name does not match the filter
                continue;
            }
            if ((_c = config.modifiers) === null || _c === void 0 ? void 0 : _c.some(modifier => !modifiers.has(modifier))) {
                // does not have the required modifiers
                continue;
            }
            if (!isCorrectType(node, config, context)) {
                // is not the correct type
                continue;
            }
            let name = originalName;
            name = validateUnderscore('leading', config, name, node, originalName);
            if (name === null) {
                // fail
                return;
            }
            name = validateUnderscore('trailing', config, name, node, originalName);
            if (name === null) {
                // fail
                return;
            }
            name = validateAffix('prefix', config, name, node, originalName);
            if (name === null) {
                // fail
                return;
            }
            name = validateAffix('suffix', config, name, node, originalName);
            if (name === null) {
                // fail
                return;
            }
            if (!validateCustom(config, name, node, originalName)) {
                // fail
                return;
            }
            if (!validatePredefinedFormat(config, name, node, originalName)) {
                // fail
                return;
            }
            // it's valid for this config, so we don't need to check any more configs
            return;
        }
    };
    // centralizes the logic for formatting the report data
    function formatReportData({ affixes, formats, originalName, processedName, position, custom, }) {
        var _a;
        return {
            type: selectorTypeToMessageString(type),
            name: originalName,
            processedName,
            position,
            affixes: affixes === null || affixes === void 0 ? void 0 : affixes.join(', '),
            formats: formats === null || formats === void 0 ? void 0 : formats.map(f => PredefinedFormats[f]).join(', '),
            regex: (_a = custom === null || custom === void 0 ? void 0 : custom.regex) === null || _a === void 0 ? void 0 : _a.toString(),
            regexMatch: (custom === null || custom === void 0 ? void 0 : custom.match) === true
                ? 'match'
                : (custom === null || custom === void 0 ? void 0 : custom.match) === false
                    ? 'not match'
                    : null,
        };
    }
    /**
     * @returns the name with the underscore removed, if it is valid according to the specified underscore option, null otherwise
     */
    function validateUnderscore(position, config, name, node, originalName) {
        const option = position === 'leading'
            ? config.leadingUnderscore
            : config.trailingUnderscore;
        if (!option) {
            return name;
        }
        const hasUnderscore = position === 'leading' ? name.startsWith('_') : name.endsWith('_');
        const trimUnderscore = position === 'leading'
            ? () => name.slice(1)
            : () => name.slice(0, -1);
        switch (option) {
            case UnderscoreOptions.allow:
                // no check - the user doesn't care if it's there or not
                break;
            case UnderscoreOptions.forbid:
                if (hasUnderscore) {
                    context.report({
                        node,
                        messageId: 'unexpectedUnderscore',
                        data: formatReportData({
                            originalName,
                            position,
                        }),
                    });
                    return null;
                }
                break;
            case UnderscoreOptions.require:
                if (!hasUnderscore) {
                    context.report({
                        node,
                        messageId: 'missingUnderscore',
                        data: formatReportData({
                            originalName,
                            position,
                        }),
                    });
                    return null;
                }
        }
        return hasUnderscore ? trimUnderscore() : name;
    }
    /**
     * @returns the name with the affix removed, if it is valid according to the specified affix option, null otherwise
     */
    function validateAffix(position, config, name, node, originalName) {
        const affixes = config[position];
        if (!affixes || affixes.length === 0) {
            return name;
        }
        for (const affix of affixes) {
            const hasAffix = position === 'prefix' ? name.startsWith(affix) : name.endsWith(affix);
            const trimAffix = position === 'prefix'
                ? () => name.slice(affix.length)
                : () => name.slice(0, -affix.length);
            if (hasAffix) {
                // matches, so trim it and return
                return trimAffix();
            }
        }
        context.report({
            node,
            messageId: 'missingAffix',
            data: formatReportData({
                originalName,
                position,
                affixes,
            }),
        });
        return null;
    }
    /**
     * @returns true if the name is valid according to the `regex` option, false otherwise
     */
    function validateCustom(config, name, node, originalName) {
        const custom = config.custom;
        if (!custom) {
            return true;
        }
        const result = custom.regex.test(name);
        if (custom.match && result) {
            return true;
        }
        if (!custom.match && !result) {
            return true;
        }
        context.report({
            node,
            messageId: 'satisfyCustom',
            data: formatReportData({
                originalName,
                custom,
            }),
        });
        return false;
    }
    /**
     * @returns true if the name is valid according to the `format` option, false otherwise
     */
    function validatePredefinedFormat(config, name, node, originalName) {
        const formats = config.format;
        if (formats === null || formats.length === 0) {
            return true;
        }
        for (const format of formats) {
            const checker = PredefinedFormatToCheckFunction[format];
            if (checker(name)) {
                return true;
            }
        }
        context.report({
            node,
            messageId: originalName === name
                ? 'doesNotMatchFormat'
                : 'doesNotMatchFormatTrimmed',
            data: formatReportData({
                originalName,
                processedName: name,
                formats,
            }),
        });
        return false;
    }
}
// #region Predefined Format Functions
/*
These format functions are taken from `tslint-consistent-codestyle/naming-convention`:
https://github.com/ajafff/tslint-consistent-codestyle/blob/ab156cc8881bcc401236d999f4ce034b59039e81/rules/namingConventionRule.ts#L603-L645

The licence for the code can be viewed here:
https://github.com/ajafff/tslint-consistent-codestyle/blob/ab156cc8881bcc401236d999f4ce034b59039e81/LICENSE
*/
/*
Why not regex here? Because it's actually really, really difficult to create a regex to handle
all of the unicode cases, and we have many non-english users that use non-english characters.
https://gist.github.com/mathiasbynens/6334847
*/
function isPascalCase(name) {
    return (name.length === 0 ||
        (name[0] === name[0].toUpperCase() && !name.includes('_')));
}
function isStrictPascalCase(name) {
    return (name.length === 0 ||
        (name[0] === name[0].toUpperCase() && hasStrictCamelHumps(name, true)));
}
function isCamelCase(name) {
    return (name.length === 0 ||
        (name[0] === name[0].toLowerCase() && !name.includes('_')));
}
function isStrictCamelCase(name) {
    return (name.length === 0 ||
        (name[0] === name[0].toLowerCase() && hasStrictCamelHumps(name, false)));
}
function hasStrictCamelHumps(name, isUpper) {
    function isUppercaseChar(char) {
        return char === char.toUpperCase() && char !== char.toLowerCase();
    }
    if (name.startsWith('_')) {
        return false;
    }
    for (let i = 1; i < name.length; ++i) {
        if (name[i] === '_') {
            return false;
        }
        if (isUpper === isUppercaseChar(name[i])) {
            if (isUpper) {
                return false;
            }
        }
        else {
            isUpper = !isUpper;
        }
    }
    return true;
}
function isSnakeCase(name) {
    return (name.length === 0 ||
        (name === name.toLowerCase() && validateUnderscores(name)));
}
function isUpperCase(name) {
    return (name.length === 0 ||
        (name === name.toUpperCase() && validateUnderscores(name)));
}
/** Check for leading trailing and adjacent underscores */
function validateUnderscores(name) {
    if (name.startsWith('_')) {
        return false;
    }
    let wasUnderscore = false;
    for (let i = 1; i < name.length; ++i) {
        if (name[i] === '_') {
            if (wasUnderscore) {
                return false;
            }
            wasUnderscore = true;
        }
        else {
            wasUnderscore = false;
        }
    }
    return !wasUnderscore;
}
const PredefinedFormatToCheckFunction = {
    [PredefinedFormats.PascalCase]: isPascalCase,
    [PredefinedFormats.StrictPascalCase]: isStrictPascalCase,
    [PredefinedFormats.camelCase]: isCamelCase,
    [PredefinedFormats.strictCamelCase]: isStrictCamelCase,
    [PredefinedFormats.UPPER_CASE]: isUpperCase,
    [PredefinedFormats.snake_case]: isSnakeCase,
};
// #endregion Predefined Format Functions
function selectorTypeToMessageString(selectorType) {
    const notCamelCase = selectorType.replace(/([A-Z])/g, ' $1');
    return notCamelCase.charAt(0).toUpperCase() + notCamelCase.slice(1);
}
exports.selectorTypeToMessageString = selectorTypeToMessageString;
function isMetaSelector(selector) {
    return selector in MetaSelectors;
}
function normalizeOption(option) {
    var _a, _b, _c, _d, _e, _f;
    let weight = 0;
    (_a = option.modifiers) === null || _a === void 0 ? void 0 : _a.forEach(mod => {
        weight |= Modifiers[mod];
    });
    (_b = option.types) === null || _b === void 0 ? void 0 : _b.forEach(mod => {
        weight |= TypeModifiers[mod];
    });
    // give selectors with a filter the _highest_ priority
    if (option.filter) {
        weight |= 1 << 30;
    }
    const normalizedOption = {
        // format options
        format: option.format ? option.format.map(f => PredefinedFormats[f]) : null,
        custom: option.custom
            ? {
                regex: new RegExp(option.custom.regex, 'u'),
                match: option.custom.match,
            }
            : null,
        leadingUnderscore: option.leadingUnderscore !== undefined
            ? UnderscoreOptions[option.leadingUnderscore]
            : null,
        trailingUnderscore: option.trailingUnderscore !== undefined
            ? UnderscoreOptions[option.trailingUnderscore]
            : null,
        prefix: option.prefix && option.prefix.length > 0 ? option.prefix : null,
        suffix: option.suffix && option.suffix.length > 0 ? option.suffix : null,
        modifiers: (_d = (_c = option.modifiers) === null || _c === void 0 ? void 0 : _c.map(m => Modifiers[m])) !== null && _d !== void 0 ? _d : null,
        types: (_f = (_e = option.types) === null || _e === void 0 ? void 0 : _e.map(m => TypeModifiers[m])) !== null && _f !== void 0 ? _f : null,
        filter: option.filter !== undefined
            ? typeof option.filter === 'string'
                ? { regex: new RegExp(option.filter, 'u'), match: true }
                : {
                    regex: new RegExp(option.filter.regex, 'u'),
                    match: option.filter.match,
                }
            : null,
        // calculated ordering weight based on modifiers
        modifierWeight: weight,
    };
    const selectors = Array.isArray(option.selector)
        ? option.selector
        : [option.selector];
    const selectorsAllowedToHaveTypes = [
        Selectors.variable,
        Selectors.parameter,
        Selectors.property,
        Selectors.parameterProperty,
        Selectors.accessor,
    ];
    const config = [];
    selectors
        .map(selector => isMetaSelector(selector) ? MetaSelectors[selector] : Selectors[selector])
        .forEach(selector => selectorsAllowedToHaveTypes.includes(selector)
        ? config.push(Object.assign({ selector: selector }, normalizedOption))
        : config.push(Object.assign(Object.assign({ selector: selector }, normalizedOption), { types: null })));
    return config;
}
function isCorrectType(node, config, context) {
    if (config.types === null) {
        return true;
    }
    const { esTreeNodeToTSNodeMap, program } = util.getParserServices(context);
    const checker = program.getTypeChecker();
    const tsNode = esTreeNodeToTSNodeMap.get(node);
    const type = checker
        .getTypeAtLocation(tsNode)
        // remove null and undefined from the type, as we don't care about it here
        .getNonNullableType();
    for (const allowedType of config.types) {
        switch (allowedType) {
            case TypeModifiers.array:
                if (isAllTypesMatch(type, t => checker.isArrayType(t) || checker.isTupleType(t))) {
                    return true;
                }
                break;
            case TypeModifiers.function:
                if (isAllTypesMatch(type, t => t.getCallSignatures().length > 0)) {
                    return true;
                }
                break;
            case TypeModifiers.boolean:
            case TypeModifiers.number:
            case TypeModifiers.string: {
                const typeString = checker.typeToString(
                // this will resolve things like true => boolean, 'a' => string and 1 => number
                checker.getWidenedType(checker.getBaseTypeOfLiteralType(type)));
                const allowedTypeString = TypeModifiers[allowedType];
                if (typeString === allowedTypeString) {
                    return true;
                }
                break;
            }
        }
    }
    return false;
}
/**
 * @returns `true` if the type (or all union types) in the given type return true for the callback
 */
function isAllTypesMatch(type, cb) {
    if (type.isUnion()) {
        return type.types.every(t => cb(t));
    }
    return cb(type);
}
//# sourceMappingURL=naming-convention.js.map