-
-
Notifications
You must be signed in to change notification settings - Fork 450
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
Implement type checking/validation for filters #4364
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
862dde2
to
7d6751b
Compare
6459776
to
975327b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
I went ahead and reimplemented However, I feel like your comment was more suggesting replacing using PossibleType = std::variant<Type, IllTyped>; This of course would be possible, but I thought that having a wrapper class would still be useful to have utility methods like If you'd like it to make use of only a variant instead of a wrapper, I can implement that. |
I'm fine with both using PossibleType = std::variant<TypeClass, IllTyped>;
class TypeClass {
public:
QString string() const;
Type unwrap() const;
bool operator==(Type) const;
bool operator==(TypeClass) const;
bool operator==(IllTyped) const;
private:
Type type_;
};
class IllTyped {
public:
QString description() const;
bool operator==(Type) const;
bool operator==(TypeClass) const;
bool operator==(IllTyped) const;
}; Then in places where we've previously checked Happy to hear your thoughts on that sort of solution - I can't see a downside to it but it might become apparent when it's actually done & used 👯 |
Updated to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
@dnsge if you can take a look at the changes I've made, we can get this merged in
@pajlada Everything looks good 👍 |
Pull request checklist:
CHANGELOG.md
was updated, if applicableDescription
This PR adds type-checking to filters. For example, the filter
channel.name == "forsen" && author.badges contains "moderator"
can be deduced to evaluate to the typeBool
. This allows us to tell the user why their filter is not working. Before, attempting to perform invalid operations likeString - Int
would silently fail while the filter would purport validity.This PR was primarily motivated by witnessing conversations in Discord where users were confused about why apparently-valid filters weren't working. Additionally, this PR separates the parsing and execution of filters so the filtering language can be easily used in other parts of Chatterino (if another use-case comes up, like advanced highlighting conditions).
This PR also adjusts some (useless) semantics (for example,
5 + "2"
no longer== 7
nor== "7"
), so the wiki will require some minor updates.Most of the code change comes from splitting Expressions into multiple files.
synthesizeType()
is the primary addition in that realm.Example of detecting type errors
Consider the filter
message.content contains ("hello" || "goodbye")
. Someone could conceivably believe this filter allows messages that contain either "hello" or "goodbye" (in fact, this example was taken from Discord). Of course, we can't compute the logical or of two strings, so this filter would silently fail.Now, the filters page reports that there was an issue with the filter, and opening the detailed output gives:
Closes #2466 (in my opinion)