[IR] More user-friendly compilation exceptions from lowerings and JS codegen
Merge-request: KT-MR-5004
This commit is contained in:
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.cli.js
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
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.serialization.metadata.KlibMetadataVersion
|
||||
import org.jetbrains.kotlin.backend.wasm.compileWasm
|
||||
import org.jetbrains.kotlin.backend.wasm.wasmPhases
|
||||
import org.jetbrains.kotlin.cli.common.*
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode.OK
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode.*
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
|
||||
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.extensions.ScriptEvaluationExtension
|
||||
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.MessageCollector
|
||||
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.IncrementalResultsConsumer
|
||||
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.ic.*
|
||||
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.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
|
||||
import org.jetbrains.kotlin.js.config.*
|
||||
@@ -59,7 +56,6 @@ import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
|
||||
import org.jetbrains.kotlin.utils.join
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
enum class ProduceKind {
|
||||
DEFAULT, // Determine what to produce based on js-v1 options
|
||||
@@ -236,7 +232,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
if (updated) {
|
||||
messageCollector.report(INFO, "IC $invalidationType cache building duration: ${System.currentTimeMillis() - start}ms")
|
||||
} 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
|
||||
}
|
||||
@@ -281,7 +280,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
}
|
||||
|
||||
if (arguments.irProduceJs) {
|
||||
messageCollector.report(INFO,"Produce executable: $outputFilePath")
|
||||
messageCollector.report(INFO, "Produce executable: $outputFilePath")
|
||||
messageCollector.report(INFO, arguments.cacheDirectories ?: "")
|
||||
|
||||
if (icCaches.isNotEmpty()) {
|
||||
@@ -384,68 +383,80 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
arguments.irPerFile -> JsGenerationGranularity.PER_FILE
|
||||
else -> JsGenerationGranularity.WHOLE_PROGRAM
|
||||
}
|
||||
|
||||
val ir = compile(
|
||||
module,
|
||||
phaseConfig,
|
||||
if (arguments.irDceDriven) PersistentIrFactory() else IrFactoryImpl,
|
||||
dceRuntimeDiagnostic = RuntimeDiagnostic.resolve(
|
||||
arguments.irDceRuntimeDiagnostic,
|
||||
messageCollector
|
||||
),
|
||||
dceDriven = arguments.irDceDriven,
|
||||
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
||||
baseClassIntoMetadata = arguments.irBaseClassInMetadata,
|
||||
safeExternalBoolean = arguments.irSafeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic = RuntimeDiagnostic.resolve(
|
||||
arguments.irSafeExternalBooleanDiagnostic,
|
||||
messageCollector
|
||||
),
|
||||
lowerPerModule = false,//icCaches.isNotEmpty(),
|
||||
granularity = granularity,
|
||||
icCompatibleIr2Js = arguments.irNewIr2Js,
|
||||
)
|
||||
|
||||
val compiledModule: CompilerResult = if (arguments.irNewIr2Js) {
|
||||
val transformer = IrModuleToJsTransformerTmp(
|
||||
ir.context,
|
||||
mainCallArguments,
|
||||
fullJs = true,
|
||||
dceJs = arguments.irDce,
|
||||
multiModule = arguments.irPerModule,
|
||||
relativeRequirePath = false,
|
||||
try {
|
||||
val ir = compile(
|
||||
module,
|
||||
phaseConfig,
|
||||
if (arguments.irDceDriven) PersistentIrFactory() else IrFactoryImpl,
|
||||
dceRuntimeDiagnostic = RuntimeDiagnostic.resolve(
|
||||
arguments.irDceRuntimeDiagnostic,
|
||||
messageCollector
|
||||
),
|
||||
dceDriven = arguments.irDceDriven,
|
||||
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
||||
baseClassIntoMetadata = arguments.irBaseClassInMetadata,
|
||||
safeExternalBoolean = arguments.irSafeExternalBoolean,
|
||||
safeExternalBooleanDiagnostic = RuntimeDiagnostic.resolve(
|
||||
arguments.irSafeExternalBooleanDiagnostic,
|
||||
messageCollector
|
||||
),
|
||||
lowerPerModule = false,//icCaches.isNotEmpty(),
|
||||
granularity = granularity,
|
||||
icCompatibleIr2Js = arguments.irNewIr2Js,
|
||||
)
|
||||
|
||||
transformer.generateModule(ir.allModules)
|
||||
} else {
|
||||
val transformer = IrModuleToJsTransformer(
|
||||
ir.context,
|
||||
mainCallArguments,
|
||||
fullJs = true,
|
||||
dceJs = arguments.irDce,
|
||||
multiModule = arguments.irPerModule,
|
||||
relativeRequirePath = false
|
||||
val compiledModule: CompilerResult = if (arguments.irNewIr2Js) {
|
||||
val transformer = IrModuleToJsTransformerTmp(
|
||||
ir.context,
|
||||
mainCallArguments,
|
||||
fullJs = true,
|
||||
dceJs = arguments.irDce,
|
||||
multiModule = arguments.irPerModule,
|
||||
relativeRequirePath = false,
|
||||
)
|
||||
|
||||
transformer.generateModule(ir.allModules)
|
||||
} else {
|
||||
val transformer = IrModuleToJsTransformer(
|
||||
ir.context,
|
||||
mainCallArguments,
|
||||
fullJs = true,
|
||||
dceJs = arguments.irDce,
|
||||
multiModule = arguments.irPerModule,
|
||||
relativeRequirePath = false,
|
||||
)
|
||||
|
||||
transformer.generateModule(ir.allModules)
|
||||
}
|
||||
|
||||
messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms")
|
||||
|
||||
|
||||
val outputs = if (arguments.irDce && !arguments.irDceDriven)
|
||||
compiledModule.outputsAfterDce!!
|
||||
else
|
||||
compiledModule.outputs!!
|
||||
|
||||
outputFile.write(outputs)
|
||||
outputs.dependencies.forEach { (name, content) ->
|
||||
outputFile.resolveSibling("$name.js").write(content)
|
||||
}
|
||||
if (arguments.generateDts) {
|
||||
val dtsFile = outputFile.withReplacedExtensionOrNull(outputFile.extension, "d.ts")!!
|
||||
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
|
||||
)
|
||||
)
|
||||
|
||||
transformer.generateModule(ir.allModules)
|
||||
}
|
||||
|
||||
messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms")
|
||||
|
||||
|
||||
|
||||
val outputs = if (arguments.irDce && !arguments.irDceDriven)
|
||||
compiledModule.outputsAfterDce!!
|
||||
else
|
||||
compiledModule.outputs!!
|
||||
|
||||
outputFile.write(outputs)
|
||||
outputs.dependencies.forEach { (name, content) ->
|
||||
outputFile.resolveSibling("$name.js").write(content)
|
||||
}
|
||||
if (arguments.generateDts) {
|
||||
val dtsFile = outputFile.withReplacedExtensionOrNull(outputFile.extension, "d.ts")!!
|
||||
dtsFile.writeText(compiledModule.tsDefinitions ?: error("No ts definitions"))
|
||||
return INTERNAL_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+98
@@ -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)
|
||||
}
|
||||
|
||||
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) {
|
||||
irFile.acceptVoid(ClassLoweringVisitor(this))
|
||||
@@ -128,7 +143,18 @@ fun BodyLoweringPass.runOnFilePostfix(
|
||||
) {
|
||||
val visitor = BodyLoweringVisitor(this, withLocalDeclarations, allowDeclarationModification)
|
||||
for (declaration in ArrayList(irFile.declarations)) {
|
||||
declaration.accept(visitor, null)
|
||||
try {
|
||||
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) {
|
||||
val visitor = Visitor(this)
|
||||
irFile.declarations.transformFlat { declaration ->
|
||||
declaration.acceptVoid(visitor)
|
||||
transformFlatRestricted(declaration)
|
||||
try {
|
||||
declaration.acceptVoid(visitor)
|
||||
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 icCompatibleIr2Js: Boolean = false,
|
||||
) : JsCommonBackendContext {
|
||||
|
||||
val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf()
|
||||
val fileToInitializerPureness: MutableMap<IrFile, Boolean> = mutableMapOf()
|
||||
val fieldToInitializer: MutableMap<IrField, IrExpression> = mutableMapOf()
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
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.ir.IrBuiltIns
|
||||
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
|
||||
|
||||
if (container !== replacement) error("Declaration has changed: ${container}")
|
||||
if (container !== replacement) compilationException("Declaration has changed", container)
|
||||
|
||||
// TODO: Track & insert parents for temporary variables
|
||||
irBody.patchDeclarationParents(container as? IrDeclarationParent ?: container.parent)
|
||||
|
||||
+10
-4
@@ -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.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
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.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
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.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
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.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
@@ -620,11 +620,17 @@ class BlockDecomposerTransformer(
|
||||
)
|
||||
|
||||
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) {
|
||||
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)
|
||||
|
||||
+12
-3
@@ -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.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
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 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'
|
||||
|
||||
// If we implement KFunctionN we also need FunctionN
|
||||
@@ -324,7 +329,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod
|
||||
JsStatementOrigins.CALLABLE_REFERENCE_INVOKE
|
||||
)
|
||||
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>()
|
||||
.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() {
|
||||
visibility = superProperty.visibility
|
||||
|
||||
+2
-1
@@ -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.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -158,7 +159,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
return createSimpleKType(type, visitedTypeParams)
|
||||
if (type is IrDynamicType)
|
||||
return createDynamicType()
|
||||
error("Unexpected type $type")
|
||||
compilationException("Unexpected type", type)
|
||||
}
|
||||
|
||||
private fun createDynamicType(): IrExpression {
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
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.backend.js.JsIrBackendContext
|
||||
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))
|
||||
|
||||
else -> error("Unknown unsigned type")
|
||||
else -> compilationException("Unknown unsigned type", expression)
|
||||
}
|
||||
}
|
||||
return when {
|
||||
|
||||
+17
-4
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
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.copyToWithoutSuperTypes
|
||||
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) {
|
||||
error("Unreachable")
|
||||
compilationException("Unreachable", irBody)
|
||||
}
|
||||
|
||||
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>,
|
||||
factoryMapping: Map<IrFieldSymbol, IrValueParameterSymbol>
|
||||
): 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.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> {
|
||||
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>()
|
||||
.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 {
|
||||
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 returnStmt = statements[0] as IrReturn
|
||||
|
||||
+6
-6
@@ -6,23 +6,20 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
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.ir.IrStatement
|
||||
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.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
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.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isArray
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
import org.jetbrains.kotlin.ir.util.isPrimitiveArray
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
|
||||
|
||||
// JS PIR (and IC) requires DeclarationTransformer instead of FileLoweringPass
|
||||
@@ -55,13 +52,16 @@ class JsAnnotationImplementationTransformer(val jsContext: JsIrBackendContext) :
|
||||
when {
|
||||
type.isPrimitiveArray() -> arraysContentEquals[type]
|
||||
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(
|
||||
implClass: IrClass,
|
||||
annotationClass: IrClass,
|
||||
generatedConstructor: IrConstructor
|
||||
) {
|
||||
throw IllegalStateException("Should not be called")
|
||||
compilationException(
|
||||
"Should not be called",
|
||||
implClass
|
||||
)
|
||||
}
|
||||
}
|
||||
+11
-8
@@ -5,11 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
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.ir.IrElement
|
||||
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.symbols.IrFunctionSymbol
|
||||
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.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
// Outlines `kotlin.js.js(code: String)` calls where JS code references Kotlin locals.
|
||||
// Makes locals usages explicit.
|
||||
@@ -96,7 +91,11 @@ private class JsCodeOutlineTransformer(
|
||||
val name = irValueDeclaration.name
|
||||
if (!name.isSpecial) {
|
||||
val identifier = name.identifier
|
||||
val currentScope = localScopes.lastOrNull() ?: error("Expecting a scope")
|
||||
val currentScope = localScopes.lastOrNull()
|
||||
?: compilationException(
|
||||
"Expecting a scope",
|
||||
irValueDeclaration
|
||||
)
|
||||
currentScope[identifier] = irValueDeclaration
|
||||
}
|
||||
}
|
||||
@@ -133,7 +132,11 @@ private class JsCodeOutlineTransformer(
|
||||
if (expression.symbol != backendContext.intrinsics.jsCode)
|
||||
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
|
||||
|
||||
// Collect used Kotlin local variables and parameters.
|
||||
|
||||
+9
-3
@@ -5,6 +5,7 @@
|
||||
|
||||
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.ir.copyTo
|
||||
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.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
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
|
||||
|
||||
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 {
|
||||
outerThisFieldSymbols.getOrPut(innerClass) {
|
||||
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 {
|
||||
origin = IrDeclarationOrigin.FIELD_FOR_OUTER_THIS
|
||||
|
||||
+3
-3
@@ -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.CommonBackendContext
|
||||
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.descriptors.DescriptorVisibilities
|
||||
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.expressions.IrBody
|
||||
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.util.file
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
|
||||
class JsSingleAbstractMethodLowering(context: CommonBackendContext) : SingleAbstractMethodLowering(context), BodyLoweringPass {
|
||||
|
||||
@@ -60,6 +59,7 @@ class JsSingleAbstractMethodLowering(context: CommonBackendContext) : SingleAbst
|
||||
// FE doesn't allow type parameters for now.
|
||||
// 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.
|
||||
return typeOperand.classOrNull?.defaultType ?: error("Unsupported SAM conversion: ${typeOperand.render()}")
|
||||
return typeOperand.classOrNull?.defaultType
|
||||
?: compilationException("Unsupported SAM conversion", typeOperand)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
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.ir.IrElement
|
||||
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.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||
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.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -134,7 +132,10 @@ fun validateIsExternal(packageFragment: IrPackageFragment) {
|
||||
fun validateNestedExternalDeclarations(declaration: IrDeclaration, isExternalTopLevel: Boolean) {
|
||||
fun IrPossiblyExternalDeclaration.checkExternal() {
|
||||
if (isExternal != isExternalTopLevel) {
|
||||
error("isExternal validation failed for declaration ${declaration.render()}")
|
||||
compilationException(
|
||||
"isExternal validation failed for declaration",
|
||||
declaration,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -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.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
@@ -118,7 +119,10 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : DeclarationTrans
|
||||
expression = (it.copyWithParameters() as IrExpressionBody).expression
|
||||
}
|
||||
is IrSyntheticBody -> it
|
||||
else -> error("Unexpected body kind: ${it.javaClass}")
|
||||
else -> compilationException(
|
||||
"Unexpected body kind",
|
||||
it,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -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.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.backend.common.ir.isPure
|
||||
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.INTERNAL
|
||||
@@ -266,7 +267,10 @@ private val IrDeclaration.correspondingProperty: IrProperty?
|
||||
is IrField -> propertyWithPersistentSafe {
|
||||
correspondingPropertySymbol?.owner
|
||||
}
|
||||
else -> error("Can be only IrProperty, IrSimpleFunction or IrField")
|
||||
else -> compilationException(
|
||||
"Can be only IrProperty, IrSimpleFunction or IrField",
|
||||
this
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-4
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
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.lower.createIrBuilder
|
||||
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.classOrNull
|
||||
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.transformChildrenVoid
|
||||
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 {
|
||||
val getter = reference.getter?.owner ?: error("Getter expected")
|
||||
val getter = reference.getter?.owner
|
||||
?: compilationException(
|
||||
"Getter expected",
|
||||
reference
|
||||
)
|
||||
return buildAccessorLambda(factory, getter, reference, boundValueParameters)
|
||||
}
|
||||
|
||||
@@ -117,10 +121,17 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
|
||||
val superName = when (accessor.symbol) {
|
||||
reference.getter -> "get"
|
||||
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 =
|
||||
classifier.owner.declarations.filterIsInstance<IrSimpleFunction>().single { it.name.asString() == superName }
|
||||
|
||||
|
||||
+11
-2
@@ -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.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.backend.common.getOrPut
|
||||
import org.jetbrains.kotlin.backend.common.ir.ValueRemapper
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
@@ -264,7 +265,11 @@ private class CallsiteRedirectionTransformer(private val context: JsIrBackendCon
|
||||
val target = expression.symbol.owner
|
||||
return if (target.isSecondaryConstructorCall) {
|
||||
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)
|
||||
}
|
||||
replaceSecondaryConstructorWithFactoryFunction(expression, factory.symbol)
|
||||
@@ -279,7 +284,11 @@ private class CallsiteRedirectionTransformer(private val context: JsIrBackendCon
|
||||
return if (target.isSecondaryConstructorCall) {
|
||||
val klass = target.parentAsClass
|
||||
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)
|
||||
}
|
||||
val newCall = replaceSecondaryConstructorWithFactoryFunction(expression, delegate.symbol)
|
||||
|
||||
+10
-2
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
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.ir.IrStatement
|
||||
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 {
|
||||
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
|
||||
|
||||
@@ -371,7 +376,10 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
toType.isLong() -> JsIrBuilder.buildCall(context.intrinsics.jsToLong).apply {
|
||||
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
|
||||
|
||||
+5
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
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.util.irCall
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
@@ -27,7 +28,10 @@ class EnumIntrinsicsTransformer(private val context: JsIrBackendContext) : Calls
|
||||
if (!enum.isEnumClass) return call
|
||||
val staticMethod = enum.findDeclaration(staticMethodPredicate)
|
||||
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)
|
||||
}
|
||||
|
||||
+10
-2
@@ -364,7 +364,11 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
val thisReceiver = this.dispatchReceiverParameter!!
|
||||
|
||||
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)
|
||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||
@@ -393,7 +397,11 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
|
||||
private fun transformInvokeMethod(createFunction: IrSimpleFunction, stateMachineFunction: IrSimpleFunction) {
|
||||
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
|
||||
functionBody.statements.clear()
|
||||
functionBody.statements.addAll(irBuilder.irBlockBody(startOffset, endOffset) {
|
||||
|
||||
-1
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
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.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
+35
-8
@@ -5,6 +5,7 @@
|
||||
|
||||
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.descriptors.ClassKind
|
||||
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.Short -> JsIntLiteral(kind.valueOf(expression).toInt())
|
||||
is IrConstKind.Int -> JsIntLiteral(kind.valueOf(expression))
|
||||
is IrConstKind.Long -> throw IllegalStateException("Long const should have been lowered at this point")
|
||||
is IrConstKind.Char -> throw IllegalStateException("Char const should have been lowered at this point")
|
||||
is IrConstKind.Long -> compilationException(
|
||||
"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.Double -> JsDoubleLiteral(kind.valueOf(expression))
|
||||
}.withSource(expression, context)
|
||||
@@ -98,7 +105,11 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
"${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)
|
||||
}
|
||||
|
||||
@@ -204,9 +215,16 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
override fun visitCall(expression: IrCall, context: JsGenerationContext): JsExpression {
|
||||
if (context.checkIfJsCode(expression.symbol)) {
|
||||
val statements = translateJsCodeIntoStatementList(
|
||||
expression.getValueArgument(0) ?: error("JsCode is expected"),
|
||||
expression.getValueArgument(0)
|
||||
?: compilationException(
|
||||
"JsCode is expected",
|
||||
expression
|
||||
),
|
||||
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
|
||||
|
||||
@@ -250,7 +268,10 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: JsGenerationContext): JsExpression {
|
||||
return when (expression.operator) {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -305,14 +326,20 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
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)
|
||||
|
||||
override fun visitRawFunctionReference(expression: IrRawFunctionReference, data: JsGenerationContext): JsExpression {
|
||||
val name = when (val function = expression.symbol.owner) {
|
||||
is IrConstructor -> data.getNameForConstructor(function)
|
||||
is IrSimpleFunction -> data.getNameForStaticFunction(function)
|
||||
else -> error("Unexpected function kind")
|
||||
else -> compilationException(
|
||||
"Unexpected function kind",
|
||||
expression
|
||||
)
|
||||
}
|
||||
return JsNameRef(name).withSource(expression, data)
|
||||
}
|
||||
|
||||
+10
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
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.utils.JsGenerationContext
|
||||
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 {
|
||||
if (data.checkIfJsCode(expression.symbol)) {
|
||||
val statements = translateJsCodeIntoStatementList(
|
||||
expression.getValueArgument(0) ?: error("JsCode is expected"),
|
||||
expression.getValueArgument(0)
|
||||
?: compilationException(
|
||||
"JsCode is expected",
|
||||
expression
|
||||
),
|
||||
data.staticContext.backendContext
|
||||
) ?: error("Cannot compute js code for ${expression.render()}")
|
||||
) ?: compilationException(
|
||||
"Cannot compute js code",
|
||||
expression
|
||||
)
|
||||
return when (statements.size) {
|
||||
0 -> JsEmpty
|
||||
1 -> statements.single().withSource(expression, data)
|
||||
|
||||
+5
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
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.Modality
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isAllowedFakeOverriddenDeclaration
|
||||
@@ -94,7 +95,10 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
is IrField -> {
|
||||
}
|
||||
else -> {
|
||||
error("Unexpected declaration in class: ${declaration.render()}")
|
||||
compilationException(
|
||||
"Unexpected declaration in class",
|
||||
declaration
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-5
@@ -5,17 +5,21 @@
|
||||
|
||||
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.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.IrConstructor
|
||||
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.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
|
||||
typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression
|
||||
@@ -91,7 +95,10 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
||||
add(intrinsics.jsClass) { call, context ->
|
||||
val typeArgument = call.getTypeArgument(0)
|
||||
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) { _, _ ->
|
||||
@@ -116,7 +123,12 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
||||
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 ->
|
||||
val args = translateCallArguments(call, context)
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ private class JsIrModuleCrossModuleReferecenceBuilder(val module: JsIrModule, va
|
||||
}.internalName
|
||||
}
|
||||
|
||||
val tagToName = module.fragments.flatMap { it.nameBindings.entries}.associate { it.key to it.value }
|
||||
val tagToName = module.fragments.flatMap { it.nameBindings.entries }.associate { it.key to it.value }
|
||||
|
||||
val resultImports = imports.associate {
|
||||
|
||||
|
||||
-1
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
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.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
+5
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
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.isSuspend
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -159,7 +160,10 @@ fun translateCall(
|
||||
return when (function) {
|
||||
property.getter -> nameRef
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -5,23 +5,23 @@
|
||||
|
||||
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.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.util.collectRealOverrides
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
|
||||
val IrFunction.realOverrideTarget: IrFunction
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> this.realOverrideTarget
|
||||
is IrConstructor -> this
|
||||
else -> error(this)
|
||||
else -> compilationException("Unexpected declaration", this)
|
||||
}
|
||||
|
||||
val IrSimpleFunction.realOverrideTarget: IrSimpleFunction
|
||||
get(): IrSimpleFunction {
|
||||
val realOverrides = collectRealOverrides()
|
||||
return realOverrides.find { it.modality != Modality.ABSTRACT } ?: realOverrides.firstOrNull() ?:
|
||||
error("No real override target found for ${this.render()}")
|
||||
return realOverrides.find { it.modality != Modality.ABSTRACT } ?: realOverrides.firstOrNull()
|
||||
?: compilationException("No real override target found", this)
|
||||
}
|
||||
Reference in New Issue
Block a user