diff --git a/.idea/dictionaries/4u7.xml b/.idea/dictionaries/4u7.xml
index 720bcaa440d..b9beee98b70 100644
--- a/.idea/dictionaries/4u7.xml
+++ b/.idea/dictionaries/4u7.xml
@@ -4,6 +4,7 @@
cidr
foldable
instrumentator
+ protobuf
redirector
diff --git a/build.gradle.kts b/build.gradle.kts
index 1ded15ee2f7..958a133d872 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -149,7 +149,7 @@ rootProject.apply {
IdeVersionConfigurator.setCurrentIde(this)
-extra["versions.protobuf-java"] = "2.6.1"
+extra["versions.protobuf"] = "2.6.1"
extra["versions.javax.inject"] = "1"
extra["versions.jsr305"] = "1.3.9"
extra["versions.jansi"] = "1.16"
@@ -317,6 +317,7 @@ allprojects {
mirrorRepo?.let(::maven)
bootstrapKotlinRepo?.let(::maven)
jcenter()
+ maven(protobufRepo)
}
configureJvmProject(javaHome!!, jvmTarget!!)
@@ -324,6 +325,7 @@ allprojects {
val commonCompilerArgs = listOfNotNull(
"-Xallow-kotlin-package",
"-Xread-deserialized-contracts",
+ "-Xjvm-default=compatibility",
"-Xprogressive".takeIf { hasProperty("test.progressive.mode") } // TODO: change to "-progressive" after bootstrap
)
@@ -750,6 +752,7 @@ fun Project.configureJvmProject(javaHome: String, javaVersion: String) {
tasks.withType {
kotlinOptions.jdkHome = javaHome
kotlinOptions.jvmTarget = javaVersion
+ kotlinOptions.freeCompilerArgs += "-Xjvm-default=compatibility"
}
tasks.withType {
diff --git a/buildSrc/src/main/kotlin/cidr/cidrTasks.kt b/buildSrc/src/main/kotlin/cidr/cidrTasks.kt
index 57147ce35c8..9708255bc11 100644
--- a/buildSrc/src/main/kotlin/cidr/cidrTasks.kt
+++ b/buildSrc/src/main/kotlin/cidr/cidrTasks.kt
@@ -55,18 +55,27 @@ fun Copy.applyCidrVersionRestrictions(
pluginVersion: String
) {
val dotsCount = productVersion.count { it == '.' }
- check(dotsCount >= 1 && dotsCount <= 2) {
+ check(dotsCount in 1..2) {
"Wrong CIDR product version format: $productVersion"
}
- val sinceBuild = if (dotsCount == 1)
+ // private product versions don't have two dots
+ val privateProductVersion = dotsCount == 1
+
+ val applyStrictProductVersionLimitation = if (privateProductVersion && strictProductVersionLimitation) {
+ // it does not make sense for private versions to apply strict version limitation
+ logger.warn("Non-public CIDR product version [$productVersion] has been specified. The corresponding `versions..strict` property will be ignored.")
+ false
+ } else strictProductVersionLimitation
+
+ val sinceBuild = if (privateProductVersion)
productVersion
else
productVersion.substringBeforeLast('.')
- val untilBuild = if (strictProductVersionLimitation)
- // if strict then restrict plugin to the same single version of CLion or AppCode
- sinceBuild + ".*"
+ val untilBuild = if (applyStrictProductVersionLimitation)
+ // if `strict` then restrict plugin to the same single version of CLion or AppCode
+ "$sinceBuild.*"
else
productVersion.substringBefore('.') + ".*"
diff --git a/buildSrc/src/main/kotlin/dependencies.kt b/buildSrc/src/main/kotlin/dependencies.kt
index 105c05a3be5..c0d44099c36 100644
--- a/buildSrc/src/main/kotlin/dependencies.kt
+++ b/buildSrc/src/main/kotlin/dependencies.kt
@@ -64,14 +64,13 @@ fun DependencyHandler.projectRuntimeJar(name: String): ProjectDependency = proje
fun DependencyHandler.projectArchives(name: String): ProjectDependency = project(name, configuration = "archives")
fun DependencyHandler.projectClasses(name: String): ProjectDependency = project(name, configuration = "classes-dirs")
-val protobufLiteProject = ":custom-dependencies:protobuf-lite"
-val protobufRelocatedProject = ":custom-dependencies:protobuf-relocated"
-fun DependencyHandler.protobufLite(): ProjectDependency =
- project(protobufLiteProject, configuration = "default").apply { isTransitive = false }
-val protobufLiteTask = "$protobufLiteProject:prepare"
+val Project.protobufVersion: String get() = findProperty("versions.protobuf") as String
-fun DependencyHandler.protobufFull(): ProjectDependency =
- project(protobufRelocatedProject, configuration = "default").apply { isTransitive = false }
+val Project.protobufRepo: String get() =
+ "https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_Protobuf),status:SUCCESS,pinned:true,tag:$protobufVersion/artifacts/content/internal/repo/"
+
+fun Project.protobufLite(): String = "org.jetbrains.kotlin:protobuf-lite:$protobufVersion"
+fun Project.protobufFull(): String = "org.jetbrains.kotlin:protobuf-relocated:$protobufVersion"
fun File.matchMaybeVersionedArtifact(baseName: String) = name.matches(baseName.toMaybeVersionedJarRegex())
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegenProvider.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegenProvider.kt
index f05c3a26d2b..0edf2d48a8b 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegenProvider.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegenProvider.kt
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.constants.ConstantValue
-import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant
-import org.jetbrains.kotlin.resolve.constants.NullValue
-import org.jetbrains.kotlin.resolve.constants.StringValue
+import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.org.objectweb.asm.Type
import java.util.ArrayList
@@ -102,7 +99,7 @@ private constructor(
private fun isIntegralConstantsSwitch(expression: KtWhenExpression, subjectType: Type): Boolean =
AsmUtil.isIntPrimitive(subjectType) &&
- checkAllItemsAreConstantsSatisfying(expression) { it is IntegerValueConstant<*> }
+ checkAllItemsAreConstantsSatisfying(expression) { it is IntegerValueConstant<*> || it is UnsignedValueConstant<*> }
private fun isStringConstantsSwitch(expression: KtWhenExpression, subjectType: Type): Boolean =
subjectType.className == String::class.java.name &&
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DeepCopyWithWrappedDescriptors.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DeepCopyWithWrappedDescriptors.kt
new file mode 100644
index 00000000000..722de16e486
--- /dev/null
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DeepCopyWithWrappedDescriptors.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2010-2018 JetBrains s.r.o. 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.backend.common
+
+import org.jetbrains.kotlin.backend.common.descriptors.*
+import org.jetbrains.kotlin.descriptors.*
+import org.jetbrains.kotlin.ir.IrElement
+import org.jetbrains.kotlin.ir.declarations.*
+import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
+import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
+import org.jetbrains.kotlin.ir.util.parentAsClass
+import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
+import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
+import org.jetbrains.kotlin.ir.visitors.acceptVoid
+
+/*
+ TODO: Does not preserve getter/setter descriptors as implementations of PropertyAccessorDescriptor.
+ This causes problems for KotlinTypeMapper.mapFunctionName (maybe other places as well)
+ */
+
+inline fun T.deepCopyWithWrappedDescriptors(initialParent: IrDeclarationParent? = null): T =
+ deepCopyWithSymbols(initialParent, DescriptorsToIrRemapper).also {
+ it.acceptVoid(WrappedDescriptorPatcher)
+ }
+
+object DescriptorsToIrRemapper : DescriptorsRemapper {
+ override fun remapDeclaredClass(descriptor: ClassDescriptor) =
+ WrappedClassDescriptor(descriptor.annotations, descriptor.source)
+
+ override fun remapDeclaredConstructor(descriptor: ClassConstructorDescriptor) =
+ WrappedClassConstructorDescriptor(descriptor.annotations, descriptor.source)
+
+ override fun remapDeclaredEnumEntry(descriptor: ClassDescriptor) =
+ WrappedClassDescriptor(descriptor.annotations, descriptor.source)
+
+ override fun remapDeclaredField(descriptor: PropertyDescriptor) =
+ WrappedFieldDescriptor(descriptor.annotations, descriptor.source)
+
+ override fun remapDeclaredSimpleFunction(descriptor: FunctionDescriptor) =
+ WrappedSimpleFunctionDescriptor(descriptor.annotations, descriptor.source)
+
+ override fun remapDeclaredTypeParameter(descriptor: TypeParameterDescriptor) =
+ WrappedTypeParameterDescriptor(descriptor.annotations, descriptor.source)
+
+ override fun remapDeclaredVariable(descriptor: VariableDescriptor) =
+ WrappedVariableDescriptor(descriptor.annotations, descriptor.source)
+
+ override fun remapDeclaredValueParameter(descriptor: ParameterDescriptor): ParameterDescriptor =
+ if (descriptor is ReceiverParameterDescriptor)
+ WrappedReceiverParameterDescriptor(descriptor.annotations, descriptor.source)
+ else
+ WrappedValueParameterDescriptor(descriptor.annotations, descriptor.source)
+}
+
+object WrappedDescriptorPatcher : IrElementVisitorVoid {
+ override fun visitElement(element: IrElement) {
+ element.acceptChildrenVoid(this)
+ }
+
+ override fun visitClass(declaration: IrClass) {
+ (declaration.descriptor as WrappedClassDescriptor).bind(declaration)
+ declaration.acceptChildrenVoid(this)
+ }
+
+ override fun visitConstructor(declaration: IrConstructor) {
+ (declaration.descriptor as WrappedClassConstructorDescriptor).bind(declaration)
+ declaration.acceptChildrenVoid(this)
+ }
+
+ override fun visitEnumEntry(declaration: IrEnumEntry) {
+ (declaration.descriptor as WrappedClassDescriptor).bind(
+ declaration.correspondingClass ?: declaration.parentAsClass
+ )
+ declaration.acceptChildrenVoid(this)
+ }
+
+ override fun visitField(declaration: IrField) {
+ (declaration.descriptor as WrappedFieldDescriptor).bind(declaration)
+ declaration.acceptChildrenVoid(this)
+ }
+
+ override fun visitFunction(declaration: IrFunction) {
+ (declaration.descriptor as WrappedSimpleFunctionDescriptor).bind(declaration as IrSimpleFunction)
+ declaration.acceptChildrenVoid(this)
+ }
+
+ override fun visitValueParameter(declaration: IrValueParameter) {
+ (declaration.descriptor as? WrappedValueParameterDescriptor)?.bind(declaration)
+ (declaration.descriptor as? WrappedReceiverParameterDescriptor)?.bind(declaration)
+ declaration.acceptChildrenVoid(this)
+ }
+
+ override fun visitTypeParameter(declaration: IrTypeParameter) {
+ (declaration.descriptor as WrappedTypeParameterDescriptor).bind(declaration)
+ declaration.acceptChildrenVoid(this)
+ }
+
+ override fun visitVariable(declaration: IrVariable) {
+ (declaration.descriptor as WrappedVariableDescriptor).bind(declaration)
+ declaration.acceptChildrenVoid(this)
+ }
+}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt
index edc5bcdf428..a94408f4a58 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt
@@ -16,9 +16,11 @@
package org.jetbrains.kotlin.backend.common.ir
+import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
+import org.jetbrains.kotlin.backend.common.descriptors.WrappedReceiverParameterDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
@@ -41,10 +43,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
-import org.jetbrains.kotlin.ir.types.IrSimpleType
-import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.ir.types.IrTypeProjection
-import org.jetbrains.kotlin.ir.types.defaultType
+import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
@@ -354,7 +353,7 @@ fun Scope.createTemporaryVariableWithWrappedDescriptor(
nameHint: String? = null,
isMutable: Boolean = false,
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE): IrVariable {
-
+
val descriptor = WrappedVariableDescriptor()
return createTemporaryVariableWithGivenDescriptor(
irExpression, nameHint, isMutable, origin, descriptor
@@ -362,3 +361,24 @@ fun Scope.createTemporaryVariableWithWrappedDescriptor(
}
val IrFunction.isOverridable: Boolean get() = this is IrSimpleFunction && this.isOverridable
+
+fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() {
+ val thisReceiverDescriptor = WrappedReceiverParameterDescriptor()
+ thisReceiver = IrValueParameterImpl(
+ startOffset, endOffset,
+ IrDeclarationOrigin.INSTANCE_RECEIVER,
+ IrValueParameterSymbolImpl(thisReceiverDescriptor),
+ Name.identifier(""),
+ index = -1,
+ type = this.symbol.typeWith(this.typeParameters.map { it.defaultType }),
+ varargElementType = null,
+ isCrossinline = false,
+ isNoinline = false
+ ).also { valueParameter ->
+ thisReceiverDescriptor.bind(valueParameter)
+ valueParameter.parent = this
+ }
+
+ assert(typeParameters.isEmpty())
+ assert(descriptor.declaredTypeParameters.isEmpty())
+}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InitializersLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InitializersLowering.kt
index 23386fb9755..bf151552c13 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InitializersLowering.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InitializersLowering.kt
@@ -7,14 +7,13 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
-import org.jetbrains.kotlin.backend.common.CompilerPhase
+import org.jetbrains.kotlin.backend.common.deepCopyWithWrappedDescriptors
+import org.jetbrains.kotlin.backend.common.descriptors.*
import org.jetbrains.kotlin.backend.common.ir.SetDeclarationsParentVisitor
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.Modality
-import org.jetbrains.kotlin.descriptors.SourceElement
-import org.jetbrains.kotlin.descriptors.Visibilities
+import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
+import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
@@ -27,6 +26,9 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
+import org.jetbrains.kotlin.ir.util.SymbolRenamer
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
@@ -143,7 +145,7 @@ class InitializersLowering(
companion object {
val clinitName = Name.special("")
- fun IrStatement.copy(containingDeclaration: IrDeclarationParent) = deepCopyWithSymbols(containingDeclaration)
- fun IrExpression.copy(containingDeclaration: IrDeclarationParent) = deepCopyWithSymbols(containingDeclaration)
+ fun IrStatement.copy(containingDeclaration: IrDeclarationParent) = deepCopyWithWrappedDescriptors(containingDeclaration)
+ fun IrExpression.copy(containingDeclaration: IrDeclarationParent) = deepCopyWithWrappedDescriptors(containingDeclaration)
}
-}
\ No newline at end of file
+}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt
index 3f3f7261577..06c7c80eed1 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt
@@ -31,17 +31,13 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
-import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
-import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
-import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
-import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
+import org.jetbrains.kotlin.ir.visitors.*
import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.name.NameUtils
import java.util.*
interface LocalNameProvider {
- fun localName(descriptor: DeclarationDescriptor): String =
- descriptor.name.asString()
+ fun localName(declaration: IrDeclarationWithName): String =
+ declaration.name.asString()
companion object {
val DEFAULT = object : LocalNameProvider {}
@@ -465,13 +461,13 @@ class LocalDeclarationsLowering(
}
}
- private fun suggestLocalName(declaration: IrDeclaration): String {
+ private fun suggestLocalName(declaration: IrDeclarationWithName): String {
localFunctions[declaration]?.let {
if (it.index >= 0)
return "lambda-${it.index}"
}
- return localNameProvider.localName(declaration.descriptor)
+ return localNameProvider.localName(declaration)
}
private fun generateNameForLiftedDeclaration(
@@ -481,7 +477,7 @@ class LocalDeclarationsLowering(
Name.identifier(
declaration.parentsWithSelf
.takeWhile { it != newOwner }
- .toList().reversed().joinToString(separator = "$") { suggestLocalName(it as IrDeclaration) }
+ .toList().reversed().joinToString(separator = "$") { suggestLocalName(it as IrDeclarationWithName) }
)
private fun createLiftedDeclaration(localFunctionContext: LocalFunctionContext) {
@@ -769,8 +765,13 @@ class LocalDeclarationsLowering(
val localClassContext = LocalClassContext(declaration)
localClasses[declaration] = localClassContext
}
+
+ override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty) {
+ // Getter and setter of local delegated properties are special generated functions and don't have closure.
+ declaration.delegate.initializer?.acceptVoid(this)
+ }
})
}
}
-}
\ No newline at end of file
+}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt
index 9e5883f7f1a..77ea77feb9c 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt
@@ -89,7 +89,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas
}
private fun rewriteSharedVariables() {
- val transformedDescriptors = HashMap()
+ val transformedSymbols = HashMap()
irFunction.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitVariable(declaration: IrVariable): IrStatement {
@@ -99,7 +99,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas
val newDeclaration = context.sharedVariablesManager.declareSharedVariable(declaration)
newDeclaration.parent = irFunction
- transformedDescriptors[declaration.symbol] = newDeclaration.symbol
+ transformedSymbols[declaration.symbol] = newDeclaration.symbol
return context.sharedVariablesManager.defineSharedValue(declaration, newDeclaration)
}
@@ -123,7 +123,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas
}
private fun getTransformedSymbol(oldSymbol: IrValueSymbol): IrVariableSymbol? =
- transformedDescriptors.getOrElse(oldSymbol) {
+ transformedSymbols.getOrElse(oldSymbol) {
assert(oldSymbol.owner !in sharedVariables) {
"Shared variable is not transformed: ${oldSymbol.owner.dump()}"
}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt
index 8634f8fe976..1f43f76c472 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.DFS
val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin"))
-val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflection"))
+val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect"))
val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier("coroutines"))
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt
index 01e16efcd73..440757354ba 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt
@@ -25,7 +25,8 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER")
object DEFAULT_IMPLS : IrDeclarationOriginImpl("DEFAULT_IMPL")
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
- object SYNTHETIC_ACCESSOR : IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR")
+ object FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL")
+ object SYNTHETIC_ACCESSOR : IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR", isSynthetic = true)
object TO_ARRAY : IrDeclarationOriginImpl("TO_ARRAY")
object JVM_STATIC_WRAPPER : IrDeclarationOriginImpl("JVM_STATIC_WRAPPER")
object JVM_OVERLOADS_WRAPPER : IrDeclarationOriginImpl("JVM_OVERLOADS_WRAPPER")
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt
index fc41fd280c9..cada69f681a 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt
@@ -76,6 +76,10 @@ class JvmBackendContext(
return find(state.module.getPackage(fqName.parent()).memberScope, fqName.shortName())
}
+ fun getIrClass(fqName: FqName): IrClassSymbol {
+ return ir.symbols.externalSymbolTable.referenceClass(getClass(fqName))
+ }
+
override fun getInternalFunctions(name: String): List {
return when (name) {
"ThrowUninitializedPropertyAccessException" ->
@@ -151,6 +155,8 @@ class JvmBackendContext(
)
val lambdaClass = calc { symbolTable.referenceClass(context.getInternalClass("Lambda")) }
+
+ fun getKFunction(parameterCount: Int) = symbolTable.referenceClass(reflectionTypes.getKFunction(parameterCount))
}
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt
index 49e18ca5629..6b082563d48 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLoweringPhases.kt
@@ -11,8 +11,8 @@ import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.makePhase
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
import org.jetbrains.kotlin.backend.jvm.lower.*
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.name.NameUtils
@@ -108,8 +108,8 @@ private val SharedVariablesPhase = makeJvmPhase(
private val LocalDeclarationsPhase = makeJvmPhase(
{ context, data ->
LocalDeclarationsLowering(context, object : LocalNameProvider {
- override fun localName(descriptor: DeclarationDescriptor): String =
- NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
+ override fun localName(declaration: IrDeclarationWithName): String =
+ NameUtils.sanitizeAsJavaIdentifier(super.localName(declaration))
}, Visibilities.PUBLIC, true).lower(data)
},
name = "JvmLocalDeclarations",
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt
index 8c243f4e976..6a9370f1b4e 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.backend.jvm.codegen
-import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
import org.jetbrains.kotlin.codegen.*
@@ -78,7 +77,7 @@ open class FunctionCodegen(private val irFunction: IrFunction, private val class
else -> if (classCodegen.irClass.isJvmInterface && irFunction.body == null) Opcodes.ACC_ABSTRACT else 0 //TODO transform interface modality on lowering to DefaultImpls
}
val nativeFlag = if (irFunction.isExternal) Opcodes.ACC_NATIVE else 0
- val syntheticFlag = if (irFunction.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR) Opcodes.ACC_SYNTHETIC else 0
+ val syntheticFlag = if (irFunction.origin.isSynthetic) Opcodes.ACC_SYNTHETIC else 0
return visibility or
modalityFlag or
staticFlag or
@@ -148,4 +147,4 @@ private fun createFrameMapWithReceivers(
}
return frameMap
-}
\ No newline at end of file
+}
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt
index 7536e6b56bc..c4556077bc0 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt
@@ -19,20 +19,14 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.descriptors.*
-import org.jetbrains.kotlin.backend.common.ir.createFakeOverrideDescriptor
+import org.jetbrains.kotlin.backend.common.ir.copyTo
+import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.lower.*
-import org.jetbrains.kotlin.backend.common.makePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
-import org.jetbrains.kotlin.backend.jvm.codegen.isInlineCall
+import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
-import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
-import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
-import org.jetbrains.kotlin.descriptors.annotations.Annotations
-import org.jetbrains.kotlin.descriptors.impl.*
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
@@ -40,9 +34,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
-import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
-import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
-import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
+import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
@@ -51,13 +43,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.resolve.inline.InlineUtil
-import org.jetbrains.kotlin.storage.LockBasedStorageManager
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance
-import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
//Hack implementation to support CR java types in lower
@@ -68,8 +54,6 @@ class CrIrType(val type: Type) : IrType {
//Originally was copied from K/Native
class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPass {
- object DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL")
-
private var functionReferenceCount = 0
private val inlineLambdaReferences = mutableSetOf()
@@ -78,11 +62,11 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
irFile.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
override fun visitCall(expression: IrCall): IrExpression {
- val descriptor = expression.descriptor
- if (descriptor.isInlineCall(context.state)) {
+ val callee = expression.symbol.owner
+ if (callee.isInlineFunction(context)) {
//TODO: more wise filtering
- descriptor.valueParameters.forEach { valueParameter ->
- if (InlineUtil.isInlineParameter(valueParameter)) {
+ callee.valueParameters.forEach { valueParameter ->
+ if (valueParameter.isInlineParameter()) {
expression.getValueArgument(valueParameter.index)?.let {
if (isInlineIrExpression(it)) {
(it as IrBlock).statements.filterIsInstance().forEach { reference ->
@@ -97,10 +81,7 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
val argumentsCount = expression.valueArgumentsCount
// Change calls to FunctionN with large N to varargs calls.
val newCall = if (argumentsCount > MAX_ARGCOUNT_WITHOUT_VARARG &&
- descriptor.containingDeclaration in listOf(
- context.builtIns.getFunction(argumentsCount),
- context.reflectionTypes.getKFunction(argumentsCount)
- )
+ callee.parentAsClass.defaultType.isFunctionOrKFunction()
) {
val vararg = IrVarargImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
@@ -108,14 +89,14 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
context.ir.symbols.any.typeWith(),
(0 until argumentsCount).map { i -> expression.getValueArgument(i)!! }
)
- val invokeFunDescriptor = context.getClass(FqName("kotlin.jvm.functions.FunctionN"))
- .getFunction("invoke", listOf(expression.type.toKotlinType()))
- val invokeFunSymbol = context.ir.symbols.externalSymbolTable.referenceSimpleFunction(invokeFunDescriptor.original)
+ val invokeFun = context.getIrClass(FqName("kotlin.jvm.functions.FunctionN")).owner.declarations.single {
+ it is IrSimpleFunction && it.name.asString() == "invoke"
+ } as IrSimpleFunction
IrCallImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
expression.type,
- invokeFunSymbol, invokeFunDescriptor,
+ invokeFun.symbol, invokeFun.descriptor,
1,
expression.origin,
expression.superQualifier?.let { context.ir.symbols.externalSymbolTable.referenceClass(it) }
@@ -139,7 +120,8 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
return expression
}
- val loweredFunctionReference = FunctionReferenceBuilder(currentScope!!.scope.scopeOwner, expression).build()
+ val currentDeclarationParent = allScopes.map { it.irElement }.last { it is IrDeclarationParent } as IrDeclarationParent
+ val loweredFunctionReference = FunctionReferenceBuilder(currentDeclarationParent, expression).build()
val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset)
return irBuilder.irBlock(expression) {
+loweredFunctionReference.functionReferenceClass
@@ -158,26 +140,28 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
val functionReferenceConstructor: IrConstructor
)
- private val kotlinPackageScope = context.builtIns.builtInsPackageScope
-
- private val continuationClassDescriptor = context.getClass(FqName("kotlin.coroutines.experimental.Continuation"))
+ private val continuationClass = context.getIrClass(FqName("kotlin.coroutines.experimental.Continuation")).owner
//private val getContinuationSymbol = context.ir.symbols.getContinuation
private inner class FunctionReferenceBuilder(
- val containingDeclaration: DeclarationDescriptor,
+ val referenceParent: IrDeclarationParent,
val irFunctionReference: IrFunctionReference
) {
- private val functionDescriptor = irFunctionReference.descriptor
- private val functionParameters = functionDescriptor.explicitParameters
- private val boundFunctionParameters = irFunctionReference.getArguments().map { it.first }
- private val unboundFunctionParameters = functionParameters - boundFunctionParameters
+ private val callee = irFunctionReference.symbol.owner
+ private val calleeParameters = callee.explicitParameters
+ private val boundCalleeParameters = irFunctionReference.getArgumentsWithIr().map { it.first }
+ private val unboundCalleeParameters = calleeParameters - boundCalleeParameters
- private lateinit var functionReferenceClassDescriptor: ClassDescriptorImpl
- private lateinit var functionReferenceClass: IrClassImpl
+ private val typeArgumentsMap = callee.typeParameters.associate { typeParam ->
+ typeParam to irFunctionReference.getTypeArgument(typeParam.index)!!
+ }
+
+
+ private lateinit var functionReferenceClass: IrClass
private lateinit var functionReferenceThis: IrValueParameterSymbol
- private lateinit var argumentToPropertiesMap: Map
+ private lateinit var argumentToFieldMap: Map
private val isLambda = irFunctionReference.origin == IrStatementOrigin.LAMBDA
@@ -189,600 +173,449 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
val startOffset = irFunctionReference.startOffset
val endOffset = irFunctionReference.endOffset
- val returnType = functionDescriptor.returnType!!
- val superTypes: MutableList = mutableListOf(
- functionReferenceOrLambda.descriptor.defaultType
+ val returnType = irFunctionReference.symbol.owner.returnType
+ val functionReferenceClassSuperTypes: MutableList = mutableListOf(
+ functionReferenceOrLambda.owner.defaultType // type arguments?
)
- val numberOfParameters = unboundFunctionParameters.size
+ val numberOfParameters = unboundCalleeParameters.size
useVararg = (numberOfParameters > MAX_ARGCOUNT_WITHOUT_VARARG)
- val functionClassDescriptor = if (useVararg)
- context.getClass(FqName("kotlin.jvm.functions.FunctionN"))
+ val functionClassSymbol = if (useVararg)
+ context.getIrClass(FqName("kotlin.jvm.functions.FunctionN"))
else
- context.getClass(FqName("kotlin.jvm.functions.Function$numberOfParameters"))
- val functionParameterTypes = unboundFunctionParameters.map { it.type }
+ context.getIrClass(FqName("kotlin.jvm.functions.Function$numberOfParameters"))
+ val functionClass = functionClassSymbol.owner
+ val functionParameterTypes = unboundCalleeParameters.map { it.type }
val functionClassTypeParameters = if (useVararg)
listOf(returnType)
else
functionParameterTypes + returnType
- superTypes += functionClassDescriptor.defaultType.replace(functionClassTypeParameters)
+ functionReferenceClassSuperTypes += IrSimpleTypeImpl(
+ functionClassSymbol,
+ hasQuestionMark = false,
+ arguments = functionClassTypeParameters.map { makeTypeProjection(it, Variance.INVARIANT) },
+ annotations = emptyList()
+ )
- var suspendFunctionClassDescriptor: ClassDescriptor? = null
- var suspendFunctionClassTypeParameters: List? = null
- val lastParameterType = unboundFunctionParameters.lastOrNull()?.type
- if (lastParameterType != null && TypeUtils.getClassDescriptor(lastParameterType) == continuationClassDescriptor) {
+ var suspendFunctionClass: IrClass? = null
+ var suspendFunctionClassTypeParameters: List? = null
+ val lastParameterType = unboundCalleeParameters.lastOrNull()?.type
+ if ((lastParameterType as? IrSimpleType)?.classifier == continuationClass) {
// If the last parameter is Continuation<> inherit from SuspendFunction.
- suspendFunctionClassDescriptor = kotlinPackageScope.getContributedClassifier(
- Name.identifier("SuspendFunction${numberOfParameters - 1}"), NoLookupLocation.FROM_BACKEND
- ) as ClassDescriptor
- suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) + lastParameterType.arguments.single().type
- superTypes += suspendFunctionClassDescriptor.defaultType.replace(suspendFunctionClassTypeParameters)
+ suspendFunctionClass = context.getIrClass(FqName("kotlin.Suspendfunction${numberOfParameters - 1}")).owner
+ suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) +
+ (lastParameterType.arguments.single() as IrTypeProjection).type
+ functionReferenceClassSuperTypes += IrSimpleTypeImpl(
+ suspendFunctionClass.symbol,
+ hasQuestionMark = false,
+ arguments = suspendFunctionClassTypeParameters.map { makeTypeProjection(it, Variance.INVARIANT) },
+ annotations = emptyList()
+ )
}
- functionReferenceClassDescriptor = ClassDescriptorImpl(
- /* containingDeclaration = */ containingDeclaration,
- /* name = */ "${functionDescriptor.name}\$${functionReferenceCount++}".synthesizedName,
- /* modality = */ Modality.FINAL,
- /* kind = */ ClassKind.CLASS,
- /* superTypes = */ superTypes,
- /* source = */ /*TODO*/ (containingDeclaration as? DeclarationDescriptorWithSource)?.source ?: NO_SOURCE,
- /* isExternal = */ false,
- LockBasedStorageManager.NO_LOCKS
- )
+ val functionReferenceClassDescriptor = WrappedClassDescriptor()
functionReferenceClass = IrClassImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
- descriptor = functionReferenceClassDescriptor
+ startOffset, endOffset,
+ JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
+ IrClassSymbolImpl(functionReferenceClassDescriptor),
+ name = "${callee.name}\$${functionReferenceCount++}".synthesizedName,
+ kind = ClassKind.CLASS,
+ visibility = Visibilities.PUBLIC,
+ modality = Modality.FINAL,
+ isCompanion = false,
+ isInner = false,
+ isData = false,
+ isExternal = false,
+ isInline = false
).apply {
- createParameterDeclarations()
- val typeTranslator = TypeTranslator(context.ir.symbols.externalSymbolTable, context.state.languageVersionSettings,
- enterTableScope=true)
- val constantValueGenerator = ConstantValueGenerator(context.state.module, context.ir.symbols.externalSymbolTable)
- typeTranslator.constantValueGenerator = constantValueGenerator
- constantValueGenerator.typeTranslator = typeTranslator
- functionReferenceClassDescriptor.typeConstructor.supertypes.mapTo(this.superTypes) {
- typeTranslator.translateType(it)
- }
+ functionReferenceClassDescriptor.bind(this)
+ parent = referenceParent
+ superTypes.addAll(functionReferenceClassSuperTypes)
+ createImplicitParameterDeclarationWithWrappedDescriptor()
}
- val contributedDescriptors = mutableListOf()
- val constructorBuilder = createConstructorBuilder()
- functionReferenceClassDescriptor.initialize(
- SimpleMemberScope(contributedDescriptors), setOf(constructorBuilder.symbol.descriptor), null
- )
-
functionReferenceThis = functionReferenceClass.thisReceiver!!.symbol
- val invokeFunctionDescriptor = functionClassDescriptor.getFunction("invoke", functionClassTypeParameters)
+ argumentToFieldMap = boundCalleeParameters.associate {
+ it to buildField(it.name.safeName(), it.type)
+ }
- val invokeMethodBuilder = createInvokeMethodBuilder(invokeFunctionDescriptor)
+ val constructor = createConstructor()
+ functionReferenceClass.declarations.add(constructor)
- constructorBuilder.initialize()
- functionReferenceClass.declarations.add(constructorBuilder.ir)
-
- invokeMethodBuilder.initialize()
- functionReferenceClass.declarations.add(invokeMethodBuilder.ir)
+ val superInvokeFunction = functionClass.functions.find { it.name.asString() == "invoke" }!!
+ val invokeMethod = createInvokeMethod(superInvokeFunction)
+ functionReferenceClass.declarations.add(invokeMethod)
if (!isLambda) {
- val getSignatureBuilder =
- createGetSignatureMethodBuilder(functionReferenceOrLambda.owner.descriptor.getFunction("getSignature", emptyList()))
- val getNameBuilder = createGetNameMethodBuilder(functionReferenceOrLambda.owner.descriptor.getProperty("name", emptyList()))
- val getOwnerBuilder =
- createGetOwnerMethodBuilder(functionReferenceOrLambda.owner.descriptor.getFunction("getOwner", emptyList()))
+ val getSignatureMethod = createGetSignatureMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getSignature"}!!)
+ val getNameMethod = createGetNameMethod(functionReferenceOrLambda.owner.properties.find { it.name.asString() == "name" }!!)
+ val getOwnerMethod = createGetOwnerMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getOwner" }!!)
- val suspendInvokeMethodBuilder =
- if (suspendFunctionClassDescriptor != null) {
- val suspendInvokeFunctionDescriptor =
- suspendFunctionClassDescriptor.getFunction("invoke", suspendFunctionClassTypeParameters!!)
- createInvokeMethodBuilder(suspendInvokeFunctionDescriptor)
+ val suspendInvokeMethod =
+ if (suspendFunctionClass != null) {
+ val suspendInvokeFunction =
+ suspendFunctionClass.functions.find { it.name.asString() == "invoke" }!!
+ createInvokeMethod(suspendInvokeFunction)
} else null
- val inheritedScope = functionReferenceOrLambda.descriptor.unsubstitutedMemberScope
- .getContributedDescriptors().mapNotNull { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) }
- .filterNot { !isLambda && (it.name.asString() == "getSignature" || it.name.asString() == "name" || it.name.asString() == "getOwner") }
-
- contributedDescriptors.addAll(
- (
- inheritedScope + invokeMethodBuilder.symbol.descriptor +
- suspendInvokeMethodBuilder?.symbol?.descriptor + getSignatureBuilder.symbol.descriptor
- ).filterNotNull()
- )
-
- getSignatureBuilder.initialize()
- functionReferenceClass.declarations.add(getSignatureBuilder.ir)
-
- getNameBuilder.initialize()
- functionReferenceClass.declarations.add(getNameBuilder.ir)
-
- getOwnerBuilder.initialize()
- functionReferenceClass.declarations.add(getOwnerBuilder.ir)
-
- suspendInvokeMethodBuilder?.let {
- it.initialize()
- functionReferenceClass.declarations.add(it.ir)
- }
+ functionReferenceClass.declarations.add(getSignatureMethod)
+ functionReferenceClass.declarations.add(getNameMethod)
+ functionReferenceClass.declarations.add(getOwnerMethod)
+ suspendInvokeMethod?.let { functionReferenceClass.declarations.add(it) }
}
- return BuiltFunctionReference(functionReferenceClass, constructorBuilder.ir)
+ return BuiltFunctionReference(functionReferenceClass, constructor)
}
- private fun createConstructorBuilder() = object : SymbolWithIrBuilder() {
+ private fun createConstructor(): IrConstructor {
+ val descriptor = WrappedClassConstructorDescriptor()
+ return IrConstructorImpl(
+ irFunctionReference.startOffset, irFunctionReference.endOffset,
+ JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
+ IrConstructorSymbolImpl(descriptor),
+ name = Name.special(""),
+ visibility = Visibilities.PUBLIC,
+ returnType = functionReferenceClass.defaultType,
+ isInline = false,
+ isExternal = false,
+ isPrimary = true
+ ).apply {
+ val constructor = this
+ descriptor.bind(this)
+ parent = functionReferenceClass
- private val kFunctionRefConstructorSymbol =
- functionReferenceOrLambda.constructors.filter { it.descriptor.valueParameters.size == if (isLambda) 1 else 2 }.single()
-
- override fun buildSymbol() = IrConstructorSymbolImpl(
- ClassConstructorDescriptorImpl.create(
- /* containingDeclaration = */ functionReferenceClassDescriptor,
- /* annotations = */ Annotations.EMPTY,
- /* isPrimary = */ false,
- /* source = */ SourceElement.NO_SOURCE
- )
- )
-
- override fun doInitialize() {
- val descriptor = symbol.descriptor as ClassConstructorDescriptorImpl
- val constructorParameters = boundFunctionParameters.mapIndexed { index, parameter ->
- parameter.copyAsValueParameter(descriptor, index, parameter.name)
- }
- descriptor.initialize(constructorParameters, Visibilities.PUBLIC)
- descriptor.returnType = functionReferenceClassDescriptor.defaultType
- }
-
- override fun buildIr(): IrConstructor {
- argumentToPropertiesMap = boundFunctionParameters.associate {
- it to buildPropertyWithBackingField(it.name.safeName(), it.type)
+ val boundArgsSet = boundCalleeParameters.toSet()
+ for (param in callee.explicitParameters) {
+ if (param in boundArgsSet) {
+ val newParam = param.copyTo(
+ constructor,
+ index = valueParameters.size,
+ type = param.type.substitute(typeArgumentsMap)
+ )
+ valueParameters.add(newParam)
+ }
}
- val startOffset = irFunctionReference.startOffset
- val endOffset = irFunctionReference.endOffset
- return IrConstructorImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
- symbol = symbol,
- returnType = symbol.descriptor.returnType.toIrType()!!
- ).apply {
- val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset)
+ val kFunctionRefConstructorSymbol =
+ functionReferenceOrLambda.constructors.filter { it.owner.valueParameters.size == if (isLambda) 1 else 2 }.single()
- createParameterDeclarations()
+ val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset)
+ body = irBuilder.irBlockBody {
+ +IrDelegatingConstructorCallImpl(
+ startOffset, endOffset, context.irBuiltIns.unitType,
+ kFunctionRefConstructorSymbol, kFunctionRefConstructorSymbol.descriptor
+ ).apply {
+ val const =
+ IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, unboundCalleeParameters.size)
+ putValueArgument(0, const)
- body = irBuilder.irBlockBody {
- +IrDelegatingConstructorCallImpl(
- startOffset, endOffset, context.irBuiltIns.unitType,
- kFunctionRefConstructorSymbol, kFunctionRefConstructorSymbol.descriptor
- ).apply {
- val const =
- IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, unboundFunctionParameters.size)
- putValueArgument(0, const)
-
- if (!isLambda) {
- val irReceiver = valueParameters.firstOrNull()
- val receiver = boundFunctionParameters.singleOrNull()
- //TODO pass proper receiver
- val receiverValue = receiver?.let {
- irGet(irReceiver!!.symbol.owner)
- } ?: irNull()
- putValueArgument(1, receiverValue)
- }
+ if (!isLambda) {
+ val irReceiver = valueParameters.firstOrNull()
+ val receiver = boundCalleeParameters.singleOrNull()
+ //TODO pass proper receiver
+ val receiverValue = receiver?.let {
+ irGet(irReceiver!!.symbol.owner)
+ } ?: irNull()
+ putValueArgument(1, receiverValue)
}
+ }
- //TODO don't write receiver again: use it from base class
- boundFunctionParameters.forEachIndexed { index, it ->
- +irSetField(
- irGet(functionReferenceThis.owner),
- argumentToPropertiesMap[it]!!.owner,
- irGet(valueParameters[index])
+ // Save all arguments to fields.
+ //TODO don't write receiver again: use it from base class
+ boundCalleeParameters.forEachIndexed { index, it ->
+ +irSetField(
+ irGet(functionReferenceThis.owner),
+ argumentToFieldMap[it]!!,
+ irGet(valueParameters[index])
+ )
+ }
+ +IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, context.irBuiltIns.unitType)
+ }
+ }
+ }
+
+ private fun createInvokeMethod(superFunction: IrSimpleFunction) : IrSimpleFunction {
+ val descriptor = WrappedSimpleFunctionDescriptor()
+ return IrFunctionImpl(
+ irFunctionReference.startOffset, irFunctionReference.endOffset,
+ JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
+ IrSimpleFunctionSymbolImpl(descriptor),
+ Name.identifier("invoke"),
+ Visibilities.PUBLIC,
+ Modality.FINAL,
+ returnType = callee.returnType,
+ isInline = false, // not sure
+ isExternal = false,
+ isTailrec = false,
+ isSuspend = superFunction.isSuspend
+ ).apply {
+ val function = this
+ descriptor.bind(this)
+ parent = functionReferenceClass
+ overriddenSymbols.add(superFunction.symbol)
+ dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
+
+ val unboundArgsSet = unboundCalleeParameters.toSet()
+ if (useVararg) {
+ valueParameters.add(superFunction.valueParameters[0].copyTo(function))
+ } else {
+ for (param in callee.explicitParameters) {
+ if (param in unboundArgsSet) {
+ val newParam = param.copyTo(
+ function,
+ index = valueParameters.size,
+ type = param.type.substitute(typeArgumentsMap)
)
+ valueParameters.add(newParam)
}
- +IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, context.irBuiltIns.unitType)
- // Save all arguments to fields.
-
- }
- }
- }
- }
-
- private fun createInvokeMethodBuilder(superFunctionDescriptor: FunctionDescriptor) =
- object : SymbolWithIrBuilder() {
-
- override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
- SimpleFunctionDescriptorImpl.create(
- /* containingDeclaration = */ functionReferenceClassDescriptor,
- /* annotations = */ Annotations.EMPTY,
- /* name = */ Name.identifier("invoke"),
- /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
- /* source = */ SourceElement.NO_SOURCE
- )
- )
-
- override fun doInitialize() {
- val descriptor = symbol.descriptor as SimpleFunctionDescriptorImpl
- val valueParameters = superFunctionDescriptor.valueParameters
- .map { it.copyAsValueParameter(descriptor, it.index) }
-
- descriptor.initialize(
- /* receiverParameterType = */ null,
- /* dispatchReceiverParameter = */ functionReferenceClassDescriptor.thisAsReceiverParameter,
- /* typeParameters = */ emptyList(),
- /* unsubstitutedValueParameters = */ valueParameters,
- /* unsubstitutedReturnType = */ superFunctionDescriptor.returnType,
- /* modality = */ Modality.FINAL,
- /* visibility = */ Visibilities.PUBLIC
- ).apply {
- overriddenDescriptors += superFunctionDescriptor
- isSuspend = superFunctionDescriptor.isSuspend
}
}
- override fun buildIr(): IrSimpleFunction {
- val startOffset = irFunctionReference.startOffset
- val endOffset = irFunctionReference.endOffset
- val ourSymbol = symbol
- return IrFunctionImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
- symbol = ourSymbol,
- returnType = ourSymbol.descriptor.returnType!!.toIrType()!!
- ).apply {
-
- val function = this
- val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
- createParameterDeclarations()
-
- body = irBuilder.irBlockBody(startOffset, endOffset) {
- val arrayGetFun = context.irBuiltIns.arrayClass.owner
- .declarations.find {
- (it as? IrSimpleFunction)?.name?.toString() == "get"
- }!! as IrSimpleFunction
-
- if (useVararg) {
- val varargParam = valueParameters.single()
- val arraySizeProperty = context.irBuiltIns.arrayClass.owner.declarations.find {
- (it as? IrProperty)?.name?.toString() == "size"
- } as IrProperty
- +irIfThen(
- irNotEquals(
- irCall(arraySizeProperty.getter!!).apply {
- dispatchReceiver = irGet(varargParam)
- },
- irInt(unboundFunctionParameters.size)
- ),
- irCall(context.irBuiltIns.illegalArgumentExceptionFun).apply {
- putValueArgument(0, irString("Expected ${unboundFunctionParameters.size} arguments"))
- }
- )
+ val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
+ body = irBuilder.irBlockBody(startOffset, endOffset) {
+ val arrayGetFun = context.irBuiltIns.arrayClass.owner.functions.find { it.name.asString() == "get" }!!
+ if (useVararg) {
+ val varargParam = valueParameters.single()
+ val arraySizeProperty = context.irBuiltIns.arrayClass.owner.properties.find { it.name.toString() == "size" }!!
+ +irIfThen(
+ irNotEquals(
+ irCall(arraySizeProperty.getter!!).apply {
+ dispatchReceiver = irGet(varargParam)
+ },
+ irInt(unboundCalleeParameters.size)
+ ),
+ irCall(context.irBuiltIns.illegalArgumentExceptionFun).apply {
+ putValueArgument(0, irString("Expected ${unboundCalleeParameters.size} arguments"))
}
- +irReturn(
- irCall(irFunctionReference.symbol).apply {
- var unboundIndex = 0
- val unboundArgsSet = unboundFunctionParameters.toSet()
+ )
+ }
+ +irReturn(
+ irCall(irFunctionReference.symbol).apply {
+ var unboundIndex = 0
- functionParameters.forEach { parameter ->
- val argument = when {
- !unboundArgsSet.contains(parameter) ->
- // Bound parameter - read from field.
- irGetField(irGet(functionReferenceThis.owner), argumentToPropertiesMap[parameter]!!.owner)
- ourSymbol.descriptor.isSuspend && unboundIndex == valueParameters.size ->
- // For suspend functions the last argument is continuation and it is implicit.
- TODO()
+ calleeParameters.forEach { parameter ->
+ val argument = when {
+ !unboundArgsSet.contains(parameter) ->
+ // Bound parameter - read from field.
+ irGetField(irGet(functionReferenceThis.owner), argumentToFieldMap[parameter]!!)
+ function.isSuspend && unboundIndex == valueParameters.size ->
+ // For suspend functions the last argument is continuation and it is implicit.
+ TODO()
// irCall(getContinuationSymbol,
// listOf(ourSymbol.descriptor.returnType!!))
- useVararg -> {
- val type = parameter.type.toIrType()!!
- val varargParam = valueParameters.single()
- irBlock(resultType = type) {
- val argValue = irTemporary(
- irCall(arrayGetFun).apply {
- dispatchReceiver = irGet(varargParam)
- putValueArgument(0, irInt(unboundIndex++))
- }
- )
- +irIfThen(
- irNotIs(irGet(argValue), type),
- irCall(context.irBuiltIns.illegalArgumentExceptionFun).apply {
- putValueArgument(0, irString("Wrong type, expected $type"))
- }
- )
- +irGet(argValue)
+ useVararg -> {
+ val type = parameter.type
+ val varargParam = valueParameters.single()
+ irBlock(resultType = type) {
+ val argValue = irTemporary(
+ irCall(arrayGetFun).apply {
+ dispatchReceiver = irGet(varargParam)
+ putValueArgument(0, irInt(unboundIndex++))
}
- }
- else -> {
- irGet(valueParameters[unboundIndex++])
- }
- }
- when (parameter) {
- functionDescriptor.dispatchReceiverParameter -> dispatchReceiver = argument
- functionDescriptor.extensionReceiverParameter -> extensionReceiver = argument
- else -> putValueArgument((parameter as ValueParameterDescriptor).index, argument)
+ )
+ +irIfThen(
+ irNotIs(irGet(argValue), type),
+ irCall(context.irBuiltIns.illegalArgumentExceptionFun).apply {
+ putValueArgument(0, irString("Wrong type, expected $type"))
+ }
+ )
+ +irGet(argValue)
}
}
-
- if (!useVararg) assert(unboundIndex == valueParameters.size) { "Not all arguments of are used" }
+ else -> {
+ irGet(valueParameters[unboundIndex++])
+ }
}
- )
- }
- }
- }
- }
+ when (parameter) {
+ callee.dispatchReceiverParameter -> dispatchReceiver = argument
+ callee.extensionReceiverParameter -> extensionReceiver = argument
+ else -> putValueArgument(parameter.index, argument)
+ }
+ }
- private fun buildPropertyWithBackingField(name: Name, type: KotlinType): IrFieldSymbol {
- val fieldSymbol = IrFieldSymbolImpl(
- JvmPropertyDescriptorImpl.createFinalField(
- name, type, functionReferenceClassDescriptor,
- Annotations.EMPTY, JavaVisibilities.PACKAGE_VISIBILITY, Opcodes.ACC_SYNTHETIC, SourceElement.NO_SOURCE
- )
- )
+ if (!useVararg) assert(unboundIndex == valueParameters.size) { "Not all arguments of are used" }
+ }
+ )
+ }
+
+ }
+ }
+
+ private fun buildField(name: Name, type: IrType): IrField {
+ val descriptor = WrappedFieldDescriptor()
+ // TODO: make it synthetic
val field = IrFieldImpl(
irFunctionReference.startOffset,
irFunctionReference.endOffset,
- DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
- fieldSymbol,
- type.toIrType()!!
- )
+ JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
+ IrFieldSymbolImpl(descriptor),
+ name,
+ type,
+ JavaVisibilities.PACKAGE_VISIBILITY,
+ isFinal = true,
+ isExternal = false,
+ isStatic = false
+ ).apply {
+ descriptor.bind(this)
+ }
functionReferenceClass.declarations.add(field)
- return fieldSymbol
+ return field
}
- private fun createGetNameMethodBuilder(superNameProperty: PropertyDescriptor) =
- object : SymbolWithIrBuilder() {
+ private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction {
+ val descriptor = WrappedSimpleFunctionDescriptor()
+ return IrFunctionImpl(
+ irFunctionReference.startOffset, irFunctionReference.endOffset,
+ JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
+ IrSimpleFunctionSymbolImpl(descriptor),
+ Name.identifier("getSignature"),
+ superFunction.visibility,
+ superFunction.modality,
+ returnType = superFunction.returnType,
+ isInline = false,
+ isExternal = false,
+ isTailrec = false,
+ isSuspend = false
+ ).apply {
+ val function = this
+ descriptor.bind(this)
+ parent = functionReferenceClass
+ overriddenSymbols.add(superFunction.symbol)
+ dispatchReceiverParameter = functionReferenceClass.thisReceiver!!.copyTo(function)
- override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
- PropertyDescriptorImpl.create(
- /* containingDeclaration = */ functionReferenceClassDescriptor,
- /* annotations = */ Annotations.EMPTY,
- superNameProperty.modality,
- superNameProperty.visibility,
- false,
- /* name = */ superNameProperty.name,
- /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
- /* source = */ SourceElement.NO_SOURCE,
- false, false, false, false, false, false
- ).let { property ->
-
- property.overriddenDescriptors += superNameProperty
- PropertyGetterDescriptorImpl(
- property,
- Annotations.EMPTY,
- Modality.OPEN,
- Visibilities.PUBLIC,
- false, false, false,
- CallableMemberDescriptor.Kind.DECLARATION,
- null,
- SourceElement.NO_SOURCE
- ).also {
- property.initialize(it, null)
- property.setType(
- /* outType = */ superNameProperty.type,
- /* typeParameters = */ superNameProperty.typeParameters,
- /* dispatchReceiverParameter = */ superNameProperty.dispatchReceiverParameter,
- /* extensionReceiverParameter= */ superNameProperty.extensionReceiverParameter
+ val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
+ body = irBuilder.irBlockBody(startOffset, endOffset) {
+ +irReturn(
+ IrConstImpl.string(
+ -1, -1, context.irBuiltIns.stringType,
+ PropertyReferenceCodegen.getSignatureString(
+ irFunctionReference.symbol.descriptor, this@CallableReferenceLowering.context.state
)
- //overriddenDescriptors += superNameProperty.getter
- }
- }
- )
-
- override fun doInitialize() {
- val descriptor = symbol.descriptor as PropertyGetterDescriptorImpl
- descriptor.initialize(superNameProperty.type)
- }
-
- override fun buildIr(): IrSimpleFunction {
- val startOffset = irFunctionReference.startOffset
- val endOffset = irFunctionReference.endOffset
- val ourSymbol = symbol
- return IrFunctionImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
- symbol = ourSymbol,
- returnType = ourSymbol.descriptor.returnType!!.toIrType()!!
- ).apply {
-
- val function = this
- val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
-
- createParameterDeclarations()
-
- body = irBuilder.irBlockBody(startOffset, endOffset) {
- +irReturn(
- IrConstImpl.string(-1, -1, context.irBuiltIns.stringType, functionDescriptor.name.asString())
- )
- }
- }
- }
- }
-
-
- private fun createGetSignatureMethodBuilder(superFunctionDescriptor: FunctionDescriptor) =
- object : SymbolWithIrBuilder() {
-
- override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
- SimpleFunctionDescriptorImpl.create(
- /* containingDeclaration = */ functionReferenceClassDescriptor,
- /* annotations = */ Annotations.EMPTY,
- /* name = */ Name.identifier("getSignature"),
- /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
- /* source = */ SourceElement.NO_SOURCE
- )
- )
-
- override fun doInitialize() {
- val descriptor = symbol.descriptor as SimpleFunctionDescriptorImpl
- val valueParameters = superFunctionDescriptor.valueParameters
- .map { it.copyAsValueParameter(descriptor, it.index) }
-
- descriptor.initialize(
- /* receiverParameterType = */ null,
- /* dispatchReceiverParameter = */ functionReferenceClassDescriptor.thisAsReceiverParameter,
- /* typeParameters = */ emptyList(),
- /* unsubstitutedValueParameters = */ valueParameters,
- /* unsubstitutedReturnType = */ superFunctionDescriptor.returnType,
- /* modality = */ Modality.FINAL,
- /* visibility = */ Visibilities.PUBLIC
- ).apply {
- overriddenDescriptors += superFunctionDescriptor
- isSuspend = superFunctionDescriptor.isSuspend
- }
- }
-
- override fun buildIr(): IrSimpleFunction {
- val startOffset = irFunctionReference.startOffset
- val endOffset = irFunctionReference.endOffset
- val ourSymbol = symbol
- return IrFunctionImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
- symbol = ourSymbol,
- returnType = ourSymbol.descriptor.returnType!!.toIrType()!!
- ).apply {
-
- val function = this
- val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
-
- createParameterDeclarations()
-
- body = irBuilder.irBlockBody(startOffset, endOffset) {
- +irReturn(
- IrConstImpl.string(
- -1, -1, context.irBuiltIns.stringType,
- PropertyReferenceCodegen.getSignatureString(
- irFunctionReference.symbol.descriptor, this@CallableReferenceLowering.context.state
- )
- )
- )
- }
- }
- }
- }
-
- private fun createGetOwnerMethodBuilder(superFunctionDescriptor: FunctionDescriptor) =
- object : SymbolWithIrBuilder() {
-
- override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
- SimpleFunctionDescriptorImpl.create(
- /* containingDeclaration = */ functionReferenceClassDescriptor,
- /* annotations = */ Annotations.EMPTY,
- /* name = */ Name.identifier("getOwner"),
- /* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
- /* source = */ SourceElement.NO_SOURCE
- )
- )
-
- override fun doInitialize() {
- val descriptor = symbol.descriptor as SimpleFunctionDescriptorImpl
- val valueParameters = superFunctionDescriptor.valueParameters
- .map { it.copyAsValueParameter(descriptor, it.index) }
-
- descriptor.initialize(
- /* receiverParameterType = */ null,
- /* dispatchReceiverParameter = */ functionReferenceClassDescriptor.thisAsReceiverParameter,
- /* typeParameters = */ emptyList(),
- /* unsubstitutedValueParameters = */ valueParameters,
- /* unsubstitutedReturnType = */ superFunctionDescriptor.returnType,
- /* modality = */ Modality.FINAL,
- /* visibility = */ Visibilities.PUBLIC
- ).apply {
- overriddenDescriptors += superFunctionDescriptor
- isSuspend = superFunctionDescriptor.isSuspend
- }
- }
-
- override fun buildIr(): IrSimpleFunction {
- val startOffset = irFunctionReference.startOffset
- val endOffset = irFunctionReference.endOffset
- val ourSymbol = symbol
- return IrFunctionImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
- symbol = ourSymbol,
- returnType = symbol.descriptor.returnType!!.toIrType()!!
- ).apply {
- val function = this
- val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
-
- createParameterDeclarations()
-
- body = irBuilder.irBlockBody(startOffset, endOffset) {
- +irReturn(
- generateCallableReferenceDeclarationContainer(irFunctionReference)
- )
- }
- }
- }
-
- fun IrBuilderWithScope.generateCallableReferenceDeclarationContainer(
- irFunctionReference: IrFunctionReference
- ): IrExpression {
- val descriptor = irFunctionReference.symbol.descriptor
- val globalContext = this@CallableReferenceLowering.context
- val state = globalContext.state
- val container = descriptor.containingDeclaration
-
- val type =
- when {
- container is ClassDescriptor ->
- // TODO: getDefaultType() here is wrong and won't work for arrays
- state.typeMapper.mapType(container.defaultType)
- container is PackageFragmentDescriptor ->
- state.typeMapper.mapOwner(descriptor)
- descriptor is VariableDescriptorWithAccessors ->
- globalContext.state.bindingContext.get(
- CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, descriptor
- )!!
- else -> state.typeMapper.mapOwner(descriptor)
- }
-
- val clazzDescriptor = globalContext.getClass(FqName("java.lang.Class"))
- val clazzSymbol = globalContext.ir.symbols.externalSymbolTable.referenceClass(clazzDescriptor)
- val clazzRef = IrClassReferenceImpl(
- UNDEFINED_OFFSET,
- UNDEFINED_OFFSET,
- clazzDescriptor.toIrType(),
- clazzSymbol,
- CrIrType(type)
- )
-
- val isContainerPackage = if (descriptor is LocalVariableDescriptor)
- DescriptorUtils.getParentOfType(descriptor, ClassDescriptor::class.java) == null
- else
- container is PackageFragmentDescriptor
-
- val reflectionClass = globalContext.getClass(FqName("kotlin.jvm.internal.Reflection"))
- return if (isContainerPackage) {
- // Note that this name is not used in reflection. There should be the name of the referenced declaration's module instead,
- // but there's no nice API to obtain that name here yet
- // TODO: write the referenced declaration's module name and use it in reflection
- val module = IrConstImpl.string(
- -1, -1, globalContext.irBuiltIns.stringType,
- state.moduleName
)
- val functionDescriptor = reflectionClass.getStaticFunction("getOrCreateKotlinPackage", emptyList())
- val functionSymbol = globalContext.ir.symbols.externalSymbolTable.referenceSimpleFunction(functionDescriptor)
- irCall(functionSymbol, functionSymbol.owner.returnType).apply {
- putValueArgument(0, clazzRef)
- putValueArgument(1, module)
- }
- } else {
- val functionDescriptor = reflectionClass.staticScope
- .getContributedFunctions(Name.identifier("getOrCreateKotlinClass"), NoLookupLocation.FROM_BACKEND)
- .single { it.valueParameters.size == 1 }
- val functionSymbol = globalContext.ir.symbols.externalSymbolTable.referenceSimpleFunction(functionDescriptor)
- irCall(functionSymbol, functionSymbol.owner.returnType).apply {
- putValueArgument(0, clazzRef)
- }
- }
+ )
}
}
+ }
+ private fun createGetNameMethod(superNameProperty: IrProperty): IrSimpleFunction {
+ val superGetter = superNameProperty.getter!!
+ val descriptor = WrappedSimpleFunctionDescriptor()
+ return IrFunctionImpl(
+ irFunctionReference.startOffset, irFunctionReference.endOffset,
+ JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
+ IrSimpleFunctionSymbolImpl(descriptor),
+ Name.identifier("getName"),
+ superGetter.visibility,
+ superGetter.modality,
+ returnType = superGetter.returnType,
+ isInline = false,
+ isExternal = false,
+ isTailrec = false,
+ isSuspend = false
+ ).apply {
+ val function = this
+ descriptor.bind(this)
+ parent = functionReferenceClass
+ overriddenSymbols.add(superGetter.symbol)
+ dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
+ val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
+ body = irBuilder.irBlockBody(startOffset, endOffset) {
+ +irReturn(
+ IrConstImpl.string(-1, -1, context.irBuiltIns.stringType, callee.name.asString())
+ )
+ }
+ }
+ }
+
+ private fun createGetOwnerMethod(superFunction: IrSimpleFunction): IrSimpleFunction {
+ val descriptor = WrappedSimpleFunctionDescriptor()
+ return IrFunctionImpl(
+ functionReferenceClass.startOffset, functionReferenceClass.endOffset,
+ JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
+ IrSimpleFunctionSymbolImpl(descriptor),
+ Name.identifier("getOwner"),
+ superFunction.visibility,
+ superFunction.modality,
+ returnType = superFunction.returnType,
+ isInline = false,
+ isExternal = false,
+ isTailrec = false,
+ isSuspend = false
+ ).apply {
+ val function = this
+ descriptor.bind(this)
+ parent = functionReferenceClass
+ overriddenSymbols.add(superFunction.symbol)
+ dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
+
+ val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
+ body = irBuilder.irBlockBody(startOffset, endOffset) {
+ +irReturn(
+ generateCallableReferenceDeclarationContainer()
+ )
+ }
+ }
+ }
+
+ fun IrBuilderWithScope.generateCallableReferenceDeclarationContainer(): IrExpression {
+ val globalContext = this@CallableReferenceLowering.context
+ val state = globalContext.state
+ val irContainer = callee.parent
+
+ val isContainerPackage =
+ ((irContainer as? IrClass)?.origin == IrDeclarationOrigin.FILE_CLASS) || irContainer is IrPackageFragment
+
+ val type = when {
+ irContainer is IrClass ->
+ // TODO: getDefaultType() here is wrong and won't work for arrays
+ state.typeMapper.mapType(irContainer.defaultType.toKotlinType())
+
+// // TODO: this code is only needed for property references, which are not yet supported.
+// descriptor is VariableDescriptorWithAccessors -> {
+// assert(false) { "VariableDescriptorWithAccessors" }
+// globalContext.state.bindingContext.get(
+// CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, descriptor
+// )!!
+// }
+
+ else -> state.typeMapper.mapOwner(callee.descriptor)
+ }
+
+ val clazz = globalContext.getIrClass(FqName("java.lang.Class")).owner
+ val clazzRef = IrClassReferenceImpl(
+ UNDEFINED_OFFSET,
+ UNDEFINED_OFFSET,
+ clazz.defaultType,
+ clazz.symbol,
+ CrIrType(type)
+ )
+
+ val reflectionClass = globalContext.getIrClass(FqName("kotlin.jvm.internal.Reflection"))
+ return if (isContainerPackage) {
+ // Note that this name is not used in reflection. There should be the name of the referenced declaration's module instead,
+ // but there's no nice API to obtain that name here yet
+ // TODO: write the referenced declaration's module name and use it in reflection
+ val module = IrConstImpl.string(
+ -1, -1, globalContext.irBuiltIns.stringType,
+ state.moduleName
+ )
+ val functionSymbol = reflectionClass.functions.find { it.owner.name.asString() == "getOrCreateKotlinPackage" }!!
+ irCall(functionSymbol, functionSymbol.owner.returnType).apply {
+ putValueArgument(0, clazzRef)
+ putValueArgument(1, module)
+ }
+ } else {
+ val functionSymbol = reflectionClass.functions.filter { it.owner.name.asString() == "getOrCreateKotlinClass" }
+ .single { it.owner.valueParameters.size == 1 }
+ irCall(functionSymbol, functionSymbol.owner.returnType).apply {
+ putValueArgument(0, clazzRef)
+ }
+ }
+ }
}
//TODO rewrite
@@ -798,38 +631,41 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa
}
}
-// Copied from K/Native IrUtils2.kt
-// TODO move IrUtils2.kt to common
-private fun IrClass.createParameterDeclarations() {
- thisReceiver = IrValueParameterImpl(
- startOffset, endOffset,
- IrDeclarationOrigin.INSTANCE_RECEIVER,
- descriptor.thisAsReceiverParameter,
- this.symbol.typeWith(this.typeParameters.map { it.defaultType }),
- null
- ).also { valueParameter ->
- valueParameter.parent = this
+// TODO: Move to IrUtils
+
+private fun IrFunction.isInlineFunction(context: JvmBackendContext) =
+ (!context.state.isInlineDisabled || typeParameters.any { it.isReified }) &&
+ (isInline || isArrayConstructorWithLambda())
+
+private fun IrFunction.isArrayConstructorWithLambda() =
+ valueParameters.size == 2 &&
+ this is IrConstructor &&
+ parentAsClass.let {
+ it.getPackageFragment()?.fqName?.asString() == "kotlin" &&
+ it.name.asString().endsWith("Array")
+ }
+
+private fun IrValueParameter.isInlineParameter() =
+ !isNoinline && !type.isNullable() && type.isFunctionOrKFunction()
+
+private fun IrType.substitute(substitutionMap: Map): IrType {
+ if (this !is IrSimpleType) return this
+
+ substitutionMap[classifier]?.let { return it }
+
+ val newArguments = arguments.map {
+ if (it is IrTypeProjection) {
+ makeTypeProjection(it.type.substitute(substitutionMap), it.variance)
+ } else {
+ it
+ }
}
- assert(typeParameters.isEmpty())
- assert(descriptor.declaredTypeParameters.isEmpty())
+ val newAnnotations = annotations.map { it.deepCopyWithSymbols() }
+ return IrSimpleTypeImpl(
+ classifier,
+ hasQuestionMark,
+ newArguments,
+ newAnnotations
+ )
}
-
-private val IrTypeParameter.defaultType: IrType get() = this.symbol.defaultType
-
-private val IrTypeParameterSymbol.defaultType: IrType
- get() = IrSimpleTypeImpl(
- this,
- false,
- emptyList(),
- emptyList()
- )
-
-
-private fun IrClassifierSymbol.typeWith(arguments: List): IrSimpleType =
- IrSimpleTypeImpl(
- this,
- false,
- arguments.map { makeTypeProjection(it, Variance.INVARIANT) },
- emptyList()
- )
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt
index 4148967835d..3edd776c043 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor
-import org.jetbrains.kotlin.backend.common.makePhase
+import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
@@ -79,6 +79,7 @@ class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
superTypes.add(context.irBuiltIns.anyType)
parent = irFile
declarations.addAll(fileClassMembers)
+ createImplicitParameterDeclarationWithWrappedDescriptor()
// TODO: figure out why reparenting leads to failing tests.
// fileClassMembers.forEach { it.parent = this }
}
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargInvokeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargInvokeLowering.kt
index 32080b5e992..21bf21b4384 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargInvokeLowering.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionNVarargInvokeLowering.kt
@@ -10,8 +10,8 @@ import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDesc
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irIfThen
-import org.jetbrains.kotlin.backend.common.makePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
+import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -52,7 +52,7 @@ class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : ClassLower
val descriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
- origin = CallableReferenceLowering.DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
+ origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
symbol = IrSimpleFunctionSymbolImpl(descriptor),
name = Name.identifier("invoke"),
visibility = Visibilities.PUBLIC,
@@ -68,7 +68,7 @@ class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : ClassLower
val varargParameterDescriptor = WrappedValueParameterDescriptor()
val varargParam = IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
- origin = CallableReferenceLowering.DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
+ origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL,
symbol = IrValueParameterSymbolImpl(varargParameterDescriptor),
name = Name.identifier("args"),
index = 0,
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt
index bbf7d75e4ef..c59fca4f864 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt
@@ -24,10 +24,12 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
-interface IrClass : IrSymbolDeclaration, IrDeclarationWithVisibility, IrDeclarationContainer, IrTypeParametersContainer {
+interface IrClass :
+ IrSymbolDeclaration, IrDeclarationWithName, IrDeclarationWithVisibility,
+ IrDeclarationContainer, IrTypeParametersContainer {
+
override val descriptor: ClassDescriptor
- val name: Name
val kind: ClassKind
val modality: Modality
val isCompanion: Boolean
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt
index 2f69f8bd230..9b162ea64b3 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
+import org.jetbrains.kotlin.name.Name
interface IrSymbolOwner : IrElement {
val symbol: IrSymbol
@@ -49,3 +50,7 @@ interface IrDeclarationWithVisibility : IrDeclaration {
val visibility: Visibility
}
+interface IrDeclarationWithName : IrDeclaration {
+ val name: Name
+}
+
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt
index bbf0c369005..fbf81f1224f 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt
@@ -28,7 +28,8 @@ interface IrDeclarationOrigin {
object DELEGATED_PROPERTY_ACCESSOR : IrDeclarationOriginImpl("DELEGATED_PROPERTY_ACCESSOR")
object DELEGATED_MEMBER : IrDeclarationOriginImpl("DELEGATED_MEMBER")
object ENUM_CLASS_SPECIAL_MEMBER : IrDeclarationOriginImpl("ENUM_CLASS_SPECIAL_MEMBER")
- object FUNCTION_FOR_DEFAULT_PARAMETER : IrDeclarationOriginImpl("FUNCTION_FOR_DEFAULT_PARAMETER")
+ object FUNCTION_FOR_DEFAULT_PARAMETER : IrDeclarationOriginImpl("FUNCTION_FOR_DEFAULT_PARAMETER", isSynthetic = true)
+ object FILE_CLASS : IrDeclarationOriginImpl("FILE_CLASS")
object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER")
object GENERATED_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_INLINE_CLASS_MEMBER")
object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA")
@@ -44,8 +45,13 @@ interface IrDeclarationOrigin {
object FIELD_FOR_ENUM_ENTRY : IrDeclarationOriginImpl("FIELD_FOR_ENUM_ENTRY")
object FIELD_FOR_ENUM_VALUES : IrDeclarationOriginImpl("FIELD_FOR_ENUM_VALUES")
object FIELD_FOR_OBJECT_INSTANCE : IrDeclarationOriginImpl("FIELD_FOR_OBJECT_INSTANCE")
+
+ val isSynthetic: Boolean get() = false
}
-abstract class IrDeclarationOriginImpl(val name: String) : IrDeclarationOrigin {
+abstract class IrDeclarationOriginImpl(
+ val name: String,
+ override val isSynthetic: Boolean = false
+) : IrDeclarationOrigin {
override fun toString(): String = name
-}
\ No newline at end of file
+}
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt
index 160c0eceddf..93252f854ff 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt
@@ -19,13 +19,10 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
-import org.jetbrains.kotlin.name.Name
-interface IrEnumEntry : IrSymbolDeclaration {
+interface IrEnumEntry : IrSymbolDeclaration, IrDeclarationWithName {
override val descriptor: ClassDescriptor
- val name: Name
-
var correspondingClass: IrClass?
var initializerExpression: IrExpression?
}
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrField.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrField.kt
index b5f770b9c35..0fdfe1efc6d 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrField.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrField.kt
@@ -9,12 +9,11 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.name.Name
-interface IrField : IrSymbolDeclaration, IrOverridableDeclaration, IrDeclarationWithVisibility, IrDeclarationParent {
+interface IrField : IrSymbolDeclaration, IrOverridableDeclaration,
+ IrDeclarationWithName, IrDeclarationWithVisibility, IrDeclarationParent {
override val descriptor: PropertyDescriptor
- val name: Name
val type: IrType
val isFinal: Boolean
val isExternal: Boolean
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt
index d4d69e31695..3547a2b57a5 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt
@@ -22,13 +22,13 @@ import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.name.Name
-interface IrFunction : IrDeclarationWithVisibility, IrTypeParametersContainer, IrSymbolOwner, IrDeclarationParent, IrReturnTarget {
+interface IrFunction :
+ IrDeclarationWithName, IrDeclarationWithVisibility, IrTypeParametersContainer, IrSymbolOwner, IrDeclarationParent, IrReturnTarget {
+
override val descriptor: FunctionDescriptor
override val symbol: IrFunctionSymbol
- val name: Name
val isInline: Boolean // NB: there's an inline constructor for Array and each primitive array class
val isExternal: Boolean
var returnType: IrType
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt
index a08662334ea..b31f45d4a0f 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt
@@ -18,12 +18,10 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.name.Name
-interface IrLocalDelegatedProperty : IrDeclaration {
+interface IrLocalDelegatedProperty : IrDeclarationWithName {
override val descriptor: VariableDescriptorWithAccessors
- val name: Name
val type: IrType
val isVar: Boolean
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt
index fe80b3c54b6..6c2710bcb4c 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt
@@ -18,13 +18,10 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
-import org.jetbrains.kotlin.descriptors.Visibility
-import org.jetbrains.kotlin.name.Name
-interface IrProperty : IrDeclarationWithVisibility {
+interface IrProperty : IrDeclarationWithName, IrDeclarationWithVisibility {
override val descriptor: PropertyDescriptor
- val name: Name
val modality: Modality
val isVar: Boolean
val isConst: Boolean
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt
index d0e9ce3323b..f13063b5d82 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt
@@ -20,13 +20,11 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
-import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
-interface IrTypeParameter : IrSymbolDeclaration {
+interface IrTypeParameter : IrSymbolDeclaration, IrDeclarationWithName {
override val descriptor: TypeParameterDescriptor
- val name: Name
val variance: Variance
val index: Int
val isReified: Boolean
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrValueDeclaration.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrValueDeclaration.kt
index 8eea46c008f..362434e3b4b 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrValueDeclaration.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrValueDeclaration.kt
@@ -8,13 +8,10 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.types.KotlinType
-interface IrValueDeclaration : IrDeclaration, IrSymbolOwner {
+interface IrValueDeclaration : IrDeclarationWithName, IrSymbolOwner {
override val descriptor: ValueDescriptor
override val symbol: IrValueSymbol
- val name: Name
val type: IrType
}
\ No newline at end of file
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt
index 7c92b710080..54b4fa15ca1 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt
@@ -33,8 +33,11 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import java.util.*
-inline fun T.deepCopyWithSymbols(initialParent: IrDeclarationParent? = null): T {
- val symbolRemapper = DeepCopySymbolRemapper()
+inline fun T.deepCopyWithSymbols(
+ initialParent: IrDeclarationParent? = null,
+ descriptorRemapper: DescriptorsRemapper = DescriptorsRemapper.DEFAULT
+): T {
+ val symbolRemapper = DeepCopySymbolRemapper(descriptorRemapper)
acceptVoid(symbolRemapper)
val typeRemapper = DeepCopyTypeRemapper(symbolRemapper)
return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper), null).patchDeclarationParents(initialParent) as T
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt
index de8e1a2302b..34f86f11232 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt
@@ -259,6 +259,9 @@ val IrClassSymbol.constructors: Sequence
val IrClass.constructors: Sequence
get() = this.declarations.asSequence().filterIsInstance()
+val IrDeclarationContainer.properties: Sequence
+ get() = declarations.asSequence().filterIsInstance()
+
val IrFunction.explicitParameters: List
get() = (listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters)
diff --git a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java
index 6f8bc399898..0d95eae5a3f 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java
@@ -852,7 +852,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
PsiBuilder.Marker atWhenStart = mark();
myKotlinParsing.parseAnnotationsList(DEFAULT, TokenSet.create(EQ, RPAR));
if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
- IElementType declType = myKotlinParsing.parseProperty(KotlinParsing.PropertyParsingMode.LOCAL);
+ IElementType declType = myKotlinParsing.parseProperty(KotlinParsing.DeclarationParsingMode.LOCAL);
atWhenStart.done(declType);
atWhenStart.setCustomEdgeTokenBinders(PrecedingDocCommentsBinder.INSTANCE, TrailingCommentsBinder.INSTANCE);
@@ -1068,7 +1068,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
KotlinParsing.ModifierDetector detector = new KotlinParsing.ModifierDetector();
myKotlinParsing.parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
- IElementType declType = parseLocalDeclarationRest(detector.isEnumDetected(), rollbackIfDefinitelyNotExpression, isScriptTopLevel);
+ IElementType declType = parseLocalDeclarationRest(detector, rollbackIfDefinitelyNotExpression, isScriptTopLevel);
if (declType != null) {
// we do not attach preceding comments (non-doc) to local variables because they are likely commenting a few statements below
@@ -1348,29 +1348,19 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
* ;
*/
@Nullable
- private IElementType parseLocalDeclarationRest(boolean isEnum, boolean failIfDefinitelyNotExpression, boolean isScriptTopLevel) {
+ private IElementType parseLocalDeclarationRest(
+ @NotNull KotlinParsing.ModifierDetector modifierDetector,
+ boolean failIfDefinitelyNotExpression,
+ boolean isScriptTopLevel
+ ) {
IElementType keywordToken = tt();
- IElementType declType = null;
-
if (failIfDefinitelyNotExpression) {
if (keywordToken != FUN_KEYWORD) return null;
return myKotlinParsing.parseFunction(/* failIfIdentifierExists = */ true);
}
- if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
- declType = myKotlinParsing.parseClass(isEnum);
- }
- else if (keywordToken == FUN_KEYWORD) {
- declType = myKotlinParsing.parseFunction();
- }
- else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
- declType = myKotlinParsing.parseLocalProperty(isScriptTopLevel);
- }
- else if (keywordToken == TYPE_ALIAS_KEYWORD) {
- declType = myKotlinParsing.parseTypeAlias();
- }
- else if (keywordToken == OBJECT_KEYWORD) {
+ if (keywordToken == OBJECT_KEYWORD) {
// Object expression may appear at the statement position: should parse it
// as expression instead of object declaration
// sample:
@@ -1382,11 +1372,12 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
if (lookahead == COLON || lookahead == LBRACE) {
return null;
}
-
- myKotlinParsing.parseObject(NameParsingMode.REQUIRED, true);
- declType = OBJECT_DECLARATION;
}
- return declType;
+
+ return myKotlinParsing.parseCommonDeclaration(
+ modifierDetector, NameParsingMode.REQUIRED,
+ isScriptTopLevel ? KotlinParsing.DeclarationParsingMode.SCRIPT_TOPLEVEL : KotlinParsing.DeclarationParsingMode.LOCAL
+ );
}
/*
@@ -1825,7 +1816,15 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
if (at(COLON) && lookahead(1) == IDENTIFIER) {
errorAndAdvance("Unexpected type specification", 2);
}
- if (!at(COMMA)) break;
+ if (!at(COMMA)) {
+ if (atSet(EXPRESSION_FIRST)) {
+ error("Expecting ','");
+ continue;
+ }
+ else {
+ break;
+ }
+ }
advance(); // COMMA
if (at(RPAR)) {
error("Expecting an argument");
diff --git a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java
index 2b9628edd9f..1e1a020a354 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java
@@ -416,32 +416,20 @@ public class KotlinParsing extends AbstractKotlinParsing {
ModifierDetector detector = new ModifierDetector();
parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
- IElementType keywordToken = tt();
- IElementType declType = null;
+ IElementType declType = parseCommonDeclaration(detector, NameParsingMode.REQUIRED, DeclarationParsingMode.MEMBER_OR_TOPLEVEL);
- if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
- declType = parseClass(detector.isEnumDetected());
- }
- else if (keywordToken == FUN_KEYWORD) {
- declType = parseFunction();
- }
- else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
- declType = parseProperty();
- }
- else if (keywordToken == TYPE_ALIAS_KEYWORD) {
- declType = parseTypeAlias();
- }
- else if (keywordToken == OBJECT_KEYWORD) {
- parseObject(NameParsingMode.REQUIRED, true);
- declType = OBJECT_DECLARATION;
- }
- else if (at(LBRACE)) {
+ if (declType == null && at(LBRACE)) {
error("Expecting a top level declaration");
parseBlock();
declType = FUN;
}
- if (declType == null) {
+ if (declType == null && at(IMPORT_KEYWORD)) {
+ error("imports are only allowed in the beginning of file");
+ parseImportDirectives();
+ decl.drop();
+ }
+ else if (declType == null) {
errorAndAdvance("Expecting a top level declaration");
decl.drop();
}
@@ -450,6 +438,35 @@ public class KotlinParsing extends AbstractKotlinParsing {
}
}
+ public IElementType parseCommonDeclaration(
+ @NotNull ModifierDetector detector,
+ @NotNull NameParsingMode nameParsingModeForObject,
+ @NotNull DeclarationParsingMode declarationParsingMode
+ ) {
+ IElementType keywordToken = tt();
+
+ if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
+ return parseClass(detector.isEnumDetected(), true);
+ }
+ else if (keywordToken == FUN_KEYWORD) {
+ return parseFunction();
+ }
+ else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
+ return parseProperty(declarationParsingMode);
+ }
+ else if (keywordToken == TYPE_ALIAS_KEYWORD) {
+ return parseTypeAlias();
+ }
+ else if (keywordToken == OBJECT_KEYWORD) {
+ parseObject(nameParsingModeForObject, true);
+ return OBJECT_DECLARATION;
+ } else if (keywordToken == IDENTIFIER && detector.isEnumDetected() && declarationParsingMode.canBeEnumUsedAsSoftKeyword) {
+ return parseClass(true, false);
+ }
+
+ return null;
+ }
+
/*
* (modifier | annotation)*
*/
@@ -793,12 +810,6 @@ public class KotlinParsing extends AbstractKotlinParsing {
PROHIBITED
}
- public enum DeclarationParsingMode {
- TOP_LEVEL,
- CLASS_MEMBER,
- LOCAL
- }
-
/*
* class
* : modifiers ("class" | "interface") SimpleName
@@ -821,15 +832,22 @@ public class KotlinParsing extends AbstractKotlinParsing {
boolean object,
NameParsingMode nameParsingMode,
boolean optionalBody,
- boolean enumClass
+ boolean enumClass,
+ boolean expectKindKeyword
) {
- if (object) {
- assert _at(OBJECT_KEYWORD);
+ if (expectKindKeyword) {
+ if (object) {
+ assert _at(OBJECT_KEYWORD);
+ }
+ else {
+ assert _atSet(CLASS_KEYWORD, INTERFACE_KEYWORD);
+ }
+ advance(); // CLASS_KEYWORD, INTERFACE_KEYWORD or OBJECT_KEYWORD
}
else {
- assert _atSet(CLASS_KEYWORD, INTERFACE_KEYWORD);
+ assert enumClass : "Currently classifiers without class/interface/object are only allowed for enums";
+ error("'class' keyword is expected after 'enum'");
}
- advance(); // CLASS_KEYWORD, INTERFACE_KEYWORD or OBJECT_KEYWORD
if (nameParsingMode == NameParsingMode.REQUIRED) {
expect(IDENTIFIER, "Name expected", CLASS_NAME_RECOVERY_SET);
@@ -914,12 +932,12 @@ public class KotlinParsing extends AbstractKotlinParsing {
return object ? OBJECT_DECLARATION : CLASS;
}
- IElementType parseClass(boolean enumClass) {
- return parseClassOrObject(false, NameParsingMode.REQUIRED, true, enumClass);
+ private IElementType parseClass(boolean enumClass, boolean expectKindKeyword) {
+ return parseClassOrObject(false, NameParsingMode.REQUIRED, true, enumClass, expectKindKeyword);
}
void parseObject(NameParsingMode nameParsingMode, boolean optionalBody) {
- parseClassOrObject(true, nameParsingMode, optionalBody, false);
+ parseClassOrObject(true, nameParsingMode, optionalBody, false, true);
}
/*
@@ -1097,7 +1115,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
ModifierDetector detector = new ModifierDetector();
parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
- IElementType declType = parseMemberDeclarationRest(detector.isEnumDetected(), detector.isDefaultDetected());
+ IElementType declType = parseMemberDeclarationRest(detector);
if (declType == null) {
errorWithRecovery("Expecting member declaration", TokenSet.EMPTY);
@@ -1108,26 +1126,16 @@ public class KotlinParsing extends AbstractKotlinParsing {
}
}
- private IElementType parseMemberDeclarationRest(boolean isEnum, boolean isDefault) {
- IElementType keywordToken = tt();
- IElementType declType = null;
- if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
- declType = parseClass(isEnum);
- }
- else if (keywordToken == FUN_KEYWORD) {
- declType = parseFunction();
- }
- else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
- declType = parseProperty();
- }
- else if (keywordToken == TYPE_ALIAS_KEYWORD) {
- declType = parseTypeAlias();
- }
- else if (keywordToken == OBJECT_KEYWORD) {
- parseObject(isDefault ? NameParsingMode.ALLOWED : NameParsingMode.REQUIRED, true);
- declType = OBJECT_DECLARATION;
- }
- else if (at(INIT_KEYWORD)) {
+ private IElementType parseMemberDeclarationRest(@NotNull ModifierDetector modifierDetector) {
+ IElementType declType = parseCommonDeclaration(
+ modifierDetector,
+ modifierDetector.isCompanionDetected() ? NameParsingMode.ALLOWED : NameParsingMode.REQUIRED,
+ DeclarationParsingMode.MEMBER_OR_TOPLEVEL
+ );
+
+ if (declType != null) return declType;
+
+ if (at(INIT_KEYWORD)) {
advance(); // init
if (at(LBRACE)) {
parseBlock();
@@ -1225,7 +1233,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
* : modifiers "typealias" SimpleName typeParameters? "=" type
* ;
*/
- IElementType parseTypeAlias() {
+ private IElementType parseTypeAlias() {
assert _at(TYPE_ALIAS_KEYWORD);
advance(); // TYPE_ALIAS_KEYWORD
@@ -1249,6 +1257,22 @@ public class KotlinParsing extends AbstractKotlinParsing {
return TYPEALIAS;
}
+ enum DeclarationParsingMode {
+ MEMBER_OR_TOPLEVEL(false, true, true),
+ LOCAL(true, false, false),
+ SCRIPT_TOPLEVEL(true, true, false);
+
+ public final boolean destructuringAllowed;
+ public final boolean accessorsAllowed;
+ public final boolean canBeEnumUsedAsSoftKeyword;
+
+ DeclarationParsingMode(boolean destructuringAllowed, boolean accessorsAllowed, boolean canBeEnumUsedAsSoftKeyword) {
+ this.destructuringAllowed = destructuringAllowed;
+ this.accessorsAllowed = accessorsAllowed;
+ this.canBeEnumUsedAsSoftKeyword = canBeEnumUsedAsSoftKeyword;
+ }
+ }
+
/*
* variableDeclarationEntry
* : SimpleName (":" type)?
@@ -1264,29 +1288,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
* (getter? setter? | setter? getter?) SEMI?
* ;
*/
- private IElementType parseProperty() {
- return parseProperty(PropertyParsingMode.MEMBER_OR_TOPLEVEL);
- }
-
- public IElementType parseLocalProperty(boolean isScriptTopLevel) {
- return parseProperty(isScriptTopLevel ? PropertyParsingMode.SCRIPT_TOPLEVEL : PropertyParsingMode.LOCAL);
- }
-
- enum PropertyParsingMode {
- MEMBER_OR_TOPLEVEL(false, true),
- LOCAL(true, false),
- SCRIPT_TOPLEVEL(true, true);
-
- public final boolean destructuringAllowed;
- public final boolean accessorsAllowed;
-
- PropertyParsingMode(boolean destructuringAllowed, boolean accessorsAllowed) {
- this.destructuringAllowed = destructuringAllowed;
- this.accessorsAllowed = accessorsAllowed;
- }
- }
-
- public IElementType parseProperty(PropertyParsingMode mode) {
+ public IElementType parseProperty(DeclarationParsingMode mode) {
assert (at(VAL_KEYWORD) || at(VAR_KEYWORD));
advance();
@@ -2255,6 +2257,12 @@ public class KotlinParsing extends AbstractKotlinParsing {
if (at(COMMA)) {
advance(); // COMMA
}
+ else if (at(COLON)) {
+ // recovery for the case "fun bar(x: Array : Int)" when we've just parsed "x: Array"
+ // error should be reported in the `parseValueParameter` call
+ //noinspection UnnecessaryContinue
+ continue;
+ }
else {
if (!at(RPAR)) error("Expecting comma or ')'");
if (!atSet(isFunctionTypeContents ? LAMBDA_VALUE_PARAMETER_FIRST : VALUE_PARAMETER_FIRST)) break;
@@ -2325,6 +2333,14 @@ public class KotlinParsing extends AbstractKotlinParsing {
if (at(COLON)) {
advance(); // COLON
+
+ if (at(IDENTIFIER) && lookahead(1) == COLON) {
+ // recovery for the case "fun foo(x: y: Int)" when we're at "y: " it's likely that this is a name of the next parameter,
+ // not a type reference of the current one
+ error("Type reference expected");
+ return false;
+ }
+
parseTypeRef();
}
else if (typeRequired) {
@@ -2348,7 +2364,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
/*package*/ static class ModifierDetector implements Consumer {
private boolean enumDetected = false;
- private boolean defaultDetected = false;
+ private boolean companionDetected = false;
@Override
public void consume(IElementType item) {
@@ -2356,7 +2372,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
enumDetected = true;
}
else if (item == KtTokens.COMPANION_KEYWORD) {
- defaultDetected = true;
+ companionDetected = true;
}
}
@@ -2364,8 +2380,8 @@ public class KotlinParsing extends AbstractKotlinParsing {
return enumDetected;
}
- public boolean isDefaultDetected() {
- return defaultDetected;
+ public boolean isCompanionDetected() {
+ return companionDetected;
}
}
diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt
index fde5e476148..726d4f273d5 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt
+++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt
@@ -22,6 +22,7 @@ import com.intellij.openapi.fileTypes.FileType
import com.intellij.psi.*
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil
+import com.intellij.util.ArrayFactory
import com.intellij.util.FileContentUtilCore
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.KtNodeTypes
@@ -54,13 +55,16 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) :
private var pathCached: String? = null
val importList: KtImportList?
- get() = findChildByTypeOrClass(KtStubElementTypes.IMPORT_LIST, KtImportList::class.java)
+ get() = importLists.firstOrNull()
+
+ private val importLists: Array
+ get() = findChildrenByTypeOrClass(KtStubElementTypes.IMPORT_LIST, KtImportList::class.java)
val fileAnnotationList: KtFileAnnotationList?
get() = findChildByTypeOrClass(KtStubElementTypes.FILE_ANNOTATION_LIST, KtFileAnnotationList::class.java)
open val importDirectives: List
- get() = importList?.imports ?: emptyList()
+ get() = importLists.flatMap { it.imports }
// scripts have no package directive, all other files must have package directives
val packageDirective: KtPackageDirective?
@@ -154,6 +158,19 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) :
return findChildByClass(elementClass)
}
+ fun >> findChildrenByTypeOrClass(
+ elementType: KtPlaceHolderStubElementType,
+ elementClass: Class
+ ): Array {
+ val stub = stub
+ if (stub != null) {
+ val arrayFactory: ArrayFactory = elementType.arrayFactory
+ return stub.getChildrenByType(elementType, arrayFactory)
+ }
+ return findChildrenByClass(elementClass)
+ }
+
+
fun findImportByAlias(name: String): KtImportDirective? =
importDirectives.firstOrNull { name == it.aliasName }
diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt
index e3ff55ad804..648125c9207 100644
--- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt
+++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt
@@ -29,22 +29,17 @@ class IsFunctor(val type: KotlinType, val isNegated: Boolean) : AbstractReducing
fun invokeWithArguments(arg: Computation): List {
return if (arg is ESValue)
- invokeWithValue(arg, null)
+ invokeWithValue(arg)
else
- arg.effects.flatMap {
- if (it !is ConditionalEffect || it.simpleEffect !is ESReturns || it.simpleEffect.value == ESConstant.WILDCARD)
- listOf(it)
- else
- invokeWithValue(it.simpleEffect.value, it.condition)
- }
+ emptyList()
}
- private fun invokeWithValue(value: ESValue, additionalCondition: ESExpression?): List {
+ private fun invokeWithValue(value: ESValue): List {
val trueIs = ESIs(value, this)
val falseIs = ESIs(value, IsFunctor(type, isNegated.not()))
- val trueResult = ConditionalEffect(trueIs.and(additionalCondition), ESReturns(true.lift()))
- val falseResult = ConditionalEffect(falseIs.and(additionalCondition), ESReturns(false.lift()))
+ val trueResult = ConditionalEffect(trueIs, ESReturns(true.lift()))
+ val falseResult = ConditionalEffect(falseIs, ESReturns(false.lift()))
return listOf(trueResult, falseResult)
}
}
\ No newline at end of file
diff --git a/compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt b/compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt
index 008ce18dd03..f37b6b89a98 100644
--- a/compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt
+++ b/compiler/testData/codegen/box/callableReference/function/sortListOfStrings.kt
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun sort(list: MutableList, comparator: (String, String) -> Int) {
diff --git a/compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt b/compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt
new file mode 100644
index 00000000000..200c3863356
--- /dev/null
+++ b/compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt
@@ -0,0 +1,21 @@
+// IGNORE_BACKEND: JVM_IR
+// WITH_RUNTIME
+
+interface Wrapper { fun runBlock() }
+
+inline fun crossInlineBuildWrapper(crossinline block: () -> Unit) = object : Wrapper {
+ override fun runBlock() {
+ block()
+ }
+}
+
+class Container {
+ val wrapper = crossInlineBuildWrapper {
+ object { }
+ }
+}
+
+fun box(): String {
+ Container().wrapper.runBlock()
+ return "OK"
+}
diff --git a/compiler/testData/codegen/box/collectionLiterals/collectionLiteralsWithConstants.kt b/compiler/testData/codegen/box/collectionLiterals/collectionLiteralsWithConstants.kt
index 32c8fe4d778..c565aab7244 100644
--- a/compiler/testData/codegen/box/collectionLiterals/collectionLiteralsWithConstants.kt
+++ b/compiler/testData/codegen/box/collectionLiterals/collectionLiteralsWithConstants.kt
@@ -1,6 +1,5 @@
// WITH_REFLECT
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
import java.util.Arrays
diff --git a/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt b/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt
index a2f540ba537..7334f3dd334 100644
--- a/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt
+++ b/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt
@@ -1,6 +1,5 @@
// !LANGUAGE: -ReleaseCoroutines
// IGNORE_BACKEND: JS_IR
-// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND: JS
diff --git a/compiler/testData/codegen/box/enum/kt20651b.kt b/compiler/testData/codegen/box/enum/kt20651b.kt
index 477e3036569..348857ff448 100644
--- a/compiler/testData/codegen/box/enum/kt20651b.kt
+++ b/compiler/testData/codegen/box/enum/kt20651b.kt
@@ -1,3 +1,5 @@
+// IGNORE_BACKEND: JVM_IR
+
interface Callback {
fun invoke(): String
}
diff --git a/compiler/testData/codegen/box/jvmName/annotationProperties.kt b/compiler/testData/codegen/box/jvmName/annotationProperties.kt
index 836c81eb8f7..b3c951f952f 100644
--- a/compiler/testData/codegen/box/jvmName/annotationProperties.kt
+++ b/compiler/testData/codegen/box/jvmName/annotationProperties.kt
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM
-// IGNORE_BACKEND: JVM_IR
// WITH_REFLECT
import kotlin.test.assertEquals
diff --git a/compiler/testData/codegen/box/reflection/annotations/retentions.kt b/compiler/testData/codegen/box/reflection/annotations/retentions.kt
index b3c2f35445c..3d9597bd113 100644
--- a/compiler/testData/codegen/box/reflection/annotations/retentions.kt
+++ b/compiler/testData/codegen/box/reflection/annotations/retentions.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/annotations/simpleFunAnnotation.kt b/compiler/testData/codegen/box/reflection/annotations/simpleFunAnnotation.kt
index 7d9e0893927..9bf7297f9b3 100644
--- a/compiler/testData/codegen/box/reflection/annotations/simpleFunAnnotation.kt
+++ b/compiler/testData/codegen/box/reflection/annotations/simpleFunAnnotation.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/annotations/simpleParamAnnotation.kt b/compiler/testData/codegen/box/reflection/annotations/simpleParamAnnotation.kt
index 49af2f9360e..6e642f79c54 100644
--- a/compiler/testData/codegen/box/reflection/annotations/simpleParamAnnotation.kt
+++ b/compiler/testData/codegen/box/reflection/annotations/simpleParamAnnotation.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/call/bound/extensionFunction.kt b/compiler/testData/codegen/box/reflection/call/bound/extensionFunction.kt
index b18ee72af00..993e4820d8d 100644
--- a/compiler/testData/codegen/box/reflection/call/bound/extensionFunction.kt
+++ b/compiler/testData/codegen/box/reflection/call/bound/extensionFunction.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/callBy/nonDefaultParameterOmitted.kt b/compiler/testData/codegen/box/reflection/callBy/nonDefaultParameterOmitted.kt
index 9f036301883..51a03692991 100644
--- a/compiler/testData/codegen/box/reflection/callBy/nonDefaultParameterOmitted.kt
+++ b/compiler/testData/codegen/box/reflection/callBy/nonDefaultParameterOmitted.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/mapping/types/genericArrayElementType.kt b/compiler/testData/codegen/box/reflection/mapping/types/genericArrayElementType.kt
index dc5789e8dbb..d8c06d8cfcd 100644
--- a/compiler/testData/codegen/box/reflection/mapping/types/genericArrayElementType.kt
+++ b/compiler/testData/codegen/box/reflection/mapping/types/genericArrayElementType.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/mapping/types/innerGenericTypeArgument.kt b/compiler/testData/codegen/box/reflection/mapping/types/innerGenericTypeArgument.kt
index 455461c89dd..6277c1abcfe 100644
--- a/compiler/testData/codegen/box/reflection/mapping/types/innerGenericTypeArgument.kt
+++ b/compiler/testData/codegen/box/reflection/mapping/types/innerGenericTypeArgument.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/mapping/types/parameterizedTypeArgument.kt b/compiler/testData/codegen/box/reflection/mapping/types/parameterizedTypeArgument.kt
index d086bef8284..e4d47a93bbf 100644
--- a/compiler/testData/codegen/box/reflection/mapping/types/parameterizedTypeArgument.kt
+++ b/compiler/testData/codegen/box/reflection/mapping/types/parameterizedTypeArgument.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/mapping/types/withNullability.kt b/compiler/testData/codegen/box/reflection/mapping/types/withNullability.kt
index 034dca0e73b..f55c3bf041b 100644
--- a/compiler/testData/codegen/box/reflection/mapping/types/withNullability.kt
+++ b/compiler/testData/codegen/box/reflection/mapping/types/withNullability.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/typeParameters/upperBounds.kt b/compiler/testData/codegen/box/reflection/typeParameters/upperBounds.kt
index 68413d3a6b2..2fdc4cea305 100644
--- a/compiler/testData/codegen/box/reflection/typeParameters/upperBounds.kt
+++ b/compiler/testData/codegen/box/reflection/typeParameters/upperBounds.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/types/classifierIsClass.kt b/compiler/testData/codegen/box/reflection/types/classifierIsClass.kt
index 1d0b234c434..d7e5396cbd9 100644
--- a/compiler/testData/codegen/box/reflection/types/classifierIsClass.kt
+++ b/compiler/testData/codegen/box/reflection/types/classifierIsClass.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/types/classifiersOfBuiltInTypes.kt b/compiler/testData/codegen/box/reflection/types/classifiersOfBuiltInTypes.kt
index e899f3526ce..cb7a4b70b99 100644
--- a/compiler/testData/codegen/box/reflection/types/classifiersOfBuiltInTypes.kt
+++ b/compiler/testData/codegen/box/reflection/types/classifiersOfBuiltInTypes.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/types/jvmErasureOfClass.kt b/compiler/testData/codegen/box/reflection/types/jvmErasureOfClass.kt
index 01c927eabbc..bea77ac9c0f 100644
--- a/compiler/testData/codegen/box/reflection/types/jvmErasureOfClass.kt
+++ b/compiler/testData/codegen/box/reflection/types/jvmErasureOfClass.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/types/subtyping/platformType.kt b/compiler/testData/codegen/box/reflection/types/subtyping/platformType.kt
index e14f13a955e..f9932a50a7d 100644
--- a/compiler/testData/codegen/box/reflection/types/subtyping/platformType.kt
+++ b/compiler/testData/codegen/box/reflection/types/subtyping/platformType.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
diff --git a/compiler/testData/codegen/box/reflection/types/subtyping/simpleGenericTypes.kt b/compiler/testData/codegen/box/reflection/types/subtyping/simpleGenericTypes.kt
index 019e398f7b7..56898204b25 100644
--- a/compiler/testData/codegen/box/reflection/types/subtyping/simpleGenericTypes.kt
+++ b/compiler/testData/codegen/box/reflection/types/subtyping/simpleGenericTypes.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/types/subtyping/typeProjection.kt b/compiler/testData/codegen/box/reflection/types/subtyping/typeProjection.kt
index f31f9bd4cdf..29863590942 100644
--- a/compiler/testData/codegen/box/reflection/types/subtyping/typeProjection.kt
+++ b/compiler/testData/codegen/box/reflection/types/subtyping/typeProjection.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/reflection/types/useSiteVariance.kt b/compiler/testData/codegen/box/reflection/types/useSiteVariance.kt
index b4364479cd7..d6b0fc3fc1f 100644
--- a/compiler/testData/codegen/box/reflection/types/useSiteVariance.kt
+++ b/compiler/testData/codegen/box/reflection/types/useSiteVariance.kt
@@ -1,4 +1,3 @@
-// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
diff --git a/compiler/testData/codegen/box/sam/constructors/comparator.kt b/compiler/testData/codegen/box/sam/constructors/comparator.kt
index 5885a026a1c..56b24616f79 100644
--- a/compiler/testData/codegen/box/sam/constructors/comparator.kt
+++ b/compiler/testData/codegen/box/sam/constructors/comparator.kt
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun box(): String {
diff --git a/compiler/testData/codegen/box/sam/constructors/nonLiteralComparator.kt b/compiler/testData/codegen/box/sam/constructors/nonLiteralComparator.kt
index c415e666343..0bef462b2a9 100644
--- a/compiler/testData/codegen/box/sam/constructors/nonLiteralComparator.kt
+++ b/compiler/testData/codegen/box/sam/constructors/nonLiteralComparator.kt
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
-// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun box(): String {
diff --git a/compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt b/compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt
new file mode 100644
index 00000000000..503349da746
--- /dev/null
+++ b/compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt
@@ -0,0 +1,35 @@
+// WITH_RUNTIME
+// IGNORE_BACKEND: JS, JVM_IR
+
+const val M1: UInt = 2147483648u
+const val M2: ULong = 9223372036854775808UL
+
+fun testUInt(x: UInt) =
+ when (x) {
+ 0u -> "none"
+ 1u -> "one"
+ 2u -> "two"
+ 3u -> "three"
+ M1 -> "M1"
+ else -> "many"
+ }
+
+fun testULong(x: ULong) =
+ when (x) {
+ 0UL -> "none"
+ 1UL -> "one"
+ 2UL -> "two"
+ 3UL -> "three"
+ M2 -> "M2"
+ else -> "many"
+ }
+
+fun box(): String {
+ val t1 = listOf(0u, 1u, 2u, 3u, 4u, M1).map { testUInt(it) }
+ if (t1 != listOf("none", "one", "two", "three", "many", "M1")) throw AssertionError("UInt: $t1")
+
+ val t2 = listOf(0UL, 1UL, 2UL, 3UL, 4UL, M2).map { testULong(it) }
+ if (t2 != listOf("none", "one", "two", "three", "many", "M2")) throw AssertionError("ULong: $t2")
+
+ return "OK"
+}
\ No newline at end of file
diff --git a/compiler/testData/codegen/box/vararg/assigningArrayToVarargInAnnotation.kt b/compiler/testData/codegen/box/vararg/assigningArrayToVarargInAnnotation.kt
index 88de13999e7..d8519bbb06a 100644
--- a/compiler/testData/codegen/box/vararg/assigningArrayToVarargInAnnotation.kt
+++ b/compiler/testData/codegen/box/vararg/assigningArrayToVarargInAnnotation.kt
@@ -1,6 +1,5 @@
// WITH_REFLECT
-// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: JavaAnn.java
diff --git a/compiler/testData/codegen/boxAgainstJava/multiplatform/annotationsViaActualTypeAliasFromBinary.kt b/compiler/testData/codegen/boxAgainstJava/multiplatform/annotationsViaActualTypeAliasFromBinary.kt
index ff743067d66..635fb7d069a 100644
--- a/compiler/testData/codegen/boxAgainstJava/multiplatform/annotationsViaActualTypeAliasFromBinary.kt
+++ b/compiler/testData/codegen/boxAgainstJava/multiplatform/annotationsViaActualTypeAliasFromBinary.kt
@@ -1,6 +1,5 @@
// !LANGUAGE: +MultiPlatformProjects
// WITH_REFLECT
-// IGNORE_BACKEND: JVM_IR
// FILE: main.kt
// See compiler/testData/diagnostics/tests/multiplatform/defaultArguments/annotationsViaActualTypeAlias2.kt
diff --git a/compiler/testData/codegen/bytecodeText/unsignedTypes/whenByUnsigned.kt b/compiler/testData/codegen/bytecodeText/unsignedTypes/whenByUnsigned.kt
new file mode 100644
index 00000000000..51691fa9be3
--- /dev/null
+++ b/compiler/testData/codegen/bytecodeText/unsignedTypes/whenByUnsigned.kt
@@ -0,0 +1,28 @@
+// WITH_RUNTIME
+// IGNORE_BACKEND: JVM_IR
+
+const val M1: UInt = 2147483648u
+
+fun testUInt1(x: UInt) =
+ when (x) {
+ 0u -> "none"
+ 1u -> "one"
+ 2u -> "two"
+ 3u -> "three"
+ else -> "many"
+ }
+
+fun testUInt2(x: UInt) =
+ when (x) {
+ 0u -> "none"
+ 1u -> "one"
+ 2u -> "two"
+ 3u -> "three"
+ M1 -> "M1"
+ else -> "many"
+ }
+
+// 2 SWITCH
+// ^ This captures both TABLESWITCH and LOOKUPSWITCH; we don't care about nuances of *SWITCH instruction generation here.
+
+// 0 IF_ICMP
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/CharacterLiterals.kt b/compiler/testData/diagnostics/tests/CharacterLiterals.kt
index b99ca7098fa..b2e07c99188 100644
--- a/compiler/testData/diagnostics/tests/CharacterLiterals.kt
+++ b/compiler/testData/diagnostics/tests/CharacterLiterals.kt
@@ -4,10 +4,10 @@ fun test(c : Char) {
test('aa')
test('a)
test('
- test(0'
- test('\n')
- test('\\')
- test('''')
+ test(0'
+ test('\n')
+ test('\\')
+ test('''')
test('\'')
test('\"')
}
diff --git a/compiler/testData/diagnostics/tests/imports/twoImportLists.kt b/compiler/testData/diagnostics/tests/imports/twoImportLists.kt
new file mode 100644
index 00000000000..83f36c6a5fc
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/imports/twoImportLists.kt
@@ -0,0 +1,105 @@
+// !WITH_NEW_INFERENCE
+// FILE:a.kt
+package a
+
+<<< FOOO
+import b.B //class
+import b.foo //function
+import b.ext //extension function
+import b.value //property
+import b.C.Companion.bar //function from companion object
+import b.C.Companion.cValue //property from companion object
+import b.constant.fff //function from val
+import b.constant.dValue //property from val
+import smth.illegal
+import b.C.smth.illegal
+
+<<<HEAD
+import b.bar.smth
+import b.bar.*
+import b.unr.unr.unr
+import unr.unr.unr
+import b.constant
+import b.E.Companion.f //val from companion object
+
+fun test(arg: B) {
+ foo(value)
+ arg.ext()
+
+ bar()
+ foo(cValue)
+
+ fff(dValue)
+
+ constant.fff(constant.dValue)
+
+ f.f()
+}
+
+// FILE:b.kt
+package b
+
+class B() {}
+
+fun foo(i: Int) = i
+
+fun B.ext() {}
+
+val value = 0
+
+class C() {
+ companion object {
+ fun bar() {}
+ val cValue = 1
+ }
+}
+
+class D() {
+ fun fff(s: String) = s
+ val dValue = "w"
+}
+
+val constant = D()
+
+class E() {
+ companion object {
+ val f = F()
+ }
+}
+
+class F() {
+ fun f() {}
+}
+
+fun bar() {}
+
+//FILE:c.kt
+package c
+
+import c.C.*
+
+object C {
+ fun f() {
+ }
+ val i = 348
+}
+
+fun foo() {
+ if (i == 3) f()
+}
+
+//FILE:d.kt
+package d
+
+import d.A.Companion.B
+import d.A.Companion.C
+
+val b : B = B()
+val c : B = C
+
+class A() {
+ companion object {
+ open class B() {}
+ object C : B() {}
+ }
+}
diff --git a/compiler/testData/diagnostics/tests/imports/twoImportLists.txt b/compiler/testData/diagnostics/tests/imports/twoImportLists.txt
new file mode 100644
index 00000000000..c875a83e7e5
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/imports/twoImportLists.txt
@@ -0,0 +1,114 @@
+package
+
+package a {
+ public fun test(/*0*/ arg: b.B): kotlin.Unit
+}
+
+package b {
+ public val constant: b.D
+ public val value: kotlin.Int = 0
+ public fun bar(): kotlin.Unit
+ public fun foo(/*0*/ i: kotlin.Int): kotlin.Int
+ public fun b.B.ext(): kotlin.Unit
+
+ public final class B {
+ public constructor B()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+
+ public final class C {
+ public constructor C()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+
+ public companion object Companion {
+ private constructor Companion()
+ public final val cValue: kotlin.Int = 1
+ public final fun bar(): kotlin.Unit
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+ }
+
+ public final class D {
+ public constructor D()
+ public final val dValue: kotlin.String = "w"
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public final fun fff(/*0*/ s: kotlin.String): kotlin.String
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+
+ public final class E {
+ public constructor E()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+
+ public companion object Companion {
+ private constructor Companion()
+ public final val f: b.F
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+ }
+
+ public final class F {
+ public constructor F()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public final fun f(): kotlin.Unit
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+}
+
+package c {
+ public fun foo(): kotlin.Unit
+
+ public object C {
+ private constructor C()
+ public final val i: kotlin.Int = 348
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public final fun f(): kotlin.Unit
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+}
+
+package d {
+ public val b: d.A.Companion.B
+ public val c: d.A.Companion.B
+
+ public final class A {
+ public constructor A()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+
+ public companion object Companion {
+ private constructor Companion()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+
+ public open class B {
+ public constructor B()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+
+ public object C : d.A.Companion.B {
+ private constructor C()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+ }
+ }
+}
diff --git a/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt b/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt
index bffac287aa9..5318cfdfede 100644
--- a/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt
+++ b/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.kt
@@ -119,7 +119,7 @@ class IllegalModifiers7() {
// Secondary constructors
class IllegalModifiers8 {
abstract
- enum
+ enum
open
inner
annotation
@@ -129,7 +129,7 @@ class IllegalModifiers8 {
final
vararg
reified
- const
+ const
constructor() {}
constructor(private enum abstract x: Int) {}
diff --git a/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.txt b/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.txt
index 2915bfd788c..7c5153ea00c 100644
--- a/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.txt
+++ b/compiler/testData/diagnostics/tests/modifiers/IllegalModifiers.txt
@@ -108,11 +108,27 @@ package illegal_modifiers {
}
public final class IllegalModifiers8 {
- public constructor IllegalModifiers8()
public constructor IllegalModifiers8(/*0*/ x: kotlin.Int)
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+
+ public abstract enum class constructor : kotlin.Enum {
+ private constructor constructor()
+ public final override /*1*/ /*fake_override*/ val name: kotlin.String
+ public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
+ protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
+ public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: illegal_modifiers.IllegalModifiers8.constructor): kotlin.Int
+ public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
+ public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class!
+ public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+
+ // Static members
+ public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): illegal_modifiers.IllegalModifiers8.constructor
+ public final /*synthesized*/ fun values(): kotlin.Array
+ }
}
public final class IllegalModifiers9 {
diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt
new file mode 100644
index 00000000000..719b21a4480
--- /dev/null
+++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt
@@ -0,0 +1,11 @@
+// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
+// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
+// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
+
+import kotlin.contracts.*
+
+fun f3(value: String?) {
+ if (!value.isNullOrEmpty() is Boolean) {
+ value.length
+ }
+}
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.txt
new file mode 100644
index 00000000000..7780a7bf0ea
--- /dev/null
+++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.txt
@@ -0,0 +1,3 @@
+package
+
+public fun f3(/*0*/ value: kotlin.String?): kotlin.Unit
diff --git a/compiler/testData/psi/EnumWithAnnotationKeyword.txt b/compiler/testData/psi/EnumWithAnnotationKeyword.txt
index 84aa9116be8..577e705ca69 100644
--- a/compiler/testData/psi/EnumWithAnnotationKeyword.txt
+++ b/compiler/testData/psi/EnumWithAnnotationKeyword.txt
@@ -23,21 +23,20 @@ KtFile: EnumWithAnnotationKeyword.kt
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
- MODIFIER_LIST
- PsiElement(enum)('enum')
- PsiWhiteSpace(' ')
- PsiElement(annotation)('annotation')
- PsiWhiteSpace(' ')
- PsiErrorElement:Expecting a top level declaration
- PsiElement(IDENTIFIER)('E1')
- PsiWhiteSpace(' ')
- FUN
- PsiErrorElement:Expecting a top level declaration
+ CLASS
+ MODIFIER_LIST
+ PsiElement(enum)('enum')
+ PsiWhiteSpace(' ')
+ PsiElement(annotation)('annotation')
+ PsiErrorElement:'class' keyword is expected after 'enum'
- BLOCK
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('E1')
+ PsiWhiteSpace(' ')
+ CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
- REFERENCE_EXPRESSION
+ ENUM_ENTRY
PsiElement(IDENTIFIER)('D')
PsiWhiteSpace('\n')
- PsiElement(RBRACE)('}')
\ No newline at end of file
+ PsiElement(RBRACE)('}')
diff --git a/compiler/testData/psi/FileStart_ERR.txt b/compiler/testData/psi/FileStart_ERR.txt
index bc430fe2284..0e22e68e59b 100644
--- a/compiler/testData/psi/FileStart_ERR.txt
+++ b/compiler/testData/psi/FileStart_ERR.txt
@@ -14,9 +14,12 @@ KtFile: FileStart_ERR.kt
PsiElement(DOT)('.')
PsiErrorElement:Expecting a top level declaration
PsiElement(IDENTIFIER)('bar')
+ PsiErrorElement:imports are only allowed in the beginning of file
+
PsiWhiteSpace('\n')
- PsiErrorElement:Expecting a top level declaration
- PsiElement(IDENTIFIER)('import')
- PsiWhiteSpace(' ')
- PsiErrorElement:Expecting a top level declaration
- PsiElement(IDENTIFIER)('foo')
\ No newline at end of file
+ IMPORT_LIST
+ IMPORT_DIRECTIVE
+ PsiElement(import)('import')
+ PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('foo')
diff --git a/compiler/testData/psi/FunctionExpressions_ERR.txt b/compiler/testData/psi/FunctionExpressions_ERR.txt
index a2f1b01c6b1..29f2093393e 100644
--- a/compiler/testData/psi/FunctionExpressions_ERR.txt
+++ b/compiler/testData/psi/FunctionExpressions_ERR.txt
@@ -575,61 +575,64 @@ KtFile: FunctionExpressions_ERR.kt
PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n\n ')
CALL_EXPRESSION
- CALL_EXPRESSION
- REFERENCE_EXPRESSION
- PsiElement(IDENTIFIER)('bar')
- VALUE_ARGUMENT_LIST
- PsiElement(LPAR)('(')
- VALUE_ARGUMENT
- REFERENCE_EXPRESSION
- PsiElement(IDENTIFIER)('public')
- PsiWhiteSpace(' ')
- PsiErrorElement:Expecting ')'
- PsiElement(fun)('fun')
- PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('public')
+ PsiErrorElement:Expecting ','
+
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
- PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
- PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
- CALL_EXPRESSION
- REFERENCE_EXPRESSION
- PsiElement(IDENTIFIER)('bar')
- VALUE_ARGUMENT_LIST
- PsiElement(LPAR)('(')
- VALUE_ARGUMENT
- REFERENCE_EXPRESSION
- PsiElement(IDENTIFIER)('open')
- PsiWhiteSpace(' ')
- PsiErrorElement:Expecting ')'
- PsiElement(fun)('fun')
- PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('open')
+ PsiErrorElement:Expecting ','
+
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
- PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
- PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
- CALL_EXPRESSION
- REFERENCE_EXPRESSION
- PsiElement(IDENTIFIER)('bar')
- VALUE_ARGUMENT_LIST
- PsiElement(LPAR)('(')
- VALUE_ARGUMENT
- REFERENCE_EXPRESSION
- PsiElement(IDENTIFIER)('final')
- PsiWhiteSpace(' ')
- PsiErrorElement:Expecting ')'
- PsiElement(fun)('fun')
- PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('final')
+ PsiErrorElement:Expecting ','
+
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
- PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
- PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
@@ -659,4 +662,4 @@ KtFile: FunctionExpressions_ERR.kt
PsiElement(IDENTIFIER)('V')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
- PsiElement(RBRACE)('}')
\ No newline at end of file
+ PsiElement(RBRACE)('}')
diff --git a/compiler/testData/psi/noCommaBetweenArguments.kt b/compiler/testData/psi/noCommaBetweenArguments.kt
new file mode 100644
index 00000000000..e54ef261891
--- /dev/null
+++ b/compiler/testData/psi/noCommaBetweenArguments.kt
@@ -0,0 +1,22 @@
+fun foo() {
+ bar1(
+ A()
+ A()
+ )
+ bar2(A() A())
+
+ bar3(x y)
+ bar4(x
+ y
+ )
+
+ bar5("" "")
+ bar6(""
+ ""
+ )
+
+ bar7({} {})
+ bar8({}
+ {}
+ )
+}
diff --git a/compiler/testData/psi/noCommaBetweenArguments.txt b/compiler/testData/psi/noCommaBetweenArguments.txt
new file mode 100644
index 00000000000..bbe4eeb9a49
--- /dev/null
+++ b/compiler/testData/psi/noCommaBetweenArguments.txt
@@ -0,0 +1,182 @@
+KtFile: noCommaBetweenArguments.kt
+ PACKAGE_DIRECTIVE
+
+ IMPORT_LIST
+
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar1')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ PsiWhiteSpace('\n ')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ OPERATION_REFERENCE
+ PsiElement(IDENTIFIER)('A')
+ PARENTHESIZED
+ PsiElement(LPAR)('(')
+ PsiErrorElement:Expecting an expression
+
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar2')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ OPERATION_REFERENCE
+ PsiElement(IDENTIFIER)('A')
+ PARENTHESIZED
+ PsiElement(LPAR)('(')
+ PsiErrorElement:Expecting an expression
+
+ PsiElement(RPAR)(')')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar3')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('x')
+ PsiWhiteSpace(' ')
+ OPERATION_REFERENCE
+ PsiElement(IDENTIFIER)('y')
+ PsiErrorElement:Expecting an element
+
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar4')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ BINARY_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('x')
+ PsiWhiteSpace('\n ')
+ OPERATION_REFERENCE
+ PsiElement(IDENTIFIER)('y')
+ PsiErrorElement:Expecting an element
+
+ PsiWhiteSpace('\n ')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar5')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ STRING_TEMPLATE
+ PsiElement(OPEN_QUOTE)('"')
+ PsiElement(CLOSING_QUOTE)('"')
+ PsiErrorElement:Expecting ','
+
+ PsiWhiteSpace(' ')
+ VALUE_ARGUMENT
+ STRING_TEMPLATE
+ PsiElement(OPEN_QUOTE)('"')
+ PsiElement(CLOSING_QUOTE)('"')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar6')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ STRING_TEMPLATE
+ PsiElement(OPEN_QUOTE)('"')
+ PsiElement(CLOSING_QUOTE)('"')
+ PsiErrorElement:Expecting ','
+
+ PsiWhiteSpace('\n ')
+ VALUE_ARGUMENT
+ STRING_TEMPLATE
+ PsiElement(OPEN_QUOTE)('"')
+ PsiElement(CLOSING_QUOTE)('"')
+ PsiWhiteSpace('\n ')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar7')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ CALL_EXPRESSION
+ LAMBDA_EXPRESSION
+ FUNCTION_LITERAL
+ PsiElement(LBRACE)('{')
+ BLOCK
+
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace(' ')
+ LAMBDA_ARGUMENT
+ LAMBDA_EXPRESSION
+ FUNCTION_LITERAL
+ PsiElement(LBRACE)('{')
+ BLOCK
+
+ PsiElement(RBRACE)('}')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('bar8')
+ VALUE_ARGUMENT_LIST
+ PsiElement(LPAR)('(')
+ VALUE_ARGUMENT
+ CALL_EXPRESSION
+ LAMBDA_EXPRESSION
+ FUNCTION_LITERAL
+ PsiElement(LBRACE)('{')
+ BLOCK
+
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n ')
+ LAMBDA_ARGUMENT
+ LAMBDA_EXPRESSION
+ FUNCTION_LITERAL
+ PsiElement(LBRACE)('{')
+ BLOCK
+
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n ')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace('\n')
+ PsiElement(RBRACE)('}')
diff --git a/compiler/testData/psi/recovery/NoGTInTypeArguments.kt b/compiler/testData/psi/recovery/NoGTInTypeArguments.kt
new file mode 100644
index 00000000000..bd8376401a2
--- /dev/null
+++ b/compiler/testData/psi/recovery/NoGTInTypeArguments.kt
@@ -0,0 +1,9 @@
+fun foo1(x: List
+ IMPORT_LIST
+
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo1')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('List')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('s')
+ PsiErrorElement:Expecting a '>'
+
+ VALUE_PARAMETER
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('String')
+ PsiElement(RPAR)(')')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo2')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('List')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ PsiWhiteSpace(' ')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('s')
+ PsiErrorElement:Expecting a '>'
+
+ VALUE_PARAMETER
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('String')
+ PsiElement(RPAR)(')')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo3')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('List')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(COMMA)(',')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(RPAR)(')')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo4')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('List')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(RPAR)(')')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo5')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('List')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(COMMA)(',')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo6')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('List')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo7')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('List')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('A')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(COMMA)(',')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ PsiErrorElement:Type expected
+
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ PsiElement(EQ)('=')
+ PsiWhiteSpace(' ')
+ INTEGER_CONSTANT
+ PsiElement(INTEGER_LITERAL)('1')
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('main')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
\ No newline at end of file
diff --git a/compiler/testData/psi/recovery/UnfinishedExtension.kt b/compiler/testData/psi/recovery/UnfinishedExtension.kt
new file mode 100644
index 00000000000..c7852538854
--- /dev/null
+++ b/compiler/testData/psi/recovery/UnfinishedExtension.kt
@@ -0,0 +1,4 @@
+fun Any.
+
+fun goodFunction() {
+}
diff --git a/compiler/testData/psi/recovery/UnfinishedExtension.txt b/compiler/testData/psi/recovery/UnfinishedExtension.txt
new file mode 100644
index 00000000000..1aec4227961
--- /dev/null
+++ b/compiler/testData/psi/recovery/UnfinishedExtension.txt
@@ -0,0 +1,28 @@
+KtFile: UnfinishedExtension.kt
+ PACKAGE_DIRECTIVE
+
+ IMPORT_LIST
+
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Any')
+ PsiElement(DOT)('.')
+ PsiErrorElement:Expecting function name
+
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('goodFunction')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n')
+ PsiElement(RBRACE)('}')
\ No newline at end of file
diff --git a/compiler/testData/psi/recovery/enumWthoutClass.kt b/compiler/testData/psi/recovery/enumWthoutClass.kt
new file mode 100644
index 00000000000..0c4a6218139
--- /dev/null
+++ b/compiler/testData/psi/recovery/enumWthoutClass.kt
@@ -0,0 +1,18 @@
+enum A { X, Y }
+
+private enum B {
+ X, Y
+}
+
+internal Q {
+ X, Y
+}
+
+fun foo() {
+ // No recovery here
+ enum A { X, Y }
+
+ private enum B {
+ X, Y
+ }
+}
diff --git a/compiler/testData/psi/recovery/enumWthoutClass.txt b/compiler/testData/psi/recovery/enumWthoutClass.txt
new file mode 100644
index 00000000000..e256c50a81e
--- /dev/null
+++ b/compiler/testData/psi/recovery/enumWthoutClass.txt
@@ -0,0 +1,137 @@
+KtFile: enumWthoutClass.kt
+ PACKAGE_DIRECTIVE
+
+ IMPORT_LIST
+
+ CLASS
+ MODIFIER_LIST
+ PsiElement(enum)('enum')
+ PsiErrorElement:'class' keyword is expected after 'enum'
+
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('A')
+ PsiWhiteSpace(' ')
+ CLASS_BODY
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace(' ')
+ ENUM_ENTRY
+ PsiElement(IDENTIFIER)('X')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ ENUM_ENTRY
+ PsiElement(IDENTIFIER)('Y')
+ PsiWhiteSpace(' ')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n\n')
+ CLASS
+ MODIFIER_LIST
+ PsiElement(private)('private')
+ PsiWhiteSpace(' ')
+ PsiElement(enum)('enum')
+ PsiErrorElement:'class' keyword is expected after 'enum'
+
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('B')
+ PsiWhiteSpace(' ')
+ CLASS_BODY
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n ')
+ ENUM_ENTRY
+ PsiElement(IDENTIFIER)('X')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ ENUM_ENTRY
+ PsiElement(IDENTIFIER)('Y')
+ PsiWhiteSpace('\n')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n\n')
+ MODIFIER_LIST
+ PsiElement(internal)('internal')
+ PsiWhiteSpace(' ')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(IDENTIFIER)('Q')
+ PsiWhiteSpace(' ')
+ FUN
+ PsiErrorElement:Expecting a top level declaration
+
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('X')
+ PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('Y')
+ PsiWhiteSpace('\n')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n ')
+ PsiComment(EOL_COMMENT)('// No recovery here')
+ PsiWhiteSpace('\n ')
+ BINARY_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('enum')
+ PsiWhiteSpace(' ')
+ OPERATION_REFERENCE
+ PsiElement(IDENTIFIER)('A')
+ PsiWhiteSpace(' ')
+ LAMBDA_EXPRESSION
+ FUNCTION_LITERAL
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER_LIST
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('X')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('Y')
+ PsiErrorElement:Expecting '->' or ','
+
+ PsiWhiteSpace(' ')
+ BLOCK
+
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n\n ')
+ BINARY_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('private')
+ PsiWhiteSpace(' ')
+ OPERATION_REFERENCE
+ PsiElement(IDENTIFIER)('enum')
+ PsiWhiteSpace(' ')
+ CALL_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('B')
+ PsiWhiteSpace(' ')
+ LAMBDA_ARGUMENT
+ LAMBDA_EXPRESSION
+ FUNCTION_LITERAL
+ PsiElement(LBRACE)('{')
+ PsiWhiteSpace('\n ')
+ VALUE_PARAMETER_LIST
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('X')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('Y')
+ PsiErrorElement:Expecting '->' or ','
+
+ PsiWhiteSpace('\n ')
+ BLOCK
+
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ PsiElement(RBRACE)('}')
\ No newline at end of file
diff --git a/compiler/testData/psi/recovery/importsWithConflict.kt b/compiler/testData/psi/recovery/importsWithConflict.kt
new file mode 100644
index 00000000000..e0cdbf05e8a
--- /dev/null
+++ b/compiler/testData/psi/recovery/importsWithConflict.kt
@@ -0,0 +1,14 @@
+package a
+
+import a1
+<<>> BAR
+
+fun bar() {}
+
+import a2
+import a4.df
+
+fun foo() {}
diff --git a/compiler/testData/psi/recovery/importsWithConflict.txt b/compiler/testData/psi/recovery/importsWithConflict.txt
new file mode 100644
index 00000000000..09438ea05f7
--- /dev/null
+++ b/compiler/testData/psi/recovery/importsWithConflict.txt
@@ -0,0 +1,90 @@
+KtFile: importsWithConflict.kt
+ PACKAGE_DIRECTIVE
+ PsiElement(package)('package')
+ PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('a')
+ PsiWhiteSpace('\n\n')
+ IMPORT_LIST
+ IMPORT_DIRECTIVE
+ PsiElement(import)('import')
+ PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('a1')
+ PsiWhiteSpace('\n')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(LT)('<')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(LT)('<')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(LT)('<')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(IDENTIFIER)('HEAD')
+ PsiErrorElement:imports are only allowed in the beginning of file
+
+ PsiWhiteSpace('\n')
+ IMPORT_LIST
+ IMPORT_DIRECTIVE
+ PsiElement(import)('import')
+ PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('a2')
+ PsiWhiteSpace('\n')
+ IMPORT_DIRECTIVE
+ PsiElement(import)('import')
+ PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('a3')
+ PsiWhiteSpace('\n')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(GT)('>')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(GT)('>')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(GT)('>')
+ PsiWhiteSpace(' ')
+ PsiErrorElement:Expecting a top level declaration
+ PsiElement(IDENTIFIER)('BAR')
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('bar')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiErrorElement:imports are only allowed in the beginning of file
+
+ PsiWhiteSpace('\n\n')
+ IMPORT_LIST
+ IMPORT_DIRECTIVE
+ PsiElement(import)('import')
+ PsiWhiteSpace(' ')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('a2')
+ PsiWhiteSpace('\n')
+ IMPORT_DIRECTIVE
+ PsiElement(import)('import')
+ PsiWhiteSpace(' ')
+ DOT_QUALIFIED_EXPRESSION
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('a4')
+ PsiElement(DOT)('.')
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('df')
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
diff --git a/compiler/testData/psi/recovery/valueParameterRecovery.kt b/compiler/testData/psi/recovery/valueParameterRecovery.kt
new file mode 100644
index 00000000000..fc9a23a8432
--- /dev/null
+++ b/compiler/testData/psi/recovery/valueParameterRecovery.kt
@@ -0,0 +1,5 @@
+fun foo(x: Int, y: z: Int) {}
+
+fun bar(x: y: Int, z: Int) {}
+
+fun baz(x: y: z: Int) {}
diff --git a/compiler/testData/psi/recovery/valueParameterRecovery.txt b/compiler/testData/psi/recovery/valueParameterRecovery.txt
new file mode 100644
index 00000000000..5c164239ae4
--- /dev/null
+++ b/compiler/testData/psi/recovery/valueParameterRecovery.txt
@@ -0,0 +1,108 @@
+KtFile: valueParameterRecovery.kt
+ PACKAGE_DIRECTIVE
+
+ IMPORT_LIST
+
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('y')
+ PsiElement(COLON)(':')
+ PsiErrorElement:Type reference expected
+
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('z')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('bar')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiErrorElement:Type reference expected
+
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('y')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('z')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('baz')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiErrorElement:Type reference expected
+
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('y')
+ PsiElement(COLON)(':')
+ PsiErrorElement:Type reference expected
+
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('z')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
diff --git a/compiler/testData/psi/recovery/valueParameterRecoveryWithTypes.kt b/compiler/testData/psi/recovery/valueParameterRecoveryWithTypes.kt
new file mode 100644
index 00000000000..211b004ae07
--- /dev/null
+++ b/compiler/testData/psi/recovery/valueParameterRecoveryWithTypes.kt
@@ -0,0 +1,2 @@
+fun foo(x: Array, : Int, w: Int) {}
+fun bar(x: Array : Int, w: Int) {}
diff --git a/compiler/testData/psi/recovery/valueParameterRecoveryWithTypes.txt b/compiler/testData/psi/recovery/valueParameterRecoveryWithTypes.txt
new file mode 100644
index 00000000000..118beb8073d
--- /dev/null
+++ b/compiler/testData/psi/recovery/valueParameterRecoveryWithTypes.txt
@@ -0,0 +1,101 @@
+KtFile: valueParameterRecoveryWithTypes.kt
+ PACKAGE_DIRECTIVE
+
+ IMPORT_LIST
+
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('foo')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Array')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(GT)('>')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiErrorElement:Parameter name expected
+
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('w')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
+ PsiWhiteSpace('\n')
+ FUN
+ PsiElement(fun)('fun')
+ PsiWhiteSpace(' ')
+ PsiElement(IDENTIFIER)('bar')
+ VALUE_PARAMETER_LIST
+ PsiElement(LPAR)('(')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Array')
+ TYPE_ARGUMENT_LIST
+ PsiElement(LT)('<')
+ TYPE_PROJECTION
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(GT)('>')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiErrorElement:Parameter name expected
+
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(COMMA)(',')
+ PsiWhiteSpace(' ')
+ VALUE_PARAMETER
+ PsiElement(IDENTIFIER)('w')
+ PsiElement(COLON)(':')
+ PsiWhiteSpace(' ')
+ TYPE_REFERENCE
+ USER_TYPE
+ REFERENCE_EXPRESSION
+ PsiElement(IDENTIFIER)('Int')
+ PsiElement(RPAR)(')')
+ PsiWhiteSpace(' ')
+ BLOCK
+ PsiElement(LBRACE)('{')
+ PsiElement(RBRACE)('}')
diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt
index 41e89f4f24f..e559b576d4d 100644
--- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt
+++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt
@@ -7,7 +7,6 @@
* SECTIONS: contracts, analysis, smartcasts
* NUMBER: 15
* DESCRIPTION: Check smartcasts working if type checking for contract function is used
- * UNEXPECTED BEHAVIOUR
* ISSUES: KT-27241
*/
@@ -40,20 +39,20 @@ import contracts.*
// TESTCASE NUMBER: 1
fun case_1(value: Any) {
if (contracts.case_1_2(contracts.case_1_1(value is Char))) {
- println(value.category)
+ println(value.category)
}
}
// TESTCASE NUMBER: 2
fun case_2(value: Any) {
if (contracts.case_2(value is Char) is Boolean) {
- println(value.category)
+ println(value.category)
}
}
// TESTCASE NUMBER: 3
fun case_3(value: String?) {
if (!value.isNullOrEmpty() is Boolean) {
- value.length
+ value.length
}
}
diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java
index ef4805ff8ad..60d319da981 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java
@@ -9071,6 +9071,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/imports/TopLevelClassVsPackage.kt");
}
+ @TestMetadata("twoImportLists.kt")
+ public void testTwoImportLists() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/imports/twoImportLists.kt");
+ }
+
@TestMetadata("WrongImport.kt")
public void testWrongImport() throws Exception {
runTest("compiler/testData/diagnostics/tests/imports/WrongImport.kt");
diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java
index ff754894fbe..fb1464af13e 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java
@@ -1341,6 +1341,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/unreachableBranches.kt");
}
+ @TestMetadata("valueOfContractedFunctionIngored.kt")
+ public void testValueOfContractedFunctionIngored() throws Exception {
+ runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt");
+ }
+
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/multieffect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
index afefaf9ecf5..f5053bfadf9 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
@@ -1341,6 +1341,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/unreachableBranches.kt");
}
+ @TestMetadata("valueOfContractedFunctionIngored.kt")
+ public void testValueOfContractedFunctionIngored() throws Exception {
+ runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt");
+ }
+
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/multieffect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java
index 057156e64e5..d8621ff8a48 100644
--- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java
@@ -9071,6 +9071,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/imports/TopLevelClassVsPackage.kt");
}
+ @TestMetadata("twoImportLists.kt")
+ public void testTwoImportLists() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/imports/twoImportLists.kt");
+ }
+
@TestMetadata("WrongImport.kt")
public void testWrongImport() throws Exception {
runTest("compiler/testData/diagnostics/tests/imports/WrongImport.kt");
diff --git a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt
index 4e99bebbd09..a24d0107679 100644
--- a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt
+++ b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt
@@ -49,7 +49,8 @@ class CodeConformanceTest : TestCase() {
"libraries/tools/kotlinp/src",
"compiler/testData/psi/kdoc",
"compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt",
- "compiler/util/src/org/jetbrains/kotlin/config/MavenComparableVersion.java"
+ "compiler/util/src/org/jetbrains/kotlin/config/MavenComparableVersion.java",
+ "custom-dependencies/protobuf/protobuf-relocated/build"
).map(::File)
private val COPYRIGHT_EXCLUDED_FILES_AND_DIRS = listOf(
@@ -57,6 +58,7 @@ class CodeConformanceTest : TestCase() {
"out",
"dist",
"custom-dependencies/android-sdk/build",
+ "custom-dependencies/protobuf/protobuf-relocated/build",
"compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt",
"idea/idea-jvm/src/org/jetbrains/kotlin/idea/copyright",
"js/js.tests/.gradle",
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
index b9dd1c3e7ac..5031eb8d2fd 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
@@ -3686,6 +3686,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/closures/closureWithParameterAndBoxing.kt");
}
+ @TestMetadata("crossinlineLocalDeclaration.kt")
+ public void testCrossinlineLocalDeclaration() throws Exception {
+ runTest("compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt");
+ }
+
@TestMetadata("doubleEnclosedLocalVariable.kt")
public void testDoubleEnclosedLocalVariable() throws Exception {
runTest("compiler/testData/codegen/box/closures/doubleEnclosedLocalVariable.kt");
@@ -24357,6 +24362,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
+
+ @TestMetadata("whenByUnsigned.kt")
+ public void testWhenByUnsigned() throws Exception {
+ runTest("compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt");
+ }
}
@TestMetadata("compiler/testData/codegen/box/vararg")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java
index 1dc515746b7..874c4355f7e 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java
@@ -3182,6 +3182,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
public void testUnsignedLongRemainder_jvm18() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongRemainder_jvm18.kt");
}
+
+ @TestMetadata("whenByUnsigned.kt")
+ public void testWhenByUnsigned() throws Exception {
+ runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/whenByUnsigned.kt");
+ }
}
@TestMetadata("compiler/testData/codegen/bytecodeText/varargs")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java
index 699c4eb0528..d5215136993 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/IrBytecodeTextTestGenerated.java
@@ -3182,6 +3182,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
public void testUnsignedLongRemainder_jvm18() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongRemainder_jvm18.kt");
}
+
+ @TestMetadata("whenByUnsigned.kt")
+ public void testWhenByUnsigned() throws Exception {
+ runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/whenByUnsigned.kt");
+ }
}
@TestMetadata("compiler/testData/codegen/bytecodeText/varargs")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
index 252dc7428dc..6d42d8dc846 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
@@ -3686,6 +3686,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/closures/closureWithParameterAndBoxing.kt");
}
+ @TestMetadata("crossinlineLocalDeclaration.kt")
+ public void testCrossinlineLocalDeclaration() throws Exception {
+ runTest("compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt");
+ }
+
@TestMetadata("doubleEnclosedLocalVariable.kt")
public void testDoubleEnclosedLocalVariable() throws Exception {
runTest("compiler/testData/codegen/box/closures/doubleEnclosedLocalVariable.kt");
@@ -24357,6 +24362,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
+
+ @TestMetadata("whenByUnsigned.kt")
+ public void testWhenByUnsigned() throws Exception {
+ runTest("compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt");
+ }
}
@TestMetadata("compiler/testData/codegen/box/vararg")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
index dafe58465c3..2e4a3fcc4ea 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
@@ -3686,6 +3686,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/closures/closureWithParameterAndBoxing.kt");
}
+ @TestMetadata("crossinlineLocalDeclaration.kt")
+ public void testCrossinlineLocalDeclaration() throws Exception {
+ runTest("compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt");
+ }
+
@TestMetadata("doubleEnclosedLocalVariable.kt")
public void testDoubleEnclosedLocalVariable() throws Exception {
runTest("compiler/testData/codegen/box/closures/doubleEnclosedLocalVariable.kt");
@@ -24362,6 +24367,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
+
+ @TestMetadata("whenByUnsigned.kt")
+ public void testWhenByUnsigned() throws Exception {
+ runTest("compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt");
+ }
}
@TestMetadata("compiler/testData/codegen/box/vararg")
diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java
index d7faf543dcc..29b3a2fa71f 100644
--- a/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java
@@ -521,6 +521,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
runTest("compiler/testData/psi/NewlinesInParentheses.kt");
}
+ @TestMetadata("noCommaBetweenArguments.kt")
+ public void testNoCommaBetweenArguments() throws Exception {
+ runTest("compiler/testData/psi/noCommaBetweenArguments.kt");
+ }
+
@TestMetadata("NonTypeBeforeDotInBaseClass.kt")
public void testNonTypeBeforeDotInBaseClass() throws Exception {
runTest("compiler/testData/psi/NonTypeBeforeDotInBaseClass.kt");
@@ -1933,6 +1938,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
runTest("compiler/testData/psi/recovery/DoWhileWithoutLPar.kt");
}
+ @TestMetadata("enumWthoutClass.kt")
+ public void testEnumWthoutClass() throws Exception {
+ runTest("compiler/testData/psi/recovery/enumWthoutClass.kt");
+ }
+
@TestMetadata("ForEmptyParentheses.kt")
public void testForEmptyParentheses() throws Exception {
runTest("compiler/testData/psi/recovery/ForEmptyParentheses.kt");
@@ -2008,6 +2018,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
runTest("compiler/testData/psi/recovery/ImportRecovery.kt");
}
+ @TestMetadata("importsWithConflict.kt")
+ public void testImportsWithConflict() throws Exception {
+ runTest("compiler/testData/psi/recovery/importsWithConflict.kt");
+ }
+
@TestMetadata("IncompleteAccessor1.kt")
public void testIncompleteAccessor1() throws Exception {
runTest("compiler/testData/psi/recovery/IncompleteAccessor1.kt");
@@ -2143,6 +2158,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
runTest("compiler/testData/psi/recovery/NoArrowInWhen.kt");
}
+ @TestMetadata("NoGTInTypeArguments.kt")
+ public void testNoGTInTypeArguments() throws Exception {
+ runTest("compiler/testData/psi/recovery/NoGTInTypeArguments.kt");
+ }
+
@TestMetadata("PackageNewLineRecovery.kt")
public void testPackageNewLineRecovery() throws Exception {
runTest("compiler/testData/psi/recovery/PackageNewLineRecovery.kt");
@@ -2158,6 +2178,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
runTest("compiler/testData/psi/recovery/SameLineStatementRecovery.kt");
}
+ @TestMetadata("UnfinishedExtension.kt")
+ public void testUnfinishedExtension() throws Exception {
+ runTest("compiler/testData/psi/recovery/UnfinishedExtension.kt");
+ }
+
@TestMetadata("ValNoName.kt")
public void testValNoName() throws Exception {
runTest("compiler/testData/psi/recovery/ValNoName.kt");
@@ -2178,6 +2203,16 @@ public class ParsingTestGenerated extends AbstractParsingTest {
runTest("compiler/testData/psi/recovery/ValueParameterNoTypeRecovery.kt");
}
+ @TestMetadata("valueParameterRecovery.kt")
+ public void testValueParameterRecovery() throws Exception {
+ runTest("compiler/testData/psi/recovery/valueParameterRecovery.kt");
+ }
+
+ @TestMetadata("valueParameterRecoveryWithTypes.kt")
+ public void testValueParameterRecoveryWithTypes() throws Exception {
+ runTest("compiler/testData/psi/recovery/valueParameterRecoveryWithTypes.kt");
+ }
+
@TestMetadata("WhenWithoutBraces.kt")
public void testWhenWithoutBraces() throws Exception {
runTest("compiler/testData/psi/recovery/WhenWithoutBraces.kt");
diff --git a/core/metadata/build.gradle.kts b/core/metadata/build.gradle.kts
index 54ce446e705..6be04082b07 100644
--- a/core/metadata/build.gradle.kts
+++ b/core/metadata/build.gradle.kts
@@ -20,11 +20,6 @@ sourceSets {
}
tasks.withType {
- dependsOn(protobufLiteTask)
sourceCompatibility = "1.6"
targetCompatibility = "1.6"
}
-
-tasks.withType {
- dependsOn(protobufLiteTask)
-}
diff --git a/custom-dependencies/protobuf-relocated/build.gradle.kts b/custom-dependencies/protobuf-relocated/build.gradle.kts
deleted file mode 100644
index 4e20d76d49c..00000000000
--- a/custom-dependencies/protobuf-relocated/build.gradle.kts
+++ /dev/null
@@ -1,62 +0,0 @@
-import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
-import java.io.File
-
-plugins {
- base
- id("pill-configurable")
-}
-
-val baseProtobuf by configurations.creating
-val baseProtobufSources by configurations.creating
-
-val resultsCfg = configurations.getByName("default")
-val resultsSourcesCfg = configurations.create("sources")
-
-val protobufVersion = rootProject.extra["versions.protobuf-java"] as String
-val protobufJarPrefix = "protobuf-$protobufVersion"
-
-val renamedSources = "$buildDir/renamedSrc/"
-val outputJarsPath = "$buildDir/libs"
-val artifactBaseName = "protobuf-java-relocated"
-
-pill {
- libraryPath = File(outputJarsPath)
-}
-
-setProperty("archivesBaseName", "$artifactBaseName-$protobufVersion")
-
-dependencies {
- baseProtobuf("com.google.protobuf:protobuf-java:$protobufVersion")
- baseProtobufSources("com.google.protobuf:protobuf-java:$protobufVersion:sources")
-}
-
-val prepare by task {
- destinationDir = File(outputJarsPath)
- baseName = artifactBaseName
- version = protobufVersion
- classifier = ""
- from(baseProtobuf.files.find { it.name.startsWith("protobuf-java") }?.canonicalPath)
-
- relocate("com.google.protobuf", "org.jetbrains.kotlin.protobuf" ) {
- exclude("META-INF/maven/com.google.protobuf/protobuf-java/pom.properties")
- }
- addArtifact("archives", this, this)
- addArtifact(resultsCfg.name, this, this)
-}
-
-val relocateSources by task {
- from(zipTree(baseProtobufSources.files.find { it.name.startsWith("protobuf-java") && it.name.endsWith("-sources.jar") }
- ?: throw GradleException("sources jar not found among ${baseProtobufSources.files}")))
- into(renamedSources)
- filter { it.replace("com.google.protobuf", "org.jetbrains.kotlin.protobuf") }
-}
-
-val prepareSources by task {
- destinationDir = File(outputJarsPath)
- baseName = artifactBaseName
- version = protobufVersion
- classifier = "sources"
- from(relocateSources)
- project.addArtifact("archives", this, this)
- addArtifact(resultsSourcesCfg.name, this, this)
-}
\ No newline at end of file
diff --git a/custom-dependencies/protobuf/build.gradle.kts b/custom-dependencies/protobuf/build.gradle.kts
new file mode 100644
index 00000000000..0b171efb1fe
--- /dev/null
+++ b/custom-dependencies/protobuf/build.gradle.kts
@@ -0,0 +1,7 @@
+
+val protobufVersion by extra("2.6.1")
+
+allprojects {
+ group = "org.jetbrains.kotlin"
+ version = protobufVersion
+}
\ No newline at end of file
diff --git a/custom-dependencies/protobuf-lite/build.gradle.kts b/custom-dependencies/protobuf/protobuf-lite/build.gradle.kts
similarity index 72%
rename from custom-dependencies/protobuf-lite/build.gradle.kts
rename to custom-dependencies/protobuf/protobuf-lite/build.gradle.kts
index 4b539e4578d..cd8d182bbf9 100644
--- a/custom-dependencies/protobuf-lite/build.gradle.kts
+++ b/custom-dependencies/protobuf/protobuf-lite/build.gradle.kts
@@ -6,21 +6,23 @@ import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.zip.ZipOutputStream
+plugins {
+ base
+ `maven-publish`
+}
+
val relocatedProtobuf by configurations.creating
val relocatedProtobufSources by configurations.creating
-val resultsCfg = configurations.create("default")
-
-val protobufVersion = rootProject.extra["versions.protobuf-java"]
+val protobufVersion: String by rootProject.extra
val protobufJarPrefix = "protobuf-$protobufVersion"
val outputJarPath = "$buildDir/libs/$protobufJarPrefix-lite.jar"
dependencies {
- relocatedProtobuf(project(":custom-dependencies:protobuf-relocated", configuration = "default"))
- relocatedProtobufSources(project(":custom-dependencies:protobuf-relocated", configuration = "sources"))
+ relocatedProtobuf(project(":protobuf-relocated"))
}
-task("prepare") {
+val prepare by tasks.creating {
inputs.files(relocatedProtobuf) // this also adds a dependency
outputs.file(outputJarPath)
doFirst {
@@ -41,7 +43,11 @@ task("prepare") {
return result
}
- val allFiles = loadAllFromJar(relocatedProtobuf.singleFile)
+ val mainJar = relocatedProtobuf.resolvedConfiguration.resolvedArtifacts.single {
+ it.name == "protobuf-relocated" && it.classifier == null
+ }.file
+
+ val allFiles = loadAllFromJar(mainJar)
val keepClasses = arrayListOf()
@@ -80,18 +86,38 @@ task("prepare") {
}
}
}
- addArtifact("archives", this, outputs.files.singleFile) {
- classifier = ""
- }
- addArtifact(resultsCfg, this, outputs.files.singleFile) {
- classifier = ""
- }
}
-val clean by task {
- delete(buildDir)
+val mainArtifact = artifacts.add(
+ "default",
+ provider {
+ prepare.outputs.files.singleFile
+ }
+) {
+ builtBy(prepare)
+ classifier = ""
}
-artifacts.add("archives", relocatedProtobufSources.files.single()) {
+val sourcesArtifact = artifacts.add(
+ "default",
+ provider {
+ relocatedProtobuf.resolvedConfiguration.resolvedArtifacts.single { it.name == "protobuf-relocated" && it.classifier == "sources" }.file
+ }
+) {
classifier = "sources"
}
+
+publishing {
+ publications {
+ create("maven") {
+ artifact(mainArtifact)
+ artifact(sourcesArtifact)
+ }
+ }
+
+ repositories {
+ maven {
+ url = uri("${rootProject.buildDir}/internal/repo")
+ }
+ }
+}
diff --git a/custom-dependencies/protobuf/protobuf-relocated/build.gradle.kts b/custom-dependencies/protobuf/protobuf-relocated/build.gradle.kts
new file mode 100644
index 00000000000..98c077ec55e
--- /dev/null
+++ b/custom-dependencies/protobuf/protobuf-relocated/build.gradle.kts
@@ -0,0 +1,80 @@
+import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
+import java.io.File
+
+plugins {
+ `java-base`
+ `maven-publish`
+ id("com.github.johnrengelman.shadow") version "4.0.3" apply false
+}
+
+repositories {
+ jcenter()
+}
+
+val baseProtobuf by configurations.creating
+val baseProtobufSources by configurations.creating
+
+val protobufVersion: String by rootProject.extra
+val protobufJarPrefix = "protobuf-$protobufVersion"
+
+val renamedSources = "$buildDir/renamedSrc/"
+val outputJarsPath = "$buildDir/libs"
+
+dependencies {
+ baseProtobuf("com.google.protobuf:protobuf-java:$protobufVersion")
+ baseProtobufSources("com.google.protobuf:protobuf-java:$protobufVersion:sources")
+}
+
+val prepare = task("prepare") {
+ destinationDir = File(outputJarsPath)
+ version = protobufVersion
+ classifier = ""
+ from(
+ provider {
+ baseProtobuf.files.find { it.name.startsWith("protobuf-java") }?.canonicalPath
+ }
+ )
+
+ relocate("com.google.protobuf", "org.jetbrains.kotlin.protobuf" ) {
+ exclude("META-INF/maven/com.google.protobuf/protobuf-java/pom.properties")
+ }
+}
+
+artifacts.add("default", prepare)
+
+val relocateSources = task("relocateSources") {
+ from(
+ provider {
+ zipTree(baseProtobufSources.files.find { it.name.startsWith("protobuf-java") && it.name.endsWith("-sources.jar") }
+ ?: throw GradleException("sources jar not found among ${baseProtobufSources.files}"))
+ }
+ )
+
+ into(renamedSources)
+
+ filter { it.replace("com.google.protobuf", "org.jetbrains.kotlin.protobuf") }
+}
+
+val prepareSources = task("prepareSources") {
+ destinationDir = File(outputJarsPath)
+ version = protobufVersion
+ classifier = "sources"
+ from(relocateSources)
+}
+
+artifacts.add("default", prepareSources)
+
+publishing {
+ publications {
+ create("maven") {
+ artifact(prepare)
+ artifact(prepareSources)
+ }
+ }
+
+ repositories {
+ maven {
+ url = uri("${rootProject.buildDir}/internal/repo")
+ }
+ }
+}
diff --git a/custom-dependencies/protobuf/settings.gradle b/custom-dependencies/protobuf/settings.gradle
new file mode 100644
index 00000000000..c8dbba7a5cf
--- /dev/null
+++ b/custom-dependencies/protobuf/settings.gradle
@@ -0,0 +1 @@
+include ":protobuf-lite", ":protobuf-relocated"
\ No newline at end of file
diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt
index 55b487a80cf..856ea0e2fb9 100644
--- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt
+++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectResolverExtension.kt
@@ -47,6 +47,8 @@ import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver
import java.io.File
import java.util.*
import kotlin.collections.HashMap
+import com.intellij.openapi.diagnostic.Logger
+import org.jetbrains.kotlin.idea.util.PsiPrecedences
var DataNode.isResolved
by NotNullableCopyableDataNodeUserDataProperty(Key.create("IS_RESOLVED"), false)
@@ -69,6 +71,7 @@ var DataNode.dependenciesCache
class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension() {
val isAndroidProjectKey = Key.findKeyByName("IS_ANDROID_PROJECT_KEY")
+ private val LOG = Logger.getInstance(PsiPrecedences::class.java)
override fun getToolingExtensionsClasses(): Set> {
return setOf(KotlinGradleModelBuilder::class.java, Unit::class.java)
@@ -190,6 +193,9 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
ideModule: DataNode,
ideProject: DataNode
) {
+ if (LOG.isDebugEnabled) {
+ LOG.debug("Start populate module dependencies. Gradle module: [$gradleModule], Ide module: [$ideModule], Ide project: [$ideProject]")
+ }
val mppModel = resolverCtx.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)
if (mppModel != null) {
mppModel.targets.filterNot { it.name == "metadata" }.forEach { target ->
@@ -227,6 +233,9 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
if (useModulePerSourceSet()) {
super.populateModuleDependencies(gradleModule, ideModule, ideProject)
}
+ if (LOG.isDebugEnabled) {
+ LOG.debug("Finish populating module dependencies. Gradle module: [$gradleModule], Ide module: [$ideModule], Ide project: [$ideProject]")
+ }
}
private fun addImplementedModuleNames(
diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt
index 4be3d13a29e..e2f4516178f 100644
--- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt
+++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt
@@ -36,6 +36,7 @@ import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.IdeaTestUtil
+import com.intellij.testFramework.TestLoggerFactory
import com.intellij.util.PathUtil
import com.intellij.util.containers.ContainerUtil
import junit.framework.TestCase
@@ -52,6 +53,7 @@ import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.jetbrains.plugins.groovy.GroovyFileType
import org.junit.Assume.assumeThat
+import org.junit.BeforeClass
import org.junit.Rule
import org.junit.rules.TestName
import org.junit.runner.RunWith
@@ -61,6 +63,8 @@ import java.io.IOException
import java.io.StringWriter
import java.net.URISyntaxException
import java.util.*
+import com.intellij.openapi.diagnostic.Logger
+import org.junit.AfterClass
// part of org.jetbrains.plugins.gradle.importing.GradleImportingTestCase
@RunWith(value = Parameterized::class)
@@ -72,6 +76,10 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
@Rule
var name = TestName()
+ @JvmField
+ @Rule
+ var testWatcher = ImportingTestWatcher()
+
@JvmField
@Rule
var versionMatcherRule = VersionMatcherRule()
@@ -276,5 +284,22 @@ abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
fun wrapperJar(): File {
return File(PathUtil.getJarPathForClass(GradleWrapperMain::class.java))
}
+
+ private var persistedLoggerFactory : Logger.Factory? = null
+
+ @JvmStatic
+ @BeforeClass
+ fun setLoggerFactory() {
+ persistedLoggerFactory = Logger.getFactory()
+ Logger.setFactory(TestLoggerFactory::class.java)
+ }
+
+ @JvmStatic
+ @AfterClass
+ fun restoreLoggerFactory() {
+ if (persistedLoggerFactory != null) {
+ Logger.setFactory(persistedLoggerFactory)
+ }
+ }
}
}
diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt.182 b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt.182
new file mode 100644
index 00000000000..37122ddd696
--- /dev/null
+++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleImportingTestCase.kt.182
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2010-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.kotlin.idea.codeInsight.gradle
+
+import com.intellij.compiler.server.BuildManager
+import com.intellij.openapi.application.PathManager
+import com.intellij.openapi.application.Result
+import com.intellij.openapi.application.WriteAction
+import com.intellij.openapi.externalSystem.model.ProjectSystemId
+import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings
+import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings
+import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListenerAdapter
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
+import com.intellij.openapi.fileEditor.FileDocumentManager
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil
+import com.intellij.openapi.fileTypes.FileTypeManager
+import com.intellij.openapi.projectRoots.JavaSdk
+import com.intellij.openapi.projectRoots.ProjectJdkTable
+import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
+import com.intellij.openapi.ui.Messages
+import com.intellij.openapi.ui.TestDialog
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.vfs.LocalFileSystem
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.testFramework.IdeaTestUtil
+import com.intellij.testFramework.TestLoggerFactory
+import com.intellij.util.PathUtil
+import com.intellij.util.containers.ContainerUtil
+import junit.framework.TestCase
+import org.gradle.util.GradleVersion
+import org.gradle.wrapper.GradleWrapperMain
+import org.intellij.lang.annotations.Language
+import org.jetbrains.annotations.NonNls
+import org.jetbrains.kotlin.gradle.KotlinSdkCreationChecker
+import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
+import org.jetbrains.kotlin.test.KotlinTestUtils
+import org.jetbrains.plugins.gradle.settings.DistributionType
+import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
+import org.jetbrains.plugins.gradle.settings.GradleSettings
+import org.jetbrains.plugins.gradle.util.GradleConstants
+import org.jetbrains.plugins.groovy.GroovyFileType
+import org.junit.Assume.assumeThat
+import org.junit.BeforeClass
+import org.junit.Rule
+import org.junit.rules.TestName
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import java.io.File
+import java.io.IOException
+import java.io.StringWriter
+import java.net.URISyntaxException
+import java.util.*
+import com.intellij.openapi.diagnostic.Logger
+import org.junit.AfterClass
+
+// part of org.jetbrains.plugins.gradle.importing.GradleImportingTestCase
+@RunWith(value = Parameterized::class)
+abstract class GradleImportingTestCase : ExternalSystemImportingTestCase() {
+
+ protected var sdkCreationChecker : KotlinSdkCreationChecker? = null
+
+ @JvmField
+ @Rule
+ var name = TestName()
+
+ @JvmField
+ @Rule
+ var testWatcher = ImportingTestWatcher()
+
+ @JvmField
+ @Rule
+ var versionMatcherRule = VersionMatcherRule()
+
+ @JvmField
+ @Parameterized.Parameter
+ var gradleVersion: String = ""
+
+ private lateinit var myProjectSettings: GradleProjectSettings
+ private lateinit var myJdkHome: String
+
+ override fun setUp() {
+ myJdkHome = IdeaTestUtil.requireRealJdkHome()
+ super.setUp()
+ assumeThat(gradleVersion, versionMatcherRule.matcher)
+ runWrite {
+ ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME)?.let {
+ ProjectJdkTable.getInstance().removeJdk(it)
+ }
+ val jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(File(myJdkHome))!!
+ val jdk = SdkConfigurationUtil.setupSdk(arrayOfNulls(0), jdkHomeDir, JavaSdk.getInstance(), true, null, GRADLE_JDK_NAME)
+ TestCase.assertNotNull("Cannot create JDK for $myJdkHome", jdk)
+ ProjectJdkTable.getInstance().addJdk(jdk!!)
+ FileTypeManager.getInstance().associateExtension(GroovyFileType.GROOVY_FILE_TYPE, "gradle")
+
+ }
+ myProjectSettings = GradleProjectSettings().apply {
+ this.isUseQualifiedModuleNames = false
+ }
+ GradleSettings.getInstance(myProject).gradleVmOptions = "-Xmx128m -XX:MaxPermSize=64m"
+ System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, GRADLE_DAEMON_TTL_MS.toString())
+ configureWrapper()
+ sdkCreationChecker = KotlinSdkCreationChecker()
+ }
+
+ override fun tearDown() {
+ try {
+ runWrite {
+ val old = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME)
+ if (old != null) {
+ SdkConfigurationUtil.removeSdk(old)
+ }
+ }
+
+ Messages.setTestDialog(TestDialog.DEFAULT)
+ FileUtil.delete(BuildManager.getInstance().buildSystemDirectory.toFile())
+ sdkCreationChecker?.removeNewKotlinSdk()
+ } finally {
+ super.tearDown()
+ }
+ }
+
+ override fun collectAllowedRoots(roots: MutableList) {
+ roots.add(myJdkHome)
+ roots.addAll(ExternalSystemTestCase.collectRootsInside(myJdkHome))
+ roots.add(PathManager.getConfigPath())
+ }
+
+ override fun getName(): String {
+ return if (name.methodName == null) super.getName() else FileUtil.sanitizeFileName(name.methodName)
+ }
+
+ override fun getTestsTempDir(): String = "gradleImportTests"
+
+ override fun getExternalSystemConfigFileName(): String = "build.gradle"
+
+ protected fun importProjectUsingSingeModulePerGradleProject() {
+ myProjectSettings.isResolveModulePerSourceSet = false
+ importProject()
+ }
+
+ override fun importProject() {
+ ExternalSystemApiUtil.subscribe(
+ myProject,
+ GradleConstants.SYSTEM_ID,
+ object : ExternalSystemSettingsListenerAdapter() {
+ override fun onProjectsLinked(settings: Collection) {
+ val item = ContainerUtil.getFirstItem(settings)
+ if (item is GradleProjectSettings) {
+ item.gradleJvm = GRADLE_JDK_NAME
+ }
+ }
+ })
+ super.importProject()
+ }
+
+ override fun importProject(@NonNls @Language("Groovy") config: String) {
+ super.importProject(
+ """
+ allprojects {
+ repositories {
+ maven {
+ url 'http://maven.labs.intellij.net/repo1'
+ }
+ }
+ }
+
+ $config
+ """.trimIndent()
+ )
+ }
+
+ override fun getCurrentExternalProjectSettings(): GradleProjectSettings = myProjectSettings
+
+ override fun getExternalSystemId(): ProjectSystemId = GradleConstants.SYSTEM_ID
+
+ @Throws(IOException::class, URISyntaxException::class)
+ private fun configureWrapper() {
+ val distributionUri = AbstractModelBuilderTest.DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion))
+
+ myProjectSettings.distributionType = DistributionType.DEFAULT_WRAPPED
+ val wrapperJarFrom = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(wrapperJar())!!
+
+ val wrapperJarFromTo = createProjectSubFile("gradle/wrapper/gradle-wrapper.jar")
+ runWrite {
+ wrapperJarFromTo.setBinaryContent(wrapperJarFrom.contentsToByteArray())
+ }
+
+ val properties = Properties()
+ properties.setProperty("distributionBase", "GRADLE_USER_HOME")
+ properties.setProperty("distributionPath", "wrapper/dists")
+ properties.setProperty("zipStoreBase", "GRADLE_USER_HOME")
+ properties.setProperty("zipStorePath", "wrapper/dists")
+ properties.setProperty("distributionUrl", distributionUri.toString())
+
+ val writer = StringWriter()
+ properties.store(writer, null)
+
+ createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString())
+ }
+
+ protected open fun testDataDirName(): String = ""
+
+ protected fun testDataDirectory(): File {
+ val baseDir = "${PluginTestCaseBase.getTestDataPathBase()}/gradle/${testDataDirName()}/"
+ return File(baseDir, getTestName(true).substringBefore("_"))
+ }
+
+ protected fun configureByFiles(): List {
+ val rootDir = testDataDirectory()
+ assert(rootDir.exists()) { "Directory ${rootDir.path} doesn't exist" }
+
+ return rootDir.walk().mapNotNull {
+ when {
+ it.isDirectory -> null
+ !it.name.endsWith(SUFFIX) -> {
+ createProjectSubFile(it.path.substringAfter(rootDir.path + File.separator), it.readText())
+ }
+ else -> null
+ }
+ }.toList()
+ }
+
+ protected fun importProjectFromTestData(): List {
+ val files = configureByFiles()
+ importProject()
+ return files
+ }
+
+ protected fun checkFiles(files: List) {
+ FileDocumentManager.getInstance().saveAllDocuments()
+
+ files.filter {
+ it.name == GradleConstants.DEFAULT_SCRIPT_NAME
+ || it.name == GradleConstants.KOTLIN_DSL_SCRIPT_NAME
+ || it.name == GradleConstants.SETTINGS_FILE_NAME
+ }
+ .forEach {
+ if (it.name == GradleConstants.SETTINGS_FILE_NAME && !File(testDataDirectory(), it.name + SUFFIX).exists()) return@forEach
+ val actualText = LoadTextUtil.loadText(it).toString()
+ val expectedFileName = if (File(testDataDirectory(), it.name + ".$gradleVersion" + SUFFIX).exists()) {
+ it.name + ".$gradleVersion" + SUFFIX
+ } else {
+ it.name + SUFFIX
+ }
+ KotlinTestUtils.assertEqualsToFile(File(testDataDirectory(), expectedFileName), actualText)
+ }
+ }
+
+
+ private fun runWrite(f: () -> Unit) {
+ object : WriteAction() {
+ override fun run(result: Result) {
+ f()
+ }
+ }.execute()
+ }
+
+ companion object {
+ const val GRADLE_JDK_NAME = "Gradle JDK"
+ private const val GRADLE_DAEMON_TTL_MS = 10000
+
+ @JvmStatic
+ protected val SUFFIX = ".after"
+
+ @JvmStatic
+ @Parameterized.Parameters(name = "{index}: with Gradle-{0}")
+ fun data(): Collection> {
+ return Arrays.asList(*AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS)
+ }
+
+ fun wrapperJar(): File {
+ return File(PathUtil.getJarPathForClass(GradleWrapperMain::class.java))
+ }
+
+ @JvmStatic
+ @BeforeClass
+ fun setLoggerFactory() {
+ Logger.setFactory(TestLoggerFactory::class.java)
+ }
+ }
+}
diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ImportingTestWatcher.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ImportingTestWatcher.kt
new file mode 100644
index 00000000000..c05ffad7e65
--- /dev/null
+++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ImportingTestWatcher.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. 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.idea.codeInsight.gradle
+
+import com.intellij.testFramework.TestLoggerFactory
+import org.junit.rules.TestWatcher
+import org.junit.runner.Description
+
+class ImportingTestWatcher : TestWatcher() {
+
+ override fun succeeded(description: Description) {
+ TestLoggerFactory.onTestFinished(true)
+ }
+
+ override fun failed(e: Throwable, description: Description) {
+ TestLoggerFactory.onTestFinished(false)
+ }
+
+ override fun starting(description: Description) {
+ TestLoggerFactory.onTestStarted()
+ }
+
+}
\ No newline at end of file
diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ImportingTestWatcher.kt.182 b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ImportingTestWatcher.kt.182
new file mode 100644
index 00000000000..4fa6d45c422
--- /dev/null
+++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/ImportingTestWatcher.kt.182
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. 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.idea.codeInsight.gradle
+
+import com.intellij.testFramework.TestLoggerFactory
+import org.junit.rules.TestWatcher
+import org.junit.runner.Description
+
+class ImportingTestWatcher : TestWatcher() {
+
+ override fun succeeded(description: Description) {
+ TestLoggerFactory.onTestFinished(true)
+ }
+
+ override fun failed(e: Throwable, description: Description) {
+ TestLoggerFactory.onTestFinished(false)
+ }
+
+}
\ No newline at end of file
diff --git a/idea/idea-maven/build.gradle.kts b/idea/idea-maven/build.gradle.kts
index 3102a8f3160..eb7536a674a 100644
--- a/idea/idea-maven/build.gradle.kts
+++ b/idea/idea-maven/build.gradle.kts
@@ -26,7 +26,10 @@ dependencies {
testCompile(projectTests(":idea:idea-test-framework"))
testCompileOnly(intellijDep())
- testCompileOnly(intellijPluginDep("maven"))
+ if (Ide.IJ()) {
+ testCompileOnly(intellijPluginDep("maven"))
+ testRuntime(intellijPluginDep("maven"))
+ }
testCompile(project(":idea:idea-native")) { isTransitive = false }
testRuntime(project(":kotlin-native:kotlin-native-library-reader")) { isTransitive = false }
@@ -51,14 +54,20 @@ dependencies {
testRuntime(intellijPluginDep("gradle"))
testRuntime(intellijPluginDep("Groovy"))
testRuntime(intellijPluginDep("coverage"))
- testRuntime(intellijPluginDep("maven"))
testRuntime(intellijPluginDep("android"))
testRuntime(intellijPluginDep("smali"))
}
-sourceSets {
- "main" { projectDefault() }
- "test" { projectDefault() }
+if (Ide.IJ()) {
+ sourceSets {
+ "main" { projectDefault() }
+ "test" { projectDefault() }
+ }
+} else {
+ sourceSets {
+ "main" { }
+ "test" { }
+ }
}
testsJar()
@@ -67,8 +76,11 @@ projectTest {
workingDir = rootDir
}
-runtimeJar {
- archiveName = "maven-ide.jar"
-}
-ideaPlugin()
\ No newline at end of file
+if (Ide.IJ()) {
+ runtimeJar {
+ archiveName = "maven-ide.jar"
+ }
+
+ ideaPlugin()
+}
diff --git a/idea/idea-maven/build.gradle.kts.as32 b/idea/idea-maven/build.gradle.kts.as32
deleted file mode 100644
index 7d78a259b88..00000000000
--- a/idea/idea-maven/build.gradle.kts.as32
+++ /dev/null
@@ -1,68 +0,0 @@
-
-plugins {
- kotlin("jvm")
- id("jps-compatible")
-}
-
-dependencies {
- compile(project(":core:util.runtime"))
- compile(project(":compiler:frontend"))
- compile(project(":compiler:frontend.java"))
- compile(project(":compiler:util"))
- compile(project(":compiler:cli-common"))
- compile(project(":kotlin-build-common"))
-
- compile(project(":js:js.frontend"))
-
- compile(project(":idea"))
- compile(project(":idea:idea-jvm"))
- compile(project(":idea:idea-jps-common"))
-
- compileOnly(intellijDep())
- excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) }
-
- testCompile(projectTests(":idea"))
- testCompile(projectTests(":compiler:tests-common"))
- testCompile(projectTests(":idea:idea-test-framework"))
-
- testCompileOnly(intellijDep())
- //testCompileOnly(intellijPluginDep("maven"))
-
- testCompile(project(":idea:idea-native")) { isTransitive = false }
- testRuntime(project(":kotlin-native:kotlin-native-library-reader")) { isTransitive = false }
- testRuntime(project(":kotlin-native:kotlin-native-utils")) { isTransitive = false }
-
- testRuntime(project(":kotlin-reflect"))
- testRuntime(project(":idea:idea-jvm"))
- testRuntime(project(":idea:idea-android"))
- testRuntime(project(":plugins:android-extensions-ide"))
- testRuntime(project(":plugins:lint"))
- testRuntime(project(":sam-with-receiver-ide-plugin"))
- testRuntime(project(":allopen-ide-plugin"))
- testRuntime(project(":noarg-ide-plugin"))
- testRuntime(project(":kotlin-scripting-idea"))
- testRuntime(project(":kotlinx-serialization-ide-plugin"))
-
- testRuntime(intellijDep())
- // TODO: the order of the plugins matters here, consider avoiding order-dependency
- testRuntime(intellijPluginDep("junit"))
- testRuntime(intellijPluginDep("testng"))
- testRuntime(intellijPluginDep("properties"))
- testRuntime(intellijPluginDep("gradle"))
- testRuntime(intellijPluginDep("Groovy"))
- testRuntime(intellijPluginDep("coverage"))
- //testRuntime(intellijPluginDep("maven"))
- testRuntime(intellijPluginDep("android"))
- testRuntime(intellijPluginDep("smali"))
-}
-
-sourceSets {
- "main" { /*projectDefault()*/ }
- "test" { /*projectDefault()*/ }
-}
-
-testsJar()
-
-projectTest {
- workingDir = rootDir
-}
diff --git a/idea/idea-maven/build.gradle.kts.as33 b/idea/idea-maven/build.gradle.kts.as33
deleted file mode 100644
index 4ecbe3f70dc..00000000000
--- a/idea/idea-maven/build.gradle.kts.as33
+++ /dev/null
@@ -1,74 +0,0 @@
-
-plugins {
- kotlin("jvm")
- id("jps-compatible")
-}
-
-dependencies {
- compile(project(":core:util.runtime"))
- compile(project(":compiler:frontend"))
- compile(project(":compiler:frontend.java"))
- compile(project(":compiler:util"))
- compile(project(":compiler:cli-common"))
- compile(project(":kotlin-build-common"))
-
- compile(project(":js:js.frontend"))
-
- compile(project(":idea"))
- compile(project(":idea:idea-jvm"))
- compile(project(":idea:idea-jps-common"))
-
- compileOnly(intellijDep())
- excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) }
-
- testCompile(projectTests(":idea"))
- testCompile(projectTests(":compiler:tests-common"))
- testCompile(projectTests(":idea:idea-test-framework"))
-
- testCompileOnly(intellijDep())
- //testCompileOnly(intellijPluginDep("maven"))
-
- testCompile(project(":idea:idea-native")) { isTransitive = false }
- testRuntime(project(":kotlin-native:kotlin-native-library-reader")) { isTransitive = false }
- testRuntime(project(":kotlin-native:kotlin-native-utils")) { isTransitive = false }
-
- testRuntime(project(":kotlin-reflect"))
- testRuntime(project(":idea:idea-jvm"))
- testRuntime(project(":idea:idea-android"))
- testRuntime(project(":plugins:android-extensions-ide"))
- testRuntime(project(":plugins:lint"))
- testRuntime(project(":sam-with-receiver-ide-plugin"))
- testRuntime(project(":allopen-ide-plugin"))
- testRuntime(project(":noarg-ide-plugin"))
- testRuntime(project(":kotlin-scripting-idea"))
- testRuntime(project(":kotlinx-serialization-ide-plugin"))
-
- testRuntime(intellijDep())
- // TODO: the order of the plugins matters here, consider avoiding order-dependency
- testRuntime(intellijPluginDep("junit"))
- testRuntime(intellijPluginDep("testng"))
- testRuntime(intellijPluginDep("properties"))
- testRuntime(intellijPluginDep("gradle"))
- testRuntime(intellijPluginDep("Groovy"))
- testRuntime(intellijPluginDep("coverage"))
- //testRuntime(intellijPluginDep("maven"))
- testRuntime(intellijPluginDep("android"))
- testRuntime(intellijPluginDep("smali"))
-}
-
-sourceSets {
- "main" { /*projectDefault()*/ }
- "test" { /*projectDefault()*/ }
-}
-
-testsJar()
-
-projectTest {
- workingDir = rootDir
-}
-
-runtimeJar {
- archiveName = "maven-ide.jar"
-}
-
-ideaPlugin()
\ No newline at end of file
diff --git a/idea/idea-maven/build.gradle.kts.as34 b/idea/idea-maven/build.gradle.kts.as34
deleted file mode 100644
index 4ecbe3f70dc..00000000000
--- a/idea/idea-maven/build.gradle.kts.as34
+++ /dev/null
@@ -1,74 +0,0 @@
-
-plugins {
- kotlin("jvm")
- id("jps-compatible")
-}
-
-dependencies {
- compile(project(":core:util.runtime"))
- compile(project(":compiler:frontend"))
- compile(project(":compiler:frontend.java"))
- compile(project(":compiler:util"))
- compile(project(":compiler:cli-common"))
- compile(project(":kotlin-build-common"))
-
- compile(project(":js:js.frontend"))
-
- compile(project(":idea"))
- compile(project(":idea:idea-jvm"))
- compile(project(":idea:idea-jps-common"))
-
- compileOnly(intellijDep())
- excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) }
-
- testCompile(projectTests(":idea"))
- testCompile(projectTests(":compiler:tests-common"))
- testCompile(projectTests(":idea:idea-test-framework"))
-
- testCompileOnly(intellijDep())
- //testCompileOnly(intellijPluginDep("maven"))
-
- testCompile(project(":idea:idea-native")) { isTransitive = false }
- testRuntime(project(":kotlin-native:kotlin-native-library-reader")) { isTransitive = false }
- testRuntime(project(":kotlin-native:kotlin-native-utils")) { isTransitive = false }
-
- testRuntime(project(":kotlin-reflect"))
- testRuntime(project(":idea:idea-jvm"))
- testRuntime(project(":idea:idea-android"))
- testRuntime(project(":plugins:android-extensions-ide"))
- testRuntime(project(":plugins:lint"))
- testRuntime(project(":sam-with-receiver-ide-plugin"))
- testRuntime(project(":allopen-ide-plugin"))
- testRuntime(project(":noarg-ide-plugin"))
- testRuntime(project(":kotlin-scripting-idea"))
- testRuntime(project(":kotlinx-serialization-ide-plugin"))
-
- testRuntime(intellijDep())
- // TODO: the order of the plugins matters here, consider avoiding order-dependency
- testRuntime(intellijPluginDep("junit"))
- testRuntime(intellijPluginDep("testng"))
- testRuntime(intellijPluginDep("properties"))
- testRuntime(intellijPluginDep("gradle"))
- testRuntime(intellijPluginDep("Groovy"))
- testRuntime(intellijPluginDep("coverage"))
- //testRuntime(intellijPluginDep("maven"))
- testRuntime(intellijPluginDep("android"))
- testRuntime(intellijPluginDep("smali"))
-}
-
-sourceSets {
- "main" { /*projectDefault()*/ }
- "test" { /*projectDefault()*/ }
-}
-
-testsJar()
-
-projectTest {
- workingDir = rootDir
-}
-
-runtimeJar {
- archiveName = "maven-ide.jar"
-}
-
-ideaPlugin()
\ No newline at end of file
diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.191 b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.191
new file mode 100644
index 00000000000..c4f6f68bc2e
--- /dev/null
+++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt.191
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.maven
+
+import com.intellij.openapi.components.PersistentStateComponent
+import com.intellij.openapi.components.State
+import com.intellij.openapi.components.Storage
+import com.intellij.openapi.components.StoragePathMacros
+import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.roots.*
+import com.intellij.openapi.roots.impl.libraries.LibraryEx
+import com.intellij.openapi.roots.libraries.Library
+import com.intellij.util.PathUtil
+import org.jdom.Element
+import org.jdom.Text
+import org.jetbrains.concurrency.AsyncPromise
+import org.jetbrains.idea.maven.importing.MavenImporter
+import org.jetbrains.idea.maven.importing.MavenRootModelAdapter
+import org.jetbrains.idea.maven.model.MavenPlugin
+import org.jetbrains.idea.maven.project.*
+import org.jetbrains.jps.model.java.JavaSourceRootType
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType
+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
+import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
+import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
+import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
+import org.jetbrains.kotlin.config.*
+import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
+import org.jetbrains.kotlin.idea.facet.*
+import org.jetbrains.kotlin.idea.framework.detectLibraryKind
+import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator
+import org.jetbrains.kotlin.idea.platform.tooling
+import org.jetbrains.kotlin.platform.IdePlatform
+import org.jetbrains.kotlin.platform.IdePlatformKind
+import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.isCommon
+import org.jetbrains.kotlin.utils.SmartList
+import org.jetbrains.kotlin.utils.addIfNotNull
+import java.io.File
+import java.util.*
+
+interface MavenProjectImportHandler {
+ companion object : ProjectExtensionDescriptor(
+ "org.jetbrains.kotlin.mavenProjectImportHandler",
+ MavenProjectImportHandler::class.java
+ )
+
+ operator fun invoke(facet: KotlinFacet, mavenProject: MavenProject)
+}
+
+class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID) {
+ companion object {
+ const val KOTLIN_PLUGIN_GROUP_ID = "org.jetbrains.kotlin"
+ const val KOTLIN_PLUGIN_ARTIFACT_ID = "kotlin-maven-plugin"
+
+ const val KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG = "sourceDirs"
+ }
+
+ override fun preProcess(
+ module: Module,
+ mavenProject: MavenProject,
+ changes: MavenProjectChanges,
+ modifiableModelsProvider: IdeModifiableModelsProvider
+ ) {
+ }
+
+ override fun process(
+ modifiableModelsProvider: IdeModifiableModelsProvider,
+ module: Module,
+ rootModel: MavenRootModelAdapter,
+ mavenModel: MavenProjectsTree,
+ mavenProject: MavenProject,
+ changes: MavenProjectChanges,
+ mavenProjectToModuleName: MutableMap,
+ postTasks: MutableList
+ ) {
+
+ if (changes.plugins) {
+ contributeSourceDirectories(mavenProject, module, rootModel)
+ }
+ }
+
+ override fun postProcess(
+ module: Module,
+ mavenProject: MavenProject,
+ changes: MavenProjectChanges,
+ modifiableModelsProvider: IdeModifiableModelsProvider
+ ) {
+ super.postProcess(module, mavenProject, changes, modifiableModelsProvider)
+
+ if (changes.dependencies) {
+ scheduleDownloadStdlibSources(mavenProject, module)
+
+ val targetLibraryKind = detectPlatformByExecutions(mavenProject)?.tooling?.libraryKind
+ if (targetLibraryKind != null) {
+ modifiableModelsProvider.getModifiableRootModel(module).orderEntries().forEachLibrary { library ->
+ if ((library as LibraryEx).kind == null) {
+ val model = modifiableModelsProvider.getModifiableLibraryModel(library) as LibraryEx.ModifiableModelEx
+ detectLibraryKind(model.getFiles(OrderRootType.CLASSES))?.let { model.kind = it }
+ }
+ true
+ }
+ }
+ }
+
+ configureFacet(mavenProject, modifiableModelsProvider, module)
+ }
+
+ private fun scheduleDownloadStdlibSources(mavenProject: MavenProject, module: Module) {
+ // TODO: here we have to process all kotlin libraries but for now we only handle standard libraries
+ val artifacts = mavenProject.dependencyArtifactIndex.data[KOTLIN_PLUGIN_GROUP_ID]?.values?.flatMap { it.filter { it.isResolved } }
+ ?: emptyList()
+
+ val librariesWithNoSources = ArrayList()
+ OrderEnumerator.orderEntries(module).forEachLibrary { library ->
+ if (library.modifiableModel.getFiles(OrderRootType.SOURCES).isEmpty()) {
+ librariesWithNoSources.add(library)
+ }
+ true
+ }
+ val libraryNames = librariesWithNoSources.mapTo(HashSet()) { it.name }
+ val toBeDownloaded = artifacts.filter { it.libraryName in libraryNames }
+
+ if (toBeDownloaded.isNotEmpty()) {
+ MavenProjectsManager.getInstance(module.project)
+ .scheduleArtifactsDownloading(listOf(mavenProject), toBeDownloaded, true, false, AsyncPromise())
+ }
+ }
+
+ private fun configureJSOutputPaths(
+ mavenProject: MavenProject,
+ modifiableRootModel: ModifiableRootModel,
+ facetSettings: KotlinFacetSettings,
+ mavenPlugin: MavenPlugin
+ ) {
+ fun parentPath(path: String): String =
+ File(path).absoluteFile.parentFile.absolutePath
+
+ val sharedOutputFile = mavenPlugin.configurationElement?.getChild("outputFile")?.text
+
+ val compilerModuleExtension = modifiableRootModel.getModuleExtension(CompilerModuleExtension::class.java) ?: return
+ val buildDirectory = mavenProject.buildDirectory
+
+ val executions = mavenPlugin.executions
+
+ executions.forEach {
+ val explicitOutputFile = it.configurationElement?.getChild("outputFile")?.text ?: sharedOutputFile
+ if (PomFile.KotlinGoals.Js in it.goals) {
+ // see org.jetbrains.kotlin.maven.K2JSCompilerMojo
+ val outputFilePath = PathUtil.toSystemDependentName(explicitOutputFile ?: "$buildDirectory/js/${mavenProject.mavenId.artifactId}.js")
+ compilerModuleExtension.setCompilerOutputPath(parentPath(outputFilePath))
+ facetSettings.productionOutputPath = outputFilePath
+ }
+ if (PomFile.KotlinGoals.TestJs in it.goals) {
+ // see org.jetbrains.kotlin.maven.KotlinTestJSCompilerMojo
+ val outputFilePath = PathUtil.toSystemDependentName(explicitOutputFile ?: "$buildDirectory/test-js/${mavenProject.mavenId.artifactId}-tests.js")
+ compilerModuleExtension.setCompilerOutputPathForTests(parentPath(outputFilePath))
+ facetSettings.testOutputPath = outputFilePath
+ }
+ }
+ }
+
+ private fun getCompilerArgumentsByConfigurationElement(
+ mavenProject: MavenProject,
+ configuration: Element?,
+ platform: IdePlatform<*, *>
+ ): List {
+ val arguments = platform.createArguments()
+
+ arguments.apiVersion = configuration?.getChild("apiVersion")?.text ?:
+ mavenProject.properties["kotlin.compiler.apiVersion"]?.toString()
+ arguments.languageVersion = configuration?.getChild("languageVersion")?.text ?:
+ mavenProject.properties["kotlin.compiler.languageVersion"]?.toString()
+ arguments.multiPlatform = configuration?.getChild("multiPlatform")?.text?.trim()?.toBoolean() ?: false
+ arguments.suppressWarnings = configuration?.getChild("nowarn")?.text?.trim()?.toBoolean() ?: false
+
+ configuration?.getChild("experimentalCoroutines")?.text?.trim()?.let {
+ arguments.coroutinesState = it
+ }
+
+ when (arguments) {
+ is K2JVMCompilerArguments -> {
+ arguments.classpath = configuration?.getChild("classpath")?.text
+ arguments.jdkHome = configuration?.getChild("jdkHome")?.text
+ arguments.jvmTarget = configuration?.getChild("jvmTarget")?.text ?:
+ mavenProject.properties["kotlin.compiler.jvmTarget"]?.toString()
+ arguments.javaParameters = configuration?.getChild("javaParameters")?.text?.toBoolean() ?: false
+ }
+ is K2JSCompilerArguments -> {
+ arguments.sourceMap = configuration?.getChild("sourceMap")?.text?.trim()?.toBoolean() ?: false
+ arguments.sourceMapPrefix = configuration?.getChild("sourceMapPrefix")?.text?.trim() ?: ""
+ arguments.sourceMapEmbedSources = configuration?.getChild("sourceMapEmbedSources")?.text?.trim() ?: "inlining"
+ arguments.outputFile = configuration?.getChild("outputFile")?.text
+ arguments.metaInfo = configuration?.getChild("metaInfo")?.text?.trim()?.toBoolean() ?: false
+ arguments.moduleKind = configuration?.getChild("moduleKind")?.text
+ arguments.main = configuration?.getChild("main")?.text
+ }
+ }
+
+ val additionalArgs = SmartList().apply {
+ val argsElement = configuration?.getChild("args")
+
+ argsElement?.content?.forEach { argElement ->
+ when (argElement) {
+ is Text -> {
+ argElement.text?.let { addAll(splitArgumentString(it)) }
+ }
+ is Element -> {
+ if (argElement.name == "arg") {
+ addIfNotNull(argElement.text)
+ }
+ }
+ }
+ }
+ }
+ parseCommandLineArguments(additionalArgs, arguments)
+
+ return ArgumentUtils.convertArgumentsToStringList(arguments)
+ }
+
+ private val compilationGoals = listOf(
+ PomFile.KotlinGoals.Compile,
+ PomFile.KotlinGoals.TestCompile,
+ PomFile.KotlinGoals.Js,
+ PomFile.KotlinGoals.TestJs,
+ PomFile.KotlinGoals.MetaData
+ )
+
+ private fun configureFacet(mavenProject: MavenProject, modifiableModelsProvider: IdeModifiableModelsProvider, module: Module) {
+ val mavenPlugin = mavenProject.findPlugin(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID) ?: return
+ val compilerVersion = mavenPlugin.version ?: LanguageVersion.LATEST_STABLE.versionString
+ val kotlinFacet = module.getOrCreateFacet(
+ modifiableModelsProvider,
+ false,
+ ExternalProjectSystemRegistry.MAVEN_EXTERNAL_SOURCE_ID
+ )
+
+ // TODO There should be a way to figure out the correct platform version
+ val platform = detectPlatform(mavenProject)?.defaultPlatform
+
+ kotlinFacet.configureFacet(compilerVersion, LanguageFeature.Coroutines.defaultState, platform, modifiableModelsProvider)
+ val facetSettings = kotlinFacet.configuration.settings
+ val configuredPlatform = kotlinFacet.configuration.settings.platform!!
+ val configuration = mavenPlugin.configurationElement
+ val sharedArguments = getCompilerArgumentsByConfigurationElement(mavenProject, configuration, configuredPlatform)
+ val executionArguments = mavenPlugin.executions
+ ?.firstOrNull { it.goals.any { it in compilationGoals } }
+ ?.configurationElement?.let { getCompilerArgumentsByConfigurationElement(mavenProject, it, configuredPlatform) }
+ parseCompilerArgumentsToFacet(sharedArguments, emptyList(), kotlinFacet, modifiableModelsProvider)
+ if (executionArguments != null) {
+ parseCompilerArgumentsToFacet(executionArguments, emptyList(), kotlinFacet, modifiableModelsProvider)
+ }
+ if (facetSettings.compilerArguments is K2JSCompilerArguments) {
+ configureJSOutputPaths(mavenProject, modifiableModelsProvider.getModifiableRootModel(module), facetSettings, mavenPlugin)
+ }
+ MavenProjectImportHandler.getInstances(module.project).forEach { it(kotlinFacet, mavenProject) }
+ setImplementedModuleName(kotlinFacet, mavenProject, module)
+ kotlinFacet.noVersionAutoAdvance()
+ }
+
+ private fun detectPlatform(mavenProject: MavenProject) =
+ detectPlatformByExecutions(mavenProject) ?: detectPlatformByLibraries(mavenProject)
+
+ private fun detectPlatformByExecutions(mavenProject: MavenProject): IdePlatformKind<*>? {
+ return mavenProject.findPlugin(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID)?.executions?.flatMap { it.goals }
+ ?.mapNotNull { goal ->
+ when (goal) {
+ PomFile.KotlinGoals.Compile, PomFile.KotlinGoals.TestCompile -> JvmIdePlatformKind
+ PomFile.KotlinGoals.Js, PomFile.KotlinGoals.TestJs -> JsIdePlatformKind
+ PomFile.KotlinGoals.MetaData -> CommonIdePlatformKind
+ else -> null
+ }
+ }?.distinct()?.singleOrNull()
+ }
+
+ private fun detectPlatformByLibraries(mavenProject: MavenProject): IdePlatformKind<*>? {
+ for (kind in IdePlatformKind.ALL_KINDS) {
+ val mavenLibraryIds = kind.tooling.mavenLibraryIds
+ if (mavenLibraryIds.any { mavenProject.findDependencies(KOTLIN_PLUGIN_GROUP_ID, it).isNotEmpty() }) {
+ // TODO we could return here the correct version
+ return kind
+ }
+ }
+
+ return null
+ }
+
+ // TODO in theory it should work like this but it doesn't as it couldn't unmark source roots that are not roots anymore.
+ // I believe this is something should be done by the underlying maven importer implementation or somewhere else in the IDEA
+ // For now there is a contributeSourceDirectories implementation that deals with the issue
+ // see https://youtrack.jetbrains.com/issue/IDEA-148280
+
+ // override fun collectSourceRoots(mavenProject: MavenProject, result: PairConsumer>) {
+ // for ((type, dir) in collectSourceDirectories(mavenProject)) {
+ // val jpsType: JpsModuleSourceRootType<*> = when (type) {
+ // SourceType.PROD -> JavaSourceRootType.SOURCE
+ // SourceType.TEST -> JavaSourceRootType.TEST_SOURCE
+ // }
+ //
+ // result.consume(dir, jpsType)
+ // }
+ // }
+
+ private fun contributeSourceDirectories(mavenProject: MavenProject, module: Module, rootModel: MavenRootModelAdapter) {
+ val directories = collectSourceDirectories(mavenProject)
+
+ val toBeAdded = directories.map { it.second }.toSet()
+ val state = module.kotlinImporterComponent
+
+ val isNonJvmModule = mavenProject
+ .plugins
+ .asSequence()
+ .filter { it.isKotlinPlugin() }
+ .flatMap { it.executions.asSequence() }
+ .flatMap { it.goals.asSequence() }
+ .any { it in PomFile.KotlinGoals.CompileGoals && it !in PomFile.KotlinGoals.JvmGoals }
+
+ val prodSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.Source else JavaSourceRootType.SOURCE
+ val testSourceRootType: JpsModuleSourceRootType<*> = if (isNonJvmModule) KotlinSourceRootType.TestSource else JavaSourceRootType.TEST_SOURCE
+
+ for ((type, dir) in directories) {
+ if (rootModel.getSourceFolder(File(dir)) == null) {
+ val jpsType: JpsModuleSourceRootType<*> = when (type) {
+ SourceType.TEST -> testSourceRootType
+ SourceType.PROD -> prodSourceRootType
+ }
+
+ rootModel.addSourceFolder(dir, jpsType)
+ }
+ }
+
+ if (isNonJvmModule) {
+ mavenProject.sources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.Source) }
+ mavenProject.testSources.forEach { rootModel.addSourceFolder(it, KotlinSourceRootType.TestSource) }
+ mavenProject.resources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.Resource) }
+ mavenProject.testResources.forEach { rootModel.addSourceFolder(it.directory, KotlinResourceRootType.TestResource) }
+ }
+
+ state.addedSources.filter { it !in toBeAdded }.forEach {
+ rootModel.unregisterAll(it, true, true)
+ state.addedSources.remove(it)
+ }
+ state.addedSources.addAll(toBeAdded)
+ }
+
+ private fun collectSourceDirectories(mavenProject: MavenProject): List> =
+ mavenProject.plugins.filter { it.isKotlinPlugin() }.flatMap { plugin ->
+ plugin.configurationElement.sourceDirectories().map { SourceType.PROD to it } +
+ plugin.executions.flatMap { execution ->
+ execution.configurationElement.sourceDirectories().map { execution.sourceType() to it }
+ }
+ }.distinct()
+
+ private fun setImplementedModuleName(kotlinFacet: KotlinFacet, mavenProject: MavenProject, module: Module) {
+ if (kotlinFacet.configuration.settings.platform.isCommon) {
+ kotlinFacet.configuration.settings.implementedModuleNames = emptyList()
+ } else {
+ val manager = MavenProjectsManager.getInstance(module.project)
+ val mavenDependencies = mavenProject.dependencies.mapNotNull { manager?.findProject(it) }
+ val implemented = mavenDependencies.filter { detectPlatformByExecutions(it).isCommon }
+
+ kotlinFacet.configuration.settings.implementedModuleNames = implemented.map { manager.findModule(it)?.name ?: it.displayName }
+ }
+ }
+}
+
+private fun MavenPlugin.isKotlinPlugin() =
+ groupId == KotlinMavenImporter.KOTLIN_PLUGIN_GROUP_ID && artifactId == KotlinMavenImporter.KOTLIN_PLUGIN_ARTIFACT_ID
+
+private fun Element?.sourceDirectories(): List =
+ this?.getChildren(KotlinMavenImporter.KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG)?.flatMap { it.children ?: emptyList() }?.map { it.textTrim }
+ ?: emptyList()
+
+private fun MavenPlugin.Execution.sourceType() =
+ goals.map { if (isTestGoalName(it)) SourceType.TEST else SourceType.PROD }
+ .distinct()
+ .singleOrNull() ?: SourceType.PROD
+
+private fun isTestGoalName(goalName: String) = goalName.startsWith("test-")
+
+private enum class SourceType {
+ PROD, TEST
+}
+
+@State(
+ name = "AutoImportedSourceRoots",
+ storages = [(Storage(file = StoragePathMacros.MODULE_FILE))]
+)
+class KotlinImporterComponent : PersistentStateComponent {
+ class State(var directories: List = ArrayList())
+
+ val addedSources: MutableSet = Collections.synchronizedSet(HashSet())
+
+ override fun loadState(state: State) {
+ addedSources.clear()
+ addedSources.addAll(state.directories)
+ }
+
+ override fun getState(): State {
+ return State(addedSources.sorted())
+ }
+}
+
+private val Module.kotlinImporterComponent: KotlinImporterComponent
+ get() = getComponent(KotlinImporterComponent::class.java) ?: throw IllegalStateException("No maven importer state configured")
diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt
index b184952f269..0db979abdac 100644
--- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt
+++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt
@@ -273,7 +273,7 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
private fun safelyGetArguments(compileKotlinTask: Task, accessor: Method?) = try {
accessor?.invoke(compileKotlinTask) as? List
} catch (e: Exception) {
- logger.info(e.message, e)
+ logger.info(e.message ?: "Unexpected exception: $e", e)
null
} ?: emptyList()
diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt.181 b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt.181
index 909e1d9fb02..a7ff5effc27 100644
--- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt.181
+++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt.181
@@ -264,7 +264,7 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
private fun safelyGetArguments(compileKotlinTask: Task, accessor: Method?) = try {
accessor?.invoke(compileKotlinTask) as? List
} catch (e: Exception) {
- logger.info(e.message, e)
+ logger.info(e.message ?: "Unexpected exception: $e", e)
null
} ?: emptyList()
diff --git a/idea/testData/checker/regression/javaStyleClassLiteralInAnnotationArguments.kt b/idea/testData/checker/regression/javaStyleClassLiteralInAnnotationArguments.kt
index 43615b3085d..430078b8aeb 100644
--- a/idea/testData/checker/regression/javaStyleClassLiteralInAnnotationArguments.kt
+++ b/idea/testData/checker/regression/javaStyleClassLiteralInAnnotationArguments.kt
@@ -2,5 +2,5 @@ annotation class A
class B
-@A(B.class)
-fun f() {}
\ No newline at end of file
+@A(B.class)
+fun f() {}
diff --git a/idea/testData/inspections/unusedImport/suppression.kt b/idea/testData/inspections/unusedImport/suppression.kt
index cd6684b02b0..4ccf8064b31 100644
--- a/idea/testData/inspections/unusedImport/suppression.kt
+++ b/idea/testData/inspections/unusedImport/suppression.kt
@@ -1,3 +1,4 @@
@file:Suppress("UnusedImport")
+package suppression
-import java.io.* // unused
\ No newline at end of file
+import java.io.* // unused
diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt
index 03e034eb022..ea61c50879a 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt
+++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt
@@ -94,7 +94,7 @@ abstract class AbstractInspectionTest : KotlinLightCodeInsightFixtureTestCase()
file.extension == "kt" -> {
val text = FileUtil.loadFile(file, true)
val fileText =
- if (text.startsWith("package"))
+ if (text.lines().any { it.startsWith("package") })
text
else
"package ${file.nameWithoutExtension};$text"
diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java
index eebcedaef57..0504e95cc66 100644
--- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java
+++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java
@@ -3086,6 +3086,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/closures/closureWithParameterAndBoxing.kt");
}
+ @TestMetadata("crossinlineLocalDeclaration.kt")
+ public void testCrossinlineLocalDeclaration() throws Exception {
+ runTest("compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt");
+ }
+
@TestMetadata("doubleEnclosedLocalVariable.kt")
public void testDoubleEnclosedLocalVariable() throws Exception {
runTest("compiler/testData/codegen/box/closures/doubleEnclosedLocalVariable.kt");
@@ -18797,6 +18802,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
+
+ @TestMetadata("whenByUnsigned.kt")
+ public void testWhenByUnsigned() throws Exception {
+ runTest("compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt");
+ }
}
@TestMetadata("compiler/testData/codegen/box/vararg")
diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java
index 73dd72e1de6..ec98f0a906d 100644
--- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java
+++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java
@@ -3086,6 +3086,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/closures/closureWithParameterAndBoxing.kt");
}
+ @TestMetadata("crossinlineLocalDeclaration.kt")
+ public void testCrossinlineLocalDeclaration() throws Exception {
+ runTest("compiler/testData/codegen/box/closures/crossinlineLocalDeclaration.kt");
+ }
+
@TestMetadata("doubleEnclosedLocalVariable.kt")
public void testDoubleEnclosedLocalVariable() throws Exception {
runTest("compiler/testData/codegen/box/closures/doubleEnclosedLocalVariable.kt");
@@ -19847,6 +19852,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testVarargsOfUnsignedTypes() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
}
+
+ @TestMetadata("whenByUnsigned.kt")
+ public void testWhenByUnsigned() throws Exception {
+ runTest("compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt");
+ }
}
@TestMetadata("compiler/testData/codegen/box/vararg")
diff --git a/libraries/stdlib/common/src/generated/_Arrays.kt b/libraries/stdlib/common/src/generated/_Arrays.kt
index 59127d8e20c..cc15c5828d8 100644
--- a/libraries/stdlib/common/src/generated/_Arrays.kt
+++ b/libraries/stdlib/common/src/generated/_Arrays.kt
@@ -5040,6 +5040,8 @@ public fun CharArray.reversedArray(): CharArray {
/**
* Sorts elements in the array in-place according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > Array.sortBy(crossinline selector: (T) -> R?): Unit {
if (size > 1) sortWith(compareBy(selector))
@@ -5047,6 +5049,8 @@ public inline fun > Array.sortBy(crossinline selecto
/**
* Sorts elements in the array in-place descending according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > Array.sortByDescending(crossinline selector: (T) -> R?): Unit {
if (size > 1) sortWith(compareByDescending(selector))
@@ -5054,6 +5058,8 @@ public inline fun > Array.sortByDescending(crossinli
/**
* Sorts elements in the array in-place descending according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > Array.sortDescending(): Unit {
sortWith(reverseOrder())
@@ -5131,6 +5137,8 @@ public fun CharArray.sortDescending(): Unit {
/**
* Returns a list of all elements sorted according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > Array.sorted(): List {
return sortedArray().asList()
@@ -5187,6 +5195,8 @@ public fun CharArray.sorted(): List {
/**
* Returns an array with all elements of this array sorted according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > Array.sortedArray(): Array {
if (isEmpty()) return this
@@ -5251,6 +5261,8 @@ public fun CharArray.sortedArray(): CharArray {
/**
* Returns an array with all elements of this array sorted descending according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > Array.sortedArrayDescending(): Array {
if (isEmpty()) return this
@@ -5315,6 +5327,8 @@ public fun CharArray.sortedArrayDescending(): CharArray {
/**
* Returns an array with all elements of this array sorted according the specified [comparator].
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun Array.sortedArrayWith(comparator: Comparator): Array {
if (isEmpty()) return this
@@ -5323,6 +5337,8 @@ public fun Array.sortedArrayWith(comparator: Comparator): Array
/**
* Returns a list of all elements sorted according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > Array.sortedBy(crossinline selector: (T) -> R?): List {
return sortedWith(compareBy(selector))
@@ -5386,6 +5402,8 @@ public inline fun > CharArray.sortedBy(crossinline selector: (
/**
* Returns a list of all elements sorted descending according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > Array.sortedByDescending(crossinline selector: (T) -> R?): List {
return sortedWith(compareByDescending(selector))
@@ -5449,6 +5467,8 @@ public inline fun > CharArray.sortedByDescending(crossinline s
/**
* Returns a list of all elements sorted descending according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > Array.sortedDescending(): List {
return sortedWith(reverseOrder())
@@ -5505,6 +5525,8 @@ public fun CharArray.sortedDescending(): List {
/**
* Returns a list of all elements sorted according to the specified [comparator].
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun Array.sortedWith(comparator: Comparator): List {
return sortedArrayWith(comparator).asList()
@@ -6702,11 +6724,15 @@ public expect fun CharArray.sort(): Unit
/**
* Sorts the array in-place according to the natural order of its elements.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public expect fun > Array.sort(): Unit
/**
* Sorts the array in-place according to the order specified by the given [comparator].
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public expect fun Array.sortWith(comparator: Comparator): Unit
diff --git a/libraries/stdlib/common/src/generated/_Collections.kt b/libraries/stdlib/common/src/generated/_Collections.kt
index 8b77a7f9ad1..1c045d13076 100644
--- a/libraries/stdlib/common/src/generated/_Collections.kt
+++ b/libraries/stdlib/common/src/generated/_Collections.kt
@@ -861,6 +861,8 @@ public fun Iterable.reversed(): List {
/**
* Sorts elements in the list in-place according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > MutableList.sortBy(crossinline selector: (T) -> R?): Unit {
if (size > 1) sortWith(compareBy(selector))
@@ -868,6 +870,8 @@ public inline fun > MutableList.sortBy(crossinline selec
/**
* Sorts elements in the list in-place descending according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > MutableList.sortByDescending(crossinline selector: (T) -> R?): Unit {
if (size > 1) sortWith(compareByDescending(selector))
@@ -875,6 +879,8 @@ public inline fun > MutableList.sortByDescending(crossin
/**
* Sorts elements in the list in-place descending according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > MutableList.sortDescending(): Unit {
sortWith(reverseOrder())
@@ -882,6 +888,8 @@ public fun > MutableList.sortDescending(): Unit {
/**
* Returns a list of all elements sorted according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > Iterable.sorted(): List {
if (this is Collection) {
@@ -894,6 +902,8 @@ public fun > Iterable.sorted(): List {
/**
* Returns a list of all elements sorted according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > Iterable.sortedBy(crossinline selector: (T) -> R?): List {
return sortedWith(compareBy(selector))
@@ -901,6 +911,8 @@ public inline fun > Iterable.sortedBy(crossinline select
/**
* Returns a list of all elements sorted descending according to natural sort order of the value returned by specified [selector] function.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public inline fun > Iterable.sortedByDescending(crossinline selector: (T) -> R?): List {
return sortedWith(compareByDescending(selector))
@@ -908,6 +920,8 @@ public inline fun > Iterable.sortedByDescending(crossinl
/**
* Returns a list of all elements sorted descending according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun > Iterable.sortedDescending(): List {
return sortedWith(reverseOrder())
@@ -915,6 +929,8 @@ public fun > Iterable.sortedDescending(): List {
/**
* Returns a list of all elements sorted according to the specified [comparator].
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*/
public fun Iterable.sortedWith(comparator: Comparator): List {
if (this is Collection) {
diff --git a/libraries/stdlib/common/src/generated/_Sequences.kt b/libraries/stdlib/common/src/generated/_Sequences.kt
index 5ea1d117639..a22b5f70cdd 100644
--- a/libraries/stdlib/common/src/generated/_Sequences.kt
+++ b/libraries/stdlib/common/src/generated/_Sequences.kt
@@ -502,6 +502,8 @@ public fun Sequence.takeWhile(predicate: (T) -> Boolean): Sequence {
/**
* Returns a sequence that yields elements of this sequence sorted according to their natural sort order.
+ *
+ * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting.
*
* The operation is _intermediate_ and _stateful_.
*/
@@ -517,6 +519,8 @@ public fun