[JS IR BE] update current lowerings for IrScript

This commit is contained in:
Vitaliy.Tikhonov
2019-08-30 15:15:46 +03:00
committed by romanart
parent d79279d8a5
commit 240abdb750
14 changed files with 116 additions and 20 deletions
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.name.FqName
interface BackendContext {
@@ -30,4 +32,5 @@ interface BackendContext {
val sharedVariablesManager: SharedVariablesManager
val declarationFactory: DeclarationFactory
val internalPackageFqn: FqName
val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
}
@@ -23,4 +23,5 @@ interface CommonBackendContext : BackendContext, LoggingContext {
fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean)
val configuration: CompilerConfiguration
val scriptMode: Boolean
}
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -71,7 +68,15 @@ abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid()
return result
}
final override fun visitScript(declaration: IrScript): IrStatement {
scopeStack.push(createScope(declaration))
val result = visitScriptNew(declaration)
scopeStack.pop()
return result
}
protected val currentFile get() = scopeStack.lastOrNull { it.irElement is IrFile }!!.irElement as IrFile
protected val currentScript get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrScriptSymbol }
protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrClassSymbol }
protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFunctionSymbol }
protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrPropertySymbol }
@@ -102,6 +107,10 @@ abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid()
open fun visitFieldNew(declaration: IrField): IrStatement {
return super.visitField(declaration)
}
open fun visitScriptNew(declaration: IrScript): IrStatement {
return super.visitScript(declaration)
}
}
abstract class IrElementVisitorVoidWithContext : IrElementVisitorVoid {
@@ -39,6 +39,12 @@ interface ClassLoweringPass : FileLoweringPass {
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
}
interface ScriptLoweringPass : FileLoweringPass {
fun lower(irScript: IrScript)
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
}
interface DeclarationContainerLoweringPass : FileLoweringPass {
fun lower(irDeclarationContainer: IrDeclarationContainer)
@@ -72,14 +78,35 @@ fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
})
}
fun ScriptLoweringPass.runOnFilePostfix(irFile: IrFile) {
irFile.acceptVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitScript(declaration: IrScript) {
declaration.acceptChildrenVoid(this)
lower(declaration)
}
})
}
fun DeclarationContainerLoweringPass.asClassLoweringPass() = object : ClassLoweringPass {
override fun lower(irClass: IrClass) {
this@asClassLoweringPass.lower(irClass)
}
}
fun DeclarationContainerLoweringPass.asScriptLoweringPass() = object : ScriptLoweringPass {
override fun lower(irScript: IrScript) {
this@asScriptLoweringPass.lower(irScript)
}
}
fun DeclarationContainerLoweringPass.runOnFilePostfix(irFile: IrFile) {
this.asClassLoweringPass().runOnFilePostfix(irFile)
this.asScriptLoweringPass().runOnFilePostfix(irFile)
this.lower(irFile as IrDeclarationContainer)
}
@@ -412,7 +412,9 @@ open class DefaultParameterInjector(
class DefaultParameterCleaner constructor(val context: CommonBackendContext) : FunctionLoweringPass {
override fun lower(irFunction: IrFunction) {
irFunction.valueParameters.forEach { it.defaultValue = null }
if (!context.scriptMode) {
irFunction.valueParameters.forEach { it.defaultValue = null }
}
}
}
@@ -5,15 +5,14 @@
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
@@ -23,8 +22,8 @@ import org.jetbrains.kotlin.name.Name
private const val INLINE_CLASS_IMPL_SUFFIX = "-impl"
// TODO: Support incremental compilation
class InlineClassLowering(val context: BackendContext) {
private val transformedFunction = mutableMapOf<IrFunctionSymbol, IrSimpleFunctionSymbol>()
class InlineClassLowering(val context: CommonBackendContext) {
private val transformedFunction = if (context.scriptMode) context.transformedFunction else mutableMapOf()
val inlineClassDeclarationLowering = object : ClassLoweringPass {
override fun lower(irClass: IrClass) {
@@ -8,6 +8,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrScript
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
//This lower takes part of old LocalDeclarationLowering job to pop up local classes from functions
@@ -27,8 +28,8 @@ class LocalClassPopupLowering(val context: BackendContext) : FileLoweringPass {
val newContainer = allScopes.asReversed().drop(1/*skip self*/).firstOrNull {
//find first class local or not;
// to reproduce original LocalDeclarationLowering behaviour add: '&& !it.irElement.isLocal' condition
it.irElement is IrClass
}?.irElement as? IrClass ?: currentFile
it.irElement is IrClass || it.irElement is IrScript
}?.irElement?.let { it as? IrClass ?: it as? IrScript } ?: currentFile
extractedLocalClasses.add(newDeclaration to newContainer)
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
}
@@ -44,8 +44,10 @@ class JsIrBackendContext(
val symbolTable: SymbolTable,
irModuleFragment: IrModuleFragment,
val additionalExportedDeclarations: Set<FqName>,
override val configuration: CompilerConfiguration
override val configuration: CompilerConfiguration,
override val scriptMode: Boolean = false
) : CommonBackendContext {
override val transformedFunction = mutableMapOf<IrFunctionSymbol, IrSimpleFunctionSymbol>()
override val builtIns = module.builtIns
@@ -39,6 +39,10 @@ abstract class AbstractBlockDecomposerLowering(context: CommonBackendContext) :
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
irDeclarationContainer.transformDeclarationsFlat { declaration ->
when (declaration) {
is IrScript -> {
lower(declaration)
listOf(declaration)
}
is IrFunction -> {
lower(declaration)
listOf(declaration)
@@ -49,6 +53,10 @@ abstract class AbstractBlockDecomposerLowering(context: CommonBackendContext) :
}
}
fun lower(irScript: IrScript) {
irScript.transform(decomposerTransformer, null)
}
fun lower(irFunction: IrFunction) {
(irFunction.body as? IrExpressionBody)?.apply {
irFunction.body = toBlockBody(irFunction)
@@ -94,7 +102,7 @@ class BlockDecomposerTransformer(
private val context: CommonBackendContext,
private val unreachableExpression: () -> IrExpression
) : IrElementTransformerVoid() {
private lateinit var function: IrFunction
private lateinit var function: IrDeclarationParent
private var tmpVarCounter: Int = 0
private val statementTransformer = StatementTransformer()
@@ -109,6 +117,30 @@ class BlockDecomposerTransformer(
private val booleanNotSymbol = context.irBuiltIns.booleanNotSymbol
override fun visitScript(declaration: IrScript): IrStatement {
function = declaration
with(declaration) {
val transformedDeclarations = declarations.map { it.transform(statementTransformer, null) as IrDeclaration }
declarations.clear()
declarations.addAll(transformedDeclarations)
val transformedStatements = mutableListOf<IrStatement>()
statements.forEach {
val transformer = if (it === statements.last()) expressionTransformer else statementTransformer
val s = it.transform(transformer, null)
if (s is IrComposite) {
transformedStatements.addAll(s.statements)
} else {
transformedStatements.add(s)
}
}
statements.clear()
statements.addAll(transformedStatements)
}
return declaration
}
override fun visitFunction(declaration: IrFunction): IrStatement {
function = declaration
tmpVarCounter = 0
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -27,7 +28,11 @@ class PrimitiveCompanionLowering(val context: JsIrBackendContext) : FileLowering
if (!irClass.isCompanion)
return null
val parent = irClass.parent as IrClass
//TODO: Figure out how to check for primitive companion in case similar to REPL in better way
val parent = irClass.parent as? IrClass
?: context.symbolTable.referenceClass(irClass.descriptor.containingDeclaration as ClassDescriptor).owner.also {
assert(context.scriptMode)
}
if (!parent.defaultType.isPrimitiveType() && !parent.defaultType.isString())
return null
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrLocalDelegatedPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName
@@ -49,6 +50,10 @@ class JvmBackendContext(
val phaseConfig: PhaseConfig,
private val firMode: Boolean
) : CommonBackendContext {
override val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
get() = TODO("not implemented")
override val scriptMode: Boolean = false
override val builtIns = state.module.builtIns
val typeMapper = IrTypeMapper(this)
val methodSignatureMapper = MethodSignatureMapper(this)
@@ -19,6 +19,8 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -34,6 +36,8 @@ class WasmBackendContext(
) : CommonBackendContext {
override val builtIns = module.builtIns
override var inVerbosePhase: Boolean = false
override val scriptMode = false
override val transformedFunction = mutableMapOf<IrFunctionSymbol, IrSimpleFunctionSymbol>()
// Place to store declarations excluded from code generation
val excludedDeclarations: IrPackageFragment by lazy {
@@ -11,6 +11,8 @@ dependencies {
compileOnly(project(":compiler:frontend.java"))
compileOnly(project(":compiler:psi"))
compileOnly(project(":compiler:plugin-api"))
compileOnly(project(":compiler:cli"))
compileOnly(project(":compiler:ir.serialization.js"))
compile(project(":kotlin-scripting-common"))
compile(project(":kotlin-scripting-jvm"))
compile(kotlinStdlib())
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.MISSING_IMPORTED_SCRIPT_FILE
import org.jetbrains.kotlin.diagnostics.Errors.MISSING_IMPORTED_SCRIPT_PSI
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
@@ -156,13 +157,16 @@ class LazyScriptDescriptor(
override fun getUnsubstitutedPrimaryConstructor() = super.getUnsubstitutedPrimaryConstructor()!!
internal val baseClassDescriptor: () -> ClassDescriptor? = resolveSession.storageManager.createNullableLazyValue {
val baseClass = getScriptingClass(
scriptCompilationConfiguration()[ScriptCompilationConfiguration.baseClass]
?: throw IllegalStateException("Base class is not configured for the script ${scriptInfo.script.containingFile}")
)
val scriptBaseType = scriptCompilationConfiguration()[ScriptCompilationConfiguration.baseClass]
?: error("Base class is not configured for the script ${scriptInfo.script.containingFile}")
val typeName = scriptBaseType.run { fromClass?.toString()?.replace("class ", "") ?: typeName }
val fqnName = FqName(typeName)
val classId = ClassId.topLevel(fqnName)
findTypeDescriptor(
baseClass,
if (baseClass.qualifiedName?.startsWith("kotlin.script.templates.standard") == true) Errors.MISSING_SCRIPT_STANDARD_TEMPLATE
classId,
typeName,
if (fqnName.parent().asString().startsWith("kotlin.script.templates.standard")) Errors.MISSING_SCRIPT_STANDARD_TEMPLATE
else Errors.MISSING_SCRIPT_BASE_CLASS
)
}