From ea83407dcef721140daee25cdf7da6713452e8f9 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 2 Sep 2016 18:09:48 +0300 Subject: [PATCH] Multiple minor fixes. --- .../jetbrains/kotlin/psi2ir/KotlinUtils.kt | 12 ++------ .../kotlin/psi2ir/generators/BodyGenerator.kt | 9 ++++-- .../kotlin/psi2ir/generators/CallGenerator.kt | 4 +-- .../generators/DataClassMembersGenerator.kt | 16 ++++++---- .../generators/ErrorExpressionGenerator.kt | 5 ++-- .../psi2ir/generators/GeneratorContext.kt | 5 +--- .../generators/SyntheticDescriptorsFactory.kt | 30 ++++++++++++------- .../ir/AbstractPsi2IrAcceptanceTestCase.kt | 2 +- .../src/org/jetbrains/kotlin/ir/IrElement.kt | 3 +- .../IrSyntheticPropertyAccessorDescriptor.kt | 3 +- .../ir/expressions/IrPropertyAccessorCall.kt | 17 +++++++++-- 11 files changed, 65 insertions(+), 41 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt index 3e4040a3d36..baa6258274e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/KotlinUtils.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.psi2ir -import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -25,7 +24,6 @@ import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.psi.KtSecondaryConstructor -import org.jetbrains.kotlin.psi2ir.generators.getResolvedCall import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch @@ -35,6 +33,7 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.upperIfFlexible +import java.lang.Exception fun KotlinType.containsNull() = KotlinTypeChecker.DEFAULT.isSubtypeOf(builtIns.nullableNothingType, this.upperIfFlexible()) @@ -42,19 +41,12 @@ fun KotlinType.containsNull() = fun KtElement.deparenthesize(): KtElement = if (this is KtExpression) KtPsiUtil.safeDeparenthesize(this) else this -val CallableDescriptor.explicitReceiverType: KotlinType? - get() { - extensionReceiverParameter?.let { return it.type } - dispatchReceiverParameter?.let { return it.type } - return null - } - fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean { var lastValueParameterIndex = -1 for (valueArgument in call.valueArguments) { val argumentMapping = getArgumentMapping(valueArgument) if (argumentMapping !is ArgumentMatch || argumentMapping.isError()) { - throw AssertionError("Value argument in function call is mapped with error") + throw Exception("Value argument in function call is mapped with error") } val argumentIndex = argumentMapping.valueParameter.index if (argumentIndex < lastValueParameterIndex) { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt index 788afd44691..06bfc60293f 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt @@ -86,8 +86,13 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: } private fun StatementGenerator.generateReturnExpression(ktExpression: KtExpression, irBlockBody: IrBlockBodyImpl) { - val irExpression = generateExpression(ktExpression) - irBlockBody.addStatement(irExpression.wrapWithReturn()) + val irReturnExpression = generateStatement(ktExpression) + if (irReturnExpression is IrExpression) { + irBlockBody.addStatement(irReturnExpression.wrapWithReturn()) + } + else { + irBlockBody.addStatement(irReturnExpression) + } } private fun IrExpression.wrapWithReturn() = diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index d0a8b6a2a78..5df2b40d48b 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -56,9 +56,9 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE if (descriptor !is ConstructorDescriptor) throw AssertionError("Constructor expected: $descriptor") return call.callReceiver.call { dispatchReceiver, extensionReceiver -> - if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver") - if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver") val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, descriptor) + irCall.dispatchReceiver = dispatchReceiver?.load() + irCall.extensionReceiver = extensionReceiver?.load() addParametersToCall(startOffset, endOffset, call, irCall, descriptor.returnType) } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt index 269128444da..134a365a322 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt @@ -19,13 +19,11 @@ package org.jetbrains.kotlin.psi2ir.generators import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrClassImpl import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.mapValueParameters -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -91,9 +89,17 @@ class DataClassMembersGenerator( private val IMUL = INT.findFirstFunction("times") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) } private val IADD = INT.findFirstFunction("plus") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) } - private fun getHashCodeFunction(type: KotlinType): CallableDescriptor = - (type.constructor.declarationDescriptor as? ClassDescriptor)?.findFirstFunction("hashCode") { it.valueParameters.isEmpty() } ?: - throw AssertionError("Unexpected type: $type") + private fun getHashCodeFunction(type: KotlinType): CallableDescriptor { + val typeConstructorDescriptor = type.constructor.declarationDescriptor + when (typeConstructorDescriptor) { + is ClassDescriptor -> + return typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() } + is TypeParameterDescriptor -> + return getHashCodeFunction(context.builtIns.anyType) // TODO + else -> + throw AssertionError("Unexpected type: $type") + } + } override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List) { buildMember(function) { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ErrorExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ErrorExpressionGenerator.kt index bb9740c1316..6354e1cb949 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ErrorExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ErrorExpressionGenerator.kt @@ -60,8 +60,9 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme val type = getErrorExpressionType(ktName) val irErrorCall = IrErrorCallExpressionImpl(ktName.startOffset, ktName.endOffset, type, "") // TODO problem description? - irErrorCall.explicitReceiver = (ktName.parent as? KtDotQualifiedExpression)?.let { - statementGenerator.generateExpression(it.receiverExpression) + irErrorCall.explicitReceiver = (ktName.parent as? KtDotQualifiedExpression)?.let { ktParent -> + if (ktParent.receiverExpression == ktName) null + else statementGenerator.generateExpression(ktParent.receiverExpression) } return irErrorCall diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt index 1f7d89179be..8345521770d 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt @@ -22,16 +22,13 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.psi2ir.PsiSourceManager import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.storage.LockBasedStorageManager -import org.jetbrains.kotlin.storage.StorageManager class GeneratorContext( val moduleDescriptor: ModuleDescriptor, val bindingContext: BindingContext ) { - val storageManager: StorageManager = LockBasedStorageManager.NO_LOCKS val sourceManager = PsiSourceManager() - val syntheticDescriptorsFactory by lazy { SyntheticDescriptorsFactory(storageManager) } + val syntheticDescriptorsFactory = SyntheticDescriptorsFactory() val reflectionTypes = ReflectionTypes(moduleDescriptor) val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/SyntheticDescriptorsFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/SyntheticDescriptorsFactory.kt index 6bff85e91ff..9bf6bd68940 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/SyntheticDescriptorsFactory.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/SyntheticDescriptorsFactory.kt @@ -20,29 +20,36 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor +import org.jetbrains.kotlin.ir.descriptors.IrSyntheticPropertyAccessorDescriptor.Kind.MEMBER_PROPERTY import org.jetbrains.kotlin.ir.descriptors.IrSyntheticPropertyAccessorDescriptor.Kind.STATIC_PROPERTY import org.jetbrains.kotlin.ir.descriptors.IrSyntheticPropertyGetterDescriptorImpl import org.jetbrains.kotlin.ir.descriptors.IrSyntheticPropertySetterDescriptorImpl -import org.jetbrains.kotlin.storage.StorageManager import java.lang.AssertionError +import java.util.* -class SyntheticDescriptorsFactory(storageManager: StorageManager) { - private val propertyGetters = storageManager.createMemoizedFunction { - property -> - when { +class SyntheticDescriptorsFactory { + private val propertyGetters = HashMap() + + private fun generateGetter(property: PropertyDescriptor): PropertyGetterDescriptor { + return when { isStaticPropertyInClass(property) -> IrSyntheticPropertyGetterDescriptorImpl(property, STATIC_PROPERTY) + isPropertyInClass(property) -> + IrSyntheticPropertyGetterDescriptorImpl(property, MEMBER_PROPERTY) else -> throw AssertionError("Don't know how to create synthetic getter for $property") } } - private val propertySetters = storageManager.createMemoizedFunction { - property -> - when { + private val propertySetters = HashMap() + + private fun generateSetter(property: PropertyDescriptor): PropertySetterDescriptor { + return when { isStaticPropertyInClass(property) -> IrSyntheticPropertySetterDescriptorImpl(property, STATIC_PROPERTY) + isPropertyInClass(property) -> + IrSyntheticPropertySetterDescriptorImpl(property, MEMBER_PROPERTY) else -> throw AssertionError("Don't know how to create synthetic setter for $property") } @@ -53,9 +60,12 @@ class SyntheticDescriptorsFactory(storageManager: StorageManager) { propertyDescriptor.dispatchReceiverParameter == null && propertyDescriptor.extensionReceiverParameter == null + private fun isPropertyInClass(propertyDescriptor: PropertyDescriptor): Boolean = + propertyDescriptor.containingDeclaration is ClassDescriptor + fun getOrCreatePropertyGetter(propertyDescriptor: PropertyDescriptor): PropertyGetterDescriptor = - propertyGetters(propertyDescriptor) + propertyGetters.getOrPut(propertyDescriptor) { generateGetter(propertyDescriptor) } fun getOrCreatePropertySetter(propertyDescriptor: PropertyDescriptor): PropertySetterDescriptor = - propertySetters(propertyDescriptor) + propertySetters.getOrPut(propertyDescriptor) { generateSetter(propertyDescriptor) } } diff --git a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractPsi2IrAcceptanceTestCase.kt b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractPsi2IrAcceptanceTestCase.kt index 7365a0814c7..6112085d970 100644 --- a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractPsi2IrAcceptanceTestCase.kt +++ b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractPsi2IrAcceptanceTestCase.kt @@ -21,6 +21,6 @@ import java.io.File abstract class AbstractPsi2IrAcceptanceTestCase : AbstractIrGeneratorTestCase() { override fun doTest(wholeFile: File, testFiles: List) { // Just make sure that nothing interesting happens - e.g., no exceptions thrown - generateIrFilesAsSingleModule(testFiles) + generateIrFilesAsSingleModule(testFiles, true) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt index 5d1e7363719..c1f04856961 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.ir +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.IrElementVisitor interface IrElement { @@ -73,7 +74,7 @@ fun IrElement.assertDetached() { } fun IrElement.throwNoSuchSlot(slot: Int): Nothing = - throw AssertionError("$this: no such slot $slot") + throw AssertionError("${this.render()}: no such slot $slot") inline fun IrElement.assertCast(): T = if (this is T) this else throw AssertionError("Expected ${T::class.simpleName}: $this") \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrSyntheticPropertyAccessorDescriptor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrSyntheticPropertyAccessorDescriptor.kt index 61537a6913d..be8ca6d1ed5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrSyntheticPropertyAccessorDescriptor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrSyntheticPropertyAccessorDescriptor.kt @@ -27,7 +27,8 @@ import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl interface IrSyntheticPropertyAccessorDescriptor : PropertyAccessorDescriptor { enum class Kind { - STATIC_PROPERTY + STATIC_PROPERTY, + MEMBER_PROPERTY } val kind: Kind diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt index 146c454d6fe..d0dd51cbc30 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt @@ -18,9 +18,7 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.ir.SETTER_ARGUMENT_INDEX -import org.jetbrains.kotlin.ir.assertDetached -import org.jetbrains.kotlin.ir.detach +import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitor abstract class IrPropertyAccessorCallBase( @@ -106,4 +104,17 @@ class IrSetterCallImpl( argumentImpl?.detach() argumentImpl = null } + + override fun getChild(slot: Int): IrElement? = + when (slot) { + SETTER_ARGUMENT_INDEX -> argumentImpl + else -> super.getChild(slot) + } + + override fun replaceChild(slot: Int, newChild: IrElement) { + when (slot) { + SETTER_ARGUMENT_INDEX -> putArgument(slot, newChild.assertCast()) + else -> super.replaceChild(slot, newChild) + } + } }