JVM_IR: Implement some BE diagnostics

TODO proper diagnostics tests with BE diagnostics
This commit is contained in:
Dmitry Petrov
2020-01-31 14:29:24 +03:00
parent c9df17f2f1
commit 8ef79f932c
14 changed files with 138 additions and 43 deletions
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
@@ -643,7 +644,7 @@ class ExpressionCodegen(
val isNonLocalReturn =
methodSignatureMapper.mapFunctionName(owner) != methodSignatureMapper.mapFunctionName(irFunction)
if (isNonLocalReturn && state.isInlineDisabled) {
//TODO: state.diagnostics.report(Errors.NON_LOCAL_RETURN_IN_DISABLED_INLINE.on(expression))
context.psiErrorBuilder.at(expression, owner).report(Errors.NON_LOCAL_RETURN_IN_DISABLED_INLINE)
genThrow(
mv, "java/lang/UnsupportedOperationException",
"Non-local returns are not allowed with inlining disabled"
@@ -5,15 +5,14 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
import org.jetbrains.kotlin.backend.jvm.ir.isLambda
import org.jetbrains.kotlin.codegen.IrExpressionLambda
import org.jetbrains.kotlin.codegen.JvmKotlinType
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.ValueKind
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
@@ -28,6 +27,7 @@ import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Type
@@ -43,15 +43,18 @@ class IrInlineCodegen(
typeParameterMappings: TypeParameterMappings<IrType>,
sourceCompiler: SourceCompilerForInline,
reifiedTypeInliner: ReifiedTypeInliner<IrType>
) : InlineCodegen<ExpressionCodegen>(
codegen, state, function.descriptor, methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
), IrCallGenerator {
) :
InlineCodegen<ExpressionCodegen>(
codegen, state, function.descriptor, methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
),
IrCallGenerator {
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
if (info.generateAssertField && (sourceCompiler as IrSourceCompilerForInline).isPrimaryCopy) {
codegen.classCodegen.generateAssertFieldIfNeeded()?.let {
codegen.classCodegen.generateAssertFieldIfNeeded()?.run {
// Generating <clinit> right now, so no longer can insert the initializer into it.
// Instead, ask ExpressionCodegen to generate the code for it directly.
it.accept(codegen, BlockInfo()).discard()
accept(codegen, BlockInfo()).discard()
}
}
}
@@ -149,13 +152,38 @@ class IrInlineCodegen(
invocationParamBuilder.markValueParametersStart()
}
private inner class IrInlineCall(
private val irFunctionAccessExpression: IrFunctionAccessExpression
) : InlineCall {
override val calleeDescriptor: CallableDescriptor =
irFunctionAccessExpression.symbol.descriptor.original
override val callElement: PsiElement?
get() =
codegen.context.psiSourceManager.findPsiElement(irFunctionAccessExpression, function)
?: codegen.context.psiSourceManager.findPsiElement(function)
override val id: Any
get() = irFunctionAccessExpression
override fun toString(): String = irFunctionAccessExpression.render()
}
override fun genCall(
callableMethod: IrCallableMethod,
codegen: ExpressionCodegen,
expression: IrFunctionAccessExpression
) {
// TODO port inlining cycle detection to IrFunctionAccessExpression & pass it
state.globalInlineContext.enterIntoInlining(null)
val inlineCall = IrInlineCall(expression)
if (!state.globalInlineContext.enterIntoInlining(inlineCall)) {
AsmUtil.genThrow(
codegen.v,
"java/lang/UnsupportedOperationException",
"Call is a part of inline call cycle: ${expression.render()}"
)
return
}
try {
performInline(
expression.symbol.owner.typeParameters.map { it.symbol },
@@ -164,7 +192,7 @@ class IrInlineCodegen(
codegen.typeMapper.typeSystem
)
} finally {
state.globalInlineContext.exitFromInliningOf(null)
state.globalInlineContext.exitFromInliningOf(inlineCall)
}
}
@@ -119,14 +119,12 @@ class PsiSourceManager : SourceManager {
fileEntriesByIrFile[irFile]
fun <E : PsiElement> findPsiElement(irElement: IrElement, irFile: IrFile, psiElementClass: KClass<E>): E? {
val psiFileEntry = fileEntriesByIrFile[irFile]
?: throw AssertionError("No PSI file for irFile $irFile")
val psiFileEntry = fileEntriesByIrFile[irFile] ?: return null
return psiFileEntry.findPsiElement(irElement, psiElementClass)
}
fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
val psiFileEntry = fileEntriesByIrFile[irFile]
?: throw AssertionError("No PSI file for irFile $irFile")
val psiFileEntry = fileEntriesByIrFile[irFile] ?: return null
return psiFileEntry.findPsiElement(irElement)
}