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 > Sequence.sorted(): Sequence { /** * Returns a sequence that yields elements of this sequence 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. * * The operation is _intermediate_ and _stateful_. */ @@ -526,6 +530,8 @@ public inline fun > Sequence.sortedBy(crossinline select /** * Returns a sequence that yields elements of this sequence 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. * * The operation is _intermediate_ and _stateful_. */ @@ -535,6 +541,8 @@ public inline fun > Sequence.sortedByDescending(crossinl /** * Returns a sequence that yields elements of this sequence 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. * * The operation is _intermediate_ and _stateful_. */ @@ -544,6 +552,8 @@ public fun > Sequence.sortedDescending(): Sequence { /** * Returns a sequence that yields elements of this sequence sorted according to the specified [comparator]. + * + * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. * * The operation is _intermediate_ and _stateful_. */ diff --git a/libraries/stdlib/js/irRuntime/generated/_ArraysJs.kt b/libraries/stdlib/js/irRuntime/generated/_ArraysJs.kt index 4af1303e786..f0617b7c9a4 100644 --- a/libraries/stdlib/js/irRuntime/generated/_ArraysJs.kt +++ b/libraries/stdlib/js/irRuntime/generated/_ArraysJs.kt @@ -1198,6 +1198,8 @@ public actual 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 actual fun > Array.sort(): Unit { if (size > 1) sortArray(this) @@ -1205,6 +1207,8 @@ public actual fun > Array.sort(): Unit { /** * Sorts the array in-place according to the order specified by the given [comparison] function. + * + * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public fun Array.sort(comparison: (a: T, b: T) -> Int): Unit { if (size > 1) sortArrayWith(this, comparison) @@ -1268,6 +1272,8 @@ public inline fun CharArray.sort(noinline comparison: (a: Char, b: Char) -> Int) /** * 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 actual fun Array.sortWith(comparator: Comparator): Unit { if (size > 1) sortArrayWith(this, comparator) diff --git a/libraries/stdlib/js/src/generated/_ArraysJs.kt b/libraries/stdlib/js/src/generated/_ArraysJs.kt index e2144d233d5..639b78f8e13 100644 --- a/libraries/stdlib/js/src/generated/_ArraysJs.kt +++ b/libraries/stdlib/js/src/generated/_ArraysJs.kt @@ -1234,6 +1234,8 @@ public actual 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 actual fun > Array.sort(): Unit { if (size > 1) sortArray(this) @@ -1241,6 +1243,8 @@ public actual fun > Array.sort(): Unit { /** * Sorts the array in-place according to the order specified by the given [comparison] function. + * + * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public fun Array.sort(comparison: (a: T, b: T) -> Int): Unit { if (size > 1) sortArrayWith(this, comparison) @@ -1304,6 +1308,8 @@ public inline fun CharArray.sort(noinline comparison: (a: Char, b: Char) -> Int) /** * 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 actual fun Array.sortWith(comparator: Comparator): Unit { if (size > 1) sortArrayWith(this, comparator) diff --git a/libraries/stdlib/js/src/kotlin/collections.kt b/libraries/stdlib/js/src/kotlin/collections.kt index a54948cec2f..a7c52b110f8 100644 --- a/libraries/stdlib/js/src/kotlin/collections.kt +++ b/libraries/stdlib/js/src/kotlin/collections.kt @@ -93,6 +93,8 @@ public actual fun Iterable.shuffled(): List = toMutableList().apply { /** * Sorts elements in the list in-place 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 actual fun > MutableList.sort(): Unit { collectionsSort(this, naturalOrder()) @@ -100,6 +102,8 @@ public actual fun > MutableList.sort(): Unit { /** * Sorts elements in the list in-place according to the order specified with [comparator]. + * + * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public actual fun MutableList.sortWith(comparator: Comparator): Unit { collectionsSort(this, comparator) @@ -109,8 +113,7 @@ private fun collectionsSort(list: MutableList, comparator: Comparator> Array.sort(): Unit { @@ -1695,6 +1697,8 @@ public actual inline fun > Array.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. + * * @throws ClassCastException if any element of the array is not [Comparable]. */ public fun Array.sort(): Unit { @@ -1703,6 +1707,8 @@ public fun Array.sort(): Unit { /** * Sorts a range in the array in-place. + * + * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public fun Array.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { java.util.Arrays.sort(this, fromIndex, toIndex) @@ -1759,6 +1765,8 @@ public fun CharArray.sort(fromIndex: Int = 0, toIndex: Int = size): 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 actual fun Array.sortWith(comparator: Comparator): Unit { if (size > 1) java.util.Arrays.sort(this, comparator) @@ -1766,6 +1774,8 @@ public actual fun Array.sortWith(comparator: Comparator): Unit /** * Sorts a range in the array in-place with the given [comparator]. + * + * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public fun Array.sortWith(comparator: Comparator, fromIndex: Int = 0, toIndex: Int = size): Unit { java.util.Arrays.sort(this, fromIndex, toIndex, comparator) diff --git a/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt b/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt index 5fc774ea036..a861574744c 100644 --- a/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt +++ b/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt @@ -22,6 +22,8 @@ public inline fun MutableList.sort(comparison: (T, T) -> Int): Unit = thr /** * Sorts elements in the list in-place 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 actual fun > MutableList.sort(): Unit { if (size > 1) java.util.Collections.sort(this) @@ -29,6 +31,8 @@ public actual fun > MutableList.sort(): Unit { /** * Sorts elements in the list in-place according to the order specified with [comparator]. + * + * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public actual fun MutableList.sortWith(comparator: Comparator): Unit { if (size > 1) java.util.Collections.sort(this, comparator) diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index 47a69294c46..54a71ebefb1 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -1451,8 +1451,8 @@ class ArraysTest { for (size in listOf(10, 100, 2000)) { val array = Array(size) { index -> Sortable(keyRange.random(), index) } - array.sortedBy { it.key }.iterator().assertStableSorted() - array.sortedByDescending { it.key }.iterator().assertStableSorted(descending = true) + array.sortedBy { it.key }.assertStableSorted() + array.sortedByDescending { it.key }.assertStableSorted(descending = true) array.sortBy { it.key } array.assertStableSorted() @@ -1488,20 +1488,10 @@ class ArraysTest { } } -private data class Sortable>(val key: K, val index: Int) : Comparable> { - override fun compareTo(other: Sortable): Int = this.key.compareTo(other.key) -} -private fun > Array>.assertStableSorted(descending: Boolean = false) = +fun > Array>.assertStableSorted(descending: Boolean = false) = iterator().assertStableSorted(descending = descending) -private fun > Iterator>.assertStableSorted(descending: Boolean = false) { - assertSorted { a, b -> - val relation = a.key.compareTo(b.key) - (if (descending) relation > 0 else relation < 0) || relation == 0 && a.index < b.index - } -} - private class ArraySortedChecker(val array: A, val comparator: Comparator) { public fun checkSorted(sorted: A.() -> R, sortedDescending: A.() -> R, iterator: R.() -> Iterator) { array.sorted().iterator().assertSorted { a, b -> comparator.compare(a, b) <= 0 } diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index 22fcbbf7be0..d5711fbc80f 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -9,7 +9,6 @@ import test.assertStaticAndRuntimeTypeIs import kotlin.test.* import test.collections.behaviors.* import test.comparisons.STRING_CASE_INSENSITIVE_ORDER -import kotlin.math.sin import kotlin.random.Random class CollectionTest { @@ -829,6 +828,21 @@ class CollectionTest { assertEquals(listOf("aa" to 20, "aa" to 3, "ab" to 3), data) } + @Test fun sortStable() { + val keyRange = 'A'..'D' + for (size in listOf(10, 100, 2000)) { + val list = MutableList(size) { index -> Sortable(keyRange.random(), index) } + + list.sorted().assertStableSorted() + list.sortedDescending().assertStableSorted(descending = true) + + list.sort() + list.assertStableSorted() + list.sortDescending() + list.assertStableSorted(descending = true) + } + } + @Test fun sortedBy() { assertEquals(listOf("two" to 3, "three" to 20), listOf("three" to 20, "two" to 3).sortedBy { it.second }) assertEquals(listOf("three" to 20, "two" to 3), listOf("three" to 20, "two" to 3).sortedBy { it.first }) @@ -862,6 +876,22 @@ class CollectionTest { expect(listOf("BAD", "dad", "cat")) { data.sortedWith(comparator.reversed().reversed()) } } + @Test fun sortByStable() { + val keyRange = 'A'..'D' + for (size in listOf(10, 100, 2000)) { + val list = MutableList(size) { index -> Sortable(keyRange.random(), index) } + + list.sortedBy { it.key }.assertStableSorted() + list.sortedByDescending { it.key }.assertStableSorted(descending = true) + + list.sortBy { it.key } + list.assertStableSorted() + + list.sortByDescending { it.key } + list.assertStableSorted(descending = true) + } + } + @Test fun decomposeFirst() { val (first) = listOf(1, 2) assertEquals(first, 1) diff --git a/libraries/stdlib/test/collections/IterableTests.kt b/libraries/stdlib/test/collections/IterableTests.kt index 274904b60b9..d090dff6c17 100644 --- a/libraries/stdlib/test/collections/IterableTests.kt +++ b/libraries/stdlib/test/collections/IterableTests.kt @@ -508,3 +508,17 @@ fun Iterator.assertSorted(isInOrder: (T, T) -> Boolean) { return } +data class Sortable>(val key: K, val index: Int) : Comparable> { + override fun compareTo(other: Sortable): Int = this.key.compareTo(other.key) +} + + +fun > Iterator>.assertStableSorted(descending: Boolean = false) { + assertSorted { a, b -> + val relation = a.key.compareTo(b.key) + (if (descending) relation > 0 else relation < 0) || relation == 0 && a.index < b.index + } +} + +fun > Iterable>.assertStableSorted(descending: Boolean = false) = + iterator().assertStableSorted(descending = descending) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt index c92f7da1673..5849f683d28 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt @@ -6,6 +6,8 @@ package templates import templates.Family.* +import templates.Ordering.stableSortNote +import templates.Ordering.appendStableSortNote object ArrayOps : TemplateGroupBase() { @@ -884,6 +886,7 @@ object ArrayOps : TemplateGroupBase() { } builder { typeParam("T : Comparable") doc { "Sorts the array in-place according to the natural order of its elements." } + appendStableSortNote() specialFor(ArraysOfPrimitives) { doc { "Sorts the array in-place." } } @@ -939,6 +942,7 @@ object ArrayOps : TemplateGroupBase() { include(ArraysOfObjects) } builder { doc { "Sorts the array in-place according to the order specified by the given [comparator]." } + appendStableSortNote() returns("Unit") on(Platform.JVM) { body { @@ -968,6 +972,7 @@ object ArrayOps : TemplateGroupBase() { body { "asDynamic().sort(comparison)" } } specialFor(ArraysOfObjects) { + appendStableSortNote() body { """if (size > 1) sortArrayWith(this, comparison)""" } } } @@ -981,6 +986,8 @@ object ArrayOps : TemplateGroupBase() { """ Sorts the array in-place according to the natural order of its elements. + $stableSortNote + @throws ClassCastException if any element of the array is not [Comparable]. """ } @@ -996,6 +1003,9 @@ object ArrayOps : TemplateGroupBase() { exclude(PrimitiveType.Boolean) } builder { doc { "Sorts a range in the array in-place." } + specialFor(ArraysOfObjects) { + appendStableSortNote() + } returns("Unit") body { "java.util.Arrays.sort(this, fromIndex, toIndex)" @@ -1007,6 +1017,7 @@ object ArrayOps : TemplateGroupBase() { include(ArraysOfObjects) } builder { doc { "Sorts a range in the array in-place with the given [comparator]." } + appendStableSortNote() returns("Unit") body { "java.util.Arrays.sort(this, fromIndex, toIndex, comparator)" diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt index e441ecf4a04..ee1246e0286 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt @@ -96,6 +96,15 @@ object Ordering : TemplateGroupBase() { } } + val stableSortNote = + "The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting." + + fun MemberBuilder.appendStableSortNote() { + doc { + doc.orEmpty().trimIndent() + "\n\n" + stableSortNote + } + } + val f_sorted = fn("sorted()") { includeDefault() exclude(PrimitiveType.Boolean) @@ -106,6 +115,9 @@ object Ordering : TemplateGroupBase() { Returns a list of all elements sorted according to their natural sort order. """ } + if (f != ArraysOfPrimitives) { + appendStableSortNote() + } returns("List") typeParam("T : Comparable") body { @@ -134,6 +146,7 @@ object Ordering : TemplateGroupBase() { doc { "Returns a sequence that yields elements of this sequence sorted according to their natural sort order." } + appendStableSortNote() sequenceClassification(intermediate, stateful) } body(Sequences) { @@ -156,6 +169,9 @@ object Ordering : TemplateGroupBase() { doc { "Returns an array with all elements of this array sorted according to their natural sort order." } + specialFor(InvariantArraysOfObjects) { + appendStableSortNote() + } typeParam("T : Comparable") returns("SELF") body { @@ -171,6 +187,9 @@ object Ordering : TemplateGroupBase() { exclude(PrimitiveType.Boolean) } builder { doc { """Sorts elements in the ${f.collection} in-place descending according to their natural sort order.""" } + if (f != ArraysOfPrimitives) { + appendStableSortNote() + } returns("Unit") typeParam("T : Comparable") specialFor(Lists) { @@ -198,6 +217,9 @@ object Ordering : TemplateGroupBase() { Returns a list of all elements sorted descending according to their natural sort order. """ } + if (f != ArraysOfPrimitives) { + appendStableSortNote() + } returns("List") typeParam("T : Comparable") body { @@ -216,6 +238,7 @@ object Ordering : TemplateGroupBase() { doc { "Returns a sequence that yields elements of this sequence sorted descending according to their natural sort order." } + appendStableSortNote() sequenceClassification(intermediate, stateful) } } @@ -227,6 +250,9 @@ object Ordering : TemplateGroupBase() { doc { "Returns an array with all elements of this array sorted descending according to their natural sort order." } + specialFor(InvariantArraysOfObjects) { + appendStableSortNote() + } typeParam("T : Comparable") returns("SELF") body(InvariantArraysOfObjects) { @@ -252,6 +278,9 @@ object Ordering : TemplateGroupBase() { Returns a list of all elements sorted according to the specified [comparator]. """ } + if (f != ArraysOfPrimitives) { + appendStableSortNote() + } body { """ if (this is Collection) { @@ -278,6 +307,7 @@ object Ordering : TemplateGroupBase() { doc { "Returns a sequence that yields elements of this sequence sorted according to the specified [comparator]." } + appendStableSortNote() sequenceClassification(intermediate, stateful) } body(Sequences) { @@ -299,6 +329,7 @@ object Ordering : TemplateGroupBase() { doc { "Returns an array with all elements of this array sorted according the specified [comparator]." } + appendStableSortNote() returns("SELF") body { """ @@ -313,6 +344,7 @@ object Ordering : TemplateGroupBase() { } builder { inline() doc { """Sorts elements in the ${f.collection} in-place according to natural sort order of the value returned by specified [selector] function.""" } + appendStableSortNote() returns("Unit") typeParam("R : Comparable") specialFor(Lists) { receiver("MutableList") } @@ -332,12 +364,16 @@ object Ordering : TemplateGroupBase() { Returns a list of all elements sorted according to natural sort order of the value returned by specified [selector] function. """ } + if (f != ArraysOfPrimitives) { + appendStableSortNote() + } specialFor(Sequences) { returns("SELF") doc { "Returns a sequence that yields elements of this sequence sorted according to natural sort order of the value returned by specified [selector] function." } + appendStableSortNote() sequenceClassification(intermediate, stateful) } body { @@ -350,6 +386,7 @@ object Ordering : TemplateGroupBase() { } builder { inline() doc { """Sorts elements in the ${f.collection} in-place descending according to natural sort order of the value returned by specified [selector] function.""" } + appendStableSortNote() returns("Unit") typeParam("R : Comparable") specialFor(Lists) { receiver("MutableList") } @@ -370,12 +407,16 @@ object Ordering : TemplateGroupBase() { Returns a list of all elements sorted descending according to natural sort order of the value returned by specified [selector] function. """ } + if (f != ArraysOfPrimitives) { + appendStableSortNote() + } specialFor(Sequences) { returns("SELF") doc { "Returns a sequence that yields elements of this sequence sorted descending according to natural sort order of the value returned by specified [selector] function." } + appendStableSortNote() sequenceClassification(intermediate, stateful) } diff --git a/plugins/uast-kotlin/build.gradle.kts.191 b/plugins/uast-kotlin/build.gradle.kts.191 deleted file mode 100644 index 6bf6f04b122..00000000000 --- a/plugins/uast-kotlin/build.gradle.kts.191 +++ /dev/null @@ -1,80 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - kotlin("jvm") - id("jps-compatible") -} - -dependencies { - compile(project(":kotlin-stdlib")) - compile(project(":core:util.runtime")) - compile(project(":compiler:backend")) - compile(project(":compiler:frontend")) - compile(project(":compiler:frontend.java")) - compile(project(":compiler:light-classes")) - - Platform[181].orHigher { - // BEWARE: Uast should not depend on IDEA. - compileOnly(intellijCoreDep()) { includeJars("intellij-core") } - compileOnly(intellijDep()) { includeJars("java-api", "java-impl", "asm-all", rootProject = rootProject) } - } - - Platform[173].orLower { - compile(project(":idea:idea-core")) - compileOnly(intellijDep()) { includeJars("openapi", "idea", "util", "extensions", "asm-all", rootProject = rootProject) } - } - - testCompile(project(":kotlin-test:kotlin-test-jvm")) - testCompile(projectTests(":compiler:tests-common")) - testCompile(commonDep("junit:junit")) - testCompile(project(":compiler:util")) - testCompile(project(":compiler:cli")) - testCompile(projectTests(":idea:idea-test-framework")) - - Platform[181].orHigher { - testCompileOnly(intellijDep()) { includeJars("java-api", "java-impl") } - } - - Platform[173].orLower { - testCompileOnly(intellijDep()) { includeJars("idea_rt") } - } - - testCompile(project(":idea:idea-native")) { isTransitive = false } - testCompile(project(":idea:idea-gradle-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-android")) - testRuntime(project(":idea:idea-gradle")) - testRuntime(project(":plugins:kapt3-idea")) { isTransitive = false } - testRuntime(project(":sam-with-receiver-ide-plugin")) - testRuntime(project(":allopen-ide-plugin")) - testRuntime(project(":noarg-ide-plugin")) - testRuntime(project(":kotlin-scripting-idea")) - testRuntime(project(":plugins:android-extensions-ide")) - testRuntime(project(":plugins:kapt3-idea")) - testRuntime(project(":kotlinx-serialization-ide-plugin")) - testRuntime(intellijDep()) - testRuntime(intellijPluginDep("junit")) - testRuntime(intellijPluginDep("gradle")) - testRuntime(intellijPluginDep("Groovy")) - testRuntime(intellijPluginDep("properties")) -} - -sourceSets { - "main" { projectDefault() } - "test" { projectDefault() } -} - -testsJar {} - -projectTest { - workingDir = rootDir -} - -val compileKotlin: KotlinCompile by tasks -compileKotlin.kotlinOptions { - freeCompilerArgs = listOf("-Xjvm-default=compatibility") -} - diff --git a/settings.gradle b/settings.gradle index 0ce7ebec63a..729707c6b40 100644 --- a/settings.gradle +++ b/settings.gradle @@ -73,8 +73,6 @@ include ":kotlin-build-common", ":core:metadata.jvm", ":core:builtins", ":core:util.runtime", - ":custom-dependencies:protobuf-relocated", - ":custom-dependencies:protobuf-lite", ":custom-dependencies:android-sdk", ":idea:fir-view", ":idea:idea-jvm", @@ -349,3 +347,6 @@ project(':kotlinx-serialization-ide-plugin').projectDir = file("$rootDir/plugins project(':kotlin-serialization').projectDir = file("$rootDir/libraries/tools/kotlin-serialization") project(':kotlin-serialization-unshaded').projectDir = file("$rootDir/libraries/tools/kotlin-serialization-unshaded") project(':kotlin-idl2k').projectDir = file("$rootDir/libraries/tools/idl2k") + +// Uncomment to use locally built protobuf-relocated +// includeBuild("custom-dependencies/protobuf")