diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 47ed6fc..0000000 --- a/build.gradle +++ /dev/null @@ -1,106 +0,0 @@ -import jetbrains.sign.GpgSignSignatoryProvider - -/* - * Copyright 2000-2021 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -buildscript { - repositories { - maven { url "https://packages.jetbrains.team/maven/p/jcs/maven" } - } - dependencies { - classpath 'com.jetbrains:jet-sign:38' - } -} - -plugins { - id "io.github.gradle-nexus.publish-plugin" version "1.1.0" -} - -ext.projectVersion = projectVersion -ext.publishingUser = System.getenv('PUBLISHING_USER') -ext.publishingPassword = System.getenv('PUBLISHING_PASSWORD') -if (ext.publishingPassword == null) { - ext.projectVersion = ext.projectVersion + '-SNAPSHOT' -} -println "##teamcity[setParameter name='java.annotations.version' value='$projectVersion']" - -allprojects { - // https://github.com/gradle/gradle/issues/847 - group 'org.jetbrains.proto' - version rootProject.ext.projectVersion - - repositories { - mavenCentral() - } -} - -nexusPublishing { - repositories { - sonatype { - username = rootProject.ext.publishingUser - password = rootProject.ext.publishingPassword - } - } -} - -subprojects { - apply plugin: 'java' - apply plugin: 'maven-publish' - apply plugin: 'signing' -} - -configure([project(':java-annotations'), project(':multiplatform-annotations')]) { - publishing { - publications.withType(MavenPublication) { - group 'org.jetbrains' - version rootProject.ext.projectVersion - - pom.withXml { - asNode().children().last() + { - resolveStrategy = DELEGATE_FIRST - name 'JetBrains Java Annotations' - description 'A set of annotations used for code inspection support and code documentation.' - url 'https://github.com/JetBrains/java-annotations' - scm { - url 'https://github.com/JetBrains/java-annotations' - connection 'scm:git:git://github.com/JetBrains/java-annotations.git' - developerConnection 'scm:git:ssh://github.com:JetBrains/java-annotations.git' - } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'https://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - developers { - developer { - id 'JetBrains' - name 'JetBrains Team' - organization 'JetBrains' - organizationUrl 'https://www.jetbrains.com' - } - } - } - } - } - } - - signing { - sign publishing.publications - signatories = new GpgSignSignatoryProvider() - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..abdf204 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,305 @@ +import jetbrains.sign.GpgSignSignatoryProvider +import org.gradle.jvm.tasks.Jar +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import plugins.publishing.* + +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +buildscript { + repositories { + maven { url = uri("https://packages.jetbrains.team/maven/p/jcs/maven") } + } + dependencies { + classpath("com.jetbrains:jet-sign:38") + } +} + +repositories { + mavenCentral() +} + +plugins { + kotlin("multiplatform") version "1.9.22" + id("io.github.gradle-nexus.publish-plugin") version "1.1.0" + `maven-publish` + signing + java +} + +var projectVersion = project.findProperty("projectVersion") as String +val publishingUser: String? = System.getenv("PUBLISHING_USER") +val publishingPassword: String? = System.getenv("PUBLISHING_PASSWORD") +if (publishingPassword == null) { + projectVersion += "-SNAPSHOT" +} +println("##teamcity[setParameter name='java.annotations.version' value='$projectVersion']") + +// https://github.com/gradle/gradle/issues/847 +group = "org.jetbrains.proto" +version = projectVersion + +kotlin { + androidNativeArm32() + androidNativeArm64() + androidNativeX86() + androidNativeX64() + + iosArm64() + iosX64() + iosSimulatorArm64() + + js(IR) { + browser {} + } + + jvmToolchain(8) + jvm { + compilations.all { + kotlinOptions.jvmTarget = "1.8" + } + withJava() + } + + linuxArm64() + linuxX64() + + macosX64() + macosArm64() + + mingwX64() + + tvosArm64() + tvosX64() + tvosSimulatorArm64() + + @Suppress("OPT_IN_USAGE") + wasmJs { + browser() + } + @Suppress("OPT_IN_USAGE") + wasmWasi { + nodejs() + } + + watchosArm32() + watchosArm64() + watchosDeviceArm64() + watchosX64() + watchosSimulatorArm64() + + sourceSets { + val commonMain by getting { + dependencies { + compileOnly("org.jetbrains.kotlin:kotlin-stdlib") + } + } + + val nonJvmMain by creating { + dependsOn(commonMain) + } + } + + targets.onEach { + if (it.platformType != KotlinPlatformType.jvm && it.platformType != KotlinPlatformType.common) { + it.compilations.getByName("main").defaultSourceSet.dependsOn(sourceSets.getByName("nonJvmMain")) + } + } + + targets.all { + compilations.all { + compilerOptions.configure { + optIn.add("kotlin.ExperimentalMultiplatform") + freeCompilerArgs.add("-Xexpect-actual-classes") + } + } + } +} + +// from https://github.com/Kotlin/kotlinx-datetime/blob/bc8adee2b9e3659e8e1c38fc09f3a4a1bdf85276/core/build.gradle.kts +tasks { + val compileJavaModuleInfo by registering(JavaCompile::class) { + val moduleName = "org.jetbrains.annotations" // this module's name + val compileKotlinJvm by getting(KotlinCompile::class) + val compileJava by getting(JavaCompile::class) + val sourceDir = file("src/jvmMain/moduleInfo/") + val targetDir = compileKotlinJvm.destinationDirectory.map { it.dir("../moduleInfo/") } + + // Use a Java 11 compiler for the module info. + javaCompiler.set(project.javaToolchains.compilerFor { languageVersion.set(JavaLanguageVersion.of(11)) }) + + // Always compile kotlin and java classes before the module descriptor. + dependsOn(compileKotlinJvm) + dependsOn(compileJava) + + // Add the module-info source file. + source(sourceDir) + + // Set the task outputs and destination dir + outputs.dir(targetDir) + destinationDirectory.set(targetDir) + + // Configure JVM compatibility + sourceCompatibility = JavaVersion.VERSION_1_9.toString() + targetCompatibility = JavaVersion.VERSION_1_9.toString() + + // Set the Java release version. + options.release.set(9) + + // Ignore warnings about using 'requires transitive' on automatic modules. + // not needed when compiling with recent JDKs, e.g. 17 + options.compilerArgs.add("-Xlint:-requires-transitive-automatic") + + // Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly. + options.compilerArgs.addAll(listOf("--patch-module", "$moduleName=${compileJava.destinationDirectory.get()}")) + + // Use the classpath of the compileKotlinJvm task. + // Also ensure that the module path is used instead of classpath. + classpath = compileKotlinJvm.libraries + modularity.inferModulePath.set(true) + } + + // Configure the JAR task so that it will include the compiled module-info class file. + val jvmJar by existing(Jar::class) { + manifest { + attributes("Multi-Release" to true) + } + from(compileJavaModuleInfo.map { it.destinationDirectory }) { + into("META-INF/versions/9/") + } + } + + val allMetadataJar by existing(Jar::class) { + archiveClassifier.set("common") + } + + val javadocJar by creating(Jar::class) { + from(javadoc) + archiveClassifier.set("javadoc") + } +} + +nexusPublishing { + repositories { + sonatype { + username.set(publishingUser) + password.set(publishingPassword) + } + } +} + +configurations { + create("javadocElements") { + attributes { + attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category::class.java, Category.DOCUMENTATION)) + attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling::class.java, Bundling.EXTERNAL)) + attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.objects.named(DocsType::class.java, DocsType.JAVADOC)) + attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)) + } + } +} + +artifacts { + add("javadocElements", tasks.getByName("javadocJar")) +} + +publishing { + val artifactBaseName = base.archivesName.get() + configureMultiModuleMavenPublishing { + val rootModule = module("rootModule") { + mavenPublication { + artifactId = artifactBaseName + groupId = "org.jetbrains" + configureKotlinPomAttributes(packaging = "jar") + } + variant("metadataApiElements") { suppressPomMetadataWarnings() } + variant("metadataSourcesElementsFromJvm") { + name = "metadataSourcesElements" + configuration { + // to avoid clash in Gradle 8+ with metadataSourcesElements configuration with the same attributes + isCanBeConsumed = false + } + attributes { + copyAttributes(from = project.configurations["metadataSourcesElements"].attributes, to = this) + } + artifact(tasks["sourcesJar"]) { + classifier = "sources-common" + } + } + variant("jvmApiElements") + variant("jvmRuntimeElements") { + configureVariantDetails { mapToMavenScope("runtime") } + } + variant("jvmSourcesElements") + variant("javadocElements") + } + val targetModules = kotlin.targets.filter { it.targetName != "jvm" && it.targetName != "metadata" }.map { target -> + val targetName = target.targetName + module("${targetName}Module") { + mavenPublication { + artifactId = "$artifactBaseName-$targetName" + groupId = "org.jetbrains" + configureKotlinPomAttributes(packaging = "klib") + } + variant("${targetName}ApiElements") + if (configurations.findByName("${targetName}RuntimeElements") != null) { + variant("${targetName}RuntimeElements") + } + variant("${targetName}SourcesElements") + } + } + + // Makes all variants from accompanying artifacts visible through `available-at` + rootModule.include(*targetModules.toTypedArray()) + } +} + +fun MavenPublication.configureKotlinPomAttributes( + packaging: String, +) { + pom { + this.packaging = packaging + name.set("JetBrains Java Annotations") + description.set("A set of annotations used for code inspection support and code documentation.") + url.set("https://github.com/JetBrains/java-annotations") + scm { + url.set("https://github.com/JetBrains/java-annotations") + connection.set("scm:git:git://github.com/JetBrains/java-annotations.git") + developerConnection.set("scm:git:ssh://github.com:JetBrains/java-annotations.git") + } + licenses { + license { + name.set("The Apache Software License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("repo") + } + } + developers { + developer { + id.set("JetBrains") + name.set("JetBrains Team") + organization.set("JetBrains") + organizationUrl.set("https://www.jetbrains.com") + } + } + } +} + +signing { + sign(publishing.publications) + signatories = GpgSignSignatoryProvider() +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..cc02e63 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + gradlePluginPortal() +} diff --git a/buildSrc/src/main/kotlin/plugins/publishing/CustomVariantPublishingDsl.kt b/buildSrc/src/main/kotlin/plugins/publishing/CustomVariantPublishingDsl.kt new file mode 100644 index 0000000..0a65dee --- /dev/null +++ b/buildSrc/src/main/kotlin/plugins/publishing/CustomVariantPublishingDsl.kt @@ -0,0 +1,206 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package plugins.publishing + +import org.gradle.api.Project +import org.gradle.api.artifacts.ConfigurablePublishArtifact +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.component.* +import org.gradle.api.internal.component.SoftwareComponentInternal +import org.gradle.api.internal.component.UsageContext +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.newInstance + +private open class ComponentsFactoryAccess +@javax.inject.Inject +constructor(val factory: SoftwareComponentFactory) + +val Project.componentFactory: SoftwareComponentFactory + get() = findProperty("_componentFactory") as SoftwareComponentFactory? + ?: objects.newInstance().factory + .also { project.extra["_componentFactory"] = it } + +fun copyAttributes(from: AttributeContainer, to: AttributeContainer) { + // capture type argument T + fun copyOneAttribute(from: AttributeContainer, to: AttributeContainer, key: Attribute) { + val value = checkNotNull(from.getAttribute(key)) + to.attribute(key, value) + } + for (key in from.keySet()) { + copyOneAttribute(from, to, key) + } +} + +class MultiModuleMavenPublishingConfiguration { + val modules = mutableMapOf() + + class Module(val name: String) { + val variants = mutableMapOf() + val includes = mutableSetOf() + + class Variant( + val configurationName: String + ) { + var name: String = configurationName + val attributesConfigurations = mutableListOf Unit>() + fun attributes(code: AttributeContainer.() -> Unit) { + attributesConfigurations += code + } + + val artifactsWithConfigurations = mutableListOf Unit>>() + fun artifact(file: Any, code: ConfigurablePublishArtifact.() -> Unit = {}) { + artifactsWithConfigurations += file to code + } + + val configurationConfigurations = mutableListOf Unit>() + fun configuration(code: Configuration.() -> Unit) { + configurationConfigurations += code + } + + val variantDetailsConfigurations = mutableListOf Unit>() + fun configureVariantDetails(code: ConfigurationVariantDetails.() -> Unit) { + variantDetailsConfigurations += code + } + + var suppressPomMetadataWarnings: Boolean = false + fun suppressPomMetadataWarnings() { suppressPomMetadataWarnings = true } + } + + val mavenPublicationConfigurations = mutableListOf Unit>() + fun mavenPublication(code: MavenPublication.() -> Unit) { + mavenPublicationConfigurations += code + } + + fun variant(fromConfigurationName: String, code: Variant.() -> Unit = {}): Variant { + val variant = variants.getOrPut(fromConfigurationName) { Variant(fromConfigurationName) } + variant.code() + return variant + } + + fun include(vararg modules: Module) { + includes.addAll(modules) + } + } + + fun module(name: String, code: Module.() -> Unit): Module { + val module = modules.getOrPut(name) { Module(name) } + module.code() + return module + } +} + +fun Project.configureMultiModuleMavenPublishing(code: MultiModuleMavenPublishingConfiguration.() -> Unit) { + val publishingConfiguration = MultiModuleMavenPublishingConfiguration() + publishingConfiguration.code() + + val components = publishingConfiguration + .modules + .mapValues { (_, module) -> project.createModulePublication(module) } + + val componentsWithExternals = publishingConfiguration + .modules + .filter { (_, module) -> module.includes.isNotEmpty() } + .mapValues { (moduleName, module) -> + val mainComponent = components[moduleName] ?: error("Component with name $moduleName wasn't created") + val externalComponents = module.includes + .map { components[it.name] ?: error("Component with name ${it.name} wasn't created") } + .toSet() + ComponentWithExternalVariants(mainComponent, externalComponents) + } + + // override some components with items from componentsWithExternals + val mergedComponents = components + componentsWithExternals + + val publicationsContainer = project.extensions.getByType().publications + for ((componentName, component) in mergedComponents) { + publicationsContainer.create(componentName) { + from(component) + val module = publishingConfiguration.modules[componentName]!! + module.mavenPublicationConfigurations.forEach { configure -> configure() } + module.variants.values.filter { it.suppressPomMetadataWarnings }.forEach { + suppressPomMetadataWarningsFor(it.name) + } + } + } +} + + +fun Project.createModulePublication(module: MultiModuleMavenPublishingConfiguration.Module): SoftwareComponent { + val component = componentFactory.adhoc(module.name) + module.variants.values.forEach { addVariant(component, it) } + + val newNames = module.variants.map { it.key to it.value.name }.filter { it.first != it.second }.toMap() + return if (newNames.isNotEmpty()) { + ComponentWithRenamedVariants(newNames, component as SoftwareComponentInternal) + } else { + component + } +} + +fun Project.addVariant(component: AdhocComponentWithVariants, variant: MultiModuleMavenPublishingConfiguration.Module.Variant) { + val configuration: Configuration = configurations.getOrCreate(variant.configurationName) + configuration.apply { + isCanBeResolved = false + + variant.attributesConfigurations.forEach { configure -> attributes.configure() } + } + + for ((artifactNotation, configure) in variant.artifactsWithConfigurations) { + artifacts.add(configuration.name, artifactNotation) { + configure() + } + } + + for (configure in variant.configurationConfigurations) { + configuration.apply(configure) + } + + component.addVariantsFromConfiguration(configuration) { + variant.variantDetailsConfigurations.forEach { configure -> configure() } + } +} + +private class RenamedVariant(val newName: String, context: UsageContext) : UsageContext by context { + override fun getName(): String = newName +} + +private class ComponentWithRenamedVariants( + val newNames: Map, + private val base: SoftwareComponentInternal +): SoftwareComponentInternal by base { + + override fun getName(): String = base.name + override fun getUsages(): Set { + return base.usages.map { + val newName = newNames[it.name] + if (newName != null) { + RenamedVariant(newName, it) + } else { + it + } + }.toSet() + } +} + +private class ComponentWithExternalVariants( + private val mainComponent: SoftwareComponent, + private val externalComponents: Set +) : ComponentWithVariants, SoftwareComponentInternal { + override fun getName(): String = mainComponent.name + + override fun getUsages(): Set = (mainComponent as SoftwareComponentInternal).usages + + override fun getVariants(): Set = externalComponents +} + +fun ConfigurationContainer.getOrCreate(name: String): Configuration = findByName(name) ?: create(name) \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index fe69cb5..5fd61ab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,3 +18,6 @@ projectVersion=25.0.0 kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.stdlib.default.dependency=false +kotlin.internal.mpp.createDefaultMultiplatformPublications=false +kotlin.native.ignoreIncorrectDependencies=true +kotlin.mpp.applyDefaultHierarchyTemplate=false \ No newline at end of file diff --git a/java-annotations/build.gradle b/java-annotations/build.gradle deleted file mode 100644 index 2fa093e..0000000 --- a/java-annotations/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2000-2021 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -sourceCompatibility = 1.8 -project.archivesBaseName = 'annotations' - -task mainJar(type: Jar) { - into ("META-INF/versions/9", { - from (project(':java-module-info').sourceSets.main.output, { - // Skip extra files from common sources compiled with Java 9 target - include("module-info.class") - }) - }) - manifest.attributes("Multi-Release": true) - from sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.FAIL -} - -task sourceJar(type: Jar) { - into ("META-INF/versions/9", { - from project(':java-module-info').sourceSets.main.java - }) - duplicatesStrategy = DuplicatesStrategy.FAIL - from sourceSets.main.java - baseName = archivesBaseName + '-sources' -} - -task javadocJar(type: Jar) { - duplicatesStrategy = DuplicatesStrategy.FAIL - from javadoc -} - -javadoc { - source = [sourceSets.main.java] -} - -artifacts { - archives mainJar, sourceJar -} - -model { - publishing { - publications { - pluginMaven(MavenPublication) { - artifactId archivesBaseName - artifact mainJar - artifact sourceJar { - classifier 'sources' - } - artifact javadocJar { - classifier 'javadoc' - } - } - } - } -} \ No newline at end of file diff --git a/java-annotations/src/main/resources/META-INF/org/jetbrains/annotations/verification.properties b/java-annotations/src/main/resources/META-INF/org/jetbrains/annotations/verification.properties deleted file mode 100644 index 8311496..0000000 --- a/java-annotations/src/main/resources/META-INF/org/jetbrains/annotations/verification.properties +++ /dev/null @@ -1,3 +0,0 @@ -#This is the verification token for the org.jetbrains:annotations SDK. -#Tue May 07 23:54:59 PDT 2024 -token=WREIUZVB7ZATTLUBCE6X3VEMXU diff --git a/java-module-info/build.gradle b/java-module-info/build.gradle deleted file mode 100644 index 75c0e99..0000000 --- a/java-module-info/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2000-2021 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -sourceCompatibility = 1.9 - -dependencies { - implementation project(':java-annotations') -} - -compileJava { - // Without common sources, compiler complains that exported packages don't exist - source = [sourceSets.main.java, project(':java-annotations').sourceSets.main.java] -} - -task mainJar(type: Jar) { -} - -javadoc.enabled = false diff --git a/multiplatform-annotations/build.gradle.kts b/multiplatform-annotations/build.gradle.kts deleted file mode 100644 index bc7d3c4..0000000 --- a/multiplatform-annotations/build.gradle.kts +++ /dev/null @@ -1,93 +0,0 @@ -import org.gradle.jvm.tasks.Jar - -plugins { - kotlin("multiplatform") version "1.9.22" -} - -kotlin { - androidNativeArm32() - androidNativeArm64() - androidNativeX86() - androidNativeX64() - - iosArm64() - iosX64() - iosSimulatorArm64() - - js(IR) { - browser {} - } - - jvmToolchain(8) - jvm { - compilations.all { - kotlinOptions.jvmTarget = "1.8" - } - withJava() - } - - linuxArm64() - linuxX64() - - macosX64() - macosArm64() - - mingwX64() - - tvosArm64() - tvosX64() - tvosSimulatorArm64() - - @Suppress("OPT_IN_USAGE") - wasmJs { - browser() - } - @Suppress("OPT_IN_USAGE") - wasmWasi { - nodejs() - } - - watchosArm32() - watchosArm64() - watchosDeviceArm64() - watchosX64() - watchosSimulatorArm64() - - sourceSets { - val commonMain by getting { - dependencies { - compileOnly("org.jetbrains.kotlin:kotlin-stdlib") - } - } - } - - /** - * @Nls contains enum class. Kotlin automatically generates - * `.entries` method for every enum and adds @NotNull to it. - * This disables `.entries` generation. - */ - targets.all { - compilations.all { - compilerOptions.configure { - freeCompilerArgs.add("-XXLanguage:-EnumEntries") - } - } - } -} - -val jvmJar by tasks.getting(Jar::class) { - into ("META-INF/versions/9") { - from (project(":multiplatform-module-info").sourceSets["main"].output) { - include("module-info.class") - } - } - manifest.attributes("Multi-Release" to true) -} - -val jvmSourcesJar by tasks.getting(Jar::class) { - into ("META-INF/versions/9") { - from (project(":multiplatform-module-info").sourceSets["main"].output) { - include("module-info.class") - } - } -} \ No newline at end of file diff --git a/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/Flow.java b/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/Flow.java deleted file mode 100644 index ee73870..0000000 --- a/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/Flow.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2000-2021 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.intellij.lang.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This annotation assists the 'Data flow to this' feature by describing data flow - * from the method parameter to the corresponding container (e.g. {@code ArrayList.add(item)}) - * or from the container to the method return value (e.g. {@code Set.toArray()}) - * or between method parameters (e.g. {@code System.arraycopy(array1, 0, array2, length)}) - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.PARAMETER, ElementType.METHOD}) -public @interface Flow { - /** - * Denotes the source of the data flow.
- * Allowed values are:
- * - *
    - *
  • {@code THIS_SOURCE} - Means that the data flows from this container.
    - * E.g. annotation for java.util.List method get(index) means the method reads contents of list and returns it.
    - * {@code @Flow(source = THIS_SOURCE) T get(int index);}
    - *
  • - *
  • - * {@code this.}Field name - means that the data flows from this container some (synthetic) field.
    - * E.g. annotation for java.util.Map.keySet() method here means that it returns data from the map from the field named "keys".
    - * {@code @Flow(source = "this.keys") Set keySet();} - *
  • - *
- * By default, the source() value is:
- *
    - *
  • - * {@link #THIS_SOURCE} if the method was annotated, e.g.
    - * {@code @Flow(sourceIsContainer=true, targetIsContainer=true) Object[] Collection.toArray()}
    - * Here the annotation tells us that java.util.Collection.toArray() method
    - * reads the contents of this collection (source=THIS_SOURCE by default) and passes it outside. - *
  • - *
  • - * Corresponding argument if the method parameter was annotated, e.g.
    - * {@code void List.add(@Flow(targetIsContainer=true) E item)}
    - * Here the annotation tells us that java.util.List.add(E item) method
    - * takes the argument (source="item" by default) and passes it to this collection. - *
  • - *
- */ - String source() default Flow.DEFAULT_SOURCE; - String DEFAULT_SOURCE = "The method argument (if parameter was annotated) or this container (if instance method was annotated)"; - String THIS_SOURCE = "this"; - - /** - * true if the data source is container and we should track not the expression but its contents.
- * E.g. the java.util.ArrayList constructor takes the collection and stores its contents:
- * ArrayList(
{@code @Flow(sourceIsContainer=true, targetIsContainer=true) Collection collection }
)
- * By default it's false. - */ - boolean sourceIsContainer() default false; - - /** - * Denotes the destination of the data flow.
- * Allowed values are:
- * - *
    - *
  • {@code THIS_TARGET} - Means that the data flows inside this container (of the class the annotated method belongs to).
    - * E.g. annotation for java.util.List method add(element) means the method takes the argument and passes it to this collection.
    - * {@code boolean add(@Flow(target=THIS_TARGET, targetIsContainer=true) E element);}
    - *
  • - *
  • - * Parameter name - means the data flows to this parameter.
    - * E.g.
    - * {@code void arraycopy(@Flow(sourceIsContainer=true, target="dest", targetIsContainer=true) Object src, int srcPos, Object dest, int destPos, int length)}
    - * means that java.lang.System.arraycopy() method takes its first argument and passes it to the "dest" parameter. - *
  • - *
  • - * {@code this.}Field name - means that the data flows to this container in some (synthetic) field.
    - * E.g. annotation for java.util.Map.put(key, value) method here means that it takes the argument 'key' and stores the data in some (hidden) field named "keys".
    - * {@code V put(@Flow(target = "this.keys", targetIsContainer=true) K key, V value);} - *
  • - *
- * By default, the target() value is:
- *
    - *
  • - * {@link #THIS_TARGET} if the parameter was annotated, e.g.
    - * {@code void List.set(int index, @Flow(targetIsContainer=true) E element)}
    - * Here the annotation tells us that java.util.List.set(index, element) method
    - * reads its second argument 'element' and passes it to this collection (target=THIS_TARGET by default). - *
  • - *
  • - * {@link #RETURN_METHOD_TARGET} if the method was annotated, e.g.:
    - * {@code @Flow(sourceIsContainer=true) E List.remove(int index)}
    - * Here the annotation tells us that java.util.List.remove(int index) method
    - * returns the data from its collection (target=RETURN_METHOD_TARGET by default). - *
  • - *
- */ - String target() default Flow.DEFAULT_TARGET; - String DEFAULT_TARGET = "This container (if the parameter was annotated) or the return value (if instance method was annotated)"; - String RETURN_METHOD_TARGET = "The return value of this method"; - String THIS_TARGET = "this"; - - /** - * true if the data target is container and we should track not the expression but its contents.
- * E.g. the java.lang.System.arraycopy() method parameter 'dest' is actually an array:
- * {@code void arraycopy(@Flow(sourceIsContainer=true, target="dest", targetIsContainer=true) Object src, int srcPos, Object dest, int destPos, int length)}
- * By default it's false. - */ - boolean targetIsContainer() default false; -} - diff --git a/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/MagicConstant.java b/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/MagicConstant.java deleted file mode 100644 index 3f02eb7..0000000 --- a/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/MagicConstant.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2000-2021 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.intellij.lang.annotations; - -import org.jetbrains.annotations.NonNls; - -import java.lang.annotation.*; - -/** - *

This annotation intended to help IntelliJ IDEA and other IDEs to detect and auto-complete int and String constants used as an enumeration. - * For example, in the {@link java.awt.Label#Label(String, int)} constructor the alignment parameter can be one of the following - * int constants: {@link java.awt.Label#LEFT}, {@link java.awt.Label#CENTER} or {@link java.awt.Label#RIGHT} - * - *

So, if @MagicConstant annotation applied to this constructor, the IDE will check the constructor usages for the allowed values. - *

E.g.
- *

{@code
- * new Label("text", 0); // 0 is not allowed
- * new Label("text", Label.LEFT); // OK
- * }
- * - *

- * @MagicConstant can be applied to: - *

    - *
  • Field, local variable, parameter. - * - *
    E.g.
    - *
    {@code @MagicConstant(intValues = {TOP, CENTER, BOTTOM})
    - * int textPosition;
    - * }
    - * The IDE will check expressions assigned to the variable for allowed values: - *
    {@code
    - *  textPosition = 0; // not allowed
    - *  textPosition = TOP; // OK
    - * }
    - * - *
  • Method - * - *
    E.g.
    - *
    {@code @MagicConstant(flagsFromClass = java.lang.reflect.Modifier.class)
    - *  public native int getModifiers();
    - * }
    - * - * The IDE will analyse getModifiers() method calls and check if its return value is used with allowed values:
    - *
    {@code
    - *  if (aClass.getModifiers() == 3) // not allowed
    - *  if (aClass.getModifiers() == Modifier.PUBLIC) // OK
    - * }
    - * - *
  • Annotation class
    - * Annotation class annotated with @MagicConstant created alias you can use to annotate - * everything as if it was annotated with @MagicConstant itself. - * - *
    E.g.
    - *
    {@code @MagicConstant(flags = {Font.PLAIN, Font.BOLD, Font.ITALIC}) }
    - *
    {@code @interface FontStyle {} }
    - * - * The IDE will check constructs annotated with @FontStyle for allowed values:
    - * @FontStyle int myStyle = 3; // not allowed
    - * @FontStyle int myStyle = Font.BOLD | Font.ITALIC; // OK
    - * - *
- * - * The @MagicConstant annotation has SOURCE retention, i.e. it is removed upon compilation and does not create any runtime overhead. - */ -@Documented -@Retention(RetentionPolicy.SOURCE) -@Target({ - ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, - ElementType.ANNOTATION_TYPE, - ElementType.METHOD - }) -public @interface MagicConstant { - /** - * @return int values (typically named constants) which are allowed here. - * E.g. - *
-   * {@code
-   * void setConfirmOpenNewProject(@MagicConstant(intValues = {OPEN_PROJECT_ASK, OPEN_PROJECT_NEW_WINDOW, OPEN_PROJECT_SAME_WINDOW})
-   *                               int confirmOpenNewProject);
-   * }
- */ - long[] intValues() default {}; - - /** - * @return String values (typically named constants) which are allowed here. - */ - @NonNls String[] stringValues() default {}; - - /** - * @return allowed int flags (i.e. values (typically named constants) which can be combined with bitwise OR operator (|). - * The difference from the {@link #intValues()} is that flags are allowed to be combined (via plus:+ or bitwise OR: |) whereas values aren't. - * The literals "0" and "-1" are also allowed to denote absence and presense of all flags respectively. - * - * E.g. - *
-   * {@code @MagicConstant(flags = {HierarchyEvent.PARENT_CHANGED,HierarchyEvent.DISPLAYABILITY_CHANGED,HierarchyEvent.SHOWING_CHANGED})
-   * int hFlags;
-   *
-   * hFlags = 3; // not allowed; should be "magic" constant.
-   * if (hFlags & (HierarchyEvent.PARENT_CHANGED | HierarchyEvent.SHOWING_CHANGED) != 0); // OK: combined several constants via bitwise OR
-   * }
- */ - long[] flags() default {}; - - /** - * @return allowed values which are defined in the specified class static final constants. - * - * E.g. - *
-   * {@code @MagicConstant(valuesFromClass = Cursor.class)
-   * int cursorType;
-   *
-   * cursorType = 11; // not allowed; should be "magic" constant.
-   * cursorType = Cursor.E_RESIZE_CURSOR; // OK: "magic" constant used.
-   * }
- */ - Class valuesFromClass() default void.class; - - /** - * @return allowed int flags which are defined in the specified class static final constants. - * The difference from the {@link #valuesFromClass()} is that flags are allowed to be combined (via plus:+ or bitwise OR: |) whereas values aren't. - * The literals "0" and "-1" are also allowed to denote absence and presense of all flags respectively. - * - * E.g. - *
-   * {@code @MagicConstant(flagsFromClass = java.awt.InputEvent.class)
-   * int eventMask;
-   *
-   * eventMask = 10; // not allowed; should be "magic" constant.
-   * eventMask = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; // OK: combined several constants via bitwise OR
-   * }
- */ - Class flagsFromClass() default void.class; -} diff --git a/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/PrintFormat.java b/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/PrintFormat.java deleted file mode 100644 index 24f7a16..0000000 --- a/multiplatform-annotations/src/jvmMain/java/org/intellij/lang/annotations/PrintFormat.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2000-2021 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.intellij.lang.annotations; - -import java.lang.annotation.Documented; - -/** - * Specifies that the method parameter is a printf-style print format pattern, - * as described in {@link java.util.Formatter}. - *

- * Code editors that support {@link Pattern} annotation will check - * the syntax of this value automatically. It could also be especially recognized to - * check whether the subsequent var-arg arguments match the expected arguments - * mentioned in the pattern. E. g., consider that the following method is annotated: - *


- * void myprintf(@PrintFormat String format, Object... args) {...}
- * 
- *

- * In this case, code editors might recognize that the following call is erroneous, - * and issue a warning: - *


- * myprintf("%d\n", "hello"); // warning: a number expected instead of "hello"
- * 
- * - * @see Pattern - */ -@Documented -@Pattern(PrintFormatPattern.PRINT_FORMAT) -public @interface PrintFormat { -} - -class PrintFormatPattern { - - // %[argument_index$][flags][width][.precision]conversion - - // Expression is taken from java.util.Formatter.fsPattern - - @Language("RegExp") - private static final String ARG_INDEX = "(?:\\d+\\$)?"; - @Language("RegExp") - private static final String FLAGS = "(?:[-#+ 0,(<]*)?"; - @Language("RegExp") - private static final String WIDTH = "(?:\\d+)?"; - @Language("RegExp") - private static final String PRECISION = "(?:\\.\\d+)?"; - @Language("RegExp") - private static final String CONVERSION = "(?:[tT])?(?:[a-zA-Z%])"; - @Language("RegExp") - private static final String TEXT = "[^%]|%%"; - - @Language("RegExp") - static final String PRINT_FORMAT = "(?:" + TEXT + "|" + - "(?:%" + - ARG_INDEX + - FLAGS + - WIDTH + - PRECISION + - CONVERSION + ")" + - ")*"; -} \ No newline at end of file diff --git a/multiplatform-module-info/build.gradle b/multiplatform-module-info/build.gradle deleted file mode 100644 index 75c0e99..0000000 --- a/multiplatform-module-info/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2000-2021 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -sourceCompatibility = 1.9 - -dependencies { - implementation project(':java-annotations') -} - -compileJava { - // Without common sources, compiler complains that exported packages don't exist - source = [sourceSets.main.java, project(':java-annotations').sourceSets.main.java] -} - -task mainJar(type: Jar) { -} - -javadoc.enabled = false diff --git a/settings.gradle b/settings.gradle index 79275d0..5c973a0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,6 +14,4 @@ * limitations under the License. */ -rootProject.name = 'annotations-parent' - -include 'java-annotations', 'java-module-info', 'multiplatform-annotations', 'multiplatform-module-info' \ No newline at end of file +rootProject.name = 'annotations' diff --git a/multiplatform-module-info/src/main/java/module-info.java b/src/commonMain/kotlin/org/intellij/lang/annotations/Identifier.kt similarity index 70% rename from multiplatform-module-info/src/main/java/module-info.java rename to src/commonMain/kotlin/org/intellij/lang/annotations/Identifier.kt index 70df97c..3195ba2 100644 --- a/multiplatform-module-info/src/main/java/module-info.java +++ b/src/commonMain/kotlin/org/intellij/lang/annotations/Identifier.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2020 JetBrains s.r.o. + * Copyright 2000-2021 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -module org.jetbrains.annotations.multiplatform { - requires static java.desktop; - exports org.intellij.lang.annotations; - exports org.jetbrains.annotations; -} \ No newline at end of file +package org.intellij.lang.annotations + +@Pattern("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*") +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Identifier() diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Language.kt b/src/commonMain/kotlin/org/intellij/lang/annotations/Language.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Language.kt rename to src/commonMain/kotlin/org/intellij/lang/annotations/Language.kt index 82eaf4c..b8c91cf 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Language.kt +++ b/src/commonMain/kotlin/org/intellij/lang/annotations/Language.kt @@ -47,7 +47,8 @@ import org.jetbrains.annotations.NonNls AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.ANNOTATION_CLASS ) -annotation class Language( +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Language( /** * Language name like "JAVA", "HTML", "XML", "RegExp", etc. * The complete list of supported languages is not specified. However, at least the following languages should be diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Pattern.kt b/src/commonMain/kotlin/org/intellij/lang/annotations/Pattern.kt similarity index 96% rename from multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Pattern.kt rename to src/commonMain/kotlin/org/intellij/lang/annotations/Pattern.kt index e8b6ac7..9b0e461 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Pattern.kt +++ b/src/commonMain/kotlin/org/intellij/lang/annotations/Pattern.kt @@ -49,7 +49,8 @@ import org.jetbrains.annotations.NonNls AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.ANNOTATION_CLASS ) -annotation class Pattern( +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Pattern( /** * A regular expression that matches all the valid string literals that assigned to the annotated variables, * passed as arguments to the annotated parameters, or returned from the annotated methods. diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/RegExp.kt b/src/commonMain/kotlin/org/intellij/lang/annotations/RegExp.kt similarity index 95% rename from multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/RegExp.kt rename to src/commonMain/kotlin/org/intellij/lang/annotations/RegExp.kt index ebf854f..10b4c1b 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/RegExp.kt +++ b/src/commonMain/kotlin/org/intellij/lang/annotations/RegExp.kt @@ -38,7 +38,8 @@ import org.jetbrains.annotations.NonNls AnnotationTarget.ANNOTATION_CLASS ) @Language("RegExp") -annotation class RegExp( +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class RegExp( /** * A constant prefix that is assumed to be implicitly added before the regular expression. */ diff --git a/src/commonMain/kotlin/org/intellij/lang/annotations/Subst.kt b/src/commonMain/kotlin/org/intellij/lang/annotations/Subst.kt new file mode 100644 index 0000000..62ac347 --- /dev/null +++ b/src/commonMain/kotlin/org/intellij/lang/annotations/Subst.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.intellij.lang.annotations + +/** + * Specifies the replacement value for non-constant variables and method return values. + * This may help static analyzers to properly parse the concatenation of several values + * which is used in @[Language] or [Pattern] context. + * + * + * Example: + *
+ * @Subst("Tahoma")
+ * final String font = new JLabel().getFont().getName();
+ *
+ * @Language("HTML")
+ * String message = "<html><span style='font: " + font + "; font-size:smaller'>"
+ * + ... + "</span></html>";
+
* + * + * + * Here the parser assumes that when `font` appears in the concatenation its value is `"Tahoma"`, + * so it can continue parsing the concatenation. + * + * + * @see Language + * + * @see Pattern + */ +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.VALUE_PARAMETER +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Subst(val value: String) diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/ApiStatus.kt b/src/commonMain/kotlin/org/jetbrains/annotations/ApiStatus.kt new file mode 100644 index 0000000..6ae5e94 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/ApiStatus.kt @@ -0,0 +1,224 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Set of annotations which can be used to specify status of API Element. + * + * @since 18.0.0 + */ +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect class ApiStatus private constructor() { + /** + * + * Indicates that a public API of the annotated element (class, method or field) is not in stable state yet. It may be renamed, changed or + * even removed in a future version. This annotation refers to API status only, it doesn't mean that the implementation has + * an 'experimental' quality. + * + * + * It's safe to use an element marked with this annotation if the usage is located in the same sources codebase as the declaration. However, + * if the declaration belongs to an external library such usages may lead to problems when the library will be updated to another version. + * + * + * If a package is marked with this annotation, all its containing classes are considered experimental. + * Subpackages of this package are not affected and should be marked independently. + * + * + * If a type is marked with this annotation, all its members are considered experimental, but its inheritors are not. + * + * + * If a method is marked with this annotation, overriding methods are not considered experimental. + */ + @MustBeDocumented + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.CLASS, + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.FILE + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class Experimental() + + /** + * Indicates that the annotated element (class, method, field, etc) must not be considered as a public API. It's made visible to allow + * usages in other packages of the declaring library, but it must not be used outside of that library. Such elements + * may be renamed, changed or removed in future versions. + * + * + * If a package is marked with this annotation, all its containing classes are considered internal. + * Subpackages of this package are not affected and should be marked independently. + * + * + * If a type is marked with this annotation, all its members are considered internal, but its inheritors are not. + * + * + * If a method is marked with this annotation, overriding methods are not considered internal. + */ + @MustBeDocumented + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.CLASS, + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.FILE + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class Internal() + + /** + * + * Indicates that a public API of the annotated element (class, method or field) is subject to deprecation in a future version. + * It's a weaker variant of [Deprecated] annotation. + * The annotated API is not supposed to be used in the new code because a better API exists, + * but it's permitted to postpone the migration of the existing code, therefore the usage is not considered a warning. + * + */ + @MustBeDocumented + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.CLASS, + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.FILE + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class Obsolete( + /** + * Specifies in which version the API became obsolete. + */ + val since: String = "" + ) + + /** + * + * Indicates that a public API of the annotated element (class, method or field) is subject to removal in a future version. + * It's a stronger variant of [Deprecated] annotation. + * + * + * Since many tools aren't aware of this annotation it should be used as an addition to `@Deprecated` annotation + * or `@deprecated` Javadoc tag only. + */ + @MustBeDocumented + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.CLASS, + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.FILE + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class ScheduledForRemoval( + /** + * Specifies in which version the API will be removed. + */ + val inVersion: String = "" + ) + + /** + * + * Indicates that the annotated element firstly appeared in the specified version of the library, so the code using that element + * won't be compatible with older versions of the library. This information may be used by IDEs and static analysis tools. + * This annotation can be used instead of '@since' Javadoc tag if it's needed to keep that information in *.class files or if you need + * to generate them automatically. + */ + @MustBeDocumented + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.CLASS, + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.FILE + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class AvailableSince( + /** + * Specifies a version where the annotation API firstly appeared. + */ + val value: String + ) + + /** + * + * Indicates that the annotated API class, interface or method **must not be extended, implemented or overridden**. + * + * + * API class, interface or method may not be marked `final` because it is extended by classes of the declaring library + * but it is not supposed to be extended outside the library. Instances of classes and interfaces marked with this annotation + * may be cast to an internal implementing class in the library code, leading to `ClassCastException` + * if a different implementation is provided by a client. + * + * + * New abstract methods may be added to such classes and interfaces in new versions of the library breaking compatibility + * with a client's implementations. + */ + @MustBeDocumented + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class NonExtendable() + + /** + * + * Indicates that the annotated method is part of SPI (Service Provider Interface), which is intended to be + * **only implemented or overridden** but not called by clients of the declaring library. + * If a class or interface is marked with this annotation it means that all its methods can be only overridden. + * + * + * Although there is a standard mechanism of `protected` methods, it is not applicable to interface's methods. + * Also, API method may be made `public` to allow calls only from different parts of the declaring library but not outside it. + * + * + * Signatures of such methods may be changed in new versions of the library in the following steps. Firstly, a method with new signature + * is added to the library delegating to the old method by default. Secondly, all clients implement the new method and remove + * implementations of the old one. This leads to compatibility breakage with code that calls the methods directly. + */ + @MustBeDocumented + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class OverrideOnly() +} \ No newline at end of file diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/Async.kt b/src/commonMain/kotlin/org/jetbrains/annotations/Async.kt new file mode 100644 index 0000000..720c4fb --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/Async.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Helper annotations for asynchronous computation. + * Used for example in IntelliJ IDEA's debugger for async stacktraces feature. + * + * @author egor + */ +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect class Async private constructor() { + /** + * Indicates that the marked method schedules async computation. + * Scheduled object is either `this`, or the annotated parameter value. + */ + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.VALUE_PARAMETER + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class Schedule() + + /** + * Indicates that the marked method executes async computation. + * Executed object is either `this`, or the annotated parameter value. + * This object needs to match with the one annotated with [Schedule] + */ + @Retention(AnnotationRetention.BINARY) + @Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.VALUE_PARAMETER + ) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + annotation class Execute() +} diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/Blocking.kt b/src/commonMain/kotlin/org/jetbrains/annotations/Blocking.kt new file mode 100644 index 0000000..10c77d2 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/Blocking.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Indicates that the annotated method is inherently blocking and should not be executed in a non-blocking context. + * + * + * When this annotation is used on a `class`, all the methods declared by the annotated class are considered + * *blocking*. + * + * + * Apart from documentation purposes this annotation is intended to be used by static analysis tools to validate against + * probable runtime errors and element contract violations. + * + * @since 22.0.0 + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.CLASS +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Blocking() diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt b/src/commonMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt new file mode 100644 index 0000000..1a72180 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Indicates that the annotated executor (CoroutineContext, Scheduler) + * allows blocking methods execution. + * + * + * If a given executor does not allow blocking calls, [NonBlockingExecutor] should be used. + * + * + * + * Example 1 (Kotlin coroutines): + *
`
+ * class BlockingExampleService {
+ * val dispatcher: @BlockingExecutor CoroutineContext
+ * get() { ... }
+ *
+ * suspend fun foo() {
+ * val result = withContext(dispatcher) {
+ * blockingBuzz() // no IDE warning
+ * }
+ * }
+ *
+ * @Blocking fun blockingBuzz() { ... }
+ * }
+`
* + * + * + * + * Example 2 (Java with Reactor framework): + *
`
+ * class BlockingExampleService {
+ * private static final @BlockingExecutor Scheduler blockingScheduler =
+ * Schedulers.newBoundedElastic(4, 10, "executor");
+ *
+ * public Flux foo(Flux urls) {
+ * return urls.publishOn(blockingScheduler)
+ * .map(url -> blockingBuzz(url));  // no IDE warning
+ * }
+ *
+ * @Blocking
+ * private String blockingBuzz(String url) { ... }
+ * }
+`
* + * + * @see Blocking + * + * @see NonBlocking + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class BlockingExecutor() diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt b/src/commonMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt new file mode 100644 index 0000000..8abec13 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt @@ -0,0 +1,42 @@ +package org.jetbrains.annotations + +/** + * Specifies that the method is impure and that its return value must be used. + * + * + * For pure methods (annotated with `@Contract(pure = true)`), + * it's implied that the resulting value is important, + * so this annotation would be redundant. + * + * + * Some impure methods have side effects and still require the return value to be used. + * For example, [java.io.InputStream.read] + * returns the number of bytes actually stored in the byte array. + * Without checking the return value, it's impossible to say how many bytes were actually read. + * + * + * This annotation should not be used if the return value of the method + * provides only *additional* information. + * For example, the main purpose of [java.util.Collection.add] + * is to modify the collection, and the return value is only interesting + * when adding an element to a set, to see if the set already contained that element before. + * + * + * When used on a type, the annotation applies to all methods that do not return `void`. + * + * + * When used on a package, the annotation applies to all types of that package. + * + * @see Contract.pure + */ +@MustBeDocumented +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.CLASS, + AnnotationTarget.FILE +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class CheckReturnValue() diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Contract.kt b/src/commonMain/kotlin/org/jetbrains/annotations/Contract.kt similarity index 98% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Contract.kt rename to src/commonMain/kotlin/org/jetbrains/annotations/Contract.kt index 978d28f..c5543aa 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Contract.kt +++ b/src/commonMain/kotlin/org/jetbrains/annotations/Contract.kt @@ -68,7 +68,8 @@ package org.jetbrains.annotations AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.CONSTRUCTOR ) -annotation class Contract( +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Contract( /** * Contains the contract clauses describing causal relations between call arguments and the returned value */ diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Debug.kt b/src/commonMain/kotlin/org/jetbrains/annotations/Debug.kt similarity index 92% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Debug.kt rename to src/commonMain/kotlin/org/jetbrains/annotations/Debug.kt index 911c6b4..340b580 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Debug.kt +++ b/src/commonMain/kotlin/org/jetbrains/annotations/Debug.kt @@ -20,19 +20,14 @@ import org.intellij.lang.annotations.Language /** * @since 18.0.0 */ -class Debug private constructor() { - /** - * Prohibited default constructor. - */ - init { - throw AssertionError("Debug should not be instantiated") - } - +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect class Debug private constructor() { /** * Allows to change the presentation of an object in debuggers */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration annotation class Renderer( /** * Expression to be evaluated and used as the textual representation of the object.

diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt b/src/commonMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt new file mode 100644 index 0000000..975f348 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * The annotation should be applied to overridable non-abstract method + * and indicates that all the overriders must invoke this method via + * superclass method invocation expression. The static analysis tools + * may report a warning if overrider fails to invoke this method. + * + * @since 20.0.0 + */ +@MustBeDocumented +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) +@Retention( + AnnotationRetention.BINARY +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class MustBeInvokedByOverriders() diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/Nls.kt b/src/commonMain/kotlin/org/jetbrains/annotations/Nls.kt new file mode 100644 index 0000000..168a559 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/Nls.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Specifies that an element of the program is a user-visible string which needs to be localized. + * This annotation is intended to be used by localization tools for + * detecting strings which should be reported as requiring localization. + * + * + * + * This annotation also could be used as a meta-annotation, to define derived annotations for convenience. + * E.g. the following annotation could be defined to annotate the strings that represent dialog titles: + * + *
+ * @Nls(capitalization = Capitalization.Title)
+ * @interface DialogTitle {}
+
* + * + * + * Note that using the derived annotation as meta-annotation is not supported. + * Meta-annotation works only one level deep. + * + * @see NonNls + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.CLASS, + AnnotationTarget.TYPE, + AnnotationTarget.FILE +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Nls(val capitalization: Capitalization = Capitalization.NotSpecified) { + @kotlin.jvm.ImplicitlyActualizedByJvmDeclaration + enum class Capitalization { + NotSpecified, + + /** + * e.g. This Is a Title + */ + Title, + + /** + * e.g. This is a sentence + */ + Sentence + } +} diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/NonBlocking.kt b/src/commonMain/kotlin/org/jetbrains/annotations/NonBlocking.kt new file mode 100644 index 0000000..4484d28 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/NonBlocking.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Indicates that the annotated method is inherently non-blocking and can be executed in a non-blocking context. + * + * + * When this annotation is used on a `class`, all the methods declared by the annotated class are considered + * *non-blocking*. + * + * + * Apart from documentation purposes this annotation is intended to be used by static analysis tools to validate against + * probable runtime errors and contract violations. + * + * @since 22.0.0 + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.CLASS +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class NonBlocking() diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt b/src/commonMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt new file mode 100644 index 0000000..59b4472 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Indicates that the annotated executor (CoroutineContext, Scheduler) + * does not allow blocking methods execution. + * + * + * + * If a given executor allows blocking calls, [BlockingExecutor] should be used. + * + * + * + * Example 1 (Kotlin coroutines): + *
`
+ * class NonBlockingExampleService {
+ * val dispatcher: @NonBlockingExecutor CoroutineContext
+ * get() { ... }
+ *
+ * suspend fun foo() {
+ * val result = withContext(dispatcher) {
+ * blockingBuzz() // IDE warning: `Possibly blocking call in non-blocking context`
+ * }
+ * }
+ *
+ * @Blocking fun blockingBuzz() { ... }
+ * }
+`
* + * + * + * + * Example 2 (Java with Reactor framework): + *
`
+ * class NonBlockingExampleService {
+ * private static final @NonBlockingExecutor Scheduler operationsScheduler =
+ * Schedulers.newParallel("parallel");
+ *
+ * public Flux foo(Flux urls) {
+ * return urls.publishOn(operationsScheduler)
+ * .filter(url -> blockingBuzz(url) != null);  // IDE warning: `Possibly blocking call in non-blocking context`
+ * }
+ *
+ * @Blocking
+ * private String blockingBuzz(String url) { ... }
+ * }
+`
* + * @see Blocking + * + * @see NonBlocking + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class NonBlockingExecutor() diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/NonNls.kt b/src/commonMain/kotlin/org/jetbrains/annotations/NonNls.kt new file mode 100644 index 0000000..7a66cc8 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/NonNls.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Specifies that an element of the program is not a user-visible string which needs to be localized, + * or does not contain such strings. This annotation is intended to be used by localization tools for + * detecting strings which should not be reported as requiring localization. + * + * * If a method parameter is annotated with `NonNls`, the strings passed + * as values of this parameter are not reported as requiring localization. + * Also, if the parameter of a property setter method is annotated with `NonNls`, values + * of that property in UI Designer forms are never highlighted as hard-coded strings. + * * If a field is annotated with `NonNls`, all string literals found in the + * initializer of the field are not reported as requiring localization. + * * If a method is called on a field, parameter or local variable annotated with `NonNls`, + * string literals passed as parameters to the method are not reported as requiring localization. + * * If a field, parameter or local variable annotated with `NonNls` is passed as a + * parameter to the `equals()` method invoked on a string literal, the literal is not + * reported as requiring localization. + * * If a field, parameter or local variable annotated with `NonNls` is found at + * the left side of an assignment expression, all string literals in the right side + * of the expression are not reported as requiring localization. + * * If a method is annotated with `NonNls`, string literals returned from the method + * are not reported as requiring localization. + * * If a class is annotated with `NonNls`, all string literals in + * the class and all its subclasses are not reported as requiring localization. + * * If a package is annotated with `NonNls`, all string literals in + * the package and all its subpackages are not reported as requiring localization. + * + * + * + * + * This annotation also could be used as a meta-annotation, to define derived annotations for convenience. + * E.g. the following annotation could be defined to annotate the strings that represent UUIDs, + * thus should not be localized: + * + *
+ * @NonNls
+ * @interface UUID {}
+
* + * + * + * Note that using the derived annotation as meta-annotation is not supported. + * Meta-annotation works only one level deep. + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.CLASS, + AnnotationTarget.TYPE, + AnnotationTarget.FILE +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class NonNls() diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/PropertyKey.kt b/src/commonMain/kotlin/org/jetbrains/annotations/PropertyKey.kt similarity index 95% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/PropertyKey.kt rename to src/commonMain/kotlin/org/jetbrains/annotations/PropertyKey.kt index 7d86045..796370e 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/PropertyKey.kt +++ b/src/commonMain/kotlin/org/jetbrains/annotations/PropertyKey.kt @@ -30,7 +30,8 @@ package org.jetbrains.annotations AnnotationTarget.FIELD, AnnotationTarget.TYPE, ) -annotation class PropertyKey( +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class PropertyKey( /** * The full-qualified name of the resource bundle in which the property keys must * be present. Consists of a full-qualified name of the package corresponding to the diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Range.kt b/src/commonMain/kotlin/org/jetbrains/annotations/Range.kt similarity index 94% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Range.kt rename to src/commonMain/kotlin/org/jetbrains/annotations/Range.kt index 64a2781..3d11088 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Range.kt +++ b/src/commonMain/kotlin/org/jetbrains/annotations/Range.kt @@ -30,7 +30,8 @@ package org.jetbrains.annotations @MustBeDocumented @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.TYPE) -annotation class Range( +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Range( /** * @return minimal allowed value (inclusive) */ diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/TestOnly.kt b/src/commonMain/kotlin/org/jetbrains/annotations/TestOnly.kt new file mode 100644 index 0000000..66da9c9 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/TestOnly.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * A member or type annotated with TestOnly claims that it should be used from testing code only. + * + * + * Apart from documentation purposes this annotation is intended to be used by static analysis tools + * to validate against element contract violations. + * + * + * This annotation means that the annotated element exposes internal data and breaks encapsulation + * of the containing class; the annotation won't prevent its use from production code, developers + * even won't see warnings if their IDE doesn't support the annotation. It's better to provide + * proper API which can be used in production as well as in tests. + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.CLASS +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class TestOnly() \ No newline at end of file diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt b/src/commonMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt new file mode 100644 index 0000000..23df008 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * An annotation which marks a [java.util.Collection] or [java.util.Map] type + * as unmodifiable. A collection or a map is unmodifiable if any mutator methods + * (e.g. [java.util.Collection.add]) throw exception or have no effect, + * and the object references stored as collection elements, map keys, and map values + * are never changed. The referenced objects themselves still could be changed if they + * are mutable. + * + * @see UnmodifiableView + * + * @since 19.0.0 + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.TYPE) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class Unmodifiable() \ No newline at end of file diff --git a/src/commonMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt b/src/commonMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt new file mode 100644 index 0000000..34d4cd7 --- /dev/null +++ b/src/commonMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * A member or type annotated with VisibleForTesting claims that its visibility is higher than necessary, + * only for testing purposes. In particular: + * + * * If public or protected member/type is annotated with VisibleForTesting, + * it's assumed that package-private access is enough for production code. + * * If package-private member/type is annotated with VisibleForTesting, + * it's assumed that private access is enough for production code. + * * It's illegal to annotate private member/type as VisibleForTesting. + * + * + * + * This annotation means that the annotated element exposes internal data and breaks encapsulation + * of the containing class; the annotation won't prevent its use from production code, developers + * even won't see warnings if their IDE doesn't support the annotation. It's better to provide + * proper API which can be used in production as well as in tests. + * + * @since 20.0.0 + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.CLASS +) +@kotlin.jvm.ImplicitlyActualizedByJvmDeclaration +expect annotation class VisibleForTesting() \ No newline at end of file diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/Flow.java b/src/jvmMain/java/org/intellij/lang/annotations/Flow.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/Flow.java rename to src/jvmMain/java/org/intellij/lang/annotations/Flow.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/Identifier.java b/src/jvmMain/java/org/intellij/lang/annotations/Identifier.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/Identifier.java rename to src/jvmMain/java/org/intellij/lang/annotations/Identifier.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/JdkConstants.java b/src/jvmMain/java/org/intellij/lang/annotations/JdkConstants.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/JdkConstants.java rename to src/jvmMain/java/org/intellij/lang/annotations/JdkConstants.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/Language.java b/src/jvmMain/java/org/intellij/lang/annotations/Language.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/Language.java rename to src/jvmMain/java/org/intellij/lang/annotations/Language.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/MagicConstant.java b/src/jvmMain/java/org/intellij/lang/annotations/MagicConstant.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/MagicConstant.java rename to src/jvmMain/java/org/intellij/lang/annotations/MagicConstant.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/Pattern.java b/src/jvmMain/java/org/intellij/lang/annotations/Pattern.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/Pattern.java rename to src/jvmMain/java/org/intellij/lang/annotations/Pattern.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/PrintFormat.java b/src/jvmMain/java/org/intellij/lang/annotations/PrintFormat.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/PrintFormat.java rename to src/jvmMain/java/org/intellij/lang/annotations/PrintFormat.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/RegExp.java b/src/jvmMain/java/org/intellij/lang/annotations/RegExp.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/RegExp.java rename to src/jvmMain/java/org/intellij/lang/annotations/RegExp.java diff --git a/java-annotations/src/main/java/org/intellij/lang/annotations/Subst.java b/src/jvmMain/java/org/intellij/lang/annotations/Subst.java similarity index 100% rename from java-annotations/src/main/java/org/intellij/lang/annotations/Subst.java rename to src/jvmMain/java/org/intellij/lang/annotations/Subst.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/ApiStatus.java b/src/jvmMain/java/org/jetbrains/annotations/ApiStatus.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/ApiStatus.java rename to src/jvmMain/java/org/jetbrains/annotations/ApiStatus.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Async.java b/src/jvmMain/java/org/jetbrains/annotations/Async.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Async.java rename to src/jvmMain/java/org/jetbrains/annotations/Async.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Blocking.java b/src/jvmMain/java/org/jetbrains/annotations/Blocking.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Blocking.java rename to src/jvmMain/java/org/jetbrains/annotations/Blocking.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/BlockingExecutor.java b/src/jvmMain/java/org/jetbrains/annotations/BlockingExecutor.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/BlockingExecutor.java rename to src/jvmMain/java/org/jetbrains/annotations/BlockingExecutor.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/CheckReturnValue.java b/src/jvmMain/java/org/jetbrains/annotations/CheckReturnValue.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/CheckReturnValue.java rename to src/jvmMain/java/org/jetbrains/annotations/CheckReturnValue.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Contract.java b/src/jvmMain/java/org/jetbrains/annotations/Contract.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Contract.java rename to src/jvmMain/java/org/jetbrains/annotations/Contract.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Debug.java b/src/jvmMain/java/org/jetbrains/annotations/Debug.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Debug.java rename to src/jvmMain/java/org/jetbrains/annotations/Debug.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/MustBeInvokedByOverriders.java b/src/jvmMain/java/org/jetbrains/annotations/MustBeInvokedByOverriders.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/MustBeInvokedByOverriders.java rename to src/jvmMain/java/org/jetbrains/annotations/MustBeInvokedByOverriders.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Nls.java b/src/jvmMain/java/org/jetbrains/annotations/Nls.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Nls.java rename to src/jvmMain/java/org/jetbrains/annotations/Nls.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/NonBlocking.java b/src/jvmMain/java/org/jetbrains/annotations/NonBlocking.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/NonBlocking.java rename to src/jvmMain/java/org/jetbrains/annotations/NonBlocking.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/NonBlockingExecutor.java b/src/jvmMain/java/org/jetbrains/annotations/NonBlockingExecutor.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/NonBlockingExecutor.java rename to src/jvmMain/java/org/jetbrains/annotations/NonBlockingExecutor.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/NonNls.java b/src/jvmMain/java/org/jetbrains/annotations/NonNls.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/NonNls.java rename to src/jvmMain/java/org/jetbrains/annotations/NonNls.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/NotNull.java b/src/jvmMain/java/org/jetbrains/annotations/NotNull.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/NotNull.java rename to src/jvmMain/java/org/jetbrains/annotations/NotNull.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Nullable.java b/src/jvmMain/java/org/jetbrains/annotations/Nullable.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Nullable.java rename to src/jvmMain/java/org/jetbrains/annotations/Nullable.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/PropertyKey.java b/src/jvmMain/java/org/jetbrains/annotations/PropertyKey.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/PropertyKey.java rename to src/jvmMain/java/org/jetbrains/annotations/PropertyKey.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Range.java b/src/jvmMain/java/org/jetbrains/annotations/Range.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Range.java rename to src/jvmMain/java/org/jetbrains/annotations/Range.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/TestOnly.java b/src/jvmMain/java/org/jetbrains/annotations/TestOnly.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/TestOnly.java rename to src/jvmMain/java/org/jetbrains/annotations/TestOnly.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/UnknownNullability.java b/src/jvmMain/java/org/jetbrains/annotations/UnknownNullability.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/UnknownNullability.java rename to src/jvmMain/java/org/jetbrains/annotations/UnknownNullability.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/Unmodifiable.java b/src/jvmMain/java/org/jetbrains/annotations/Unmodifiable.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/Unmodifiable.java rename to src/jvmMain/java/org/jetbrains/annotations/Unmodifiable.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/UnmodifiableView.java b/src/jvmMain/java/org/jetbrains/annotations/UnmodifiableView.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/UnmodifiableView.java rename to src/jvmMain/java/org/jetbrains/annotations/UnmodifiableView.java diff --git a/java-annotations/src/main/java/org/jetbrains/annotations/VisibleForTesting.java b/src/jvmMain/java/org/jetbrains/annotations/VisibleForTesting.java similarity index 100% rename from java-annotations/src/main/java/org/jetbrains/annotations/VisibleForTesting.java rename to src/jvmMain/java/org/jetbrains/annotations/VisibleForTesting.java diff --git a/java-module-info/src/main/java/module-info.java b/src/jvmMain/moduleInfo/module-info.java similarity index 100% rename from java-module-info/src/main/java/module-info.java rename to src/jvmMain/moduleInfo/module-info.java diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Identifier.kt b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Identifier.kt similarity index 95% rename from multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Identifier.kt rename to src/nonJvmMain/kotlin/org/intellij/lang/annotations/Identifier.kt index 70a48d6..ca0af40 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Identifier.kt +++ b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Identifier.kt @@ -16,4 +16,4 @@ package org.intellij.lang.annotations @Pattern("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*") -annotation class Identifier +actual annotation class Identifier diff --git a/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Language.kt b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Language.kt new file mode 100644 index 0000000..b36b271 --- /dev/null +++ b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Language.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.intellij.lang.annotations + +import org.jetbrains.annotations.NonNls + +/** + * Specifies that an element of the program represents a string that is a source code on a specified language. + * Code editors may use this annotation to enable syntax highlighting, code completion and other features + * inside the literals that assigned to the annotated variables, passed as arguments to the annotated parameters, + * or returned from the annotated methods. + * + * + * This annotation also could be used as a meta-annotation, to define derived annotations for convenience. + * E.g. the following annotation could be defined to annotate the strings that represent Java methods: + * + *
+ * @Language(value = "JAVA", prefix = "class X{", suffix = "}")
+ * @interface JavaMethod {}
+
* + * + * + * Note that using the derived annotation as meta-annotation is not supported. + * Meta-annotation works only one level deep. + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.ANNOTATION_CLASS +) +actual annotation class Language( + /** + * Language name like "JAVA", "HTML", "XML", "RegExp", etc. + * The complete list of supported languages is not specified. However, at least the following languages should be + * recognized: + * + * * "JAVA" - Java programming language + * * "HTML" - HTML + * * "XML" - XML + * * "RegExp" - Regular expression supported by Java [java.util.regex.Pattern] + * + */ + @get:NonNls actual val value: String, + /** + * A constant prefix that is assumed to be implicitly added before the literal. + * This helps to apply proper highlighting when the program element represents only a part of the valid program. + * E.g. if the method parameter accepts a Java method, it could be annotated as + * `void methodProcessor(@Language(value="JAVA", prefix="class X {", suffix="}")`. + */ + @get:NonNls actual val prefix: String = "", + /** + * A constant suffix that is assumed to be implicitly added after the literal. See [.prefix] for details. + */ + @get:NonNls actual val suffix: String = "" +) \ No newline at end of file diff --git a/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Pattern.kt b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Pattern.kt new file mode 100644 index 0000000..670cefd --- /dev/null +++ b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Pattern.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.intellij.lang.annotations + +import org.jetbrains.annotations.NonNls + +/** + * Specifies that an element of the program represents a string that must completely match given regular expression. + * Code editors may use this annotation to report errors if the literals that assigned to the annotated variables, + * passed as arguments to the annotated parameters, or returned from the annotated methods, do not match the supplied + * pattern. + * + * + * This annotation also could be used as a meta-annotation, to define other annotations for convenience. + * E.g. the following annotation could be defined to annotate the strings that represent UUIDs: + * + *
+ * @Pattern("[\\dA-Fa-f]{8}-[\\dA-Fa-f]{4}-[\\dA-Fa-f]{4}-[\\dA-Fa-f]{4}-[\\dA-Fa-f]{12}")
+ * @interface UUID {}
+
* + * + * + * Note that using the derived annotation as meta-annotation is not supported. + * Meta-annotation works only one level deep. + * + * @see RegExp + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.ANNOTATION_CLASS +) +actual annotation class Pattern( + /** + * A regular expression that matches all the valid string literals that assigned to the annotated variables, + * passed as arguments to the annotated parameters, or returned from the annotated methods. + */ + @get:Language("RegExp") @get:NonNls actual val value: String +) diff --git a/src/nonJvmMain/kotlin/org/intellij/lang/annotations/RegExp.kt b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/RegExp.kt new file mode 100644 index 0000000..dd2ac3a --- /dev/null +++ b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/RegExp.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.intellij.lang.annotations + +import org.jetbrains.annotations.NonNls + +/** + * Specifies that an element of the program represents a string that is a regular expression text supported + * by [java.util.regex.Pattern]. + * Code editors may use this annotation to enable syntax highlighting, code completion and other features + * inside the literals that assigned to the annotated variables, passed as arguments to the annotated parameters, + * or returned from the annotated methods. + * + * @see Language + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.ANNOTATION_CLASS +) +@Language("RegExp") +actual annotation class RegExp( + /** + * A constant prefix that is assumed to be implicitly added before the regular expression. + */ + @get:NonNls actual val prefix: String = "", + /** + * A constant suffix that is assumed to be implicitly added after the regular expression. + */ + @get:NonNls actual val suffix: String = "" +) diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Subst.kt b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Subst.kt similarity index 96% rename from multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Subst.kt rename to src/nonJvmMain/kotlin/org/intellij/lang/annotations/Subst.kt index 7770593..feaeb8d 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/intellij/lang/annotations/Subst.kt +++ b/src/nonJvmMain/kotlin/org/intellij/lang/annotations/Subst.kt @@ -49,4 +49,4 @@ package org.intellij.lang.annotations AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER ) -annotation class Subst(val value: String) +actual annotation class Subst(actual val value: String) diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/ApiStatus.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/ApiStatus.kt similarity index 94% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/ApiStatus.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/ApiStatus.kt index 7bd66aa..ec33881 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/ApiStatus.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/ApiStatus.kt @@ -20,7 +20,7 @@ package org.jetbrains.annotations * * @since 18.0.0 */ -class ApiStatus private constructor() { +actual class ApiStatus private actual constructor() { /** * Prohibited default constructor. */ @@ -60,7 +60,7 @@ class ApiStatus private constructor() { AnnotationTarget.FIELD, AnnotationTarget.FILE ) - annotation class Experimental + actual annotation class Experimental /** * Indicates that the annotated element (class, method, field, etc) must not be considered as a public API. It's made visible to allow @@ -89,7 +89,7 @@ class ApiStatus private constructor() { AnnotationTarget.FIELD, AnnotationTarget.FILE ) - annotation class Internal + actual annotation class Internal /** * @@ -111,11 +111,11 @@ class ApiStatus private constructor() { AnnotationTarget.FIELD, AnnotationTarget.FILE ) - annotation class Obsolete( + actual annotation class Obsolete( /** * Specifies in which version the API became obsolete. */ - val since: String = "" + actual val since: String = "" ) /** @@ -139,11 +139,11 @@ class ApiStatus private constructor() { AnnotationTarget.FIELD, AnnotationTarget.FILE ) - annotation class ScheduledForRemoval( + actual annotation class ScheduledForRemoval( /** * Specifies in which version the API will be removed. */ - val inVersion: String = "" + actual val inVersion: String = "" ) /** @@ -165,11 +165,11 @@ class ApiStatus private constructor() { AnnotationTarget.FIELD, AnnotationTarget.FILE ) - annotation class AvailableSince( + actual annotation class AvailableSince( /** * Specifies a version where the annotation API firstly appeared. */ - val value: String + actual val value: String ) /** @@ -194,7 +194,7 @@ class ApiStatus private constructor() { AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER ) - annotation class NonExtendable + actual annotation class NonExtendable /** * @@ -219,5 +219,5 @@ class ApiStatus private constructor() { AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER ) - annotation class OverrideOnly + actual annotation class OverrideOnly } \ No newline at end of file diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Async.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Async.kt similarity index 93% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Async.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/Async.kt index f7cc1ae..d4105da 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Async.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Async.kt @@ -21,7 +21,7 @@ package org.jetbrains.annotations * * @author egor */ -class Async private constructor() { +actual class Async private actual constructor() { /** * Prohibited default constructor. */ @@ -41,7 +41,7 @@ class Async private constructor() { AnnotationTarget.CONSTRUCTOR, AnnotationTarget.VALUE_PARAMETER ) - annotation class Schedule + actual annotation class Schedule /** * Indicates that the marked method executes async computation. @@ -56,5 +56,5 @@ class Async private constructor() { AnnotationTarget.CONSTRUCTOR, AnnotationTarget.VALUE_PARAMETER ) - annotation class Execute + actual annotation class Execute } diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Blocking.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Blocking.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Blocking.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/Blocking.kt index 626dadf..75df61a 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Blocking.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Blocking.kt @@ -37,4 +37,4 @@ package org.jetbrains.annotations AnnotationTarget.CONSTRUCTOR, AnnotationTarget.CLASS ) -annotation class Blocking +actual annotation class Blocking diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt index 1419ea9..70235b6 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/BlockingExecutor.kt @@ -65,4 +65,4 @@ package org.jetbrains.annotations @MustBeDocumented @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) -annotation class BlockingExecutor +actual annotation class BlockingExecutor diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt index 9a2d2b8..5f5d0a4 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/CheckReturnValue.kt @@ -38,4 +38,4 @@ package org.jetbrains.annotations AnnotationTarget.CLASS, AnnotationTarget.FILE ) -annotation class CheckReturnValue +actual annotation class CheckReturnValue diff --git a/src/nonJvmMain/kotlin/org/jetbrains/annotations/Contract.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Contract.kt new file mode 100644 index 0000000..a35289a --- /dev/null +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Contract.kt @@ -0,0 +1,113 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Specifies some aspects of the method behavior depending on the arguments. Can be used by tools for advanced data flow analysis. + * Note that this annotation just describes how the code works and doesn't add any functionality by means of code generation. + * + * + * + * Method contract has the following syntax:

+ *
`contract ::= (clause ';')* clause
+ * clause ::= args '->' effect
+ * args ::= ((arg ',')* arg )?
+ * arg ::= value-constraint
+ * value-constraint ::= '_' | 'null' | '!null' | 'false' | 'true'
+ * effect ::= value-constraint | 'fail' | 'this' | 'new' | 'param'`
+ * + * + * + * The constraints denote the following:

+ * + * * _ - any value + * * null - null value + * * !null - a value statically proved to be not-null + * * true - true boolean value + * * false - false boolean value + * + * + * The additional return values denote the following:

+ * + * * fail - the method throws an exception, if the arguments satisfy argument constraints + * * new - (supported in IntelliJ IDEA since version 2018.2) the method returns a non-null new object which is distinct from any other object existing in the heap prior to method execution. If method is also pure, then we can be sure that the new object is not stored to any field/array and will be lost if method return value is not used. + * * this - (supported in IntelliJ IDEA since version 2018.2) the method returns its qualifier value (not applicable for static methods) + * * param1, param2, ... - (supported in IntelliJ IDEA since version 2018.2) the method returns its first (second, ...) parameter value + * + * Examples: + * + * + * `@Contract("_, null -> null")` - the method returns null if its second argument is null

+ * `@Contract("_, null -> null; _, !null -> !null")` - the method returns null if its second argument is null and not-null otherwise

+ * `@Contract("true -> fail")` - a typical `assertFalse` method which throws an exception if `true` is passed to it

+ * `@Contract("_ -> this")` - the method always returns its qualifier (e.g. [StringBuilder.append]).

+ * `@Contract("null -> fail; _ -> param1")` - the method throws an exception if the first argument is null, + * otherwise it returns the first argument (e.g. `Objects.requireNonNull`).

+ * `@Contract("!null, _ -> param1; null, !null -> param2; null, null -> fail")` - the method returns the first non-null argument, + * or throws an exception if both arguments are null (e.g. `Objects.requireNonNullElse` in Java 9).

+ * + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.CONSTRUCTOR +) +actual annotation class Contract( + /** + * Contains the contract clauses describing causal relations between call arguments and the returned value + */ + @get:NonNls actual val value: String = "", + /** + * Specifies that the annotated method has no visible side effects. + * If its return value is not used, removing its invocation won't + * affect program state and change the semantics, unless method call throws an exception. + * Exception throwing is not considered to be a side effect. + * + * + * Method should not be marked as pure if it does not produce a side-effect by itself, + * but it could be used to establish a happens-before relation between an event in + * another thread, so changes performed in another thread might become visible in current thread + * after this method invocation. Examples of such methods are [Object.wait], [Thread.join] + * or [AtomicBoolean.get]. On the other hand, some synchronized methods like [java.util.Vector.get] + * could be marked as pure, because the purpose of synchronization here is to keep the collection internal integrity + * rather than to wait for an event in another thread. + * + * + * "Invisible" side effects (such as logging) that don't affect the "important" program semantics are allowed.



+ * + * + * This annotation may be used for more precise data flow analysis, and + * to check that the method's return value is actually used in the call place. + */ + actual val pure: Boolean = false, + /** + * Contains a specifier which describes which method parameters can be mutated during the method call. + * + * + * + * + * + * +
Possible values:
"this"Method mutates the receiver object, and doesn't mutates any objects passed as arguments (cannot be applied for static method or constructor)
"param"Method mutates the sole argument and doesn't mutate the receiver object (if applicable)
"param1", "param2", ...Method mutates the N-th argument
"this,param1"Method mutates the receiver and first argument and doesn't mutate any other arguments
* + * + * **Warning: This annotation parameter is experimental and may be changed or removed without further notice!** + * @return a mutation specifier string + */ + @get:ApiStatus.Experimental @get:NonNls actual val mutates: String = "" +) diff --git a/src/nonJvmMain/kotlin/org/jetbrains/annotations/Debug.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Debug.kt new file mode 100644 index 0000000..82b7f97 --- /dev/null +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Debug.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +import org.intellij.lang.annotations.Language + +/** + * @since 18.0.0 + */ +actual class Debug private actual constructor() { + /** + * Prohibited default constructor. + */ + init { + throw AssertionError("Debug should not be instantiated") + } + + /** + * Allows to change the presentation of an object in debuggers + */ + @Target(AnnotationTarget.CLASS) + @Retention(AnnotationRetention.BINARY) + actual annotation class Renderer( + /** + * Expression to be evaluated and used as the textual representation of the object.

+ * `this` refers to the class instance being presented + */ + @get:Language( + value = "JAVA", + prefix = "class Renderer{String \$text(){return ", + suffix = ";}}" + ) @get:NonNls actual val text: String = "", + /** + * Expression to be evaluated to obtain an array of object's children.

+ * Usually the result is an array of elements in a collection, or an array of entries in a map.

+ * `this` refers to the class instance being presented + */ + @get:Language( + value = "JAVA", + prefix = "class Renderer{Object[] \$childrenArray(){return ", + suffix = ";}}" + ) @get:NonNls actual val childrenArray: String = "", + /** + * Expression to be evaluated to check if the object has any children at all.

+ * This should work faster than [.childrenArray] and return boolean.

+ * `this` refers to the class instance being presented + */ + @get:Language( + value = "JAVA", + prefix = "class Renderer{boolean \$hasChildren(){return ", + suffix = ";}}" + ) @get:NonNls actual val hasChildren: String = "" + ) +} diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt similarity index 95% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt index 89e7dfe..d6719f2 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/MustBeInvokedByOverriders.kt @@ -28,4 +28,4 @@ package org.jetbrains.annotations @Retention( AnnotationRetention.BINARY ) -annotation class MustBeInvokedByOverriders +actual annotation class MustBeInvokedByOverriders diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Nls.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Nls.kt similarity index 93% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Nls.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/Nls.kt index ba004c5..8885ca2 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Nls.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Nls.kt @@ -49,8 +49,8 @@ package org.jetbrains.annotations AnnotationTarget.TYPE, AnnotationTarget.FILE ) -annotation class Nls(val capitalization: Capitalization = Capitalization.NotSpecified) { - enum class Capitalization { +actual annotation class Nls(actual val capitalization: Capitalization = Capitalization.NotSpecified) { + actual enum class Capitalization { NotSpecified, /** diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonBlocking.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/NonBlocking.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonBlocking.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/NonBlocking.kt index 303c4a4..81b8ea1 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonBlocking.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/NonBlocking.kt @@ -37,4 +37,4 @@ package org.jetbrains.annotations AnnotationTarget.CONSTRUCTOR, AnnotationTarget.CLASS ) -annotation class NonBlocking +actual annotation class NonBlocking diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt index a103c99..293719d 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/NonBlockingExecutor.kt @@ -65,4 +65,4 @@ package org.jetbrains.annotations @MustBeDocumented @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) -annotation class NonBlockingExecutor +actual annotation class NonBlockingExecutor diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonNls.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/NonNls.kt similarity index 99% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonNls.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/NonNls.kt index 7228bba..55f81cc 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/NonNls.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/NonNls.kt @@ -70,4 +70,4 @@ package org.jetbrains.annotations AnnotationTarget.TYPE, AnnotationTarget.FILE ) -annotation class NonNls +actual annotation class NonNls diff --git a/src/nonJvmMain/kotlin/org/jetbrains/annotations/PropertyKey.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/PropertyKey.kt new file mode 100644 index 0000000..a081b8e --- /dev/null +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/PropertyKey.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * Specifies that a method parameter, local variable, field or a method return value + * must be a valid property key in a specific resource bundle. When a string literal + * which is not a property key in the specified bundle is passed as a parameter, + * static analyzers may highlight it as an error. The annotation is also could be used + * by IDEs to provide completion in string literals passed as parameters. + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.FIELD, + AnnotationTarget.TYPE, +) +actual annotation class PropertyKey( + /** + * The full-qualified name of the resource bundle in which the property keys must + * be present. Consists of a full-qualified name of the package corresponding to the + * directory where the resource bundle is located and the base name of the resource + * bundle (with no locale specifier or extension), separated with a dot. + */ + @get:NonNls actual val resourceBundle: String +) diff --git a/src/nonJvmMain/kotlin/org/jetbrains/annotations/Range.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Range.kt new file mode 100644 index 0000000..e2bc96a --- /dev/null +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Range.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2021 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.annotations + +/** + * An annotation which allows to specify for integral type (byte, char, short, int, long) an allowed values range. + * Applying this annotation to other types is not correct. + * + * + * Example: + *
`public @Range(from = 0, to = Integer.MAX_VALUE) int length() {
+ * return this.length; // returns a non-negative integer
+ * }`
+ * + * @since 17.0.0 + */ +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.TYPE) +actual annotation class Range( + /** + * @return minimal allowed value (inclusive) + */ + actual val from: Long, + /** + * @return maximal allowed value (inclusive) + */ + actual val to: Long +) \ No newline at end of file diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/TestOnly.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/TestOnly.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/TestOnly.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/TestOnly.kt index a3e16fb..585c64f 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/TestOnly.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/TestOnly.kt @@ -38,4 +38,4 @@ package org.jetbrains.annotations AnnotationTarget.FIELD, AnnotationTarget.CLASS ) -annotation class TestOnly \ No newline at end of file +actual annotation class TestOnly \ No newline at end of file diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt index dae1bdb..d1a2baa 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/Unmodifiable.kt @@ -30,4 +30,4 @@ package org.jetbrains.annotations @MustBeDocumented @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.TYPE) -annotation class Unmodifiable \ No newline at end of file +actual annotation class Unmodifiable \ No newline at end of file diff --git a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt b/src/nonJvmMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt similarity index 97% rename from multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt rename to src/nonJvmMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt index 068dc78..ce49dd5 100644 --- a/multiplatform-annotations/src/commonMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt +++ b/src/nonJvmMain/kotlin/org/jetbrains/annotations/VisibleForTesting.kt @@ -44,4 +44,4 @@ package org.jetbrains.annotations AnnotationTarget.FIELD, AnnotationTarget.CLASS ) -annotation class VisibleForTesting \ No newline at end of file +actual annotation class VisibleForTesting \ No newline at end of file