Skip to content

Properly use ruleSeverity properties of rule converters during conversion #1468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 3, 2022
Merged

Properly use ruleSeverity properties of rule converters during conversion #1468

merged 4 commits into from
May 3, 2022

Conversation

hyperupcall
Copy link
Contributor

@hyperupcall hyperupcall commented May 1, 2022

PR Checklist

Overview

It seems that if ruleSeverity is specified within a rule of a converter, it is not properly applied when converting to the ESLint rules. The linked page mentions it specifically for semicolon, but it seems to be more general

For example, the following TSLint rules will both have a ruleSeverity of error since true is the first array element

{
    "rules": {
        "semicolon": [true, "always"],
        "no-variable-usage-before-declaration": [true]
    }
}

This translates directly to the following ESLint, even though we do { ruleName: "semi", ruleSeverity: "off" }, etc. in the converters

{
    "rules": {
        "no-use-before-define": "error",
        "semi": "error"
    }
}

The patches fix this by setting the converted ruleSeverity with the explicitly specified rule.ruleSeverity if it is truthy

The following show the full resulting ESLint configs before and after the code changes (using the aforementioned TSLint config)

Before:

.eslintrc.json
{
    "env": {
        "browser": true,
        "es6": true
    },
    "extends": [
        "prettier"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "project": "tsconfig.json",
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint"
    ],
    "root": true,
    "rules": {
        "@typescript-eslint/member-delimiter-style": [
            "error",
            {
                "multiline": {
                    "delimiter": "semi",
                    "requireLast": true
                },
                "singleline": {
                    "delimiter": "semi",
                    "requireLast": false
                }
            }
        ],
        "@typescript-eslint/no-use-before-define": [
            "error",
            {
                "variables": true
            }
        ],
        "@typescript-eslint/semi": [
            "error",
            "always"
        ],
        "no-use-before-define": "error",
        "semi": "error"
    }
}

After:

.eslintrc.json
{
    "env": {
        "browser": true,
        "es6": true
    },
    "extends": [
        "prettier"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "project": "tsconfig.json",
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint"
    ],
    "root": true,
    "rules": {
        "@typescript-eslint/member-delimiter-style": [
            "error",
            {
                "multiline": {
                    "delimiter": "semi",
                    "requireLast": true
                },
                "singleline": {
                    "delimiter": "semi",
                    "requireLast": false
                }
            }
        ],
        "@typescript-eslint/no-use-before-define": [
            "error",
            {
                "variables": true
            }
        ],
        "@typescript-eslint/semi": [
            "error",
            "always"
        ],
        "no-use-before-define": "off",
        "semi": "off"
    }
}

@hyperupcall hyperupcall changed the title fix: Properly use ruleSeverity properties of rule converters in conversion fix: Properly use ruleSeverity properties of rule converters during conversion May 1, 2022
@hyperupcall hyperupcall changed the title fix: Properly use ruleSeverity properties of rule converters during conversion Properly use ruleSeverity properties of rule converters during conversion May 1, 2022
Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great so far, thanks for starting this!

Just requesting changes on an additional test. Everything else is nitpicking 😄 .

Comment on lines 358 to 360
const conversionResult: {
rules: { ruleName: string; ruleSeverity: ESLintRuleSeverity }[];
} = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the array type there is the ConvertedRuleChanges exported by ruleConverter.ts.

Suggested change
const conversionResult: {
rules: { ruleName: string; ruleSeverity: ESLintRuleSeverity }[];
} = {
const conversionResult: {
rules: ConvertedRuleChanges[];
} = {

Although, I think this would be a bit cleaner:

const rules: ConvertedRuleChanges[] = [
    {
        ruleName: "eslint-rule-a",
        ruleSeverity: "off",
    },
];

const { tslintRule, converters, mergers } = setupConversionEnvironment({
    ruleSeverity: "error",
    conversionResult: { rules },
    ruleToMerge: rules[0].ruleName,
});

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll incorporate those changes - agree that it looks cleaner! :)

const { converted } = convertRules(
{ ruleConverters: converters, ruleMergers: mergers },
{ [tslintRule.ruleName]: tslintRule },
new Map<string, string[]>(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the type arguments can be inferred here.

Suggested change
new Map<string, string[]>(),
new Map(),

Eventually we'll have a no-inferrable-type-arguments rule or some such in typescript-eslint... one day!

@@ -353,6 +353,45 @@ describe("convertRules", () => {
]).toContainEqual(converted);
});

it("merges when a rule's ruleSeverity explicitly differs from its TSLint equivalent", () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test case looks good and we should include it. Great!

But I think we should also test for the case described in the issue: that there are two output rules from the converter, one turned off and one with the original rule severity. Could you please add a test case for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure! I'll incorporate that new test case in my upcoming modifications ^w^

@JoshuaKGoldberg JoshuaKGoldberg added the status: waiting for author The PR author should address requested changes label May 1, 2022
@hyperupcall
Copy link
Contributor Author

hyperupcall commented May 3, 2022

Thank you for your feedback! I'll be pushing the new changes within the next day

EDIT: Done! I also edited the test name to make it sound a bit better

This additionally ensures that the ruleSeverities during the conversion
aren't always treated exactly the same. Moreover, it tests the case that
if ruleSeverity isn't specified, the default (its respective TSLint equivalent)
is used instead.
@JoshuaKGoldberg JoshuaKGoldberg added status: waiting for reviewer Waiting for a maintainer to review and removed status: waiting for author The PR author should address requested changes labels May 3, 2022
Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look great, thanks as always @hyperupcall! ✨

@JoshuaKGoldberg JoshuaKGoldberg removed the status: waiting for reviewer Waiting for a maintainer to review label May 3, 2022
@JoshuaKGoldberg JoshuaKGoldberg merged commit c149210 into typescript-eslint:main May 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Conversion of TSLint semicolon rule seems incorrect?
2 participants