Compare commits

..

5 Commits

Author SHA1 Message Date
Igor Chevdar
de840b7e70 [IR][cache] Fix for https://youtrack.jetbrains.com/issue/KT-44764
The .konanLibrary is cached for each declaration for performance purposes, but it is only ok to do it
after IR has been lowered to its final state (or at least when declarations aren't being moved around),
so the fix respects that by only taking .konanLibrary of a IrFile (it is assumed that files stay on their place
during entire backend lowering procedure).

(cherry picked from commit e021138368b48e306ba99a96f47d93ecbe039f4d)
2021-03-15 10:35:33 +01:00
Alexander Udalov
99bf2c48a1 Fix/suppress some warnings
(cherry picked from commit d8a43c216925b3a9e1475b786978436835a57927)
2021-03-15 10:35:10 +01:00
Igor Chevdar
2d88f0cd79 Disposed target data
(cherry picked from commit 250be87acf66d5c780fb593f46da3540a536e049)
2021-03-15 10:20:27 +01:00
Vladimir Ivanov
842dbb9006 Add test for [KT-3706]
Issue is already fixed by metadata-based cinterop

(cherry picked from commit fd4f5b2c07ebdc431d6243ac087f911ee30e88ca)
2021-03-15 10:18:29 +01:00
Vladimir Ivanov
6594fac213 Fix sample file naming for case-sensitive FS
(cherry picked from commit 72235c31852fba4f2ab330d8178197c2584b1cda)
2021-03-15 10:16:20 +01:00
1536 changed files with 8694 additions and 70781 deletions

2
.gitignore vendored
View File

@@ -32,8 +32,6 @@ build/
.idea/modules
.idea/runConfigurations/JPS_*.xml
.idea/runConfigurations/PILL_*.xml
.idea/runConfigurations/_FP_*.xml
.idea/runConfigurations/_MT_*.xml
.idea/libraries
.idea/modules.xml
.idea/gradle.xml

View File

@@ -1,8 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="sebastiansellmair">
<words>
<w>cinterops</w>
<w>interops</w>
</words>
</dictionary>
</component>

View File

@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Generate Compiler Tests" type="GradleRunConfiguration" factoryName="Gradle">
<configuration default="false" name="Generate Compiler Tests" type="GradleRunConfiguration" factoryName="Gradle" folderName="Generators">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$/compiler" />

View File

@@ -106,8 +106,6 @@ To reproduce TeamCity build use `-Pteamcity=true` flag. Local builds don't run p
**OPTIONAL:** Some artifacts, mainly Maven plugin ones, are built separately with Maven.
Refer to [libraries/ReadMe.md](libraries/ReadMe.md) for details.
To build Kotlin/Native, see
[kotlin-native/README.md](kotlin-native/README.md#building-from-source).
### Building for different versions of IntelliJ IDEA and Android Studio
@@ -147,6 +145,28 @@ From this root project there are Run/Debug Configurations for running `IDEA` or
* Run the `IDEA` run configuration in the project
* A child IntelliJ IDEA with the Kotlin plugin will then startup
### Including into composite build
To include kotlin compiler into [composite build](https://docs.gradle.org/current/userguide/composite_builds.html) you need to define `dependencySubstitution` for `kotlin-compiler` module in `settings.gradle.kts`
```Kotlin
includeBuild("/path/to/kotlin") {
dependencySubstitution {
substitute(module("org.jetbrains.kotlin:kotlin-compiler"))
.with(project(":include:kotlin-compiler"))
}
}
```
or in `settings.gradle`
```Groovy
includeBuild('/path/to/kotlin') {
dependencySubstitution {
substitute module('org.jetbrains.kotlin:kotlin-compiler') with project(':include:kotlin-compiler')
}
}
```
# License
Kotlin is distributed under the terms of the Apache License (Version 2.0). See [license folder](license/README.md) for details.

View File

@@ -27,7 +27,7 @@ buildscript {
dependencies {
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
classpath(kotlin("serialization", bootstrapKotlinVersion))
classpath("org.jetbrains.dokka:dokka-gradle-plugin:0.9.17")
@@ -159,7 +159,6 @@ rootProject.apply {
from(rootProject.file("gradle/checkArtifacts.gradle.kts"))
from(rootProject.file("gradle/checkCacheability.gradle.kts"))
from(rootProject.file("gradle/retryPublishing.gradle.kts"))
from(rootProject.file("gradle/modularizedTestConfigurations.gradle.kts"))
}
IdeVersionConfigurator.setCurrentIde(project)

View File

@@ -11,8 +11,10 @@ buildscript {
repositories {
if (cacheRedirectorEnabled) {
maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com")
maven("https://cache-redirector.jetbrains.com/maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
} else {
jcenter()
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
}
@@ -22,7 +24,7 @@ buildscript {
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${project.bootstrapKotlinVersion}")
}
@@ -82,9 +84,10 @@ extra["versions.androidDxSources"] = "5.0.0_r2"
extra["customDepsOrg"] = "kotlin.build"
repositories {
mavenCentral()
jcenter()
maven("https://jetbrains.bintray.com/intellij-third-party-dependencies/")
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
maven("https://kotlin.bintray.com/kotlinx")
gradlePluginPortal()
extra["bootstrapKotlinRepo"]?.let {
@@ -144,8 +147,8 @@ java {
dependencies {
implementation(kotlin("stdlib", embeddedKotlinVersion))
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
implementation("com.gradle.publish:plugin-publish-plugin:0.13.0")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
implementation("com.gradle.publish:plugin-publish-plugin:0.12.0")
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
implementation("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")

View File

@@ -20,7 +20,7 @@ buildscript {
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
}
}

View File

@@ -10,16 +10,31 @@ import java.io.File
import org.gradle.api.Project
open class PillExtension {
/*
* Here's how you can specify a custom variant:
* `./gradlew pill -Dpill.variant=<NAME>`
*/
enum class Variant {
BASE, // Includes compiler and IDE (default)
FULL, // Includes compiler, IDE and Gradle plugin
// Default variant (./gradlew pill)
BASE() {
override val includes = setOf(BASE)
},
// Full variant (./gradlew pill -Dpill.variant=full)
FULL() {
override val includes = setOf(BASE, FULL)
},
// Do not import the project to JPS model, but set some options for it
NONE() {
override val includes = emptySet<Variant>()
},
// 'BASE' if the "jps-compatible" plugin is applied, 'NONE' otherwise
DEFAULT() {
override val includes = emptySet<Variant>()
};
abstract val includes: Set<Variant>
}
open var variant: Variant? = null
open var variant: Variant = Variant.DEFAULT
open var excludedDirs: List<File> = emptyList()
@@ -30,7 +45,7 @@ open class PillExtension {
@Suppress("unused")
fun serialize() = mapOf<String, Any?>(
"variant" to variant?.name,
"variant" to variant.name,
"excludedDirs" to excludedDirs
)
}

View File

@@ -46,7 +46,6 @@ val kotlinGradlePluginAndItsRequired = arrayOf(
":kotlin-gradle-subplugin-example",
":kotlin-stdlib-common",
":kotlin-stdlib",
":kotlin-stdlib-jdk7",
":kotlin-stdlib-jdk8",
":kotlin-stdlib-js",
":examples:annotation-processor-example",

View File

@@ -52,14 +52,13 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.getMappingFileName;
public class ClassFileFactory implements OutputFileCollection {
private final GenerationState state;
private final ClassBuilderFactory builderFactory;
private final Map<String, OutAndSourceFileList> generators = Collections.synchronizedMap(new LinkedHashMap<>());
private final Map<String, OutAndSourceFileList> generators = new LinkedHashMap<>();
private boolean isDone = false;
@@ -347,9 +346,7 @@ public class ClassFileFactory implements OutputFileCollection {
@Override
public byte[] asBytes(ClassBuilderFactory factory) {
synchronized(this) {
return factory.asBytes(classBuilder);
}
return factory.asBytes(classBuilder);
}
@Override

View File

@@ -9,16 +9,15 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.utils.threadLocal
import java.util.*
class GlobalInlineContext(private val diagnostics: DiagnosticSink) {
// Ordered set of declarations and inline calls being generated right now.
// No call in it should point to a declaration that's before it in the stack.
private val inlineCallsAndDeclarations by threadLocal { LinkedList<Any? /* CallableDescriptor | PsiElement? */>() }
private val inlineDeclarationSet by threadLocal { mutableSetOf<CallableDescriptor>() }
private val inlineCallsAndDeclarations = LinkedList<Any? /* CallableDescriptor | PsiElement? */>()
private val inlineDeclarationSet = mutableSetOf<CallableDescriptor>()
private val typesUsedInInlineFunctions by threadLocal { LinkedList<MutableSet<String>>() }
private val typesUsedInInlineFunctions = LinkedList<MutableSet<String>>()
fun enterDeclaration(descriptor: CallableDescriptor) {
assert(descriptor.original !in inlineDeclarationSet) { "entered inlining cycle on $descriptor" }

View File

@@ -28,14 +28,12 @@ class InlineCache {
}
inline fun <K, V : Any> SLRUMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
synchronized(this) {
val value = get(key)
return if (value == null) {
val answer = defaultValue()
put(key, answer)
answer
} else {
value
}
val value = get(key)
return if (value == null) {
val answer = defaultValue()
put(key, answer)
answer
} else {
value
}
}

View File

@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.codegen.inline
import com.intellij.psi.PsiElement
import com.intellij.util.ArrayUtil
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
@@ -598,6 +599,14 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
return (directMember as? ImportedFromObjectCallableDescriptor<*>)?.callableFromObject ?: directMember
}
private fun cloneMethodNode(methodNode: MethodNode): MethodNode {
methodNode.instructions.resetLabels()
return MethodNode(
Opcodes.API_VERSION, methodNode.access, methodNode.name, methodNode.desc, methodNode.signature,
ArrayUtil.toStringArray(methodNode.exceptions)
).also(methodNode::accept)
}
private fun doCreateMethodNodeFromCompiled(
callableDescriptor: CallableMemberDescriptor,
state: GenerationState,

View File

@@ -625,13 +625,3 @@ fun MethodNode.preprocessSuspendMarkers(forInline: Boolean, keepFakeContinuation
}
}
}
fun cloneMethodNode(methodNode: MethodNode): MethodNode {
synchronized(methodNode) {
methodNode.instructions.resetLabels()
return MethodNode(
Opcodes.API_VERSION, methodNode.access, methodNode.name, methodNode.desc, methodNode.signature,
methodNode.exceptions.toTypedArray()
).also(methodNode::accept)
}
}

View File

@@ -57,8 +57,6 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
override fun onUseAsTainted() {
hazard = true
}
fun canRewrite() = !hazard && initCallInsn != null
}
private class Transformer(private val internalClassName: String, private val methodNode: MethodNode) {
@@ -74,7 +72,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
assignLocalVars(frames)
for (refValue in refValues) {
if (refValue.canRewrite()) {
if (!refValue.hazard) {
rewriteRefValue(refValue)
}
}

View File

@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import java.util.concurrent.ConcurrentHashMap
class BuilderFactoryForDuplicateClassNameDiagnostics(
@@ -30,7 +29,7 @@ class BuilderFactoryForDuplicateClassNameDiagnostics(
private val diagnostics: DiagnosticSink
) : ClassNameCollectionClassBuilderFactory(builderFactory) {
private val className = ConcurrentHashMap<String, JvmDeclarationOrigin>()
private val className = hashMapOf<String, JvmDeclarationOrigin> ()
override fun handleClashingNames(internalName: String, origin: JvmDeclarationOrigin) {
val another = className.getOrPut(internalName, { origin })

View File

@@ -49,6 +49,7 @@ dependencies {
testCompile(projectTests(":compiler:fir:raw-fir:light-tree2fir"))
testCompile(projectTests(":compiler:fir:fir2ir"))
testCompile(projectTests(":compiler:fir:analysis-tests:legacy-fir-tests"))
testCompile(projectTests(":compiler:visualizer"))
testCompile(projectTests(":generators:test-generator"))
testCompile(project(":compiler:ir.ir2cfg"))
testCompile(project(":compiler:ir.tree")) // used for deepCopyWithSymbols call that is removed by proguard from the compiler TODO: make it more straightforward

View File

@@ -42,8 +42,6 @@ found top-level declarations to <destination dir> (*.kotlin_builtins files)"""
assert(missing.isEmpty()) { "These source directories are missing: $missing" }
BuiltInsSerializer(dependOnOldBuiltIns = false).serialize(destDir, srcDirs, listOf()) { totalSize, totalFiles ->
if (System.getProperty("kotlin.builtins.serializer.log") == "true") {
println("Total bytes written: $totalSize to $totalFiles files")
}
println("Total bytes written: $totalSize to $totalFiles files")
}
}

View File

@@ -74,7 +74,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
@Argument(
value = "-jvm-target",
valueDescription = "<version>",
description = "Target version of the generated JVM bytecode (1.6 (DEPRECATED), 1.8, 9, 10, 11, 12, 13, 14, 15 or 16), default is 1.8"
description = "Target version of the generated JVM bytecode (1.6 (DEPRECATED), 1.8, 9, 10, 11, 12, 13, 14 or 15), default is 1.8"
)
var jvmTarget: String? by NullableStringFreezableVar(JvmTarget.DEFAULT.description)
@@ -84,12 +84,8 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
// Advanced options
@DeprecatedOption(removeAfter = "1.5", level = DeprecationLevel.WARNING)
@GradleOption(DefaultValues.BooleanFalseDefault::class)
@Argument(
value = "-Xuse-ir",
description = "Use the IR backend. This option has no effect unless the language version less than 1.5 is used"
)
@Argument(value = "-Xuse-ir", description = "Use the IR backend")
var useIR: Boolean by FreezableVar(false)
@GradleOption(DefaultValues.BooleanFalseDefault::class)
@@ -493,7 +489,6 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise""
result[JvmAnalysisFlags.enableJvmPreview] = enableJvmPreview
result[AnalysisFlags.allowUnstableDependencies] = allowUnstableDependencies || useFir
result[JvmAnalysisFlags.disableUltraLightClasses] = disableUltraLightClasses
result[JvmAnalysisFlags.useIR] = useIR
return result
}

View File

@@ -13,7 +13,6 @@ import com.intellij.psi.search.PsiSearchScopeUtil
import com.intellij.util.SmartList
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.components.FilesByFacadeFqNameIndexer
@@ -110,7 +109,7 @@ class CliKotlinAsJavaSupport(
}
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? =
KtLightClassForSourceDeclaration.create(classOrObject, traceHolder.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode))
KtLightClassForSourceDeclaration.create(classOrObject)
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? =
KtLightClassForScript.create(script)

View File

@@ -283,7 +283,7 @@ class KotlinCoreEnvironment private constructor(
fun addKotlinSourceRoots(rootDirs: List<File>) {
val roots = rootDirs.map { KotlinSourceRoot(it.absolutePath, isCommon = false) }
sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots).toSet() - sourceFiles
sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots)
}
fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider {

View File

@@ -33,9 +33,6 @@ object JvmAnalysisFlags {
@JvmStatic
val enableJvmPreview by AnalysisFlag.Delegates.Boolean
@JvmStatic
val useIR by AnalysisFlag.Delegates.Boolean
private object Delegates {
object JavaTypeEnhancementStateWarnByDefault {
operator fun provideDelegate(instance: Any?, property: KProperty<*>): AnalysisFlag.Delegate<JavaTypeEnhancementState> =

View File

@@ -32,7 +32,6 @@ enum class JvmTarget(
JVM_13("13", Opcodes.V12 + 1),
JVM_14("14", Opcodes.V12 + 2),
JVM_15("15", Opcodes.V12 + 3),
JVM_16("16", Opcodes.V12 + 4),
;
companion object {

View File

@@ -750,11 +750,6 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
}
@TestMetadata("twoLocalLambdasWithSameName.kt")
public void testTwoLocalLambdasWithSameName() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/twoLocalLambdasWithSameName.kt");
}
@TestMetadata("typeAliasWithNotNullBound.kt")
public void testTypeAliasWithNotNullBound() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/typeAliasWithNotNullBound.kt");

View File

@@ -3,9 +3,9 @@
}
public open class NonNullNever : R|kotlin/Any| {
@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) public open field field: R|kotlin/String?|
@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) public open field field: R|@EnhancedNullability kotlin/String?|
@R|MyNullable|() public open fun foo(@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) x: R|kotlin/String?|, @R|MyNullable|() y: R|kotlin/CharSequence?|): R|kotlin/String?|
@R|MyNullable|() public open fun foo(@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) x: R|@EnhancedNullability kotlin/String?|, @R|MyNullable|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String?|
public constructor(): R|NonNullNever|

View File

@@ -1,7 +1,7 @@
public open class Simple : R|kotlin/Any| {
@R|javax/annotation/Nullable|() public open field field: R|kotlin/String?|
@R|javax/annotation/Nullable|() public open field field: R|@EnhancedNullability kotlin/String?|
@R|javax/annotation/Nullable|() public open fun foo(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|kotlin/CharSequence?|): R|kotlin/String?|
@R|javax/annotation/Nullable|() public open fun foo(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String?|
@R|javax/annotation/Nonnull|() public open fun bar(): R|@EnhancedNullability kotlin/String|

View File

@@ -1,7 +1,7 @@
public open class Strange : R|kotlin/Any| {
@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) public open field field: R|ft<kotlin/String, kotlin/String?>|
@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) public open fun foo(@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.ALWAYS|()) x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) y: R|kotlin/CharSequence?|): R|kotlin/String?|
@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) public open fun foo(@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.ALWAYS|()) x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) y: R|@EnhancedNullability kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String?|
@R|javax/annotation/Nonnull|() public open fun bar(): R|@EnhancedNullability kotlin/String|

View File

@@ -1,9 +1,9 @@
@R|FieldsAreNullable|() public open class A : R|kotlin/Any| {
public open field field: R|kotlin/String?|
public open field field: R|@EnhancedNullability kotlin/String?|
@R|javax/annotation/Nonnull|() public open field nonNullField: R|@EnhancedNullability kotlin/String|
public open fun foo(q: R|ft<kotlin/String, kotlin/String?>|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
public open fun foo(q: R|ft<kotlin/String, kotlin/String?>|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
@R|javax/annotation/Nonnull|() public open fun bar(): R|@EnhancedNullability kotlin/String|

View File

@@ -1,5 +1,5 @@
@R|spr/NonNullApi|() public open class A : R|kotlin/Any| {
public open fun foo(x: R|@EnhancedNullability kotlin/String|, @R|spr/Nullable|() y: R|kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String|
public open fun foo(x: R|@EnhancedNullability kotlin/String|, @R|spr/Nullable|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String|
@R|spr/ForceFlexibility|() public open fun bar(x: R|ft<kotlin/String, kotlin/String?>|, @R|javax/annotation/Nonnull|() y: R|@EnhancedNullability kotlin/CharSequence|): R|ft<kotlin/String, kotlin/String?>|

View File

@@ -5,9 +5,9 @@
public open fun foo3(x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/String|
@R|javax/annotation/Nullable|() public open fun bar1(@R|javax/annotation/Nullable|() x: R|kotlin/String?|): R|kotlin/String?|
@R|javax/annotation/Nullable|() public open fun bar1(@R|javax/annotation/Nullable|() x: R|@EnhancedNullability kotlin/String?|): R|@EnhancedNullability kotlin/String?|
@R|javax/annotation/Nullable|() public open fun bar2(@R|javax/annotation/Nullable|() x: R|kotlin/String?|): R|kotlin/String?|
@R|javax/annotation/Nullable|() public open fun bar2(@R|javax/annotation/Nullable|() x: R|@EnhancedNullability kotlin/String?|): R|@EnhancedNullability kotlin/String?|
public open fun baz(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/String|
@@ -21,9 +21,9 @@
public abstract fun foo3(x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/CharSequence|
@R|javax/annotation/Nullable|() public abstract fun bar1(@R|javax/annotation/Nullable|() x: R|kotlin/String?|): R|kotlin/CharSequence?|
@R|javax/annotation/Nullable|() public abstract fun bar1(@R|javax/annotation/Nullable|() x: R|@EnhancedNullability kotlin/String?|): R|@EnhancedNullability kotlin/CharSequence?|
@R|javax/annotation/Nullable|() public abstract fun bar2(@R|javax/annotation/Nullable|() x: R|kotlin/String?|): R|kotlin/CharSequence?|
@R|javax/annotation/Nullable|() public abstract fun bar2(@R|javax/annotation/Nullable|() x: R|@EnhancedNullability kotlin/String?|): R|@EnhancedNullability kotlin/CharSequence?|
public abstract fun baz(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/CharSequence|
@@ -33,7 +33,7 @@
@R|javax/annotation/Nonnull|() public open fun foo2(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/String|
public open fun bar1(x: R|kotlin/String?|): R|kotlin/String?|
public open fun bar1(x: R|@EnhancedNullability kotlin/String?|): R|@EnhancedNullability kotlin/String?|
public open fun baz(x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/String|
@@ -45,9 +45,9 @@
public open fun foo2(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/String|
public open fun bar1(x: R|kotlin/String?|): R|kotlin/String?|
public open fun bar1(x: R|@EnhancedNullability kotlin/String?|): R|@EnhancedNullability kotlin/String?|
@R|javax/annotation/Nullable|() public open fun bar2(@R|javax/annotation/Nullable|() x: R|kotlin/String?|): R|kotlin/String?|
@R|javax/annotation/Nullable|() public open fun bar2(@R|javax/annotation/Nullable|() x: R|@EnhancedNullability kotlin/String?|): R|@EnhancedNullability kotlin/String?|
public open fun baz(x: R|@EnhancedNullability kotlin/String|): R|@EnhancedNullability kotlin/String|

View File

@@ -1,13 +1,13 @@
@R|NonNullApi|() public open class A : R|kotlin/Any| {
public open field field: R|@EnhancedNullability kotlin/String|
public open fun foo(x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String|
public open fun foo(x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String|
@R|NullableApi|() public open fun foobar(x: R|kotlin/String?|, @R|NonNullApi|() y: R|@EnhancedNullability kotlin/CharSequence|): R|kotlin/String?|
@R|NullableApi|() public open fun foobar(x: R|@EnhancedNullability kotlin/String?|, @R|NonNullApi|() y: R|@EnhancedNullability kotlin/CharSequence|): R|@EnhancedNullability kotlin/String?|
public open fun bar(): R|@EnhancedNullability kotlin/String|
@R|javax/annotation/Nullable|() public open fun baz(): R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|
@R|javax/annotation/Nullable|() public open fun baz(): R|ft<@EnhancedNullability kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, @EnhancedNullability kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|
public constructor(): R|A|

View File

@@ -1,7 +1,7 @@
@R|javax/annotation/ParametersAreNonnullByDefault|() public open class A : R|kotlin/Any| {
@R|javax/annotation/Nullable|() public open field field: R|kotlin/String?|
@R|javax/annotation/Nullable|() public open field field: R|@EnhancedNullability kotlin/String?|
public open fun foo(q: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
public open fun foo(q: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
@R|javax/annotation/Nonnull|() public open fun bar(): R|@EnhancedNullability kotlin/String|

View File

@@ -1,7 +1,7 @@
public open class A : R|kotlin/Any| {
@R|javax/annotation/Nullable|() public open field field: R|kotlin/String?|
@R|javax/annotation/Nullable|() public open field field: R|@EnhancedNullability kotlin/String?|
public open fun foo(q: R|ft<kotlin/String, kotlin/String?>|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
public open fun foo(q: R|ft<kotlin/String, kotlin/String?>|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
@R|javax/annotation/Nonnull|() public open fun bar(): R|@EnhancedNullability kotlin/String|
@@ -9,9 +9,9 @@ public open class A : R|kotlin/Any| {
}
public open class A2 : R|kotlin/Any| {
@R|javax/annotation/Nullable|() public open field field: R|kotlin/String?|
@R|javax/annotation/Nullable|() public open field field: R|@EnhancedNullability kotlin/String?|
public open fun foo(q: R|ft<kotlin/String, kotlin/String?>|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
public open fun foo(q: R|ft<kotlin/String, kotlin/String?>|, @R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|, @R|javax/annotation/CheckForNull|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
@R|javax/annotation/Nonnull|() public open fun bar(): R|@EnhancedNullability kotlin/String|

View File

@@ -1,11 +1,11 @@
@R|spr/NonNullApi|() public open class A : R|kotlin/Any| {
public open field field: R|ft<kotlin/String, kotlin/String?>|
public open fun foo(x: R|@EnhancedNullability kotlin/String|, @R|spr/Nullable|() y: R|kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String|
public open fun foo(x: R|@EnhancedNullability kotlin/String|, @R|spr/Nullable|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|@EnhancedNullability kotlin/String|
public open fun bar(): R|@EnhancedNullability kotlin/String|
@R|spr/Nullable|() public open fun baz(): R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|
@R|spr/Nullable|() public open fun baz(): R|ft<@EnhancedNullability kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, @EnhancedNullability kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|
public constructor(): R|A|

View File

@@ -1,11 +1,11 @@
public open class A : R|kotlin/Any| {
public open field field: R|ft<kotlin/String, kotlin/String?>|
public open fun foo(x: R|ft<kotlin/String, kotlin/String?>|, @R|spr/Nullable|() y: R|kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
public open fun foo(x: R|ft<kotlin/String, kotlin/String?>|, @R|spr/Nullable|() y: R|@EnhancedNullability kotlin/CharSequence?|): R|ft<kotlin/String, kotlin/String?>|
public open fun bar(): R|ft<kotlin/String, kotlin/String?>|
@R|spr/Nullable|() public open fun baz(): R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|
@R|spr/Nullable|() public open fun baz(): R|ft<@EnhancedNullability kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>>?, @EnhancedNullability kotlin/collections/List<ft<kotlin/String, kotlin/String?>>?>|
public constructor(): R|test/A|

View File

@@ -1,19 +0,0 @@
FILE: twoLocalLambdasWithSameName.kt
public abstract interface R : R|kotlin/Any| {
}
public final fun takeInt(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun test(fn: R|R.() -> kotlin/String|): R|kotlin/Unit| {
lval renderer: R|<anonymous>| = object : R|R| {
private constructor(): R|<anonymous>| {
super<R|kotlin/Any|>()
}
public final fun render(fn: R|R.() -> kotlin/Int|): R|kotlin/Unit| {
lval result: R|kotlin/Int| = R|<local>/fn|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Int|>|(this@R|/<anonymous>|)
R|/takeInt|(R|<local>/result|)
}
}
}

View File

@@ -1,13 +0,0 @@
// ISSUE: KT-45316
interface R
fun takeInt(x: Int) {}
fun test(fn: R.() -> String) { // (1)
val renderer = object : R {
fun render(fn: R.() -> Int) { // (2)
val result = fn()
takeInt(result)
}
}
}

View File

@@ -9,7 +9,7 @@ FILE: annotationArgumentKClassLiteralTypeError.kt
}
public final val <reified T> R|T|.test: R|kotlin/Any|
public inline get(): R|<anonymous><T>| {
public get(): R|<anonymous><T>| {
^ @R|Ann|(<implicitArrayOf>(<getClass>(R|T|), <getClass>(Q|kotlin/Array|))) object : R|kotlin/Any| {
private constructor(): R|<anonymous><T>| {
super<R|kotlin/Any|>()

View File

@@ -11,7 +11,7 @@ FILE: nullableIntegerLiteralType.kt
}
}
<Inapplicable(MAY_THROW_RUNTIME_ERROR): /takeInt>#(R|<local>/x|)
<Inapplicable(INAPPLICABLE): /takeInt>#(R|<local>/x|)
}
public final fun test_2(b: R|kotlin/Boolean|, y: R|kotlin/Int|): R|kotlin/Unit| {
lval x: R|kotlin/Int?| = when () {
@@ -23,5 +23,5 @@ FILE: nullableIntegerLiteralType.kt
}
}
<Inapplicable(MAY_THROW_RUNTIME_ERROR): /takeInt>#(R|<local>/x|)
<Inapplicable(INAPPLICABLE): /takeInt>#(R|<local>/x|)
}

View File

@@ -21,6 +21,6 @@ FILE: main.kt
}
public final fun test_1(b: R|B<kotlin/Int>|, x: R|kotlin/Int|, inv: R|Inv<kotlin/Int>|): R|kotlin/Unit| {
R|<local>/b|.R|SubstitutionOverride</B.take: R|kotlin/String|>|(R|<local>/x|)
R|<local>/b|.<Inapplicable(MAY_THROW_RUNTIME_ERROR): /B.take>#(Null(null))
R|<local>/b|.<Inapplicable(INAPPLICABLE): /B.take>#(Null(null))
R|<local>/b|.R|SubstitutionOverride</B.takeInv: R|kotlin/String|>|(R|<local>/inv|)
}

View File

@@ -11,8 +11,8 @@ fun Any?.isNotNull(): Boolean {
@OptIn(ExperimentalContracts::class)
val Any?.isNotNull: Boolean
get() {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (this@isNotNull != null)
}
}<!>
return this@isNotNull != null
}

View File

@@ -6,16 +6,16 @@ interface A {
var Any?.isNotNull: Boolean
get() {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns(true) implies (this@isNotNull != null)
}
}<!>
return this != null
}
set(value) {
contract {
<!WRONG_IMPLIES_CONDITION!>contract {
returns() implies (this@isNotNull != null)
require(this != null)
}
}<!>
}
fun test_1(a: A?) {

View File

@@ -869,12 +869,6 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
}
@Test
@TestMetadata("twoLocalLambdasWithSameName.kt")
public void testTwoLocalLambdasWithSameName() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/twoLocalLambdasWithSameName.kt");
}
@Test
@TestMetadata("typeAliasWithNotNullBound.kt")
public void testTypeAliasWithNotNullBound() throws Exception {

View File

@@ -876,12 +876,6 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
}
@Test
@TestMetadata("twoLocalLambdasWithSameName.kt")
public void testTwoLocalLambdasWithSameName() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/twoLocalLambdasWithSameName.kt");
}
@Test
@TestMetadata("typeAliasWithNotNullBound.kt")
public void testTypeAliasWithNotNullBound() throws Exception {

View File

@@ -2091,12 +2091,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/backingField/kt782packageLevel.kt");
}
@Test
@TestMetadata("LocalDeclarations.kt")
public void testLocalDeclarations() throws Exception {
runTest("compiler/testData/diagnostics/tests/backingField/LocalDeclarations.kt");
}
@Test
@TestMetadata("SetterWithExplicitType.kt")
public void testSetterWithExplicitType() throws Exception {
@@ -10084,6 +10078,28 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/functionLiterals/return/unresolvedReferenceInReturnBlock.kt");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/functionLiterals/suspend")
@TestDataPath("$PROJECT_ROOT")
public class Suspend {
@Test
public void testAllFilesPresentInSuspend() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/functionLiterals/suspend"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("disabled.kt")
public void testDisabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/suspend/disabled.kt");
}
@Test
@TestMetadata("enabled.kt")
public void testEnabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/suspend/enabled.kt");
}
}
}
@Nested
@@ -12558,12 +12574,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/starProjectionRegression.kt");
}
@Test
@TestMetadata("substituteCapturedTypesWithTypeVariables.kt")
public void testSubstituteCapturedTypesWithTypeVariables() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/substituteCapturedTypesWithTypeVariables.kt");
}
@Test
@TestMetadata("topLevelCapturingInsideReturnType.kt")
public void testTopLevelCapturingInsideReturnType() throws Exception {
@@ -25735,12 +25745,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/smartCasts/threeImplicitReceivers.kt");
}
@Test
@TestMetadata("throwInTry.kt")
public void testThrowInTry() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/throwInTry.kt");
}
@Test
@TestMetadata("twoImplicitReceivers.kt")
public void testTwoImplicitReceivers() throws Exception {
@@ -29587,6 +29591,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/unsignedTypes/unsignedLiteralsInsideConstVals.kt");
}
@Test
@TestMetadata("unsignedLiteralsOn1_2.kt")
public void testUnsignedLiteralsOn1_2() throws Exception {
runTest("compiler/testData/diagnostics/tests/unsignedTypes/unsignedLiteralsOn1_2.kt");
}
@Test
@TestMetadata("unsignedLiteralsOverflowSignedBorder.kt")
public void testUnsignedLiteralsOverflowSignedBorder() throws Exception {
@@ -33603,6 +33613,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalOnWholeModule.kt");
}
@Test
@TestMetadata("experimentalUnsignedLiterals.kt")
public void testExperimentalUnsignedLiterals() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalUnsignedLiterals.kt");
}
@Test
@TestMetadata("fullFqNameUsage.kt")
public void testFullFqNameUsage() throws Exception {

View File

@@ -160,10 +160,6 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
parameter<KtModifierKeywordToken>("modifier2")
}
val REDUNDANT_OPEN_IN_INTERFACE by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.OPEN_MODIFIER)
val WRONG_MODIFIER_TARGET by error<FirSourceElement, PsiElement> {
parameter<KtModifierKeywordToken>("modifier")
parameter<String>("target")
}
}
val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") {
@@ -235,6 +231,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier")
}
val NO_TYPE_FOR_TYPE_PARAMETER by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_OBJECT by error<FirSourceElement, PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error<FirSourceElement, PsiElement>()
@@ -248,24 +245,11 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val TYPE_PARAMETER_IN_CATCH_CLAUSE by error<FirSourceElement, PsiElement>()
val GENERIC_THROWABLE_SUBCLASS by error<FirSourceElement, KtTypeParameterList>()
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error<FirSourceElement, KtClassOrObject>(PositioningStrategy.DECLARATION_NAME)
val KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirTypeParameterSymbol>("typeParameter")
}
val TYPE_PARAMETER_AS_REIFIED by error<FirSourceElement, PsiElement> {
parameter<FirTypeParameterSymbol>("typeParameter")
}
}
val REFLECTION by object : DiagnosticGroup("Reflection") {
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
val CLASS_LITERAL_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error<FirSourceElement, KtExpression>()
val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error<FirSourceElement, PsiElement> {
parameter<ConeKotlinType>("lhsType")
}
}
val OVERRIDES by object : DiagnosticGroup("overrides") {
@@ -357,7 +341,6 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val FORBIDDEN_VARARG_PARAMETER_TYPE by error<FirSourceElement, KtParameter>(PositioningStrategy.PARAMETER_VARARG_MODIFIER) {
parameter<ConeKotlinType>("varargParameterType")
}
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error<FirSourceElement, KtParameter>()
}
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
@@ -427,12 +410,6 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val VAL_REASSIGNMENT by error<FirSourceElement, KtExpression> {
parameter<FirPropertySymbol>("variable")
}
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning<FirSourceElement, KtExpression> {
parameter<FirPropertySymbol>("variable")
}
val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error<FirSourceElement, KtExpression> {
parameter<FirPropertySymbol>("variable")
}
val WRONG_INVOCATION_KIND by warning<FirSourceElement, PsiElement> {
parameter<AbstractFirBasedSymbol<*>>("declaration")
parameter<EventOccurrencesRange>("requiredRange")
@@ -471,15 +448,6 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val INVALID_IF_AS_EXPRESSION by error<FirSourceElement, KtIfExpression>(PositioningStrategy.IF_EXPRESSION)
}
val CONTEXT_TRACKING by object : DiagnosticGroup("Context tracking") {
val TYPE_PARAMETER_IS_NOT_AN_EXPRESSION by error<FirSourceElement, KtSimpleNameExpression> {
parameter<FirTypeParameterSymbol>("typeParameter")
}
val TYPE_PARAMETER_ON_LHS_OF_DOT by error<FirSourceElement, KtSimpleNameExpression> {
parameter<FirTypeParameterSymbol>("typeParameter")
}
}
val FUNCTION_CONTRACTS by object : DiagnosticGroup("Function contracts") {
val ERROR_IN_CONTRACT_DESCRIPTION by error<FirSourceElement, KtElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
parameter<String>("reason")

View File

@@ -145,7 +145,6 @@ object FirErrors {
val DEPRECATED_MODIFIER_PAIR by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
val INCOMPATIBLE_MODIFIERS by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
val REDUNDANT_OPEN_IN_INTERFACE by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.OPEN_MODIFIER)
val WRONG_MODIFIER_TARGET by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, String>()
// Inline classes
val INLINE_CLASS_NOT_TOP_LEVEL by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
@@ -183,6 +182,7 @@ object FirErrors {
val UPPER_BOUND_VIOLATED by error2<FirSourceElement, PsiElement, FirTypeParameterSymbol, ConeKotlinType>()
val TYPE_ARGUMENTS_NOT_ALLOWED by error0<FirSourceElement, PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<FirSourceElement, PsiElement, Int, FirClassLikeSymbol<*>>()
val NO_TYPE_FOR_TYPE_PARAMETER by error0<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_OBJECT by error0<FirSourceElement, PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error0<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error0<FirSourceElement, PsiElement>()
@@ -193,14 +193,10 @@ object FirErrors {
val TYPE_PARAMETER_IN_CATCH_CLAUSE by error0<FirSourceElement, PsiElement>()
val GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtTypeParameterList>()
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtClassOrObject>(SourceElementPositioningStrategies.DECLARATION_NAME)
val KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE by error1<FirSourceElement, KtNamedDeclaration, FirTypeParameterSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
val TYPE_PARAMETER_AS_REIFIED by error1<FirSourceElement, PsiElement, FirTypeParameterSymbol>()
// Reflection
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error0<FirSourceElement, KtExpression>()
val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error1<FirSourceElement, PsiElement, ConeKotlinType>()
// overrides
val NOTHING_TO_OVERRIDE by error1<FirSourceElement, KtModifierListOwner, FirMemberDeclaration>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
@@ -235,7 +231,6 @@ object FirErrors {
val USELESS_VARARG_ON_PARAMETER by warning0<FirSourceElement, KtParameter>()
val MULTIPLE_VARARG_PARAMETERS by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
val FORBIDDEN_VARARG_PARAMETER_TYPE by error1<FirSourceElement, KtParameter, ConeKotlinType>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error0<FirSourceElement, KtParameter>()
// Properties & accessors
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
@@ -275,8 +270,6 @@ object FirErrors {
// Control flow diagnostics
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, KtSimpleNameExpression, FirPropertySymbol>()
val VAL_REASSIGNMENT by error1<FirSourceElement, KtExpression, FirPropertySymbol>()
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning1<FirSourceElement, KtExpression, FirPropertySymbol>()
val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error1<FirSourceElement, KtExpression, FirPropertySymbol>()
val WRONG_INVOCATION_KIND by warning3<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>, EventOccurrencesRange, EventOccurrencesRange>()
val LEAKED_IN_PLACE_LAMBDA by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>()
val WRONG_IMPLIES_CONDITION by warning0<FirSourceElement, PsiElement>()
@@ -291,10 +284,6 @@ object FirErrors {
val NO_ELSE_IN_WHEN by error1<FirSourceElement, KtWhenExpression, List<WhenMissingCase>>(SourceElementPositioningStrategies.WHEN_EXPRESSION)
val INVALID_IF_AS_EXPRESSION by error0<FirSourceElement, KtIfExpression>(SourceElementPositioningStrategies.IF_EXPRESSION)
// Context tracking
val TYPE_PARAMETER_IS_NOT_AN_EXPRESSION by error1<FirSourceElement, KtSimpleNameExpression, FirTypeParameterSymbol>()
val TYPE_PARAMETER_ON_LHS_OF_DOT by error1<FirSourceElement, KtSimpleNameExpression, FirTypeParameterSymbol>()
// Function contracts
val ERROR_IN_CONTRACT_DESCRIPTION by error1<FirSourceElement, KtElement, String>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)

View File

@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.contracts.coneEffects
import org.jetbrains.kotlin.fir.contracts.description.*
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.resolve.dfa.*
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.BlockExitNode
@@ -24,7 +23,6 @@ import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.JumpNode
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneType
@@ -63,7 +61,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
effects.forEach { effect ->
val wrongCondition = graph.exitNode.previousCfgNodes.any {
isWrongConditionOnNode(it, effect as ConeConditionalEffectDeclaration, function, logicSystem, dataFlowInfo, context)
isWrongConditionOnNode(it, effect as ConeConditionalEffectDeclaration, function, logicSystem, dataFlowInfo)
}
if (wrongCondition) {
@@ -79,8 +77,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
effectDeclaration: ConeConditionalEffectDeclaration,
function: FirFunction<*>,
logicSystem: LogicSystem<PersistentFlow>,
dataFlowInfo: DataFlowInfo,
context: CheckerContext
dataFlowInfo: DataFlowInfo
): Boolean {
val effect = effectDeclaration.effect as ConeReturnsEffectDeclaration
val builtinTypes = function.session.builtinTypes
@@ -95,7 +92,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
if (isReturn && resultExpression is FirWhenExpression) {
return node.collectBranchExits().any {
isWrongConditionOnNode(it, effectDeclaration, function, logicSystem, dataFlowInfo, context)
isWrongConditionOnNode(it, effectDeclaration, function, logicSystem, dataFlowInfo)
}
}
@@ -113,16 +110,15 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
}
}
val conditionStatements = effectDeclaration.condition.buildTypeStatements(
function, logicSystem, dataFlowInfo.variableStorage, flow, context
) ?: return false
val conditionStatements =
effectDeclaration.condition.buildTypeStatements(function, logicSystem, dataFlowInfo.variableStorage, flow) ?: return false
for ((realVar, requiredTypeStatement) in conditionStatements) {
val fixedRealVar = typeStatements.keys.find { it.identifier == realVar.identifier } ?: realVar
val resultTypeStatement = typeStatements[fixedRealVar]
val resultType = mutableListOf<ConeKotlinType>().apply {
addIfNotNull(function.getParameterType(fixedRealVar.identifier.symbol, context))
addIfNotNull(function.getParameterType(fixedRealVar.identifier.symbol))
if (resultTypeStatement != null) addAll(resultTypeStatement.exactType)
}.let { typeContext.intersectTypesOrNull(it) }
@@ -158,12 +154,11 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
function: FirFunction<*>,
logicSystem: LogicSystem<*>,
variableStorage: VariableStorage,
flow: Flow,
context: CheckerContext
flow: Flow
): MutableTypeStatements? = when (this) {
is ConeBinaryLogicExpression -> {
val left = left.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
val right = right.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
val left = left.buildTypeStatements(function, logicSystem, variableStorage, flow)
val right = right.buildTypeStatements(function, logicSystem, variableStorage, flow)
if (left != null && right != null) {
if (kind == LogicOperationKind.AND) {
left.apply { mergeTypeStatements(right) }
@@ -171,16 +166,16 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
} else (left ?: right)
}
is ConeIsInstancePredicate -> {
val fir = function.getParameterSymbol(arg.parameterIndex, context).fir
val fir = function.getParameterSymbol(arg.parameterIndex).fir
val realVar = variableStorage.getOrCreateRealVariable(flow, fir.symbol, fir)
realVar?.to(simpleTypeStatement(realVar, !isNegated, type))?.let { mutableMapOf(it) }
}
is ConeIsNullPredicate -> {
val fir = function.getParameterSymbol(arg.parameterIndex, context).fir
val fir = function.getParameterSymbol(arg.parameterIndex).fir
val realVar = variableStorage.getOrCreateRealVariable(flow, fir.symbol, fir)
realVar?.to(simpleTypeStatement(realVar, isNegated, function.session.builtinTypes.anyType.type))?.let { mutableMapOf(it) }
}
is ConeLogicalNot -> arg.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
is ConeLogicalNot -> arg.buildTypeStatements(function, logicSystem, variableStorage, flow)
?.mapValuesTo(mutableMapOf()) { (_, value) -> value.invert() }
else -> null
@@ -217,31 +212,11 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
return nodes
}
private val CheckerContext.containingProperty: FirProperty?
get() = (containingDeclarations.asReversed().firstOrNull { it is FirProperty } as? FirProperty)
private fun FirFunction<*>.getParameterType(symbol: AbstractFirBasedSymbol<*>, context: CheckerContext): ConeKotlinType? {
val typeRef = if (this.symbol == symbol) {
if (symbol is FirPropertyAccessorSymbol) {
context.containingProperty?.receiverTypeRef
} else {
receiverTypeRef
}
} else {
valueParameters.find { it.symbol == symbol }?.returnTypeRef
}
return typeRef?.coneType
private fun FirFunction<*>.getParameterType(symbol: AbstractFirBasedSymbol<*>): ConeKotlinType? {
return (if (this.symbol == symbol) receiverTypeRef else valueParameters.find { it.symbol == symbol }?.returnTypeRef)?.coneType
}
private fun FirFunction<*>.getParameterSymbol(index: Int, context: CheckerContext): AbstractFirBasedSymbol<*> {
return if (index == -1) {
if (symbol !is FirPropertyAccessorSymbol) {
symbol
} else {
context.containingProperty?.symbol ?: symbol
}
} else {
this.valueParameters[index].symbol
}
private fun FirFunction<*>.getParameterSymbol(index: Int): AbstractFirBasedSymbol<*> {
return if (index == -1) this.symbol else this.valueParameters[index].symbol
}
}

View File

@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.fir.analysis.cfa
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentMapOf
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.EdgeLabel
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.NormalPath
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.TryExpressionExitNode
abstract class PathAwareControlFlowInfo<P : PathAwareControlFlowInfo<P, S>, S : ControlFlowInfo<S, *, *>>(
map: PersistentMap<EdgeLabel, S>,
@@ -40,24 +43,11 @@ abstract class PathAwareControlFlowInfo<P : PathAwareControlFlowInfo<P, S>, S :
val hasAbnormalLabels = map.keys.any { !it.isNormal }
return if (hasAbnormalLabels) {
// { |-> ..., l1 |-> I1, l2 |-> I2, ... }
// { |-> ... l1 |-> I1, l2 |-> I2, ... }
// | l1 // path exit: if the given info has non-null labels, this acts like a filtering
// { |-> I1 } // NB: remove the path label, except for uncaught exception path
// { |-> I1 } // NB: remove the path info
if (map.keys.contains(label)) {
if (label == UncaughtExceptionPath) {
// Special case: uncaught exception path, which still represents an uncaught exception path
// Target node is most likely fun/init exit, and we should keep info separated.
constructor(persistentMapOf(label to map[label]!!))
} else {
// { |-> I }
// | l1 // e.g., enter to proxy1 with l1
// { l1 -> I }
// ...
// { |-> ..., l1 -> I', ... }
// | l1 // e.g., exit proxy1 with l1
// { l1 -> I' }
constructor(persistentMapOf(NormalPath to map[label]!!))
}
constructor(persistentMapOf(NormalPath to map[label]!!))
} else {
/* This means no info for the specific label. */
empty()

View File

@@ -127,7 +127,7 @@ fun ConeKotlinType.toRegularClass(session: FirSession): FirRegularClass? {
return safeAs<ConeClassLikeType>()?.fullyExpandedType(session)?.toRegularClass(session)
}
fun ConeKotlinType.isInline(session: FirSession): Boolean = toRegularClass(session)?.isInline == true
fun ConeKotlinType.isInline(session: FirSession) : Boolean = toRegularClass(session)?.isInline == true
/**
* Returns the FirRegularClass associated with this
@@ -143,7 +143,7 @@ fun FirTypeRef.toRegularClass(session: FirSession): FirRegularClass? {
inline fun <reified T : Any> FirQualifiedAccessExpression.getDeclaration(): T? {
return this.calleeReference.safeAs<FirResolvedNamedReference>()
?.resolvedSymbol
?.fir.safeAs()
?.fir.safeAs<T>()
}
/**
@@ -153,6 +153,17 @@ inline fun <reified T : Any> FirQualifiedAccessExpression.getDeclaration(): T? {
fun FirSymbolOwner<*>.getContainingClass(context: CheckerContext): FirClassLikeDeclaration<*>? =
this.safeAs<FirCallableMemberDeclaration<*>>()?.containingClass()?.toSymbol(context.session)?.fir
/**
* Returns the FirClassLikeDeclaration the type alias is pointing
* to provided `this` is a FirTypeAlias. Returns this otherwise.
*/
fun FirClassLikeDeclaration<*>.followAlias(session: FirSession): FirClassLikeDeclaration<*> {
return this.safeAs<FirTypeAlias>()
?.expandedTypeRef
?.firClassLike(session)
?: return this
}
/**
* Returns the FirClassLikeDeclaration that the
* sequence of FirTypeAlias'es points to starting

View File

@@ -11,7 +11,6 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack
@@ -24,7 +23,6 @@ abstract class CheckerContext {
abstract val implicitReceiverStack: ImplicitReceiverStack
abstract val containingDeclarations: List<FirDeclaration>
abstract val qualifiedAccesses: List<FirQualifiedAccess>
abstract val getClassCalls: List<FirGetClassCall>
abstract val sessionHolder: SessionHolder
abstract val returnTypeCalculator: ReturnTypeCalculator
abstract val suppressedDiagnostics: Set<String>
@@ -59,7 +57,6 @@ class PersistentCheckerContext private constructor(
override val implicitReceiverStack: PersistentImplicitReceiverStack,
override val containingDeclarations: PersistentList<FirDeclaration>,
override val qualifiedAccesses: PersistentList<FirQualifiedAccess>,
override val getClassCalls: PersistentList<FirGetClassCall>,
override val sessionHolder: SessionHolder,
override val returnTypeCalculator: ReturnTypeCalculator,
override val suppressedDiagnostics: PersistentSet<String>,
@@ -71,7 +68,6 @@ class PersistentCheckerContext private constructor(
PersistentImplicitReceiverStack(),
persistentListOf(),
persistentListOf(),
persistentListOf(),
sessionHolder,
returnTypeCalculator,
persistentSetOf(),
@@ -85,7 +81,6 @@ class PersistentCheckerContext private constructor(
implicitReceiverStack.add(name, value),
containingDeclarations,
qualifiedAccesses,
getClassCalls,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -100,7 +95,6 @@ class PersistentCheckerContext private constructor(
implicitReceiverStack,
containingDeclarations.add(declaration),
qualifiedAccesses,
getClassCalls,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -115,22 +109,6 @@ class PersistentCheckerContext private constructor(
implicitReceiverStack,
containingDeclarations,
qualifiedAccesses.add(qualifiedAccess),
getClassCalls,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
allInfosSuppressed,
allWarningsSuppressed,
allErrorsSuppressed
)
}
fun addGetClassCall(getClassCall: FirGetClassCall): PersistentCheckerContext {
return PersistentCheckerContext(
implicitReceiverStack,
containingDeclarations,
qualifiedAccesses,
getClassCalls.add(getClassCall),
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics,
@@ -151,7 +129,6 @@ class PersistentCheckerContext private constructor(
implicitReceiverStack,
containingDeclarations,
qualifiedAccesses,
getClassCalls,
sessionHolder,
returnTypeCalculator,
suppressedDiagnostics.addAll(diagnosticNames),

View File

@@ -13,19 +13,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.isConst
import org.jetbrains.kotlin.lexer.KtTokens
object FirConstPropertyChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isConst) return
if (declaration.isVar) {
val constModifier = declaration.getModifier(KtTokens.CONST_KEYWORD)
constModifier?.let {
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token, "vars", context)
}
}
val classKind = (context.containingDeclarations.lastOrNull() as? FirRegularClass)?.classKind
if (classKind != ClassKind.OBJECT && context.containingDeclarations.size > 1) {
reporter.reportOn(declaration.source, FirErrors.CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, context)

View File

@@ -32,7 +32,7 @@ object FirConstructorAllowedChecker : FirConstructorChecker() {
reporter.reportOn(source, FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM, context)
}
ClassKind.CLASS -> if (containingClass is FirRegularClass && containingClass.modality == Modality.SEALED) {
val modifierList = source.getModifierList() ?: return
val modifierList = with(FirModifierList) { source.getModifierList() } ?: return
val hasIllegalModifier = modifierList.modifiers.any {
it.token != KtTokens.PROTECTED_KEYWORD && it.token != KtTokens.PRIVATE_KEYWORD
}

View File

@@ -5,11 +5,9 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.modality
@@ -18,11 +16,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.FirBackingFieldReference
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.lexer.KtTokens
internal fun isInsideExpectClass(containingClass: FirRegularClass, context: CheckerContext): Boolean {
@@ -91,7 +85,7 @@ internal fun checkPropertyInitializer(
context: CheckerContext
) {
val inInterface = containingClass?.isInterface == true
val hasAbstractModifier = KtTokens.ABSTRACT_KEYWORD in modifierList
val hasAbstractModifier = modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true
val isAbstract = property.isAbstract || hasAbstractModifier
if (isAbstract) {
if (property.initializer == null && property.delegate == null && property.returnTypeRef is FirImplicitTypeRef) {
@@ -174,36 +168,8 @@ internal fun checkPropertyAccessors(
reporter: DiagnosticReporter,
context: CheckerContext
) {
if (property.isVal) {
if (property.getter != null) {
var reassignment: FirBackingFieldReference? = null
// TODO: consider replacing this with normal VariableAssignmentChecker and reporting all 'field = ...' in getter (not just 1st)
// This way is a bit hacky and does not handle diagnostic suppression normally
val visitor = object : FirVisitorVoid() {
override fun visitElement(element: FirElement) {
element.acceptChildren(this)
}
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment) {
// Report the first violation (to match FE 1.0 behavior)
if (reassignment != null) return
val backingFieldReference = variableAssignment.lValue as? FirBackingFieldReference
if (backingFieldReference?.resolvedSymbol?.fir == property) {
reassignment = backingFieldReference
}
}
}
property.getter?.body?.accept(visitor, null)
reassignment?.source?.let {
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField)) {
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, property.symbol, context)
} else {
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, property.symbol, context)
}
}
}
property.setter?.source?.let {
property.setter?.source?.let {
if (property.isVal) {
reporter.reportOn(it, FirErrors.VAL_WITH_SETTER, context)
}
}
@@ -218,5 +184,6 @@ internal val FirClass<*>.canHaveOpenMembers: Boolean get() = modality() != Modal
internal fun FirRegularClass.isInlineOrValueClass(): Boolean {
if (this.classKind != ClassKind.CLASS) return false
return isInline || hasModifier(KtTokens.VALUE_KEYWORD)
val modifierList = with(FirModifierList) { source.getModifierList() }
return isInline || modifierList?.modifiers?.any { it.token == KtTokens.VALUE_KEYWORD } == true
}

View File

@@ -5,17 +5,13 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isInline
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOnWithSuppression
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.arrayElementType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isUnsignedTypeOrNullableUnsignedType
@@ -24,32 +20,13 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
object FirFunctionParameterChecker : FirFunctionChecker() {
override fun check(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
checkVarargParameters(declaration, context, reporter)
checkParameterTypes(declaration, context, reporter)
}
private fun checkParameterTypes(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
for (valueParameter in declaration.valueParameters) {
val returnTypeRef = valueParameter.returnTypeRef
if (returnTypeRef !is FirErrorTypeRef) continue
// type problems on real source are already reported by ConeDiagnostic.toFirDiagnostics
if (returnTypeRef.source?.kind == FirRealSourceElementKind) continue
val diagnostic = returnTypeRef.diagnostic
if (diagnostic is ConeSimpleDiagnostic && diagnostic.kind == DiagnosticKind.ValueParameterWithNoTypeAnnotation) {
reporter.reportOnWithSuppression(
valueParameter,
FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION,
context
)
}
}
}
private fun checkVarargParameters(function: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
val varargParameters = function.valueParameters.filter { it.isVararg }
if (varargParameters.size > 1) {
for (parameter in varargParameters) {
reporter.reportOnWithSuppression(parameter, FirErrors.MULTIPLE_VARARG_PARAMETERS, context)
reporter.reportOn(parameter.source ?: continue, FirErrors.MULTIPLE_VARARG_PARAMETERS, context)
}
}
@@ -61,8 +38,8 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
// Note: comparing with FE1.0, we skip checking if the type is not primitive because primitive types are not inline. That
// is any primitive values are already allowed by the inline check.
) {
reporter.reportOnWithSuppression(
varargParameter,
reporter.reportOn(
varargParameter.source ?: continue,
FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE,
varargParameterType,
context

View File

@@ -173,7 +173,8 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
private fun FirValueParameter.isNotFinalReadOnly(primaryConstructorProperty: FirProperty?): Boolean {
if (primaryConstructorProperty == null) return true
val isOpen = hasModifier(KtTokens.OPEN_KEYWORD)
val modifierList = with(FirModifierList) { source.getModifierList() }
val isOpen = modifierList?.modifiers?.any { it.token == KtTokens.OPEN_KEYWORD } == true
return isVararg || !primaryConstructorProperty.isVal || isOpen
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2010-2021 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.inference.isKClassType
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.types.*
// See FE1.0 [KClassWithIncorrectTypeArgumentChecker]
object FirKClassWithIncorrectTypeArgumentChecker : FirFileChecker() {
override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) {
for (topLevelDeclaration in declaration.declarations) {
if (topLevelDeclaration is FirCallableMemberDeclaration<*>) {
checkTopLevelDeclaration(topLevelDeclaration, context, reporter)
}
}
}
// When a type parameter is used as a type argument for KClass, it shouldn't be nullable.
// bad: fun <T> test1() = T::class
// okay: fun <T: Any> test2() = T::class
private fun checkTopLevelDeclaration(
declaration: FirCallableMemberDeclaration<*>,
context: CheckerContext,
reporter: DiagnosticReporter
) {
val source = declaration.source ?: return
if (source.kind is FirFakeSourceElementKind) return
val returnType = declaration.returnTypeRef.coneType
if (!returnType.isKClassTypeWithErrorOrNullableArgument(context.session.inferenceComponents.ctx)) return
val typeArgument = (returnType.typeArguments[0] as ConeKotlinTypeProjection).type
typeArgument.typeParameterFromError?.let {
reporter.reportOn(source, FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE, it.symbol, context)
}
}
private fun ConeKotlinType.isKClassTypeWithErrorOrNullableArgument(context: ConeInferenceContext): Boolean {
if (!this.isKClassType()) return false
val argumentType = typeArguments.toList().singleOrNull()?.let {
when (it) {
is ConeStarProjection -> null
is ConeKotlinTypeProjection -> it.type
}
} ?: return false
with(context) {
argumentType.typeParameterFromError?.let { typeParameter ->
return typeParameter.toConeType().isNullableType()
}
return argumentType is ConeKotlinErrorType || argumentType.isNullableType()
}
}
private val ConeKotlinType.typeParameterFromError: FirTypeParameter?
get() = ((this as? ConeKotlinErrorType)?.diagnostic as? ConeTypeParameterInQualifiedAccess)?.symbol?.fir
}

View File

@@ -34,8 +34,8 @@ object FirMemberFunctionsChecker : FirRegularClassChecker() {
if (source.kind is FirFakeSourceElementKind) return
// If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`.
// So, our source of truth should be the full modifier list retrieved from the source.
val modifierList = source.getModifierList()
val hasAbstractModifier = KtTokens.ABSTRACT_KEYWORD in modifierList
val modifierList = with(FirModifierList) { source.getModifierList() }
val hasAbstractModifier = modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true
val isAbstract = function.isAbstract || hasAbstractModifier
if (isAbstract) {
if (!containingDeclaration.canHaveAbstractDeclaration) {
@@ -49,7 +49,7 @@ object FirMemberFunctionsChecker : FirRegularClassChecker() {
}
}
val isInsideExpectClass = isInsideExpectClass(containingDeclaration, context)
val hasOpenModifier = KtTokens.OPEN_KEYWORD in modifierList
val hasOpenModifier = modifierList?.modifiers?.any { it.token == KtTokens.OPEN_KEYWORD } == true
if (!function.hasBody) {
if (containingDeclaration.isInterface) {
if (Visibilities.isPrivate(function.visibility)) {

View File

@@ -146,7 +146,7 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
if (source.kind is FirFakeSourceElementKind) return
// If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`.
// So, our source of truth should be the full modifier list retrieved from the source.
val modifierList = property.source.getModifierList()
val modifierList = with(FirModifierList) { property.source.getModifierList() }
checkPropertyInitializer(
containingDeclaration,
@@ -159,7 +159,7 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
checkPropertyAccessors(property, reporter, context)
checkExpectDeclarationVisibilityAndBody(property, source, reporter, context)
val hasAbstractModifier = KtTokens.ABSTRACT_KEYWORD in modifierList
val hasAbstractModifier = modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true
val isAbstract = property.isAbstract || hasAbstractModifier
if (containingDeclaration.isInterface &&
Visibilities.isPrivate(property.visibility) &&
@@ -203,7 +203,7 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
}
}
val hasOpenModifier = KtTokens.OPEN_KEYWORD in modifierList
val hasOpenModifier = modifierList?.modifiers?.any { it.token == KtTokens.OPEN_KEYWORD } == true
if (hasOpenModifier &&
containingDeclaration.isInterface &&
!hasAbstractModifier &&

View File

@@ -169,7 +169,7 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
if (!isDeclarationMappedToSourceCorrectly(declaration, source)) return
if (context.containingDeclarations.last() is FirDefaultPropertyAccessor) return
val modifierList = source.getModifierList()
val modifierList = with(FirModifierList) { source.getModifierList() }
modifierList?.let { checkModifiers(it, declaration, reporter, context) }
}

View File

@@ -12,7 +12,6 @@ import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtModifierList
@@ -45,9 +44,19 @@ internal sealed class FirModifierList {
}
}
operator fun get(token: KtModifierKeywordToken): FirModifier<*>? = modifiers.firstOrNull { it.token == token }
operator fun contains(token: KtModifierKeywordToken): Boolean = modifiers.any { it.token == token }
companion object {
fun FirSourceElement?.getModifierList(): FirModifierList? {
return when (this) {
null -> null
is FirPsiSourceElement<*> -> (psi as? KtModifierListOwner)?.modifierList?.let { FirPsiModifierList(it) }
is FirLightSourceElement -> {
val modifierListNode = lighterASTNode.getChildren(treeStructure).find { it?.tokenType == KtNodeTypes.MODIFIER_LIST }
?: return null
FirLightModifierList(modifierListNode, treeStructure)
}
}
}
}
}
private val MODIFIER_KEYWORD_SET = TokenSet.orSet(KtTokens.SOFT_KEYWORDS, TokenSet.create(KtTokens.IN_KEYWORD, KtTokens.FUN_KEYWORD))
@@ -73,21 +82,3 @@ internal sealed class FirModifier<Node : Any>(val node: Node, val token: KtModif
abstract val source: FirSourceElement
}
internal fun FirSourceElement?.getModifierList(): FirModifierList? {
return when (this) {
null -> null
is FirPsiSourceElement<*> -> (psi as? KtModifierListOwner)?.modifierList?.let { FirModifierList.FirPsiModifierList(it) }
is FirLightSourceElement -> {
val modifierListNode = lighterASTNode.getChildren(treeStructure).find { it?.tokenType == KtNodeTypes.MODIFIER_LIST }
?: return null
FirModifierList.FirLightModifierList(modifierListNode, treeStructure)
}
}
}
internal operator fun FirModifierList?.contains(token: KtModifierKeywordToken): Boolean = this?.contains(token) == true
internal fun FirDeclaration.getModifier(token: KtModifierKeywordToken): FirModifier<*>? = source.getModifierList()?.get(token)
internal fun FirDeclaration.hasModifier(token: KtModifierKeywordToken): Boolean = token in source.getModifierList()

View File

@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirModifierList.Companion.getModifierList
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -28,7 +29,7 @@ object FirOpenMemberChecker : FirClassChecker() {
memberDeclaration is FirConstructor
) continue
val source = memberDeclaration.source ?: continue
if (memberDeclaration.isOpen || memberDeclaration.hasModifier(KtTokens.OPEN_KEYWORD) && source.shouldReportOpenFromSource) {
if (memberDeclaration.isOpen || (source.hasOpenModifierInSource && source.shouldReportOpenFromSource)) {
if (declaration.classKind == ClassKind.OBJECT) {
reporter.reportOn(source, FirErrors.NON_FINAL_MEMBER_IN_OBJECT, context)
} else {
@@ -38,6 +39,7 @@ object FirOpenMemberChecker : FirClassChecker() {
}
}
private val FirSourceElement.hasOpenModifierInSource: Boolean get() = getModifierList()?.modifiers?.any { it.token == KtTokens.OPEN_KEYWORD } == true
private val FirSourceElement.shouldReportOpenFromSource: Boolean
get() = when (kind) {
FirRealSourceElementKind,

View File

@@ -28,7 +28,8 @@ object FirTopLevelFunctionsChecker : FirFileChecker() {
if (source.kind is FirFakeSourceElementKind) return
// If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`.
// So, our source of truth should be the full modifier list retrieved from the source.
if (function.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return
val modifierList = with(FirModifierList) { source.getModifierList() }
if (modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true) return
if (function.isExternal) return
if (!function.hasBody && !function.isExpect) {
reporter.reportOn(source, FirErrors.NON_MEMBER_FUNCTION_NO_BODY, function, context)

View File

@@ -26,7 +26,7 @@ object FirTopLevelPropertiesChecker : FirFileChecker() {
if (source.kind is FirFakeSourceElementKind) return
// If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`.
// So, our source of truth should be the full modifier list retrieved from the source.
val modifierList = source.getModifierList()
val modifierList = with(FirModifierList) { source.getModifierList() }
checkPropertyInitializer(
containingClass = null,

View File

@@ -1,46 +0,0 @@
/*
* Copyright 2010-2021 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration.jvm
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirMemberDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirModifierList
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.getModifier
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.getModifierList
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.lexer.KtTokens
// TODO: Move this to different, JVM-specific module?
object FirJvmExternalDeclarationChecker : FirMemberDeclarationChecker() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isExternal) return
val source = declaration.source ?: return
if (source.kind is FirFakeSourceElementKind) return
// WRONG_MODIFIER_TARGET on external constructor is intentionally NOT covered in this checker.
if (declaration !is FirFunction<*>) {
val target = when (declaration) {
is FirProperty -> "property"
is FirRegularClass -> "class"
else -> "non-function declaration"
}
val externalModifier = declaration.getModifier(KtTokens.EXTERNAL_KEYWORD)
externalModifier?.let {
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token, target, context)
}
}
// TODO: Implement checkers for these JVM-specific errors (see ExternalFunChecker in FE1.0):
// - EXTERNAL_DECLARATION_IN_INTERFACE
// - EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT
// - EXTERNAL_DECLARATION_CANNOT_HAVE_BODY
// - EXTERNAL_DECLARATION_CANNOT_BE_INLINED
}
}

View File

@@ -13,11 +13,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens.QUEST
@@ -27,6 +25,7 @@ object FirGetClassCallChecker : FirBasicExpressionChecker() {
val source = expression.source ?: return
if (source.kind is FirFakeSourceElementKind) return
val argument = expression.argument as? FirResolvedQualifier ?: return
// Note that raw FIR drops marked nullability "?" in, e.g., `A?::class`, `A<T?>::class`, or `A<T?>?::class`.
// That is, AST structures for those expressions have token type QUEST, whereas FIR element doesn't have any information about it.
//
@@ -37,33 +36,10 @@ object FirGetClassCallChecker : FirBasicExpressionChecker() {
//
// Only the 2nd example is valid, and we want to check if token type QUEST doesn't exist at the same level as COLONCOLON.
val markedNullable = source.getChild(QUEST, depth = 1) != null
val argument = expression.argument
val isNullable = markedNullable ||
(argument as? FirResolvedQualifier)?.isNullableLHSForCallableReference == true ||
argument.typeRef.coneType.isMarkedNullable ||
argument.typeRef.coneType.isNullableTypeParameter(context.session.inferenceComponents.ctx)
if (isNullable) {
if (argument.canBeDoubleColonLHSAsType) {
reporter.reportOn(source, FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, context)
} else {
reporter.reportOn(
argument.source,
FirErrors.EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS,
argument.typeRef.coneType,
context
)
}
if (argument.isNullableLHSForCallableReference || markedNullable) {
reporter.reportOn(source, FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, context)
return
}
argument.safeAsTypeParameterSymbol?.let {
if (!it.fir.isReified) {
// E.g., fun <T: Any> foo(): Any = T::class
reporter.reportOn(source, FirErrors.TYPE_PARAMETER_AS_REIFIED, it, context)
}
}
if (argument !is FirResolvedQualifier) return
// TODO: differentiate RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS
if (argument.typeArguments.isNotEmpty() && !argument.typeRef.coneType.isAllowedInClassLiteral(context)) {
val typeParameters = (argument.symbol?.fir as? FirTypeParameterRefsOwner)?.typeParameters
@@ -77,30 +53,6 @@ object FirGetClassCallChecker : FirBasicExpressionChecker() {
}
}
private fun ConeKotlinType.isNullableTypeParameter(context: ConeInferenceContext): Boolean {
if (this !is ConeTypeParameterType) return false
val typeParameter = lookupTag.typeParameterSymbol.fir
with(context) {
return !typeParameter.isReified &&
// E.g., fun <T> f2(t: T): Any = t::class
typeParameter.toConeType().isNullableType()
}
}
private val FirExpression.canBeDoubleColonLHSAsType: Boolean
get() {
return this is FirResolvedQualifier ||
this is FirResolvedReifiedParameterReference ||
safeAsTypeParameterSymbol != null
}
private val FirExpression.safeAsTypeParameterSymbol: FirTypeParameterSymbol?
get() {
return ((this as? FirQualifiedAccessExpression)
?.calleeReference as? FirResolvedNamedReference)
?.resolvedSymbol as? FirTypeParameterSymbol
}
private fun ConeKotlinType.isAllowedInClassLiteral(context: CheckerContext): Boolean =
when (this) {
is ConeClassLikeType -> {

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2010-2021 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedReifiedParameterReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
checkExplicitReceiver(expression, context, reporter)
checkExpressionItself(expression, context, reporter)
}
private fun checkExpressionItself(
expression: FirQualifiedAccessExpression,
context: CheckerContext,
reporter: DiagnosticReporter
) {
// Make sure the current qualified access is not part of another qualified access or class literals.
// E.g., for `T::toString`, which is a callable reference (a subtype of qualified access), type parameter T is checked once as an
// explicit receiver (or LHS). When we visit `T` (as a qualified access), we should not regard it as an expression here.
if (context.qualifiedAccesses.size > 1 || context.getClassCalls.isNotEmpty()) return
val diagnostic = expression.typeRef.coneTypeParameterInQualifiedAccess ?: return
val source = expression.source ?: return
reporter.reportOn(source, FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION, diagnostic.symbol, context)
}
private fun checkExplicitReceiver(
expression: FirQualifiedAccessExpression,
context: CheckerContext,
reporter: DiagnosticReporter
) {
val explicitReceiver = expression.explicitReceiver
val typeParameterSymbol =
(explicitReceiver as? FirResolvedReifiedParameterReference)?.symbol
?: explicitReceiver?.typeRef?.coneTypeParameterInQualifiedAccess?.symbol
?: return
if (expression is FirCallableReferenceAccess) {
reporter.reportOn(expression.source, FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS, context)
} else {
reporter.reportOn(explicitReceiver?.source, FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT, typeParameterSymbol, context)
}
}
private val FirTypeRef.coneTypeParameterInQualifiedAccess: ConeTypeParameterInQualifiedAccess?
get() = (this as? FirErrorTypeRef)?.diagnostic as? ConeTypeParameterInQualifiedAccess
}

View File

@@ -214,10 +214,6 @@ abstract class AbstractDiagnosticCollector(
visitWithQualifiedAccess(qualifiedAccessExpression)
}
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Nothing?) {
visitWithGetClassCall(getClassCall)
}
private inline fun visitWithDeclaration(
declaration: FirDeclaration,
block: () -> Unit = { declaration.acceptChildren(this, null) }
@@ -256,17 +252,6 @@ abstract class AbstractDiagnosticCollector(
context = existingContext
}
}
private fun visitWithGetClassCall(getClassCall: FirGetClassCall) {
val existingContext = context
context = context.addGetClassCall(getClassCall)
try {
getClassCall.runComponents()
getClassCall.acceptChildren(this, null)
} finally {
context = existingContext
}
}
}
protected open fun getDeclarationActionOnDeclarationEnter(declaration: FirDeclaration): DiagnosticCollectorDeclarationAction =

View File

@@ -31,7 +31,7 @@ class DeclarationCheckersDiagnosticComponent(
}
override fun visitRegularClass(regularClass: FirRegularClass, data: CheckerContext) {
(checkers.memberDeclarationCheckers + checkers.regularClassCheckers).check(regularClass, data, reporter)
checkers.regularClassCheckers.check(regularClass, data, reporter)
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: CheckerContext) {

View File

@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNED_VALUE_IS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT
@@ -55,10 +54,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_VARARG_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_WITHOUT_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR
@@ -82,7 +81,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_CLA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
@@ -111,18 +109,17 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_B
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NESTED_CLASS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NESTED_CLASS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NONE_APPLICABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS
@@ -136,6 +133,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ELSE_IN_WHEN
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_TYPE_FOR_TYPE_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR
@@ -185,11 +183,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NO
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_ENUM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_REIFIED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VARIABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNNECESSARY_LATEINIT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL
@@ -201,12 +196,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_OPERATOR_C
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_WITH_SETTER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARARG_OUTSIDE_PARENTHESES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_EXPECTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT
@@ -216,7 +208,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_ANNOTATION_PA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_OVERRIDDEN_BY_VAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_INVOCATION_KIND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TARGET
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS
@Suppress("unused")
@@ -357,7 +348,6 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING)
map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", TO_STRING, TO_STRING)
map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members")
map.put(WRONG_MODIFIER_TARGET, "Modifier ''{0}'' is not applicable to ''{1}''", TO_STRING, TO_STRING)
// Applicability
map.put(NONE_APPLICABLE, "None of the following functions are applicable: {0}", SYMBOLS)
@@ -383,6 +373,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
null,
TO_STRING
)
map.put(NO_TYPE_FOR_TYPE_PARAMETER, "There're no types suitable for this type parameter") // &
map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects")
// map.put(ILLEGAL_PROJECTION_USAGE, ...) // &
map.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters")
@@ -399,25 +390,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(REIFIED_TYPE_IN_CATCH_CLAUSE, "Reified type is forbidden for catch parameter")
map.put(TYPE_PARAMETER_IN_CATCH_CLAUSE, "Type parameter is forbidden for catch parameter")
map.put(
KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE,
"Declaration has an inconsistent return type. " +
"Please add upper bound Any for type parameter ''{0}'' or specify return type explicitly",
SYMBOL
)
map.put(TYPE_PARAMETER_AS_REIFIED, "Cannot use ''{0}'' as reified type parameter. Use a class instead", SYMBOL)
// Reflection
map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of a callable reference cannot be a type parameter")
map.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left hand side of a class literal")
map.put(NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, "Type in a class literal must not be nullable")
map.put(
EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS,
"Expression in a class literal has a nullable type ''{0}'', use !! to make the type non-nullable",
RENDER_TYPE
)
// Inline and value classes
map.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes cannot be local or inner")
@@ -530,7 +505,6 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless")
map.put(MULTIPLE_VARARG_PARAMETERS, "Multiple vararg-parameters are prohibited")
map.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE)
map.put(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION, "A type annotation is required on a value parameter")
// Properties & accessors
map.put(
@@ -596,8 +570,6 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
// Control flow diagnostics
map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME)
map.put(VAL_REASSIGNMENT, "Val cannot be reassigned", PROPERTY_NAME)
map.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD, "Reassignment of read-only property via backing field is deprecated", PROPERTY_NAME)
map.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, "Reassignment of read-only property via backing field", PROPERTY_NAME)
map.put(
WRONG_INVOCATION_KIND,
"{2} wrong invocation kind: given {3} case, but {4} case is possible",
@@ -639,14 +611,6 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", WHEN_MISSING_CASES)
map.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression")
// Context tracking
map.put(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION, "Type parameter ''{0}'' is not an expression", SYMBOL)
map.put(
TYPE_PARAMETER_ON_LHS_OF_DOT,
"Type parameter ''{0}'' cannot have or inherit a companion object, so it cannot be on the left hand side of dot",
SYMBOL
)
// Function contracts
map.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description", TO_STRING)

View File

@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.render
@@ -28,7 +27,6 @@ object FirDiagnosticRenderers {
when (symbol) {
is FirClassLikeSymbol<*> -> symbol.classId.asString()
is FirCallableSymbol<*> -> symbol.callableId.toString()
is FirTypeParameterSymbol -> symbol.name.asString()
else -> "???"
}
}

View File

@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.ifEmpty
private fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnostic<FirSourceElement>? = when (this) {
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.name?.asString() ?: "<No name>")
@@ -50,7 +51,6 @@ private fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnos
is ConeIntermediateDiagnostic -> null
is ConeContractDescriptionError -> FirErrors.ERROR_IN_CONTRACT_DESCRIPTION.on(source, this.reason)
is ConeTypeParameterSupertype -> FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE.on(source, this.reason)
is ConeTypeParameterInQualifiedAccess -> null // reported in various checkers instead
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
}
@@ -146,7 +146,7 @@ private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0<FirSourceEl
DiagnosticKind.JumpOutsideLoop -> FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
DiagnosticKind.NotLoopLabel -> FirErrors.NOT_A_LOOP_LABEL
DiagnosticKind.VariableExpected -> FirErrors.VARIABLE_EXPECTED
DiagnosticKind.ValueParameterWithNoTypeAnnotation -> FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
DiagnosticKind.NoTypeForTypeParameter -> FirErrors.NO_TYPE_FOR_TYPE_PARAMETER
DiagnosticKind.UnknownCallableKind -> FirErrors.UNKNOWN_CALLABLE_KIND
DiagnosticKind.IllegalProjectionUsage -> FirErrors.ILLEGAL_PROJECTION_USAGE
DiagnosticKind.MissingStdlibClass -> FirErrors.MISSING_STDLIB_CLASS

View File

@@ -40,10 +40,6 @@ object ConeStarProjection : ConeTypeProjection() {
get() = ProjectionKind.STAR
}
sealed class ConeKotlinTypeProjection : ConeTypeProjection() {
abstract val type: ConeKotlinType
}
data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection() {
override val kind: ProjectionKind
get() = ProjectionKind.IN
@@ -54,16 +50,6 @@ data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : Cone
get() = ProjectionKind.OUT
}
val ConeTypeProjection.type: ConeKotlinType?
get() = when (this) {
ConeStarProjection -> null
is ConeKotlinTypeProjection -> type
is ConeKotlinType -> this
}
val ConeTypeProjection.isStarProjection: Boolean
get() = this == ConeStarProjection
// We assume type IS an invariant type projection to prevent additional wrapper here
// (more exactly, invariant type projection contains type)
sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, TypeArgumentListMarker {
@@ -82,12 +68,17 @@ sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, Type
final override fun toString(): String {
return render()
}
abstract override fun equals(other: Any?): Boolean
abstract override fun hashCode(): Int
}
sealed class ConeSimpleKotlinType : ConeKotlinType(), SimpleTypeMarker
sealed class ConeKotlinTypeProjection : ConeTypeProjection() {
abstract val type: ConeKotlinType
}
typealias ConeKotlinErrorType = ConeClassErrorType
class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLikeLookupTag()
@@ -171,8 +162,7 @@ data class ConeCapturedType(
val lowerType: ConeKotlinType?,
override val nullability: ConeNullability = ConeNullability.NOT_NULL,
val constructor: ConeCapturedTypeConstructor,
override val attributes: ConeAttributes = ConeAttributes.Empty,
val isProjectionNotNull: Boolean = false
override val attributes: ConeAttributes = ConeAttributes.Empty
) : ConeSimpleKotlinType(), CapturedTypeMarker {
constructor(
captureStatus: CaptureStatus, lowerType: ConeKotlinType?, projection: ConeTypeProjection,
@@ -325,13 +315,6 @@ open class ConeTypeVariable(name: String) : TypeVariableMarker {
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
override val name: Name get() = Name.identifier(debugName)
var isContainedInInvariantOrContravariantPositions: Boolean = false
private set
fun recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter() {
isContainedInInvariantOrContravariantPositions = true
}
}
abstract class ConeIntegerLiteralType(

View File

@@ -16,8 +16,3 @@ fun FirSessionFactory.FirSessionConfigurator.registerExtendedCommonCheckers() {
useCheckers(ExtendedExpressionCheckers)
useCheckers(ExtendedDeclarationCheckers)
}
// TODO: Move this to different, JVM-specific module?
fun FirSessionFactory.FirSessionConfigurator.registerJvmCheckers() {
useCheckers(JvmDeclarationCheckers)
}

View File

@@ -70,7 +70,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
)
override val fileCheckers: Set<FirFileChecker> = setOf(
FirKClassWithIncorrectTypeArgumentChecker,
FirTopLevelFunctionsChecker,
FirTopLevelPropertiesChecker,
)

View File

@@ -22,7 +22,6 @@ object CommonExpressionCheckers : ExpressionCheckers() {
FirProjectionsOnNonClassTypeArgumentChecker,
FirUpperBoundViolatedChecker,
FirTypeArgumentsNotAllowedExpressionChecker,
FirTypeParameterInQualifiedAccessChecker,
FirSealedClassConstructorCallChecker,
)
override val functionCallCheckers: Set<FirFunctionCallChecker> = setOf()

View File

@@ -1,16 +0,0 @@
/*
* Copyright 2010-2021 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/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.checkers
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.*
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.jvm.FirJvmExternalDeclarationChecker
// TODO: Move this to different, JVM-specific module?
object JvmDeclarationCheckers : DeclarationCheckers() {
override val memberDeclarationCheckers: Set<FirMemberDeclarationChecker> = setOf(
FirJvmExternalDeclarationChecker,
)
}

View File

@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.analysis.extensions.additionalCheckers
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.caches.FirThreadUnsafeCachesFactory
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers
import org.jetbrains.kotlin.fir.extensions.BunchOfRegisteredExtensions
import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.registerExtensions
@@ -95,7 +94,6 @@ object FirSessionFactory {
FirSessionConfigurator(this).apply {
registerCommonCheckers()
registerJvmCheckers()
init()
}.configure()

View File

@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -23,7 +22,6 @@ interface Fir2IrComponents {
val irBuiltIns: IrBuiltIns
val builtIns: Fir2IrBuiltIns
val irFactory: IrFactory
val lock: IrLock
val classifierStorage: Fir2IrClassifierStorage
val declarationStorage: Fir2IrDeclarationStorage

View File

@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.fir.signaturer.FirMangler
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -37,7 +36,4 @@ class Fir2IrComponentsStorage(
override lateinit var annotationGenerator: AnnotationGenerator
override lateinit var callGenerator: CallAndReferenceGenerator
override lateinit var fakeOverrideGenerator: FakeOverrideGenerator
override val lock: IrLock
get() = symbolTable.lock
}

View File

@@ -866,9 +866,8 @@ class Fir2IrDeclarationStorage(
irClass: IrClass,
callableDeclaration: FirCallableDeclaration<*>
): FirCallableDeclaration<*>? {
if (irClass is Fir2IrLazyClass) {
irClass.getFakeOverridesByName(callableDeclaration.symbol.callableId.callableName)
}
// Init lazy class if necessary
irClass.declarations
return fakeOverridesInClass[irClass]?.get(callableDeclaration)
}
@@ -1145,42 +1144,40 @@ class Fir2IrDeclarationStorage(
val fir = firSymbol.fir as F
val irParent by lazy { findIrParent(fir) }
val signature by lazy { signatureComposer.composeSignature(fir) }
synchronized(symbolTable.lock) {
getCachedIrDeclaration(fir) {
// Parent calculation provokes declaration calculation for some members from IrBuiltIns
@Suppress("UNUSED_EXPRESSION") irParent
signature
}?.let { return it.symbol }
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin)
// TODO: package fragment members (?)
when (val parent = irParent) {
is Fir2IrLazyClass -> {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) {
"Should not have reference to public API uncached property from source code"
}
signature?.let {
return createIrLazyDeclaration(it, parent, declarationOrigin).symbol
}
getCachedIrDeclaration(fir) {
// Parent calculation provokes declaration calculation for some members from IrBuiltIns
@Suppress("UNUSED_EXPRESSION") irParent
signature
}?.let { return it.symbol }
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin)
// TODO: package fragment members (?)
when (val parent = irParent) {
is Fir2IrLazyClass -> {
assert(parentOrigin != IrDeclarationOrigin.DEFINED) {
"Should not have reference to public API uncached property from source code"
}
is IrLazyClass -> {
val unwrapped = fir.unwrapFakeOverrides()
if (unwrapped !== fir) {
when (unwrapped) {
is FirSimpleFunction -> {
return getIrFunctionSymbol(unwrapped.symbol)
}
is FirProperty -> {
return getIrPropertySymbol(unwrapped.symbol)
}
signature?.let {
return createIrLazyDeclaration(it, parent, declarationOrigin).symbol
}
}
is IrLazyClass -> {
val unwrapped = fir.unwrapFakeOverrides()
if (unwrapped !== fir) {
when (unwrapped) {
is FirSimpleFunction -> {
return getIrFunctionSymbol(unwrapped.symbol)
}
is FirProperty -> {
return getIrPropertySymbol(unwrapped.symbol)
}
}
}
}
return createIrDeclaration(irParent, declarationOrigin).apply {
(this as IrDeclaration).setAndModifyParent(irParent)
}.symbol
}
return createIrDeclaration(irParent, declarationOrigin).apply {
(this as IrDeclaration).setAndModifyParent(irParent)
}.symbol
}
private fun computeDeclarationOrigin(
@@ -1226,9 +1223,7 @@ class Fir2IrDeclarationStorage(
private fun getIrVariableSymbol(firVariable: FirVariable<*>): IrVariableSymbol {
return localStorage.getVariable(firVariable)?.symbol
?: run {
throw IllegalArgumentException("Cannot find variable ${firVariable.render()} in local storage")
}
?: throw IllegalArgumentException("Cannot find variable ${firVariable.render()} in local storage")
}
fun getIrValueSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol {

View File

@@ -176,7 +176,9 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) {
fun generate(klass: FirClass<*>): List<FirDeclaration> {
val propertyParametersCount = irClass.primaryConstructor?.explicitParameters?.size ?: 0
val properties = irClass.properties.filter { it.backingField != null }.take(propertyParametersCount).toList()
val properties = irClass.declarations
.filterIsInstance<IrProperty>()
.take(propertyParametersCount)
if (properties.isEmpty()) {
return emptyList()
}

View File

@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.name.Name
class FakeOverrideGenerator(
private val components: Fir2IrComponents,
@@ -71,86 +70,60 @@ class FakeOverrideGenerator(
val useSiteMemberScope = klass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
val superTypesCallableNames = useSiteMemberScope.getCallableNames()
val realDeclarationSymbols = realDeclarations.filterIsInstance<FirSymbolOwner<*>>().mapTo(mutableSetOf(), FirSymbolOwner<*>::symbol)
val isLocal = klass !is FirRegularClass || klass.isLocal
for (name in superTypesCallableNames) {
generateFakeOverridesForName(this, useSiteMemberScope, name, klass, result, realDeclarationSymbols)
useSiteMemberScope.processFunctionsByName(name) { functionSymbol ->
createFakeOverriddenIfNeeded(
klass, this, isLocal, functionSymbol,
declarationStorage::getCachedIrFunction,
declarationStorage::createIrFunction,
createFakeOverrideSymbol = { firFunction, callableSymbol ->
FirFakeOverrideGenerator.createSubstitutionOverrideFunction(
session, firFunction, callableSymbol,
newDispatchReceiverType = klass.defaultType(),
derivedClassId = klass.symbol.classId,
isExpect = (klass as? FirRegularClass)?.isExpect == true
)
},
baseFunctionSymbols,
result,
containsErrorTypes = { irFunction ->
irFunction.returnType.containsErrorType() || irFunction.valueParameters.any { it.type.containsErrorType() }
},
realDeclarationSymbols,
FirTypeScope::getDirectOverriddenFunctions,
useSiteMemberScope,
)
}
useSiteMemberScope.processPropertiesByName(name) { propertySymbol ->
createFakeOverriddenIfNeeded(
klass, this, isLocal, propertySymbol,
declarationStorage::getCachedIrProperty,
declarationStorage::createIrProperty,
createFakeOverrideSymbol = { firProperty, callableSymbol ->
FirFakeOverrideGenerator.createSubstitutionOverrideProperty(
session, firProperty, callableSymbol,
newDispatchReceiverType = klass.defaultType(),
derivedClassId = klass.symbol.classId,
isExpect = (klass as? FirRegularClass)?.isExpect == true
)
},
basePropertySymbols,
result,
containsErrorTypes = { irProperty ->
irProperty.backingField?.type?.containsErrorType() == true ||
irProperty.getter?.returnType?.containsErrorType() == true
},
realDeclarationSymbols,
FirTypeScope::getDirectOverriddenProperties,
useSiteMemberScope,
)
}
}
return result
}
@OptIn(ExperimentalStdlibApi::class)
fun generateFakeOverridesForName(
irClass: IrClass,
name: Name,
firClass: FirClass<*>
): List<IrDeclaration> = buildList {
val useSiteMemberScope = firClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
generateFakeOverridesForName(
irClass, useSiteMemberScope, name, firClass, this,
// This parameter is only needed for data-class methods that is irrelevant for lazy library classes
realDeclarationSymbols = emptySet()
)
}
private fun generateFakeOverridesForName(
irClass: IrClass,
useSiteMemberScope: FirTypeScope,
name: Name,
firClass: FirClass<*>,
result: MutableList<IrDeclaration>,
realDeclarationSymbols: Set<AbstractFirBasedSymbol<*>>
) {
val isLocal = firClass !is FirRegularClass || firClass.isLocal
useSiteMemberScope.processFunctionsByName(name) { functionSymbol ->
createFakeOverriddenIfNeeded(
firClass, irClass, isLocal, functionSymbol,
declarationStorage::getCachedIrFunction,
declarationStorage::createIrFunction,
createFakeOverrideSymbol = { firFunction, callableSymbol ->
FirFakeOverrideGenerator.createSubstitutionOverrideFunction(
session, firFunction, callableSymbol,
newDispatchReceiverType = firClass.defaultType(),
derivedClassId = firClass.symbol.classId,
isExpect = (firClass as? FirRegularClass)?.isExpect == true
)
},
baseFunctionSymbols,
result,
containsErrorTypes = { irFunction ->
irFunction.returnType.containsErrorType() || irFunction.valueParameters.any { it.type.containsErrorType() }
},
realDeclarationSymbols,
FirTypeScope::getDirectOverriddenFunctions,
useSiteMemberScope,
)
}
useSiteMemberScope.processPropertiesByName(name) { propertySymbol ->
createFakeOverriddenIfNeeded(
firClass, irClass, isLocal, propertySymbol,
declarationStorage::getCachedIrProperty,
declarationStorage::createIrProperty,
createFakeOverrideSymbol = { firProperty, callableSymbol ->
FirFakeOverrideGenerator.createSubstitutionOverrideProperty(
session, firProperty, callableSymbol,
newDispatchReceiverType = firClass.defaultType(),
derivedClassId = firClass.symbol.classId,
isExpect = (firClass as? FirRegularClass)?.isExpect == true
)
},
basePropertySymbols,
result,
containsErrorTypes = { irProperty ->
irProperty.backingField?.type?.containsErrorType() == true ||
irProperty.getter?.returnType?.containsErrorType() == true
},
realDeclarationSymbols,
FirTypeScope::getDirectOverriddenProperties,
useSiteMemberScope,
)
}
}
internal fun calcBaseSymbolsForFakeOverrideFunction(
klass: FirClass<*>,
fakeOverride: IrSimpleFunction,
@@ -185,16 +158,10 @@ class FakeOverrideGenerator(
computeDirectOverridden: FirTypeScope.(S) -> List<S>,
scope: FirTypeScope,
) {
if (originalSymbol !is S) return
if (originalSymbol !is S || originalSymbol in realDeclarationSymbols) return
val classLookupTag = klass.symbol.toLookupTag()
val originalDeclaration = originalSymbol.fir
if (originalSymbol.dispatchReceiverClassOrNull() == classLookupTag && !originalDeclaration.origin.fromSupertypes) return
// Data classes' methods from Any (toString/equals/hashCode) are not handled by the line above because they have Any-typed dispatch receiver
// (there are no special FIR method for them, it's just fake overrides)
// But they are treated differently in IR (real declarations have already been declared before) and such methods are present among realDeclarationSymbols
if (originalSymbol in realDeclarationSymbols) return
if (originalDeclaration.visibility == Visibilities.Private) return
val origin = IrDeclarationOrigin.FAKE_OVERRIDE

View File

@@ -38,7 +38,7 @@ interface AbstractFir2IrLazyDeclaration<F : FirMemberDeclaration, D : IrDeclarat
}
}
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(lock) {
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar {
fir.annotations.mapNotNull {
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
}

View File

@@ -68,7 +68,7 @@ abstract class AbstractFir2IrLazyFunction<F : FirMemberDeclaration>(
get() = null
set(_) = error("We should never need to store body of external functions.")
override var visibility: DescriptorVisibility by lazyVar(lock) {
override var visibility: DescriptorVisibility by lazyVar {
components.visibilityConverter.convertToDescriptorVisibility(fir.visibility)
}

View File

@@ -96,11 +96,11 @@ class Fir2IrLazyClass(
override val isFun: Boolean
get() = fir.isFun
override var superTypes: List<IrType> by lazyVar(lock) {
override var superTypes: List<IrType> by lazyVar {
fir.superTypeRefs.map { it.toIrType(typeConverter) }
}
override var thisReceiver: IrValueParameter? by lazyVar(lock) {
override var thisReceiver: IrValueParameter? by lazyVar {
symbolTable.enterScope(this)
val typeArguments = fir.typeParameters.map {
IrSimpleTypeImpl(
@@ -117,14 +117,7 @@ class Fir2IrLazyClass(
receiver
}
private val fakeOverridesByName = mutableMapOf<Name, Collection<IrDeclaration>>()
fun getFakeOverridesByName(name: Name): Collection<IrDeclaration> = fakeOverridesByName.getOrPut(name) {
fakeOverrideGenerator.generateFakeOverridesForName(this@Fir2IrLazyClass, name, fir)
.also(fakeOverrideGenerator::bindOverriddenSymbols)
}
override val declarations: MutableList<IrDeclaration> by lazyVar(lock) {
override val declarations: MutableList<IrDeclaration> by lazyVar {
val result = mutableListOf<IrDeclaration>()
val processedNames = mutableSetOf<Name>()
// NB: it's necessary to take all callables from scope,
@@ -173,11 +166,11 @@ class Fir2IrLazyClass(
else -> continue
}
}
for (name in scope.getCallableNames()) {
result += getFakeOverridesByName(name)
with(fakeOverrideGenerator) {
val fakeOverrides = getFakeOverrides(fir, fir.declarations)
bindOverriddenSymbols(fakeOverrides)
result += fakeOverrides
}
// TODO: remove this check to save time
for (declaration in result) {
if (declaration.parent != this) {

View File

@@ -67,11 +67,11 @@ class Fir2IrLazyConstructor(
error("Mutating Fir2Ir lazy elements is not possible")
}
override var returnType: IrType by lazyVar(lock) {
override var returnType: IrType by lazyVar {
fir.returnTypeRef.toIrType(typeConverter)
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
val containingClass = parent as? IrClass
val outerClass = containingClass?.parentClassOrNull
if (containingClass?.isInner == true && outerClass != null) {
@@ -92,7 +92,7 @@ class Fir2IrLazyConstructor(
error("Mutating Fir2Ir lazy elements is not possible")
}
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
override var valueParameters: List<IrValueParameter> by lazyVar {
declarationStorage.enterScope(this)
fir.valueParameters.mapIndexed { index, valueParameter ->
declarationStorage.createIrParameter(

View File

@@ -86,7 +86,7 @@ class Fir2IrLazyProperty(
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
override var backingField: IrField? by lazyVar(lock) {
override var backingField: IrField? by lazyVar {
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
val parent = parent
when {
@@ -126,7 +126,7 @@ class Fir2IrLazyProperty(
}
}
override var getter: IrSimpleFunction? by lazyVar(lock) {
override var getter: IrSimpleFunction? by lazyVar {
if (fir.isConst) return@lazyVar null
Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
@@ -155,7 +155,7 @@ class Fir2IrLazyProperty(
}
}
override var setter: IrSimpleFunction? by lazyVar(lock) {
override var setter: IrSimpleFunction? by lazyVar {
if (!fir.isVar) null else Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
when {

View File

@@ -45,11 +45,11 @@ class Fir2IrLazyPropertyAccessor(
override val name: Name
get() = Name.special("<${if (isSetter) "set" else "get"}-${firParentProperty.name}>")
override var returnType: IrType by lazyVar(lock) {
override var returnType: IrType by lazyVar {
if (isSetter) irBuiltIns.unitType else firParentProperty.returnTypeRef.toIrType(typeConverter, conversionTypeContext)
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
val containingClass = parent as? IrClass
if (containingClass != null && shouldHaveDispatchReceiver(containingClass, firParentProperty)
) {
@@ -57,13 +57,13 @@ class Fir2IrLazyPropertyAccessor(
} else null
}
override var extensionReceiverParameter: IrValueParameter? by lazyVar(lock) {
override var extensionReceiverParameter: IrValueParameter? by lazyVar {
firParentProperty.receiverTypeRef?.let {
createThisReceiverParameter(it.toIrType(typeConverter, conversionTypeContext))
}
}
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
override var valueParameters: List<IrValueParameter> by lazyVar {
if (!isSetter) emptyList()
else {
declarationStorage.enterScope(this)
@@ -81,7 +81,7 @@ class Fir2IrLazyPropertyAccessor(
}
}
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar(lock) {
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar {
firParentProperty.generateOverriddenAccessorSymbols(
firParentClass,
!isSetter,

View File

@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.initialSignatureAttr
import org.jetbrains.kotlin.fir.originalIfFakeOverride
import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
@@ -37,24 +38,24 @@ class Fir2IrLazySimpleFunction(
override val name: Name
get() = fir.name
override var returnType: IrType by lazyVar(lock) {
override var returnType: IrType by lazyVar {
fir.returnTypeRef.toIrType(typeConverter)
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
override var dispatchReceiverParameter: IrValueParameter? by lazyVar {
val containingClass = parent as? IrClass
if (containingClass != null && shouldHaveDispatchReceiver(containingClass, fir)) {
createThisReceiverParameter(thisType = containingClass.thisReceiver?.type ?: error("No this receiver for containing class"))
} else null
}
override var extensionReceiverParameter: IrValueParameter? by lazyVar(lock) {
override var extensionReceiverParameter: IrValueParameter? by lazyVar {
fir.receiverTypeRef?.let {
createThisReceiverParameter(it.toIrType(typeConverter))
}
}
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
override var valueParameters: List<IrValueParameter> by lazyVar {
declarationStorage.enterScope(this)
fir.valueParameters.mapIndexed { index, valueParameter ->
declarationStorage.createIrParameter(
@@ -67,11 +68,11 @@ class Fir2IrLazySimpleFunction(
}
}
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar(lock) {
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by lazyVar {
val parent = parent
if (isFakeOverride && parent is Fir2IrLazyClass) {
fakeOverrideGenerator.calcBaseSymbolsForFakeOverrideFunction(
firParent, this, fir.symbol
firParent, this, fir.symbol.originalIfFakeOverride()!!
)
fakeOverrideGenerator.getOverriddenSymbolsForFakeOverride(this)?.let { return@lazyVar it }
}

View File

@@ -61,7 +61,7 @@ class FirBasedSignatureComposer(private val mangler: FirMangler) : Fir2IrSignatu
if (declaration is FirRegularClass && declaration.classId.isLocal) return null
if (declaration is FirCallableMemberDeclaration<*>) {
if (declaration.visibility == Visibilities.Local) return null
if (declaration.dispatchReceiverClassOrNull()?.classId?.isLocal == true || containingClass?.classId?.isLocal == true) return null
if (declaration.symbol.dispatchReceiverClassOrNull()?.classId?.isLocal == true || containingClass?.classId?.isLocal == true) return null
}
val builder = SignatureBuilder()
try {

View File

@@ -2522,12 +2522,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
@TestMetadata("compiler/testData/codegen/box/callableReference/adaptedReferences")
@TestDataPath("$PROJECT_ROOT")
public class AdaptedReferences {
@Test
@TestMetadata("adaptedVarargFunImportedFromObject.kt")
public void testAdaptedVarargFunImportedFromObject() throws Exception {
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/adaptedVarargFunImportedFromObject.kt");
}
@Test
public void testAllFilesPresentInAdaptedReferences() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
@@ -5793,12 +5787,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/closures/capturedVarsOptimization/kt44347.kt");
}
@Test
@TestMetadata("kt45446.kt")
public void testKt45446() throws Exception {
runTest("compiler/testData/codegen/box/closures/capturedVarsOptimization/kt45446.kt");
}
@Test
@TestMetadata("sharedSlotsWithCapturedVars.kt")
public void testSharedSlotsWithCapturedVars() throws Exception {
@@ -12078,24 +12066,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt");
}
@Test
@TestMetadata("kt36853.kt")
public void testKt36853() throws Exception {
runTest("compiler/testData/codegen/box/defaultArguments/kt36853.kt");
}
@Test
@TestMetadata("kt36853_nestedObject.kt")
public void testKt36853_nestedObject() throws Exception {
runTest("compiler/testData/codegen/box/defaultArguments/kt36853_nestedObject.kt");
}
@Test
@TestMetadata("kt36853a.kt")
public void testKt36853a() throws Exception {
runTest("compiler/testData/codegen/box/defaultArguments/kt36853a.kt");
}
@Test
@TestMetadata("kt36972_companion.kt")
public void testKt36972_companion() throws Exception {
@@ -12750,12 +12720,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/delegatedProperty/insideInlinedObjectMultiModule.kt");
}
@Test
@TestMetadata("javaDelegateTopLevel.kt")
public void testJavaDelegateTopLevel() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/javaDelegateTopLevel.kt");
}
@Test
@TestMetadata("kt35707.kt")
public void testKt35707() throws Exception {
@@ -12774,12 +12738,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/delegatedProperty/kt4138.kt");
}
@Test
@TestMetadata("kt45431.kt")
public void testKt45431() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/kt45431.kt");
}
@Test
@TestMetadata("kt6722.kt")
public void testKt6722() throws Exception {
@@ -13288,12 +13246,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/delegation/inClassDeclaration.kt");
}
@Test
@TestMetadata("inDataClass.kt")
public void testInDataClass() throws Exception {
runTest("compiler/testData/codegen/box/delegation/inDataClass.kt");
}
@Test
@TestMetadata("kt8154.kt")
public void testKt8154() throws Exception {
@@ -14114,18 +14066,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@Test
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@Test
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@Test
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
@@ -15072,12 +15012,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt");
}
@Test
@TestMetadata("incorrectBytecodeWithEnhancedNullability.kt")
public void testIncorrectBytecodeWithEnhancedNullability() throws Exception {
runTest("compiler/testData/codegen/box/fir/incorrectBytecodeWithEnhancedNullability.kt");
}
@Test
@TestMetadata("IrBuiltIns.kt")
public void testIrBuiltIns() throws Exception {
@@ -15648,12 +15582,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/functions/max.kt");
}
@Test
@TestMetadata("mutualInline.kt")
public void testMutualInline() throws Exception {
runTest("compiler/testData/codegen/box/functions/mutualInline.kt");
}
@Test
@TestMetadata("nothisnoclosure.kt")
public void testNothisnoclosure() throws Exception {
@@ -17782,12 +17710,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/inlineClasses/kt44141.kt");
}
@Test
@TestMetadata("kt44867.kt")
public void testKt44867() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/kt44867.kt");
}
@Test
@TestMetadata("mangledDefaultParameterFunction.kt")
public void testMangledDefaultParameterFunction() throws Exception {
@@ -18732,24 +18654,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
public void testJavaSam() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/funInterface/javaSam.kt");
}
@Test
@TestMetadata("javaSamReturnResult.kt")
public void testJavaSamReturnResult() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/funInterface/javaSamReturnResult.kt");
}
@Test
@TestMetadata("returnIC.kt")
public void testReturnIC() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/funInterface/returnIC.kt");
}
@Test
@TestMetadata("returnResult.kt")
public void testReturnResult() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/funInterface/returnResult.kt");
}
}
@Nested
@@ -19518,12 +19422,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/innerNested/createdNestedInOuterMember.kt");
}
@Test
@TestMetadata("extenderNestedClass.kt")
public void testExtenderNestedClass() throws Exception {
runTest("compiler/testData/codegen/box/innerNested/extenderNestedClass.kt");
}
@Test
@TestMetadata("extensionFun.kt")
public void testExtensionFun() throws Exception {
@@ -20504,18 +20402,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/intReturnTypeAsNumber.kt");
}
@Test
@TestMetadata("interfaceMemberRef.kt")
public void testInterfaceMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/interfaceMemberRef.kt");
}
@Test
@TestMetadata("kt45581.kt")
public void testKt45581() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/functionRefToJavaInterface/kt45581.kt");
}
@Test
@TestMetadata("localFunction1.kt")
public void testLocalFunction1() throws Exception {
@@ -23440,12 +23326,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/jvmStatic/kt35716.kt");
}
@Test
@TestMetadata("kt45408.kt")
public void testKt45408() throws Exception {
runTest("compiler/testData/codegen/box/jvmStatic/kt45408.kt");
}
@Test
@TestMetadata("kt9897_static.kt")
public void testKt9897_static() throws Exception {
@@ -36630,12 +36510,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/regressions/kt4281.kt");
}
@Test
@TestMetadata("kt44993.kt")
public void testKt44993() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt44993.kt");
}
@Test
@TestMetadata("kt5056.kt")
public void testKt5056() throws Exception {

View File

@@ -809,12 +809,6 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/declarations/provideDelegate/differentReceivers.kt");
}
@Test
@TestMetadata("javaDelegate.kt")
public void testJavaDelegate() throws Exception {
runTest("compiler/testData/ir/irText/declarations/provideDelegate/javaDelegate.kt");
}
@Test
@TestMetadata("local.kt")
public void testLocal() throws Exception {
@@ -1364,12 +1358,6 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/expressions/kt42321.kt");
}
@Test
@TestMetadata("kt44993.kt")
public void testKt44993() throws Exception {
runTest("compiler/testData/ir/irText/expressions/kt44993.kt");
}
@Test
@TestMetadata("kt45022.kt")
public void testKt45022() throws Exception {
@@ -1841,12 +1829,6 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.kt");
}
@Test
@TestMetadata("varargFunImportedFromObject.kt")
public void testVarargFunImportedFromObject() throws Exception {
runTest("compiler/testData/ir/irText/expressions/callableReferences/varargFunImportedFromObject.kt");
}
@Test
@TestMetadata("withAdaptationForSam.kt")
public void testWithAdaptationForSam() throws Exception {
@@ -2116,12 +2098,6 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/firProblems/AnnotationLoader.kt");
}
@Test
@TestMetadata("ArrayMap.kt")
public void testArrayMap() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/ArrayMap.kt");
}
@Test
@TestMetadata("candidateSymbol.kt")
public void testCandidateSymbol() throws Exception {

View File

@@ -116,6 +116,9 @@ class FirJavaClass @FirImplementationDetail internal constructor(
typeParameters.transformInplace(transformer, data)
return this
}
override fun replaceSource(newSource: FirSourceElement?) {
}
}
@FirBuilderDsl

View File

@@ -138,6 +138,9 @@ class FirJavaConstructor @FirImplementationDetail constructor(
override fun replaceBody(newBody: FirBlock?) {
error("Body cannot be replaced for FirJavaConstructor")
}
override fun replaceSource(newSource: FirSourceElement?) {
}
}
@FirBuilderDsl

View File

@@ -141,6 +141,9 @@ class FirJavaField @FirImplementationDetail constructor(
override fun <D> transformDelegate(transformer: FirTransformer<D>, data: D): FirField {
return this
}
override fun replaceSource(newSource: FirSourceElement?) {
}
}
@FirBuilderDsl

View File

@@ -172,6 +172,9 @@ class FirJavaMethod @FirImplementationDetail constructor(
override fun replaceContractDescription(newContractDescription: FirContractDescription) {
}
override fun replaceSource(newSource: FirSourceElement?) {
}
}
val ALL_JAVA_OPERATION_NAMES =

View File

@@ -141,6 +141,9 @@ class FirJavaValueParameter @FirImplementationDetail constructor(
override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) {
}
override fun replaceSource(newSource: FirSourceElement?) {
}
}
@FirBuilderDsl

View File

@@ -219,7 +219,7 @@ private fun ConeKotlinType.getEnhancedNullability(
if (!position.shouldEnhance()) return this.isMarkedNullable.noChange()
return when (qualifiers.nullability) {
NullabilityQualifier.NULLABLE -> true.noChange()
NullabilityQualifier.NULLABLE -> true.enhancedNullability()
NullabilityQualifier.NOT_NULL -> false.enhancedNullability()
else -> this.isMarkedNullable.noChange()
}

View File

@@ -54,6 +54,8 @@ class FirJavaTypeRef(
return this
}
override fun replaceSource(newSource: FirSourceElement?) {}
override fun toString(): String {
return type.render()
}

Some files were not shown because too many files have changed in this diff Show More