Multiple minor fixes.

This commit is contained in:
Dmitry Petrov
2016-09-02 18:09:48 +03:00
committed by Dmitry Petrov
parent da93f57afb
commit ea83407dce
11 changed files with 65 additions and 41 deletions
@@ -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) {
@@ -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() =
@@ -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)
}
}
@@ -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<PropertyDescriptor>) {
buildMember(function) {
@@ -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
@@ -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
@@ -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<PropertyDescriptor, PropertyGetterDescriptor> {
property ->
when {
class SyntheticDescriptorsFactory {
private val propertyGetters = HashMap<PropertyDescriptor, PropertyGetterDescriptor>()
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<PropertyDescriptor, PropertySetterDescriptor> {
property ->
when {
private val propertySetters = HashMap<PropertyDescriptor, PropertySetterDescriptor>()
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) }
}
@@ -21,6 +21,6 @@ import java.io.File
abstract class AbstractPsi2IrAcceptanceTestCase : AbstractIrGeneratorTestCase() {
override fun doTest(wholeFile: File, testFiles: List<TestFile>) {
// Just make sure that nothing interesting happens - e.g., no exceptions thrown
generateIrFilesAsSingleModule(testFiles)
generateIrFilesAsSingleModule(testFiles, true)
}
}
@@ -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 <reified T : IrElement> IrElement.assertCast(): T =
if (this is T) this else throw AssertionError("Expected ${T::class.simpleName}: $this")
@@ -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
@@ -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)
}
}
}