Multiple minor fixes.
This commit is contained in:
committed by
Dmitry Petrov
parent
da93f57afb
commit
ea83407dce
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+11
-5
@@ -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) {
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
+1
-4
@@ -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
-10
@@ -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) }
|
||||
}
|
||||
|
||||
+1
-1
@@ -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")
|
||||
+2
-1
@@ -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
|
||||
|
||||
+14
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user