Skip to content

Commit

Permalink
(WIP) K1only annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
Godin committed Nov 28, 2024
1 parent f9128ed commit be84088
Show file tree
Hide file tree
Showing 88 changed files with 109 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ import org.jetbrains.kotlin.references.fe10.base.DummyKtFe10ReferenceResolutionH
import org.jetbrains.kotlin.references.fe10.base.KtFe10ReferenceResolutionHelper
import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension

/**
* Marker indicating that
* annotated [org.sonarsource.kotlin.api.checks.KotlinCheck]
* can be executed only in K1 mode.
*/
annotation class K1only

internal fun configureK1AnalysisApiServices(env: KotlinCoreEnvironment) {
val application = env.projectEnvironment.environment.application
if (application.getServiceIfCreated(KtFe10ReferenceResolutionHelper::class.java) == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.sonarsource.analyzer.commons.regex.finders.AnchorPrecedenceFinder
import org.sonarsource.kotlin.api.regex.AbstractRegexCheck
import org.sonarsource.kotlin.api.regex.RegexContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5850")
class AnchorPrecedenceCheck : AbstractRegexCheck() {
override fun visitRegex(regex: RegexParseResult, regexContext: RegexContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private val STICKY_BROADCAST_NAMES = setOf(
"sendStickyOrderedBroadcastAsUser",
)

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5320")
class AndroidBroadcastingCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ private val PRIMITIVE_ARRAY_REPLACEMENT = mapOf("hashCode" to "contentHashCode",
private val OBJECT_ARRAY_REPLACEMENT = mapOf("hashCode" to "contentDeepHashCode", "toString" to "contentDeepToString")
private val ARRAY_OF_ARRAY_REPLACEMENT = mapOf("contentHashCode" to "contentDeepHashCode", "contentToString" to "contentDeepToString")

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S2116")
class ArrayHashCodeAndToStringCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ private val KEY_GEN_BUILDER_SET_AUTH_MATCHER = FunMatcher(qualifier = BUILDER, n
withArguments("kotlin.Boolean")
}

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6288")
class AuthorisingNonAuthenticatedUsersCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(KEY_GEN_BUILDER_BUILD_MATCHER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ private val ANDROIDX_AUTH = FunMatcher(qualifier = "androidx.biometric.Biometric

private const val MESSAGE = """Make sure performing a biometric authentication without a "CryptoObject" is safe here."""

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6293")
class BiometricAuthWithoutCryptoCheck : CallAbstractCheck() {
override val functionsToVisit = setOf(ANDROID_HARDWARE_AUTH, ANDROIDX_AUTH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ private val GET_INSTANCE_MATCHER = FunMatcher(qualifier = "javax.crypto.Cipher",
private val GET_BYTES_MATCHER = FunMatcher(qualifier = "kotlin.text", name = "toByteArray")
private val IV_PARAMETER_SPEC_MATCHER = ConstructorMatcher("javax.crypto.spec.IvParameterSpec")

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S3329")
class CipherBlockChainingCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(CIPHER_INIT_MATCHER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ private val GCM_PARAMETER_SPEC_MATCHER = ConstructorMatcher("javax.crypto.spec.G

private val GET_BYTES_MATCHER = FunMatcher(qualifier = "kotlin.text", name = "toByteArray")

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6432")
class CipherModeOperationCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(CIPHER_INIT_MATCHER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ private val ANDROID_SET_MIXED_CONTENT_MODE = FunMatcher(definingSupertype = "and

private fun msg(insecure: String, replaceWith: String) = "Using $insecure is insecure. Use $replaceWith instead."

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5332")
class ClearTextProtocolCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private val COLLECTIONS_FUN_MATCHER = FunMatcher(definingSupertype = "kotlin.col

private const val MESSAGE = "Collections should not be passed as arguments to their own methods."

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S2114")
class CollectionCallingItselfCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(MUTABLE_COLLECTION_FUN_MATCHER, COLLECTIONS_FUN_MATCHER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ val funMatcherToArgumentIndexMap = mapOf(

const val ISSUE_MESSAGE = "This key/object cannot ever be present in the collection"

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S2175")
class CollectionInappropriateCallsCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ private val mutableCollections =
"kotlin.collections.MutableCollection"
)

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6524")
class CollectionShouldBeImmutableCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ val ISSUE_MESSAGE_SIZE_NEVER_LT = """The size of an array/collection is never "<
val ISSUE_MESSAGE_SIZE_ALWAYS_GTEQ =
"""The size of an array/collection is always ">=0", update this test to either ".isNotEmpty()" or ".isEmpty()"."""

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S3981")
class CollectionSizeAndArrayLengthCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import org.sonarsource.kotlin.api.frontend.KotlinFileContext
private const val COROUTINE_SCOPE = "kotlinx.coroutines.CoroutineScope"
private const val MESSAGE = "Extension functions on CoroutineScope should not be suspending."

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6312")
class CoroutineScopeFunSuspendingCheck : AbstractCheck() {
override fun visitNamedFunction(function: KtNamedFunction, kotlinFileContext: KotlinFileContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ private val LAUNCH_ASYNC_MATCHER = FunMatcher(qualifier = KOTLINX_COROUTINES_PAC
withNames("launch", "async")
}

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6316")
class CoroutinesTimeoutApiUnusedCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(FunMatcher(definingSupertype = "$KOTLINX_COROUTINES_PACKAGE.Job", name = "cancel"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ private val WEAK_METHOD_MATCHERS = listOf(
private val DEPRECATED_SPRING_PASSWORD_ENCODER_METHODS = DEPRECATED_SPRING_PASSWORD_ENCODERS.map(::ConstructorMatcher).toList() +
FunMatcher(qualifier = "org.springframework.security.crypto.password.NoOpPasswordEncoder", name = GET_INSTANCE)

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S4790")
class DataHashingCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.sonarsource.kotlin.api.frontend.KotlinFileContext

private const val MESSAGE = "Make sure this debug feature is deactivated before delivering the code in production."

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S4507")
class DebugFeatureEnabledCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import org.sonarsource.kotlin.api.checks.returnType
import org.sonarsource.kotlin.api.checks.returnTypeAsString
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6514")
class DelegationPatternCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.sonarsource.kotlin.api.checks.AbstractCheck
import org.sonarsource.kotlin.api.checks.annotatedElement
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S1133")
class DeprecatedCodeCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.sonar.check.Rule
import org.sonarsource.kotlin.api.checks.AbstractCheck
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S1874")
class DeprecatedCodeUsedCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.sonarsource.kotlin.api.reporting.SecondaryLocation
import org.sonarsource.kotlin.api.reporting.KotlinTextRanges.textRange
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S1871")
class DuplicateBranchCheck : AbstractBranchDuplication() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.sonarsource.analyzer.commons.regex.finders.DuplicatesInCharacterClass
import org.sonarsource.kotlin.api.regex.AbstractRegexCheck
import org.sonarsource.kotlin.api.regex.RegexContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5869")
class DuplicatesInCharacterClassCheck : AbstractRegexCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ private val PATTERN_FIND = FunMatcher(qualifier = "java.util.regex.Matcher", nam
private val STRING_IS_EMPTY = FunMatcher(qualifier = KOTLIN_TEXT, name = "isEmpty")
private val REGEX_FIND = FunMatcher(qualifier = "kotlin.text.Regex", name = "find")

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5846")
class EmptyLineRegexCheck : AbstractRegexCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.sonarsource.analyzer.commons.regex.finders.EmptyStringRepetitionFinde
import org.sonarsource.kotlin.api.regex.AbstractRegexCheck
import org.sonarsource.kotlin.api.regex.RegexContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5842")
class EmptyStringRepetitionCheck : AbstractRegexCheck() {
override fun visitRegex(regex: RegexParseResult, regexContext: RegexContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ val CIPHER_GET_INSTANCE_MATCHER = FunMatcher {
name = "getInstance"
}

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5542")
class EncryptionAlgorithmCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ private val EQUALS_MATCHER = FunMatcher {
withArguments(ANY_TYPE)
}

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S2097")
class EqualsArgumentTypeCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.sonarsource.kotlin.api.reporting.SecondaryLocation
import org.sonarsource.kotlin.api.reporting.KotlinTextRanges.textRange
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6519")
class EqualsMethodUsageCheck : CallAbstractCheck() {
override val functionsToVisit = setOf(FunMatcher { name = EQUALS_METHOD_NAME; withArguments(ANY_TYPE) })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ private val EXPECTED_OVERRIDES = listOf(
}
)

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6218")
class EqualsOverriddenWithArrayFieldCheck : AbstractCheck() {
override fun visitClass(klass: KtClass, context: KotlinFileContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ private val hashCodeMatcher = FunMatcher {
withNoArguments()
}

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S1206")
class EqualsOverridenWithHashCodeCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private val DISALLOWED_TYPES = listOf(

private const val MESSAGE = "Don't expose mutable flow types."

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6305")
class ExposedMutableFlowCheck : AbstractCheck() {
override fun visitProperty(property: KtProperty, kotlinFileContext: KotlinFileContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ private val HOTSPOT_PROPS = listOf(
"obbDirs",
)

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5324")
class ExternalAndroidStorageAccessCheck : CallAbstractCheck() {
override val functionsToVisit = HOTSPOT_FUNS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.sonarsource.kotlin.api.frontend.KotlinFileContext

private const val MESSAGE = "Unused coroutines Flow."

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6314")
class FinalFlowOperationCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(FunMatcher(returnType = COROUTINES_FLOW))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import org.sonarsource.kotlin.api.frontend.KotlinFileContext
private val FORBIDDEN_RETURN_TYPES = listOf(COROUTINES_FLOW, COROUTINES_CHANNEL)
private const val MESSAGE = """Functions returning "Flow" or "Channel" should not be suspending"""

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6309")
class FlowChannelReturningFunsNotSuspendingCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.sonarsource.analyzer.commons.regex.finders.GraphemeInClassFinder
import org.sonarsource.kotlin.api.regex.AbstractRegexCheck
import org.sonarsource.kotlin.api.regex.RegexContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5868")
class GraphemeClustersInClassesCheck : AbstractRegexCheck() {
override fun visitRegex(regex: RegexParseResult, regexContext: RegexContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import org.sonarsource.kotlin.api.checks.FunMatcher
import org.sonarsource.kotlin.api.checks.simpleName
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S899")
class IgnoredOperationStatusCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.sonarsource.kotlin.api.checks.FunMatcher
import org.sonarsource.kotlin.api.checks.FunMatcherImpl
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6518")
class IndexedAccessCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.sonarsource.kotlin.api.frontend.secondaryOf
private const val MESSAGE = "Avoid hardcoded dispatchers."
private const val DISPATCHERS_OBJECT = "$KOTLINX_COROUTINES_PACKAGE.Dispatchers"

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6310")
class InjectableDispatchersCheck : CallAbstractCheck() {
override val functionsToVisit = FUNS_ACCEPTING_DISPATCHERS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.sonarsource.kotlin.api.checks.AbstractCheck
import org.sonarsource.kotlin.api.checks.getType
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6517")
class InterfaceCouldBeFunctionalCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.sonarsource.kotlin.api.frontend.KotlinFileContext

private const val MESSAGE_MULTIPLE_ERRORS = "Fix the syntax errors inside this regex."

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5856")
class InvalidRegexCheck : AbstractRegexCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.sonarsource.kotlin.api.frontend.KotlinFileContext

private val JAVA_CLASS_KEYWORDS = listOf("java", "javaClass")

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6202")
class IsInstanceMethodCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.sonarsource.kotlin.api.checks.AbstractCheck
import org.sonarsource.kotlin.api.checks.isExhaustive
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6510")
class LiftReturnStatementCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ val BLOCKING_ANNOTATIONS = setOf(
"javax.net.ssl.SSLException",
)

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6307")
class MainSafeCoroutinesCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.sonarsource.kotlin.api.reporting.message
import org.sonarsource.kotlin.api.checks.determineType
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6611")
class MapValuesShouldBeAccessedSafelyCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ private const val ENCRYPTION_KEY = "encryptionKey"
private const val CHANGE_PASSWORD = "changePassword"
private val CREATE_CHAR_BYTE_ARRAY = FunMatcher(qualifier = "kotlin") { withNames("byteArrayOf", "charArrayOf") }

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6301")
class MobileDatabaseEncryptionKeysCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ private val RESULT_SET_GET = FunMatcher(qualifier = "java.sql.ResultSet", nameRe
withArguments(ArgumentMatcher(INT_TYPE), ArgumentMatcher.ANY)
}

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S2695")
class PreparedStatementAndResultSetCheck : CallAbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import org.sonarsource.kotlin.api.frontend.secondaryOf
private val GETTER_PREFIX = Regex("""^(get|is)\p{javaUpperCase}""")
private val SETTER_PREFIX = Regex("""^set\p{javaUpperCase}""")

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6512")
class PropertyGetterAndSetterUsageCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ private val RANDOM_CONSTRUCTOR_TYPES = setOf(
"org.apache.commons.lang.math.JVMRandom"
)

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S2245")
class PseudoRandomCheck : AbstractCheck() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.sonar.check.Rule
import org.sonarsource.kotlin.api.checks.AbstractCheck
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6530")
class ReasonableTypeCastsCheck : AbstractCheck() {
override fun visitKtFile(file: KtFile, context: KotlinFileContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.sonarsource.kotlin.api.checks.FunMatcher
import org.sonarsource.kotlin.api.checks.isNull
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S5322")
class ReceivingIntentsCheck : CallAbstractCheck() {
override val functionsToVisit = listOf(
Expand Down
Loading

0 comments on commit be84088

Please sign in to comment.