[IR] More user-friendly compilation exceptions from lowerings and JS codegen

Merge-request: KT-MR-5004
This commit is contained in:
Ilya Goncharov
2021-11-25 13:21:34 +00:00
committed by Space
parent 844876a974
commit 98bedf7eed
31 changed files with 439 additions and 150 deletions
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.cli.js
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.backend.common.CompilationException
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.backend.wasm.compileWasm import org.jetbrains.kotlin.backend.wasm.compileWasm
import org.jetbrains.kotlin.backend.wasm.wasmPhases import org.jetbrains.kotlin.backend.wasm.wasmPhases
import org.jetbrains.kotlin.cli.common.* import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR import org.jetbrains.kotlin.cli.common.ExitCode.*
import org.jetbrains.kotlin.cli.common.ExitCode.OK
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.RUNTIME_DIAGNOSTIC_EXCEPTION import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.RUNTIME_DIAGNOSTIC_EXCEPTION
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.RUNTIME_D
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil import org.jetbrains.kotlin.cli.common.messages.MessageUtil
@@ -35,15 +36,11 @@ import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.backend.js.ic.actualizeCacheForModule
import org.jetbrains.kotlin.ir.backend.js.ic.buildCache
import org.jetbrains.kotlin.ir.backend.js.ic.checkCaches
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
import org.jetbrains.kotlin.ir.backend.js.ic.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
import org.jetbrains.kotlin.ir.backend.js.ic.*
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformerTmp import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformerTmp
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
import org.jetbrains.kotlin.js.config.* import org.jetbrains.kotlin.js.config.*
@@ -59,7 +56,6 @@ import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
import org.jetbrains.kotlin.utils.join import org.jetbrains.kotlin.utils.join
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.lang.IllegalArgumentException
enum class ProduceKind { enum class ProduceKind {
DEFAULT, // Determine what to produce based on js-v1 options DEFAULT, // Determine what to produce based on js-v1 options
@@ -236,7 +232,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
if (updated) { if (updated) {
messageCollector.report(INFO, "IC $invalidationType cache building duration: ${System.currentTimeMillis() - start}ms") messageCollector.report(INFO, "IC $invalidationType cache building duration: ${System.currentTimeMillis() - start}ms")
} else { } else {
messageCollector.report(INFO, "IC $invalidationType cache up-to-date check duration: ${System.currentTimeMillis() - start}ms") messageCollector.report(
INFO,
"IC $invalidationType cache up-to-date check duration: ${System.currentTimeMillis() - start}ms"
)
} }
return OK return OK
} }
@@ -384,7 +383,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
arguments.irPerFile -> JsGenerationGranularity.PER_FILE arguments.irPerFile -> JsGenerationGranularity.PER_FILE
else -> JsGenerationGranularity.WHOLE_PROGRAM else -> JsGenerationGranularity.WHOLE_PROGRAM
} }
try {
val ir = compile( val ir = compile(
module, module,
phaseConfig, phaseConfig,
@@ -424,7 +423,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
fullJs = true, fullJs = true,
dceJs = arguments.irDce, dceJs = arguments.irDce,
multiModule = arguments.irPerModule, multiModule = arguments.irPerModule,
relativeRequirePath = false relativeRequirePath = false,
) )
transformer.generateModule(ir.allModules) transformer.generateModule(ir.allModules)
@@ -433,7 +432,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms") messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms")
val outputs = if (arguments.irDce && !arguments.irDceDriven) val outputs = if (arguments.irDce && !arguments.irDceDriven)
compiledModule.outputsAfterDce!! compiledModule.outputsAfterDce!!
else else
@@ -447,6 +445,19 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
val dtsFile = outputFile.withReplacedExtensionOrNull(outputFile.extension, "d.ts")!! val dtsFile = outputFile.withReplacedExtensionOrNull(outputFile.extension, "d.ts")!!
dtsFile.writeText(compiledModule.tsDefinitions ?: error("No ts definitions")) dtsFile.writeText(compiledModule.tsDefinitions ?: error("No ts definitions"))
} }
} catch (e: CompilationException) {
messageCollector.report(
ERROR,
e.stackTraceToString(),
CompilerMessageLocation.create(
path = e.path,
line = e.line,
column = e.column,
lineContent = e.content
)
)
return INTERNAL_ERROR
}
} }
return OK return OK
@@ -0,0 +1,98 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.path
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
import org.jetbrains.kotlin.ir.util.fileOrNull
class CompilationException(
message: String,
// file is not known in any moment, need to set it later in catch to save stacktrace
var file: IrFile?,
val ir: Any?, /* IrElement | IrType */
cause: Throwable? = null
) : RuntimeException(message, cause) {
override val message: String
get() = buildString {
appendLine("Back-end: Please report this problem https://kotl.in/issue")
path?.let { appendLine("$it:$line:$column") }
content?.let { appendLine("Problem with `$it`") }
append("Details: " + super.message)
}
val line: Int
get() {
val irStartOffset = irStartOffset
?: return UNDEFINED_OFFSET
val lineNumber = file?.fileEntry?.getLineNumber(irStartOffset)
?: return UNDEFINED_OFFSET
return lineNumber + 1
}
val column: Int
get() {
val irStartOffset = irStartOffset
?: return UNDEFINED_OFFSET
val columnNumber = file?.fileEntry?.getColumnNumber(irStartOffset)
?: return UNDEFINED_OFFSET
return columnNumber + 1
}
private val irStartOffset: Int?
get() = (ir as? IrElement)?.startOffset
val path: String?
get() = file?.path
val content: String?
get() = when (ir) {
is IrElement -> ir.dumpKotlinLike()
is IrType -> ir.dumpKotlinLike()
else -> null
}
}
fun compilationException(message: String, element: IrElement): Nothing {
throw CompilationException(message, null, element)
}
fun compilationException(message: String, type: IrType?): Nothing {
throw CompilationException(message, null, type)
}
fun compilationException(message: String, declaration: IrDeclaration): Nothing {
val file = try {
declaration.fileOrNull
} catch (e: Throwable) {
null
}
throw CompilationException(message, file, declaration)
}
fun Throwable.wrapWithCompilationException(
message: String,
file: IrFile,
element: IrElement?
): CompilationException {
return CompilationException(
"$message: ${this::class.qualifiedName}: ${this.message}",
file,
element,
cause = this
).apply {
stackTrace = this@wrapWithCompilationException.stackTrace
}
}
@@ -67,7 +67,22 @@ interface BodyAndScriptBodyLoweringPass : BodyLoweringPass {
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile) override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
} }
fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) } fun FileLoweringPass.lower(
moduleFragment: IrModuleFragment
) = moduleFragment.files.forEach {
try {
lower(it)
} catch (e: CompilationException) {
e.file = it
throw e
} catch (e: Throwable) {
throw e.wrapWithCompilationException(
"Internal error in file lowering",
it,
null
)
}
}
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) { fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
irFile.acceptVoid(ClassLoweringVisitor(this)) irFile.acceptVoid(ClassLoweringVisitor(this))
@@ -128,7 +143,18 @@ fun BodyLoweringPass.runOnFilePostfix(
) { ) {
val visitor = BodyLoweringVisitor(this, withLocalDeclarations, allowDeclarationModification) val visitor = BodyLoweringVisitor(this, withLocalDeclarations, allowDeclarationModification)
for (declaration in ArrayList(irFile.declarations)) { for (declaration in ArrayList(irFile.declarations)) {
try {
declaration.accept(visitor, null) declaration.accept(visitor, null)
} catch (e: CompilationException) {
e.file = irFile
throw e
} catch (e: Throwable) {
throw e.wrapWithCompilationException(
"Internal error in body lowering",
irFile,
declaration
)
}
} }
} }
@@ -214,8 +240,19 @@ interface DeclarationTransformer : FileLoweringPass {
override fun lower(irFile: IrFile) { override fun lower(irFile: IrFile) {
val visitor = Visitor(this) val visitor = Visitor(this)
irFile.declarations.transformFlat { declaration -> irFile.declarations.transformFlat { declaration ->
try {
declaration.acceptVoid(visitor) declaration.acceptVoid(visitor)
transformFlatRestricted(declaration) transformFlatRestricted(declaration)
} catch (e: CompilationException) {
e.file = irFile
throw e
} catch (e: Throwable) {
throw e.wrapWithCompilationException(
"Internal error in declaration transformer",
irFile,
declaration
)
}
} }
} }
@@ -62,6 +62,7 @@ class JsIrBackendContext(
val granularity: JsGenerationGranularity = JsGenerationGranularity.WHOLE_PROGRAM, val granularity: JsGenerationGranularity = JsGenerationGranularity.WHOLE_PROGRAM,
val icCompatibleIr2Js: Boolean = false, val icCompatibleIr2Js: Boolean = false,
) : JsCommonBackendContext { ) : JsCommonBackendContext {
val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf() val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf()
val fileToInitializerPureness: MutableMap<IrFile, Boolean> = mutableMapOf() val fileToInitializerPureness: MutableMap<IrFile, Boolean> = mutableMapOf()
val fieldToInitializer: MutableMap<IrField, IrExpression> = mutableMapOf() val fieldToInitializer: MutableMap<IrField, IrExpression> = mutableMapOf()
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.lower.AbstractValueUsageTransformer import org.jetbrains.kotlin.backend.common.lower.AbstractValueUsageTransformer
import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
@@ -33,7 +34,7 @@ abstract class AbstractValueUsageLowering(val context: JsCommonBackendContext) :
val replacement = container.transform(this, null) as IrDeclaration val replacement = container.transform(this, null) as IrDeclaration
if (container !== replacement) error("Declaration has changed: ${container}") if (container !== replacement) compilationException("Declaration has changed", container)
// TODO: Track & insert parents for temporary variables // TODO: Track & insert parents for temporary variables
irBody.patchDeclarationParents(container as? IrDeclarationParent ?: container.parent) irBody.patchDeclarationParents(container as? IrDeclarationParent ?: container.parent)
@@ -7,21 +7,21 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.isElseBranch import org.jetbrains.kotlin.backend.common.ir.isElseBranch
import org.jetbrains.kotlin.backend.common.ir.isPure
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.backend.common.ir.isPure
import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.transformStatement import org.jetbrains.kotlin.ir.transformStatement
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -620,11 +620,17 @@ class BlockDecomposerTransformer(
) )
expression.receiver = newArguments[0] expression.receiver = newArguments[0]
?: error("No new receiver in destructured composite for:\n${expression.dump()}") ?: compilationException(
"No new receiver in destructured composite",
expression
)
for (i in expression.arguments.indices) { for (i in expression.arguments.indices) {
expression.arguments[i] = newArguments[i + 1] expression.arguments[i] = newArguments[i + 1]
?: error("No argument #$i in destructured composite for:\n${expression.dump()}") ?: compilationException(
"No argument #$i in destructured composite",
expression
)
} }
newStatements.add(expression) newStatements.add(expression)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.ir.moveBodyTo import org.jetbrains.kotlin.backend.common.ir.moveBodyTo
@@ -120,7 +121,11 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod
private val referenceType = reference.type as IrSimpleType private val referenceType = reference.type as IrSimpleType
private val superFunctionInterface: IrClass = referenceType.classOrNull?.owner ?: error("Expected functional type") private val superFunctionInterface: IrClass = referenceType.classOrNull?.owner
?: compilationException(
"Expected functional type",
reference
)
private val isKReference = superFunctionInterface.name.identifier[0] == 'K' private val isKReference = superFunctionInterface.name.identifier[0] == 'K'
// If we implement KFunctionN we also need FunctionN // If we implement KFunctionN we also need FunctionN
@@ -324,7 +329,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod
JsStatementOrigins.CALLABLE_REFERENCE_INVOKE JsStatementOrigins.CALLABLE_REFERENCE_INVOKE
) )
else -> else ->
error("unknown function kind: ${callee.render()}") compilationException("unknown function kind", callee)
} }
} }
@@ -411,7 +416,11 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod
.filterIsInstance<IrProperty>() .filterIsInstance<IrProperty>()
.single { it.name == Name.identifier("name") } // In K/Wasm interfaces can have fake overridden properties from Any .single { it.name == Name.identifier("name") } // In K/Wasm interfaces can have fake overridden properties from Any
val supperGetter = superProperty.getter ?: error("Expected getter for KFunction.name property") val supperGetter = superProperty.getter
?: compilationException(
"Expected getter for KFunction.name property",
superProperty
)
val nameProperty = clazz.addProperty() { val nameProperty = clazz.addProperty() {
visibility = superProperty.visibility visibility = superProperty.visibility
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -158,7 +159,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
return createSimpleKType(type, visitedTypeParams) return createSimpleKType(type, visitedTypeParams)
if (type is IrDynamicType) if (type is IrDynamicType)
return createDynamicType() return createDynamicType()
error("Unexpected type $type") compilationException("Unexpected type", type)
} }
private fun createDynamicType(): IrExpression { private fun createDynamicType(): IrExpression {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
@@ -55,7 +56,7 @@ class ConstTransformer(private val context: JsIrBackendContext) : IrElementTrans
uLongClassSymbol -> lowerConst(uLongClassSymbol, { _, _, _, v -> createLong(v) }, IrConstKind.Long.valueOf(expression)) uLongClassSymbol -> lowerConst(uLongClassSymbol, { _, _, _, v -> createLong(v) }, IrConstKind.Long.valueOf(expression))
else -> error("Unknown unsigned type") else -> compilationException("Unknown unsigned type", expression)
} }
} }
return when { return when {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyToWithoutSuperTypes import org.jetbrains.kotlin.backend.common.ir.copyToWithoutSuperTypes
import org.jetbrains.kotlin.backend.common.lower.LoweredStatementOrigins import org.jetbrains.kotlin.backend.common.lower.LoweredStatementOrigins
@@ -61,7 +62,7 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
} }
override fun lower(irBody: IrBody, container: IrDeclaration) { override fun lower(irBody: IrBody, container: IrDeclaration) {
error("Unreachable") compilationException("Unreachable", irBody)
} }
private inner class CallableReferenceClassTransformer(private val ctorToFactoryMap: MutableMap<IrConstructorSymbol, IrSimpleFunctionSymbol>) : IrElementTransformerVoid() { private inner class CallableReferenceClassTransformer(private val ctorToFactoryMap: MutableMap<IrConstructorSymbol, IrSimpleFunctionSymbol>) : IrElementTransformerVoid() {
@@ -109,7 +110,11 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
invokeMapping: Map<IrValueParameterSymbol, IrValueParameterSymbol>, invokeMapping: Map<IrValueParameterSymbol, IrValueParameterSymbol>,
factoryMapping: Map<IrFieldSymbol, IrValueParameterSymbol> factoryMapping: Map<IrFieldSymbol, IrValueParameterSymbol>
): IrBlockBody { ): IrBlockBody {
val body = invokeFun.body ?: error("invoke() method has to have a body") val body = invokeFun.body
?: compilationException(
"invoke() method has to have a body",
invokeFun
)
fun IrExpression.getValue(d: IrValueSymbol): IrExpression = IrGetValueImpl(startOffset, endOffset, d) fun IrExpression.getValue(d: IrValueSymbol): IrExpression = IrGetValueImpl(startOffset, endOffset, d)
fun IrExpression.getCastedValue(d: IrValueSymbol, toType: IrType): IrExpression = fun IrExpression.getCastedValue(d: IrValueSymbol, toType: IrType): IrExpression =
@@ -180,7 +185,11 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
} }
private fun capturedFieldsToParametersMap(constructor: IrConstructor, factoryFunction: IrSimpleFunction): Map<IrFieldSymbol, IrValueParameterSymbol> { private fun capturedFieldsToParametersMap(constructor: IrConstructor, factoryFunction: IrSimpleFunction): Map<IrFieldSymbol, IrValueParameterSymbol> {
val statements = constructor.body?.let { it.cast<IrBlockBody>().statements } ?: error("Expecting Body for function ref constructor") val statements = constructor.body?.let { it.cast<IrBlockBody>().statements }
?: compilationException(
"Expecting Body for function ref constructor",
constructor
)
val fieldSetters = statements.filterIsInstance<IrSetField>() val fieldSetters = statements.filterIsInstance<IrSetField>()
.filter { it.origin == LoweredStatementOrigins.STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE } .filter { it.origin == LoweredStatementOrigins.STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE }
@@ -193,7 +202,11 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
} }
private fun extractReferenceReflectionName(getter: IrSimpleFunction): IrExpression { private fun extractReferenceReflectionName(getter: IrSimpleFunction): IrExpression {
val body = getter.body?.cast<IrBlockBody>() ?: error("Expected body for ${getter.render()}") val body = getter.body?.cast<IrBlockBody>()
?: compilationException(
"Expected body",
getter
)
val statements = body.statements val statements = body.statements
val returnStmt = statements[0] as IrReturn val returnStmt = statements[0] as IrReturn
@@ -6,23 +6,20 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isArray import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.util.isAnnotationClass import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.util.isPrimitiveArray import org.jetbrains.kotlin.ir.util.isPrimitiveArray
import org.jetbrains.kotlin.ir.util.render
// JS PIR (and IC) requires DeclarationTransformer instead of FileLoweringPass // JS PIR (and IC) requires DeclarationTransformer instead of FileLoweringPass
@@ -55,13 +52,16 @@ class JsAnnotationImplementationTransformer(val jsContext: JsIrBackendContext) :
when { when {
type.isPrimitiveArray() -> arraysContentEquals[type] type.isPrimitiveArray() -> arraysContentEquals[type]
else -> arraysContentEquals.entries.singleOrNull { (k, _) -> k.isArray() }?.value else -> arraysContentEquals.entries.singleOrNull { (k, _) -> k.isArray() }?.value
} ?: error("Can't find an Arrays.contentEquals method for array type ${type.render()}") } ?: compilationException("Can't find an Arrays.contentEquals method for array type", type)
override fun implementAnnotationPropertiesAndConstructor( override fun implementAnnotationPropertiesAndConstructor(
implClass: IrClass, implClass: IrClass,
annotationClass: IrClass, annotationClass: IrClass,
generatedConstructor: IrConstructor generatedConstructor: IrConstructor
) { ) {
throw IllegalStateException("Should not be called") compilationException(
"Should not be called",
implClass
)
} }
} }
@@ -5,11 +5,8 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
@@ -30,14 +27,12 @@ import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import java.lang.IllegalStateException
// Outlines `kotlin.js.js(code: String)` calls where JS code references Kotlin locals. // Outlines `kotlin.js.js(code: String)` calls where JS code references Kotlin locals.
// Makes locals usages explicit. // Makes locals usages explicit.
@@ -96,7 +91,11 @@ private class JsCodeOutlineTransformer(
val name = irValueDeclaration.name val name = irValueDeclaration.name
if (!name.isSpecial) { if (!name.isSpecial) {
val identifier = name.identifier val identifier = name.identifier
val currentScope = localScopes.lastOrNull() ?: error("Expecting a scope") val currentScope = localScopes.lastOrNull()
?: compilationException(
"Expecting a scope",
irValueDeclaration
)
currentScope[identifier] = irValueDeclaration currentScope[identifier] = irValueDeclaration
} }
} }
@@ -133,7 +132,11 @@ private class JsCodeOutlineTransformer(
if (expression.symbol != backendContext.intrinsics.jsCode) if (expression.symbol != backendContext.intrinsics.jsCode)
return null return null
val jsCodeArg = expression.getValueArgument(0) ?: error("Expected js code string") val jsCodeArg = expression.getValueArgument(0)
?: compilationException(
"Expected js code string",
expression
)
val jsStatements = translateJsCodeIntoStatementList(jsCodeArg, backendContext) ?: return null val jsStatements = translateJsCodeIntoStatementList(jsCodeArg, backendContext) ?: return null
// Collect used Kotlin local variables and parameters. // Collect used Kotlin local variables and parameters.
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.getOrPut import org.jetbrains.kotlin.backend.common.getOrPut
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
@@ -18,7 +19,6 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class JsInnerClassesSupport(mapping: JsMapping, private val irFactory: IrFactory) : InnerClassesSupport { class JsInnerClassesSupport(mapping: JsMapping, private val irFactory: IrFactory) : InnerClassesSupport {
@@ -27,11 +27,17 @@ class JsInnerClassesSupport(mapping: JsMapping, private val irFactory: IrFactory
private val originalInnerClassPrimaryConstructorByClass = mapping.originalInnerClassPrimaryConstructorByClass private val originalInnerClassPrimaryConstructorByClass = mapping.originalInnerClassPrimaryConstructorByClass
override fun getOuterThisField(innerClass: IrClass): IrField = override fun getOuterThisField(innerClass: IrClass): IrField =
if (!innerClass.isInner) throw AssertionError("Class is not inner: ${innerClass.dump()}") if (!innerClass.isInner) compilationException(
"Class is not inner",
innerClass
)
else { else {
outerThisFieldSymbols.getOrPut(innerClass) { outerThisFieldSymbols.getOrPut(innerClass) {
val outerClass = innerClass.parent as? IrClass val outerClass = innerClass.parent as? IrClass
?: throw AssertionError("No containing class for inner class ${innerClass.dump()}") ?: compilationException(
"No containing class for inner class",
innerClass
)
irFactory.buildField { irFactory.buildField {
origin = IrDeclarationOrigin.FIELD_FOR_OUTER_THIS origin = IrDeclarationOrigin.FIELD_FOR_OUTER_THIS
@@ -8,10 +8,10 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.ScopeWithIr import org.jetbrains.kotlin.backend.common.ScopeWithIr
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.lower.SingleAbstractMethodLowering import org.jetbrains.kotlin.backend.common.lower.SingleAbstractMethodLowering
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.file
import org.jetbrains.kotlin.ir.util.parentClassOrNull import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.ir.util.render
class JsSingleAbstractMethodLowering(context: CommonBackendContext) : SingleAbstractMethodLowering(context), BodyLoweringPass { class JsSingleAbstractMethodLowering(context: CommonBackendContext) : SingleAbstractMethodLowering(context), BodyLoweringPass {
@@ -60,6 +59,7 @@ class JsSingleAbstractMethodLowering(context: CommonBackendContext) : SingleAbst
// FE doesn't allow type parameters for now. // FE doesn't allow type parameters for now.
// And since there is a to-do in common SingleAbstractMethodLowering (at function visitTypeOperator), // And since there is a to-do in common SingleAbstractMethodLowering (at function visitTypeOperator),
// we don't have to be more saint than a pope here. // we don't have to be more saint than a pope here.
return typeOperand.classOrNull?.defaultType ?: error("Unsupported SAM conversion: ${typeOperand.render()}") return typeOperand.classOrNull?.defaultType
?: compilationException("Unsupported SAM conversion", typeOperand)
} }
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.addChild import org.jetbrains.kotlin.backend.common.ir.addChild
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
@@ -14,10 +15,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.getJsQualifier
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
import org.jetbrains.kotlin.ir.util.constructedClass import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -134,7 +132,10 @@ fun validateIsExternal(packageFragment: IrPackageFragment) {
fun validateNestedExternalDeclarations(declaration: IrDeclaration, isExternalTopLevel: Boolean) { fun validateNestedExternalDeclarations(declaration: IrDeclaration, isExternalTopLevel: Boolean) {
fun IrPossiblyExternalDeclaration.checkExternal() { fun IrPossiblyExternalDeclaration.checkExternal() {
if (isExternal != isExternalTopLevel) { if (isExternal != isExternalTopLevel) {
error("isExternal validation failed for declaration ${declaration.render()}") compilationException(
"isExternal validation failed for declaration",
declaration,
)
} }
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
@@ -118,7 +119,10 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : DeclarationTrans
expression = (it.copyWithParameters() as IrExpressionBody).expression expression = (it.copyWithParameters() as IrExpressionBody).expression
} }
is IrSyntheticBody -> it is IrSyntheticBody -> it
else -> error("Unexpected body kind: ${it.javaClass}") else -> compilationException(
"Unexpected body kind",
it,
)
} }
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.isPure import org.jetbrains.kotlin.backend.common.ir.isPure
import org.jetbrains.kotlin.backend.common.ir.isTopLevel import org.jetbrains.kotlin.backend.common.ir.isTopLevel
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.INTERNAL import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.INTERNAL
@@ -266,7 +267,10 @@ private val IrDeclaration.correspondingProperty: IrProperty?
is IrField -> propertyWithPersistentSafe { is IrField -> propertyWithPersistentSafe {
correspondingPropertySymbol?.owner correspondingPropertySymbol?.owner
} }
else -> error("Can be only IrProperty, IrSimpleFunction or IrField") else -> compilationException(
"Can be only IrProperty, IrSimpleFunction or IrField",
this
)
} }
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
@@ -20,7 +21,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.file
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -101,7 +101,11 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
} }
private fun buildGetterLambda(factory: IrSimpleFunction, reference: IrPropertyReference, boundValueParameters: List<IrValueParameter>): IrExpression { private fun buildGetterLambda(factory: IrSimpleFunction, reference: IrPropertyReference, boundValueParameters: List<IrValueParameter>): IrExpression {
val getter = reference.getter?.owner ?: error("Getter expected") val getter = reference.getter?.owner
?: compilationException(
"Getter expected",
reference
)
return buildAccessorLambda(factory, getter, reference, boundValueParameters) return buildAccessorLambda(factory, getter, reference, boundValueParameters)
} }
@@ -117,10 +121,17 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
val superName = when (accessor.symbol) { val superName = when (accessor.symbol) {
reference.getter -> "get" reference.getter -> "get"
reference.setter -> "set" reference.setter -> "set"
else -> error("Unexpected accessor ${accessor.render()}") else -> compilationException(
"Unexpected accessor",
accessor
)
} }
val classifier = (reference.type as IrSimpleType).classOrNull ?: error("Simple type expected") val classifier = (reference.type as IrSimpleType).classOrNull
?: compilationException(
"Simple type expected",
reference
)
val supperAccessor = val supperAccessor =
classifier.owner.declarations.filterIsInstance<IrSimpleFunction>().single { it.name.asString() == superName } classifier.owner.declarations.filterIsInstance<IrSimpleFunction>().single { it.name.asString() == superName }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.getOrPut import org.jetbrains.kotlin.backend.common.getOrPut
import org.jetbrains.kotlin.backend.common.ir.ValueRemapper import org.jetbrains.kotlin.backend.common.ir.ValueRemapper
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
@@ -264,7 +265,11 @@ private class CallsiteRedirectionTransformer(private val context: JsIrBackendCon
val target = expression.symbol.owner val target = expression.symbol.owner
return if (target.isSecondaryConstructorCall) { return if (target.isSecondaryConstructorCall) {
val factory = with(context) { val factory = with(context) {
if (es6mode) mapping.secondaryConstructorToDelegate[target] ?: error("Not found IrFunction for secondary ctor") if (es6mode) mapping.secondaryConstructorToDelegate[target]
?: compilationException(
"Not found IrFunction for secondary ctor",
expression
)
else buildConstructorFactory(target, target.parentAsClass) else buildConstructorFactory(target, target.parentAsClass)
} }
replaceSecondaryConstructorWithFactoryFunction(expression, factory.symbol) replaceSecondaryConstructorWithFactoryFunction(expression, factory.symbol)
@@ -279,7 +284,11 @@ private class CallsiteRedirectionTransformer(private val context: JsIrBackendCon
return if (target.isSecondaryConstructorCall) { return if (target.isSecondaryConstructorCall) {
val klass = target.parentAsClass val klass = target.parentAsClass
val delegate = with(context) { val delegate = with(context) {
if (es6mode) mapping.secondaryConstructorToDelegate[target] ?: error("Not found IrFunction for secondary ctor") if (es6mode) mapping.secondaryConstructorToDelegate[target]
?: compilationException(
"Not found IrFunction for secondary ctor",
expression
)
else buildConstructorDelegate(target, klass) else buildConstructorDelegate(target, klass)
} }
val newCall = replaceSecondaryConstructorWithFactoryFunction(expression, delegate.symbol) val newCall = replaceSecondaryConstructorWithFactoryFunction(expression, delegate.symbol)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.isPure import org.jetbrains.kotlin.backend.common.ir.isPure
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
@@ -262,7 +263,11 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass {
private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: IrType): IrExpression { private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: IrType): IrExpression {
val typeParameterSymbol = val typeParameterSymbol =
(toType.classifierOrNull as? IrTypeParameterSymbol) ?: error("expected type parameter, but $toType") (toType.classifierOrNull as? IrTypeParameterSymbol)
?: compilationException(
"expected type parameter, but $toType",
argument
)
val typeParameter = typeParameterSymbol.owner val typeParameter = typeParameterSymbol.owner
@@ -371,7 +376,10 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass {
toType.isLong() -> JsIrBuilder.buildCall(context.intrinsics.jsToLong).apply { toType.isLong() -> JsIrBuilder.buildCall(context.intrinsics.jsToLong).apply {
putValueArgument(0, argument()) putValueArgument(0, argument())
} }
else -> error("Unreachable execution (coercion to non-Integer type") else -> compilationException(
"Unreachable execution (coercion to non-Integer type)",
expression
)
} }
newStatements += if (isNullable) JsIrBuilder.buildIfElse(toType, nullCheck(argument()), litNull, casted) else casted newStatements += if (isNullable) JsIrBuilder.buildIfElse(toType, nullCheck(argument()), litNull, casted) else casted
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower.calls package org.jetbrains.kotlin.ir.backend.js.lower.calls
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.irCall
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
@@ -27,7 +28,10 @@ class EnumIntrinsicsTransformer(private val context: JsIrBackendContext) : Calls
if (!enum.isEnumClass) return call if (!enum.isEnumClass) return call
val staticMethod = enum.findDeclaration(staticMethodPredicate) val staticMethod = enum.findDeclaration(staticMethodPredicate)
if (staticMethod == null || !staticMethod.isStaticMethodOfClass) if (staticMethod == null || !staticMethod.isStaticMethodOfClass)
throw IllegalStateException("Enum class should have static method for ${call.symbol.owner.name}") compilationException(
"Enum class should have static method for ${call.symbol.owner.name}",
call
)
return irCall(call, staticMethod.symbol) return irCall(call, staticMethod.symbol)
} }
@@ -364,7 +364,11 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
val thisReceiver = this.dispatchReceiverParameter!! val thisReceiver = this.dispatchReceiverParameter!!
val boundFields = val boundFields =
context.mapping.capturedFields[coroutineClass] ?: error("No captured values for class ${coroutineClass.render()}") context.mapping.capturedFields[coroutineClass]
?: compilationException(
"No captured values",
coroutineClass
)
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
body = irBuilder.irBlockBody(startOffset, endOffset) { body = irBuilder.irBlockBody(startOffset, endOffset) {
@@ -393,7 +397,11 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
private fun transformInvokeMethod(createFunction: IrSimpleFunction, stateMachineFunction: IrSimpleFunction) { private fun transformInvokeMethod(createFunction: IrSimpleFunction, stateMachineFunction: IrSimpleFunction) {
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
val thisReceiver = function.dispatchReceiverParameter ?: error("Expected dispatch receiver for invoke") val thisReceiver = function.dispatchReceiverParameter
?: compilationException(
"Expected dispatch receiver for invoke",
function
)
val functionBody = function.body as IrBlockBody val functionBody = function.body as IrBlockBody
functionBody.statements.clear() functionBody.statements.clear()
functionBody.statements.addAll(irBuilder.irBlockBody(startOffset, endOffset) { functionBody.statements.addAll(irBuilder.irBlockBody(startOffset, endOffset) {
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.irCall
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.isElseBranch import org.jetbrains.kotlin.backend.common.ir.isElseBranch
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
@@ -58,8 +59,14 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
is IrConstKind.Byte -> JsIntLiteral(kind.valueOf(expression).toInt()) is IrConstKind.Byte -> JsIntLiteral(kind.valueOf(expression).toInt())
is IrConstKind.Short -> JsIntLiteral(kind.valueOf(expression).toInt()) is IrConstKind.Short -> JsIntLiteral(kind.valueOf(expression).toInt())
is IrConstKind.Int -> JsIntLiteral(kind.valueOf(expression)) is IrConstKind.Int -> JsIntLiteral(kind.valueOf(expression))
is IrConstKind.Long -> throw IllegalStateException("Long const should have been lowered at this point") is IrConstKind.Long -> compilationException(
is IrConstKind.Char -> throw IllegalStateException("Char const should have been lowered at this point") "Long const should have been lowered at this point",
expression
)
is IrConstKind.Char -> compilationException(
"Char const should have been lowered at this point",
expression
)
is IrConstKind.Float -> JsDoubleLiteral(toDoubleConst(kind.valueOf(expression))) is IrConstKind.Float -> JsDoubleLiteral(toDoubleConst(kind.valueOf(expression)))
is IrConstKind.Double -> JsDoubleLiteral(kind.valueOf(expression)) is IrConstKind.Double -> JsDoubleLiteral(kind.valueOf(expression))
}.withSource(expression, context) }.withSource(expression, context)
@@ -98,7 +105,11 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
"${field.render()} in non-external class ${fieldParent.render()}" "${field.render()} in non-external class ${fieldParent.render()}"
} }
val receiver = expression.receiver?.accept(this, context) ?: error("Expect expression.receiver to not be null") val receiver = expression.receiver?.accept(this, context)
?: compilationException(
"Expect expression.receiver to not be null",
expression
)
return JsNameRef(field.getJsNameOrKotlinName().identifier, receiver).withSource(expression, context) return JsNameRef(field.getJsNameOrKotlinName().identifier, receiver).withSource(expression, context)
} }
@@ -204,9 +215,16 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
override fun visitCall(expression: IrCall, context: JsGenerationContext): JsExpression { override fun visitCall(expression: IrCall, context: JsGenerationContext): JsExpression {
if (context.checkIfJsCode(expression.symbol)) { if (context.checkIfJsCode(expression.symbol)) {
val statements = translateJsCodeIntoStatementList( val statements = translateJsCodeIntoStatementList(
expression.getValueArgument(0) ?: error("JsCode is expected"), expression.getValueArgument(0)
?: compilationException(
"JsCode is expected",
expression
),
context.staticContext.backendContext context.staticContext.backendContext
) ?: error("Cannot compute js code for ${expression.render()}") ) ?: compilationException(
"Cannot compute js code",
expression
)
if (statements.isEmpty()) return JsPrefixOperation(JsUnaryOperator.VOID, JsIntLiteral(3)) // TODO: report warning or even error if (statements.isEmpty()) return JsPrefixOperation(JsUnaryOperator.VOID, JsIntLiteral(3)) // TODO: report warning or even error
@@ -250,7 +268,10 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: JsGenerationContext): JsExpression { override fun visitTypeOperator(expression: IrTypeOperatorCall, data: JsGenerationContext): JsExpression {
return when (expression.operator) { return when (expression.operator) {
IrTypeOperator.REINTERPRET_CAST -> expression.argument.accept(this, data) IrTypeOperator.REINTERPRET_CAST -> expression.argument.accept(this, data)
else -> error("All type operator calls except REINTERPRET_CAST should be lowered at this point: ${expression.operator}") else -> compilationException(
"All type operator calls except REINTERPRET_CAST should be lowered at this point",
expression
)
}.withSource(expression, data) }.withSource(expression, data)
} }
@@ -305,14 +326,20 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
expression.arguments.map { it.accept(this, data) } expression.arguments.map { it.accept(this, data) }
) )
else -> error("Unexpected operator ${expression.operator}: ${expression.render()}") else -> compilationException(
"Unexpected operator ${expression.operator}",
expression
)
}.withSource(expression, data) }.withSource(expression, data)
override fun visitRawFunctionReference(expression: IrRawFunctionReference, data: JsGenerationContext): JsExpression { override fun visitRawFunctionReference(expression: IrRawFunctionReference, data: JsGenerationContext): JsExpression {
val name = when (val function = expression.symbol.owner) { val name = when (val function = expression.symbol.owner) {
is IrConstructor -> data.getNameForConstructor(function) is IrConstructor -> data.getNameForConstructor(function)
is IrSimpleFunction -> data.getNameForStaticFunction(function) is IrSimpleFunction -> data.getNameForStaticFunction(function)
else -> error("Unexpected function kind") else -> compilationException(
"Unexpected function kind",
expression
)
} }
return JsNameRef(name).withSource(expression, data) return JsNameRef(name).withSource(expression, data)
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
@@ -134,9 +135,16 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
override fun visitCall(expression: IrCall, data: JsGenerationContext): JsStatement { override fun visitCall(expression: IrCall, data: JsGenerationContext): JsStatement {
if (data.checkIfJsCode(expression.symbol)) { if (data.checkIfJsCode(expression.symbol)) {
val statements = translateJsCodeIntoStatementList( val statements = translateJsCodeIntoStatementList(
expression.getValueArgument(0) ?: error("JsCode is expected"), expression.getValueArgument(0)
?: compilationException(
"JsCode is expected",
expression
),
data.staticContext.backendContext data.staticContext.backendContext
) ?: error("Cannot compute js code for ${expression.render()}") ) ?: compilationException(
"Cannot compute js code",
expression
)
return when (statements.size) { return when (statements.size) {
0 -> JsEmpty 0 -> JsEmpty
1 -> statements.single().withSource(expression, data) 1 -> statements.single().withSource(expression, data)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.backend.js.export.isAllowedFakeOverriddenDeclaration import org.jetbrains.kotlin.ir.backend.js.export.isAllowedFakeOverriddenDeclaration
@@ -94,7 +95,10 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
is IrField -> { is IrField -> {
} }
else -> { else -> {
error("Unexpected declaration in class: ${declaration.render()}") compilationException(
"Unexpected declaration in class",
declaration
)
} }
} }
} }
@@ -5,17 +5,21 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef
import org.jetbrains.kotlin.ir.backend.js.utils.invokeFunForLambda
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.*
typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression
@@ -91,7 +95,10 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
add(intrinsics.jsClass) { call, context -> add(intrinsics.jsClass) { call, context ->
val typeArgument = call.getTypeArgument(0) val typeArgument = call.getTypeArgument(0)
typeArgument?.getClassRef(context) typeArgument?.getClassRef(context)
?: error("Type argument of jsClass must be statically known class, but " + typeArgument?.render()) ?: compilationException(
"Type argument of jsClass must be statically known class",
typeArgument
)
} }
add(intrinsics.jsNewTarget) { _, _ -> add(intrinsics.jsNewTarget) { _, _ ->
@@ -116,7 +123,12 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
typeArgument.getClassRef(context) typeArgument.getClassRef(context)
} }
addIfNotNull(intrinsics.jsCode) { _, _ -> error("Should not be called") } addIfNotNull(intrinsics.jsCode) { call, _ ->
compilationException(
"Should not be called",
call
)
}
add(intrinsics.jsArrayLength) { call, context -> add(intrinsics.jsArrayLength) { call, context ->
val args = translateCallArguments(call, context) val args = translateCallArguments(call, context)
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.backend.common.ir.isElseBranch import org.jetbrains.kotlin.backend.common.ir.isElseBranch
import org.jetbrains.kotlin.backend.common.ir.isSuspend import org.jetbrains.kotlin.backend.common.ir.isSuspend
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
@@ -159,7 +160,10 @@ fun translateCall(
return when (function) { return when (function) {
property.getter -> nameRef property.getter -> nameRef
property.setter -> jsAssignment(nameRef, arguments.single()) property.setter -> jsAssignment(nameRef, arguments.single())
else -> error("Function must be an accessor of corresponding property") else -> compilationException(
"Function must be an accessor of corresponding property",
function
)
} }
} }
} }
@@ -5,23 +5,23 @@
package org.jetbrains.kotlin.ir.backend.js.utils package org.jetbrains.kotlin.ir.backend.js.utils
import org.jetbrains.kotlin.backend.common.compilationException
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.collectRealOverrides import org.jetbrains.kotlin.ir.util.collectRealOverrides
import org.jetbrains.kotlin.ir.util.render
val IrFunction.realOverrideTarget: IrFunction val IrFunction.realOverrideTarget: IrFunction
get() = when (this) { get() = when (this) {
is IrSimpleFunction -> this.realOverrideTarget is IrSimpleFunction -> this.realOverrideTarget
is IrConstructor -> this is IrConstructor -> this
else -> error(this) else -> compilationException("Unexpected declaration", this)
} }
val IrSimpleFunction.realOverrideTarget: IrSimpleFunction val IrSimpleFunction.realOverrideTarget: IrSimpleFunction
get(): IrSimpleFunction { get(): IrSimpleFunction {
val realOverrides = collectRealOverrides() val realOverrides = collectRealOverrides()
return realOverrides.find { it.modality != Modality.ABSTRACT } ?: realOverrides.firstOrNull() ?: return realOverrides.find { it.modality != Modality.ABSTRACT } ?: realOverrides.firstOrNull()
error("No real override target found for ${this.render()}") ?: compilationException("No real override target found", this)
} }