Skip to content
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

SpanMarkPointMissingMaskDetector - Ensure that span flags are checked correctly #14

Merged
merged 20 commits into from Jan 19, 2022

Conversation

slack-jallen
Copy link
Contributor

@slack-jallen slack-jallen commented Dec 15, 2021

Summary

Ensure that span flags are checked correctly.

Incorrect
spanned.getSpanFlags(span) == Spanned.INCLUSIVE_INCLUSIVE

Correct
spanned.getSpanFlags(span) and Spanned.SPAN_POINT_MARK_MASK == Spanned.INCLUSIVE_INCLUSIVE

Why
Spans flags may have priority bits or other bits set.

image

Requirements (place an x in each [ ])

The following point can be removed after setting up CI (such as Travis) with coverage reports (such as Codecov)

  • I've written tests to cover the new code and functionality included in this PR.

The following point can be removed after setting up a CLA reporting tool such as cla-assistant.io

@slack-jallen slack-jallen marked this pull request as ready for review December 15, 2021 17:14
@slack-jallen slack-jallen changed the title Hunvil and josh/span point mark SpanPointMarkDangerousCheckDetector - Ensure that span flags are checked correctly Jan 3, 2022
ZacSweers
ZacSweers previously approved these changes Jan 5, 2022
Copy link
Collaborator

@ZacSweers ZacSweers left a comment

Choose a reason for hiding this comment

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

Nice work! Mostly little nits and suggestions

@ZacSweers ZacSweers self-requested a review January 5, 2022 17:35
Copy link
Collaborator

@ZacSweers ZacSweers left a comment

Choose a reason for hiding this comment

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

Whoops sorry didn't mean to approve just yet

@ZacSweers ZacSweers dismissed their stale review January 5, 2022 17:35

Whoops sorry didn't mean to approve just yet

slack-jallen and others added 6 commits January 6, 2022 11:25
…sCheckDetector.kt

Co-authored-by: Zac Sweers <pandanomic@gmail.com>
- make this name match the others
- move class out to be top-level in the file
- check UastBinaryOperator.EQUALS
- functions can all be private
- raw string
- use the in operator
- make this an extension function
- rename to resolveQualifiedNameOrNull()
- use a reference expression here
- exercises different levels of imports (constant directly, class + reference, fully qualified reference).
- visitBinaryExpression - prefix on all of these are redundant
- remove @language("kotlin")
- indent inconsistency
- keep these names simple
…llen/slack-lints into hunvil-and-josh/span-point-mark
No need to call .trimIndent() in issue registration strings; they are already trimmed by indent by lint when displaying to users [LintImplTrimIndent]
@ZacSweers
Copy link
Collaborator

ZacSweers commented Jan 18, 2022

Let's make these commits finer grained in the future (i.e. only logical groupings, not buckets). Especially with the main merge.

image

Comment on lines 46 to 49
Spans flags can have priority or other bits set. \
Ensure that Span flags are checked using \
`currentFlag and Spanned.SPAN_POINT_MARK_MASK == desiredFlag` \
rather than just `currentFlag == desiredFlag`
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

