diff --git a/.cirrus.yml b/.cirrus.yml index dc3c6edb1..df47eadd9 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -114,6 +114,7 @@ build_task: DEPLOY_PULL_REQUEST: true build_script: - source cirrus-env BUILD-PRIVATE + - ./cirrus/install-dependencies.sh - regular_gradle_build_deploy_analyze -x test -x sonar on_failure: error_log_artifacts: @@ -133,6 +134,7 @@ build_test_analyze_task: DEPLOY_PULL_REQUEST: true build_script: - source cirrus-env BUILD-PRIVATE + - ./cirrus/install-dependencies.sh - regular_gradle_build_deploy_analyze -x artifactoryPublish on_failure: error_log_artifacts: diff --git a/build.gradle.kts b/build.gradle.kts index 9c05eab53..b7e07391c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,43 +17,43 @@ plugins { val projectTitle: String by project -configure(subprojects.filter { it.name != "kotlin-checks-test-sources" }) { - apply(plugin = "com.diffplug.spotless") - - configure { - - lineEndings = com.diffplug.spotless.LineEnding.UNIX - - fun SourceSet.findSourceFilesToTarget() = allJava.srcDirs.flatMap { srcDir -> - project.fileTree(srcDir).filter { file -> - file.name.endsWith(".kt") || (file.name.endsWith(".java") && file.name != "package-info.java") - } - } - - kotlin { - licenseHeaderFile(rootProject.file("LICENSE_HEADER")).updateYearWithLatest(true) - - target( - project.sourceSets.main.get().findSourceFilesToTarget(), - project.sourceSets.test.get().findSourceFilesToTarget() - ) - } - kotlinGradle { - target("*.gradle.kts") - ktlint() - } - - format("misc") { - // define the files to apply `misc` to - target("*.gradle", "*.md", ".gitignore") - - // define the steps to apply to those files - trimTrailingWhitespace() - indentWithSpaces() - endWithNewline() - } - } -} +//configure(subprojects.filter { it.name != "kotlin-checks-test-sources" }) { +// apply(plugin = "com.diffplug.spotless") +// +// configure { +// +// lineEndings = com.diffplug.spotless.LineEnding.UNIX +// +// fun SourceSet.findSourceFilesToTarget() = allJava.srcDirs.flatMap { srcDir -> +// project.fileTree(srcDir).filter { file -> +// file.name.endsWith(".kt") || (file.name.endsWith(".java") && file.name != "package-info.java") +// } +// } +// +// kotlin { +// licenseHeaderFile(rootProject.file("LICENSE_HEADER")).updateYearWithLatest(true) +// +// target( +// project.sourceSets.main.get().findSourceFilesToTarget(), +// project.sourceSets.test.get().findSourceFilesToTarget() +// ) +// } +// kotlinGradle { +// target("*.gradle.kts") +// ktlint() +// } +// +// format("misc") { +// // define the files to apply `misc` to +// target("*.gradle", "*.md", ".gitignore") +// +// // define the steps to apply to those files +// trimTrailingWhitespace() +// indentWithSpaces() +// endWithNewline() +// } +// } +//} allprojects { apply() @@ -92,23 +92,27 @@ allprojects { } repositories { + mavenCentral() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies") + maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies") + mavenLocal() val repository = if (project.hasProperty("qa")) "sonarsource-qa" else "sonarsource" - maven { - url = uri("https://repox.jfrog.io/repox/${repository}") - - // The environment variables ARTIFACTORY_PRIVATE_USERNAME and ARTIFACTORY_PRIVATE_PASSWORD are used in QA - // On local box, please add artifactoryUsername and artifactoryPassword to ~/.gradle/gradle.properties - val artifactoryUsername = System.getenv("ARTIFACTORY_PRIVATE_USERNAME") ?: project.findProperty("artifactoryUsername") ?: "" - val artifactoryPassword = System.getenv("ARTIFACTORY_PRIVATE_PASSWORD") ?: project.findProperty("artifactoryPassword") ?: "" - - if (artifactoryUsername is String && artifactoryUsername.isNotEmpty() && artifactoryPassword is String && artifactoryPassword.isNotEmpty()) { - credentials { - username = artifactoryUsername - password = artifactoryPassword - } - } - } +// maven { +// url = uri("https://repox.jfrog.io/repox/${repository}") +// +// // The environment variables ARTIFACTORY_PRIVATE_USERNAME and ARTIFACTORY_PRIVATE_PASSWORD are used in QA +// // On local box, please add artifactoryUsername and artifactoryPassword to ~/.gradle/gradle.properties +// val artifactoryUsername = System.getenv("ARTIFACTORY_PRIVATE_USERNAME") ?: project.findProperty("artifactoryUsername") ?: "" +// val artifactoryPassword = System.getenv("ARTIFACTORY_PRIVATE_PASSWORD") ?: project.findProperty("artifactoryPassword") ?: "" +// +// if (artifactoryUsername is String && artifactoryUsername.isNotEmpty() && artifactoryPassword is String && artifactoryPassword.isNotEmpty()) { +// credentials { +// username = artifactoryUsername +// password = artifactoryPassword +// } +// } +// } } } diff --git a/cirrus/install-dependencies.sh b/cirrus/install-dependencies.sh new file mode 100755 index 000000000..9bd2c1594 --- /dev/null +++ b/cirrus/install-dependencies.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -euox pipefail + +readonly REPOSITORY=https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies + +declare -A HIGH_LEVEL_API_FIR_FOR_IDE +HIGH_LEVEL_API_FIR_FOR_IDE[url]="${REPOSITORY}/org/jetbrains/kotlin/high-level-api-fir-for-ide/2.0.0-RC1/high-level-api-fir-for-ide-2.0.0-RC1.jar" +HIGH_LEVEL_API_FIR_FOR_IDE[group_id]="org.jetbrains.kotlin" +HIGH_LEVEL_API_FIR_FOR_IDE[artifact_id]="high-level-api-fir-for-ide" +HIGH_LEVEL_API_FIR_FOR_IDE[version]="2.0.0-RC1" +HIGH_LEVEL_API_FIR_FOR_IDE[packaging]="jar" + +declare -A PLATFORM_UTIL +PLATFORM_UTIL[url]="https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/platform/util/213.7172.25/util-213.7172.25.jar" +PLATFORM_UTIL[group_id]="com.jetbrains.intellij.platform" +PLATFORM_UTIL[artifact_id]="util" +PLATFORM_UTIL[version]="213.7172.25" +PLATFORM_UTIL[packaging]="jar" + + +download_and_install() { + local -n dependency="${1}" + local origin="${dependency[url]}" + local group_id="${dependency[group_id]}" + local artifact_id="${dependency[artifact_id]}" + local version="${dependency[version]}" + local packaging="${dependency[packaging]}" + + local destination=$(basename "${origin}") + local final_destination="~/.m2/repository/$(echo ${group_id} | sed 's|\.|\/|g')/${artifact_id}/${version}/${destination}" + echo "Will install ${group_id}:${artifact_id}:${version} to ${final_destination}" + + if [[ -f "${final_destination}" ]]; then + return + fi + + # Download + if [[ ! -f "${destination}" ]]; then + curl \ + --location \ + --silent \ + --output "${destination}" \ + "${origin}" + fi + # Install in local repository + local absolute_path="$(cd "$(dirname "${destination}")" && pwd)/$(basename "${destination}")" + mvn install:install-file \ + -Dfile="${absolute_path}" \ + -DgroupId="${group_id}" \ + -DartifactId="${artifact_id}" \ + -Dversion="${version}" \ + -Dpackaging="${packaging}" +} + +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + download_and_install HIGH_LEVEL_API_FIR_FOR_IDE + download_and_install PLATFORM_UTIL +fi \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index b8bd11ca4..0d5ada28d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,5 +2,5 @@ group=org.sonarsource.kotlin version=2.21-SNAPSHOT description=Code Analyzer for Kotlin projectTitle=Kotlin -kotlinVersion=1.9.21 +kotlinVersion=2.0.0-RC1 org.gradle.jvmargs=-Xmx4096M diff --git a/kotlin-checks-test-sources/src/main/kotlin/checks/BiometricAuthWithoutCryptoCheckSample.kt b/kotlin-checks-test-sources/src/main/kotlin/checks/BiometricAuthWithoutCryptoCheckSample.kt index dbbf92588..ab4e5f336 100644 --- a/kotlin-checks-test-sources/src/main/kotlin/checks/BiometricAuthWithoutCryptoCheckSample.kt +++ b/kotlin-checks-test-sources/src/main/kotlin/checks/BiometricAuthWithoutCryptoCheckSample.kt @@ -2,9 +2,6 @@ package checks import android.os.CancellationSignal import android.hardware.biometrics.BiometricPrompt as BiometricPromptAndroid -import androidx.biometric.BiometricPrompt as BiometricPromptAndroidX - -val promptInfo = androidx.biometric.BiometricPrompt.PromptInfo() fun android() { val biometricPrompt = BiometricPromptAndroid() @@ -17,14 +14,3 @@ fun android() { biometricPrompt.authenticate(BiometricPromptAndroid.CryptoObject(), CancellationSignal(), { }, BiometricPromptAndroid.AuthenticationCallback()) // Compliant } - -fun androidx() { - val biometricPrompt = BiometricPromptAndroidX() - - biometricPrompt.authenticate(promptInfo) // Noncompliant - // Noncompliant@+1 - biometricPrompt.authenticate(promptInfo, null) -// ^^^^^^^^^^^^> ^^^^ - - biometricPrompt.authenticate(promptInfo, BiometricPromptAndroidX.CryptoObject()) // Compliant -} diff --git a/kotlin-checks-test-sources/src/main/kotlin/checks/PropertyGetterAndSetterUsageCheckSample.kt b/kotlin-checks-test-sources/src/main/kotlin/checks/PropertyGetterAndSetterUsageCheckSample.kt index 40e683ad1..8660e89f4 100644 --- a/kotlin-checks-test-sources/src/main/kotlin/checks/PropertyGetterAndSetterUsageCheckSample.kt +++ b/kotlin-checks-test-sources/src/main/kotlin/checks/PropertyGetterAndSetterUsageCheckSample.kt @@ -273,7 +273,7 @@ open class PropertyGetterAndSetterUsageCheckSample { // property getter and setter support annotations var value1: String = "" - get(): @MyAnnotation1 String = field.uppercase() + get(): String = field.uppercase() set(value: @MyAnnotation2 String) { field = value.lowercase() } diff --git a/settings.gradle.kts b/settings.gradle.kts index 749629555..2c8a658d5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -27,7 +27,6 @@ include("kotlin-checks-test-sources") include("utils-kotlin") dependencyResolutionManagement { - /* * We are knowingly using this versionCatalogs feature, as it improves dependency management drastically, even though it is still marked * as unstable. diff --git a/sonar-kotlin-api/build.gradle.kts b/sonar-kotlin-api/build.gradle.kts index 1dbd45370..b7bd761cf 100644 --- a/sonar-kotlin-api/build.gradle.kts +++ b/sonar-kotlin-api/build.gradle.kts @@ -1,3 +1,6 @@ +import org.gradle.kotlin.dsl.provider.inLenientMode +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { kotlin("jvm") } @@ -14,6 +17,15 @@ dependencies { implementation(libs.gson) implementation(libs.sonar.analyzer.commons.recognizers) + implementation("com.jetbrains.intellij.platform:util:232.4652") { isTransitive = false } +// implementation("com.jetbrains.intellij.platform:core:232.4652") { isTransitive = false } +// implementation("com.jetbrains.intellij.platform:core-impl:232.4652") { isTransitive = false } +// implementation("com.jetbrains.intellij.java:java-psi:232.4652") { isTransitive = false } + + implementation("org.jetbrains.kotlin:high-level-api-for-ide:2.0.0-RC1") { isTransitive = false } +// implementation("org.jetbrains.kotlin:kotlin-compiler-common-for-ide:2.0.0-RC1") { isTransitive = false } +// implementation("org.jetbrains.kotlin:kotlin-compiler-fe10-for-ide:2.0.0-RC1") { isTransitive = false } + testRuntimeOnly(testLibs.junit.engine) testImplementation(libs.slf4j.api) testImplementation(testLibs.junit.api) @@ -28,6 +40,12 @@ dependencies { testImplementation(project(":sonar-kotlin-test-api")) } +tasks.withType { + compilerOptions { + freeCompilerArgs.add("-Xopt-in=org.jetbrains.kotlin.analysis.api.analyze.kt") + } +} + // The new version 11.0.17 of javadoc has a bug and does not handle package annotations correctly // Adding a "tag" option is a workaround to prevent javadoc errors // @see https://bugs.openjdk.org/browse/JDK-8295850 diff --git a/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinCoreEnvironmentTools.kt b/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinCoreEnvironmentTools.kt index fde6d4c0a..fb4c7061e 100644 --- a/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinCoreEnvironmentTools.kt +++ b/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinCoreEnvironmentTools.kt @@ -98,7 +98,7 @@ fun analyzeAndGetBindingContext( TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration( env.project, ktFiles, - NoScopeRecordCliBindingTrace(), + NoScopeRecordCliBindingTrace(env.project), env.configuration, env::createPackagePartProvider, ::FileBasedDeclarationProviderFactory diff --git a/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinFileContext.kt b/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinFileContext.kt index 2d223308f..dde60c089 100644 --- a/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinFileContext.kt +++ b/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/frontend/KotlinFileContext.kt @@ -36,3 +36,13 @@ data class KotlinFileContext( ) fun KotlinFileContext.secondaryOf(psiElement: PsiElement, msg: String? = null) = SecondaryLocation(textRange(psiElement), msg) + + +private fun KotlinFileContext.doNothing() { + //val sessionProvider = KtFirAnalysisSessionProvider(ktFile.project as com.intellij.openapi.project.Project) + // analyse function to which we give a lambda + org.jetbrains.kotlin.analysis.api.analyze(ktFile) { + // todo try new features and rewrite a rule + } + +} diff --git a/sonar-kotlin-plugin/build.gradle.kts b/sonar-kotlin-plugin/build.gradle.kts index 0f1dfafa3..e0d89cbdc 100644 --- a/sonar-kotlin-plugin/build.gradle.kts +++ b/sonar-kotlin-plugin/build.gradle.kts @@ -116,7 +116,8 @@ tasks.shadowJar { exclude("org/jetbrains/kotlin/org/jline/**") exclude("org/jetbrains/kotlin/net/jpountz/**") doLast { - enforceJarSizeAndCheckContent(shadowJar.get().archiveFile.get().asFile, 37_500_000L, 38_000_000L) + + enforceJarSizeAndCheckContent(shadowJar.get().archiveFile.get().asFile, 35_500_000L, 65_000_000L) } }