Skip to content
This repository has been archived by the owner on Dec 1, 2024. It is now read-only.

Add an optional lintMarkerAllowList #517

Closed
wants to merge 8 commits into from

Conversation

lexidor
Copy link
Contributor

@lexidor lexidor commented Sep 17, 2022

fixes #458

@@ -18,8 +18,13 @@ final class HHClientLinter implements Linter {
use LinterTrait;
use SuppressibleTrait;

const type TConfig =
shape(?'ignore_except' => vec<int>, ?'ignore' => vec<int>, ...);
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 have added ignoreExcept as an alternative spelling of ignore_except.
I wanted to match the case of lintMarkerAllowList in global scope.

The following looks wrong:

{
  "ignore_except": [],
  "lintMarkerAllowList": []
}

Copy link
Contributor

Choose a reason for hiding this comment

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

The internal coding convention in Meta Platforms prefers lowercase_with_underscores for shape keys, although existing HHAST code base includes both lowerCamelCases and lowercase_with_underscores for shape keys.

$target = shape('name' => $name, 'use_clause' => $clause);

const type TConfig = shape(?'exceptionSuffixes' => vec<string>);

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 usually prefer snake_case as well, but I am trying to stay consistent with the hhast-lint.json format, which is 95% camelCase and 5% English with spaces.

camelCase

builtinLinters, extraLinters, disabledLinters, disabledAutoFixes, disableAllAutoFixes, disableAllLinters, linterConfigs, namespaceAliases, exceptionSuffixes.

English with spaces

line ending

The latter is a mistake on my part, but this can be fixed, since the linter doesn't observe the value for "line ending" (yet). So I can safely migrate this over to lineEnding without breaking BC.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough. Let's document hhast-lint.json and TConfig about the state of lowerCamelCases usage.

@Atry
Copy link
Contributor

Atry commented Sep 19, 2022

Close and reopen to trigger CI

@Atry Atry closed this Sep 19, 2022
@Atry Atry reopened this Sep 19, 2022
@lexidor
Copy link
Contributor Author

lexidor commented Sep 19, 2022

Asking for feedback for HHClientLinter.
This linter is special, because it is an amalgamation of hundreds of rules.
The option "allow comments for HHClientLinter" could not be a simple binary toggle.
I have added the lintMarkerAllowList option to HHClientLinter to allow for granular tuning.

I completely ignore the global lintMarkerAllowList in HHClientLinter. So when "lintMarkerAllowList": ["UnusedUseClause"] is configured HHClientLinter will still honor its own suppression comments.

I did this, because of the following confusing example.

{
  "roots": ["src/"],
  "lintMarkerAllowList": [],
  "linterConfigs": {
    "HHClientLinter": {
      "lintMarkerAllowList": [5555]
    }
  }
}

This is conflicting, because the global list says, no markers allowed, but HHClientLinter allows marker 5555. I would expect HHClientLinter to respect its own config here. But this means, if you want to disallow all markers, you need to set two empty lists. One for HHClientLinter and one at the global level.

I also considered to error out when HHClientLinter receives a lintMarkerAllowList in its own config when shouldAllowSuppressionComments() is false. But this requires you to repeat yourself. First add HHClientLinter linter to the global list and then fine-tune the HHClientLinter config.

Which of these two would be right for the hhast project? Which would be the least surprising?

@Atry
Copy link
Contributor

Atry commented Sep 19, 2022

Do we really need the lintMarkerAllowList setting for HHClientLinter if there is such the lintMarkerAllowList global setting?

@lexidor
Copy link
Contributor Author

lexidor commented Sep 19, 2022

Do we really need the lintMarkerAllowList setting for HHClientLinter if there is such the lintMarkerAllowList global setting?

The global list contains only classnames. HHClientLinter has many sublinters:

  • SketchyNullCheckLinter
  • BooleanExpressionAlwaysFalseLinter
  • DontUseTheCloneOperatorLinter
  • DontUseSafeMemberAccessOnNonnullLinter
  • DontImplicitlyConvertStringToBoolLinter

These are not classnames. The sublinters of HHClientLinter are unnamed. They can't be included in the global list.

@Atry
Copy link
Contributor

Atry commented Sep 19, 2022

There is no "sublinter" concept in HHAST. A marker is for a lint error code, whose name could be either a class name without the -Linter suffix or an integer code. Given the setting name lintMarkerAllowList, I would expect it contains both class names without the -Linter suffix and integer codes.

@Atry
Copy link
Contributor

Atry commented Sep 19, 2022

Given that the proposed setting is for markers, not linters, it would be straightforward to evaluate the allow list when parsing markers globally, instead of implementing the feature in each linter.

@lexidor
Copy link
Contributor Author

lexidor commented Sep 19, 2022

There is no "sublinter" concept in HHAST. A marker is for a lint error code, whose name could be either a class name or an integer code. Given the setting name lintMarkerAllowList, I would expect it contains both class names and integer codes.

That would be worth it. I'll type it as keyset<arraykey>.

@Atry
Copy link
Contributor

Atry commented Sep 19, 2022

arraykey might be better. I typed it as string because it was string long before we introduced HHClientLinter and changing the type would break existing code.

@lexidor
Copy link
Contributor Author

lexidor commented Sep 19, 2022

Given that the proposed setting is for markers, not linters, it would be straightforward to evaluate the allow list when parsing markers globally, instead of implementing the feature in each linter.

* Parsing line based markers at https://github.com/hhvm/hhast/blob/5bc52f7af5df17b65a513227483e56d75fa7cafc/src/File.hack#L42

* Parsing AST based markers at https://github.com/hhvm/hhast/blob/5bc52f7af5df17b65a513227483e56d75fa7cafc/src/Linters/suppress_ast_linter_error.hack#L19

I am assuming you are proposing to add a new function besides is_linter_error_suppressed that returns a tri-state.

enum SuppressionState : int {
  NOT_SUPPRESSED = 0;
  SUPPRESSED = 1;
  DISALLOWED_SUPPRESSION = 2;
}

I could then reimplement the is_linter_error_suppressed as get_suppression_state($linter, $node, $root, /*is suppression allowed*/ true) === SuppressionState::SUPPRESSED.

I am not so sure about how I would change the signature of erroCodesToSuppress. Any suggestions?

@Atry
Copy link
Contributor

Atry commented Sep 19, 2022

I would create a new linter to raise lint errors for markers not in the allow list, and let all other linters simply ignore markers not in the allow list.

@lexidor
Copy link
Contributor Author

lexidor commented Sep 19, 2022

I would create a new linter to raise lint errors for markers not in the allow list, and let all other linters simply ignore markers not in the allow list.

That is a very interesting approach I had not considered before. That is a great idea! Thanks for your input. I will rework my PR.

If that new linter would be impossible to suppress, we'd already be done. That could be done by automatically adding DontUseSuppressionMarkersThatAreNotDeclaredInLintMarkerAllowListLinter to the lintMarkerAllowList, because that would cause and infinite suppression regression.

Then we barely have to change anything about suppression comment logic. We just need to defang HHAST_IGNORE_ALL for DontUseSuppressionMarkersThatAreNotDeclaredInLintMarkerAllowList.

// We just need to defang this IGNORE_ALL, since this would suppress itself.
/*HHAST_IGNORE_ALL[DontUseSuppressionMarkersThatAreNotDeclaredInLintMarkerAllowList]*/

// After that...
/*HHAST_FIXME[DontUseSuppressionMarkersThatAreNotDeclaredInLintMarkerAllowList]
  Oh wait, I can't, since it is turtles all the way down. */
/*HHAST_FIXME[DontUseSuppressionMarkersThatAreNotDeclaredInLintMarkerAllowList]
  Suppressing the don't use markers linter*/
/*HHAST_FIXME[DontUseSuppressionMarkersThatAreNotDeclaredInLintMarkerAllowList]
  Suppressing the don't suppress MustUseBracesForControlFlow linter */
/*HHAST_FIXME[MustUseBracesForControlFlow]*/
if ($xyzzy) return;

@lexidor
Copy link
Contributor Author

lexidor commented Sep 19, 2022

Converting to draft, will redo using a new linter. DontUseSuppressionMarkersThatAreNotDeclaredInLintMarkerAllowListLinter is a placeholder name btw.

@lexidor lexidor marked this pull request as draft September 19, 2022 19:07
lexidor added a commit to lexidor/hhast that referenced this pull request Sep 19, 2022
lexidor added a commit to lexidor/hhast that referenced this pull request Sep 19, 2022
Atry pushed a commit that referenced this pull request Nov 1, 2022
* Document the hhast-lint.json file in detail

linters-usage.md does not document these options and suggests reading the sources instead.
Although the type is somewhat well commented,
I felt like a bit of conventional documentation would go a long way.

* Update linters-usage to refer to configuring-hhast-lint

* Make hhast a dev dependency by default

* Oops, you dropped something...

* Typo fixes

* Fix href of link and more bad spelling

* Remove lintMarkerAllowList documentation

This feature will be implemented as a linter instead.

* Document case sensitivity

Refers to: #517 (comment)

* Document the lowerCamelCase in a comment

See: #517 (comment)

* Remove section that referred to lintMarkerAllowList
@lexidor
Copy link
Contributor Author

lexidor commented May 24, 2023

Parking this PR, the idea will be implemented as a new linter instead.

@lexidor lexidor closed this May 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ RFC ] Adding an optional allow list to hhast-lint.json
3 participants