/**
* Checks for SpanPointMarkDangerousCheck. See [ISSUE].
*/
class SpanPointMarkDangerousCheckDetector : Detector(), SourceCodeScanner {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I've been thinking about this and I think "dangerous" is too strong of a word here. Let's pick something else, like "incorrect" or "missing mask check", something to that effect that's more descriptive

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How do you like SpanMarkPointMissingMaskDetector?

Copy link
Collaborator

Choose a reason for hiding this comment

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

sounds good to me 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in 961528c and 34bb19e

Comment on lines 36 to 38
/**
* Checks for SpanPointMarkDangerousCheck. See [ISSUE].
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit:

Suggested change
/**
* Checks for SpanPointMarkDangerousCheck. See [ISSUE].
*/
/** Checks for SpanPointMarkDangerousCheck. See [ISSUE]. */

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in affa6e8

companion object {
val ISSUE = Issue.create(
id = "SpanPointMarkDangerousCheck",
briefDescription = "Check Span Flags Using Bitmask",
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be a sentence not a title

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in f4b4da4

Comment on lines 110 to 112
private fun matchesMarkPoint(expression: UExpression): Boolean {
return getQualifiedName(expression) in MARK_POINT_FIELDS
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
private fun matchesMarkPoint(expression: UExpression): Boolean {
return getQualifiedName(expression) in MARK_POINT_FIELDS
}
private fun matchesMarkPoint(expression: UExpression) = getQualifiedName(expression) in MARK_POINT_FIELDS

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in 1ff3397

import org.jetbrains.uast.UReferenceExpression
import org.jetbrains.uast.tryResolve

fun UExpression.resolveQualifiedNameOrNull(): String? {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add this to an existing util file rather than its own dedicated one. Also please write a short doc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in 130aa73

}
}

private fun getQualifiedName(expression: UExpression): String? {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be an extension?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you prefer an extension in util file or private extension in this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in 7804c86

return getQualifiedName(expression) in MARK_POINT_FIELDS
}

private fun matchesMask(expression: UExpression): Boolean {
Copy link
Collaborator

Choose a reason for hiding this comment

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

extension? Also seems like this should be "isBinaryExpressionWithMaskOperand" rather than matches? Descriptiveness is better here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ditto, Do you prefer an extension in util file or private extension in this file?

Copy link
Collaborator

Choose a reason for hiding this comment

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

this isn't reusable elsewhere so keep it here. Same with the other ones

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in a4ed477 and bc78adc

}
}

private fun matchesMarkPoint(expression: UExpression): Boolean {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Extension + maybe rename to isMarkPointFieldName?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ditto, Do you prefer an extension in util file or private extension in this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 Fixed in 4a7d8ac and 86bb369

@slack-jallen
Copy link
Contributor Author

Especially with the main merge.

What do you mean by especially with the merge?

@ZacSweers
Copy link
Collaborator

I believe after a merge, github kind of loses track of how to link shas and I get a page like this. Comments here don't appear to show up in the regular review. So, the better isolated they are the better because it's easier to review quickly. Large "address CR" commits are noisy and essentially require a re-review rather than just confirmation.

image

@slack-jallen
Copy link
Contributor Author

@ZacSweers Thanks for your feedback! I learned a couple things. Note that I usually take a more reserved approach to extension functions, as they make polymorphism down the road more difficult.

@ZacSweers
Copy link
Collaborator

Note that I usually take a more reserved approach to extension functions, as they make polymorphism down the road more difficult.

Not sure I follow. In bytecode, these are the same and they're just purely functional

fun computeStuff(param: String): String = ...


fun String.computeStuff(): String = ...

@ZacSweers ZacSweers changed the title SpanPointMarkDangerousCheckDetector - Ensure that span flags are checked correctly SpanMarkPointMissingMaskDetector - Ensure that span flags are checked correctly Jan 19, 2022
@ZacSweers ZacSweers merged commit 8500848 into slackhq:main Jan 19, 2022
@ZacSweers
Copy link
Collaborator

Nice work!

@slack-jallen
Copy link
Contributor Author

Note that I usually take a more reserved approach to extension functions, as they make polymorphism down the road more difficult.

Not sure I follow. In bytecode, these are the same and they're just purely functional

fun computeStuff(param: String): String = ...


fun String.computeStuff(): String = ...

What I mean is:

open class SomeAwesomeClass {
   fun doStuff()...
   open fun doOtherStuff()...
}

class MyClassThatDoesWhatIWant {
   override fun doOtherStuff()....
}

// ... dependency inject MyClassThatDoesWhatIWant instead of SomeAwesomeClass

vs.

class SomeAwesomeClass {
}

fun SomeAwesomeClass.doStuff()...
fun SomeAwesomeClass.doOtherStuff()...

... Oh no, SomeAwesomeClass doesn't do what I want, but I can't use polymorphism to change it

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.

None yet

2 participants