[IR] create IrScript, infrastructure for it and update visitors

This commit is contained in:
Vitaliy.Tikhonov
2019-08-30 14:18:21 +03:00
committed by romanart
parent f13e05de7d
commit 14510c1da3
15 changed files with 142 additions and 8 deletions
@@ -53,6 +53,12 @@ class PropertiesLowering(
return declaration return declaration
} }
override fun visitScript(declaration: IrScript): IrStatement {
declaration.transformChildrenVoid(this)
declaration.transformDeclarationsFlat { lowerProperty(it, ClassKind.CLASS) }
return declaration
}
private fun lowerProperty(declaration: IrDeclaration, kind: ClassKind): List<IrDeclaration>? = private fun lowerProperty(declaration: IrDeclaration, kind: ClassKind): List<IrDeclaration>? =
if (declaration is IrProperty) if (declaration is IrProperty)
if (skipExternalProperties && declaration.isEffectivelyExternal()) listOf(declaration) else { if (skipExternalProperties && declaration.isEffectivelyExternal()) listOf(declaration) else {
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.JsEmpty
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
import org.jetbrains.kotlin.js.backend.ast.JsStatement
import org.jetbrains.kotlin.js.backend.ast.JsVars
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
class IrDeclarationToJsTransformer : BaseIrElementToJsNodeTransformer<JsStatement, JsGenerationContext> { class IrDeclarationToJsTransformer : BaseIrElementToJsNodeTransformer<JsStatement, JsGenerationContext> {
@@ -44,4 +47,11 @@ class IrDeclarationToJsTransformer : BaseIrElementToJsNodeTransformer<JsStatemen
override fun visitVariable(declaration: IrVariable, context: JsGenerationContext): JsStatement { override fun visitVariable(declaration: IrVariable, context: JsGenerationContext): JsStatement {
return declaration.accept(IrElementToJsStatementTransformer(), context) return declaration.accept(IrElementToJsStatementTransformer(), context)
} }
override fun visitScript(irScript: IrScript, context: JsGenerationContext): JsStatement {
return JsGlobalBlock().apply {
statements += irScript.declarations.map { it.accept(this@IrDeclarationToJsTransformer, context) }
statements += irScript.statements.map { it.accept(IrElementToJsStatementTransformer(), context) }
}
}
} }
@@ -8,11 +8,12 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.js.backend.ast.JsBlock import org.jetbrains.kotlin.js.backend.ast.JsBlock
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
class IrFileToJsTransformer : BaseIrElementToJsNodeTransformer<JsBlock, JsGenerationContext> { class IrFileToJsTransformer : BaseIrElementToJsNodeTransformer<JsBlock, JsGenerationContext> {
override fun visitFile(declaration: IrFile, data: JsGenerationContext): JsBlock { override fun visitFile(declaration: IrFile, data: JsGenerationContext): JsBlock {
val fileContext = data.newDeclaration() val fileContext = data.newDeclaration()
val block = JsBlock() val block = JsGlobalBlock()
declaration.declarations.forEach { declaration.declarations.forEach {
block.statements.add(it.accept(IrDeclarationToJsTransformer(), fileContext)) block.statements.add(it.accept(IrDeclarationToJsTransformer(), fileContext))
@@ -25,15 +25,17 @@ import org.jetbrains.kotlin.utils.DFS
class IrModuleToJsTransformer( class IrModuleToJsTransformer(
private val backendContext: JsIrBackendContext, private val backendContext: JsIrBackendContext,
private val mainFunction: IrSimpleFunction?, private val mainFunction: IrSimpleFunction?,
private val mainArguments: List<String>? private val mainArguments: List<String>?,
private val generateScriptModule: Boolean = false,
var namer: NameTables = NameTables(emptyList())
) { ) {
val moduleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!! val moduleName = backendContext.configuration[CommonConfigurationKeys.MODULE_NAME]!!
private val moduleKind = backendContext.configuration[JSConfigurationKeys.MODULE_KIND]!! private val moduleKind = backendContext.configuration[JSConfigurationKeys.MODULE_KIND]!!
private fun generateModuleBody(module: IrModuleFragment, context: JsGenerationContext): List<JsStatement> { private fun generateModuleBody(module: IrModuleFragment, context: JsGenerationContext): List<JsStatement> {
val statements = mutableListOf( val statements = mutableListOf<JsStatement>().also {
JsStringLiteral("use strict").makeStmt() if (!generateScriptModule) it += JsStringLiteral("use strict").makeStmt()
) }
val preDeclarationBlock = JsBlock() val preDeclarationBlock = JsBlock()
val postDeclarationBlock = JsBlock() val postDeclarationBlock = JsBlock()
@@ -37,7 +37,7 @@ class IrNamerImpl(private val newNameTables: NameTables) : IrNamer {
} }
override fun getNameForField(field: IrField): JsName { override fun getNameForField(field: IrField): JsName {
return if (field.isStatic) { return if (field.isStatic || field.parent is IrScript) {
getNameForStaticDeclaration(field) getNameForStaticDeclaration(field)
} else { } else {
getNameForMemberField(field) getNameForMemberField(field)
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 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.ir.declarations
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
//TODO: make IrScript as IrPackageFragment, because script is used as a file, not as a class
//NOTE: declarations and statements stored separately
interface IrScript : IrSymbolDeclaration<IrScriptSymbol>, IrDeclarationContainer, IrDeclarationWithName, IrDeclarationParent {
val statements: MutableList<IrStatement>
// NOTE: is the result of the FE conversion, because there script interpreted as a class and has receiver
var thisReceiver: IrValueParameter
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2019 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.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
private val SCRIPT_ORIGIN = object : IrDeclarationOriginImpl("FIELD_FOR_OBJECT_INSTANCE") {}
class IrScriptImpl(
override val symbol: IrScriptSymbol,
override val name: Name
) : IrScript, IrDeclarationBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SCRIPT_ORIGIN) {
override val declarations: MutableList<IrDeclaration> = mutableListOf()
override val statements: MutableList<IrStatement> = mutableListOf()
override lateinit var thisReceiver: IrValueParameter
override val descriptor: ScriptDescriptor = symbol.descriptor
init {
symbol.bind(this)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitScript(this, data)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
declarations.forEach { it.accept(visitor, data) }
statements.forEach { it.accept(visitor, data) }
thisReceiver.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
declarations.transform { it.transform(transformer, data) }
statements.transform { it.transform(transformer, data) }
thisReceiver = thisReceiver.transform(transformer, data)
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.symbols
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrScript
import org.jetbrains.kotlin.ir.expressions.IrReturnableBlock import org.jetbrains.kotlin.ir.expressions.IrReturnableBlock
import org.jetbrains.kotlin.ir.util.IrSymbolVisitor import org.jetbrains.kotlin.ir.util.IrSymbolVisitor
import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker
@@ -96,6 +97,13 @@ interface IrClassSymbol :
visitor.visitClassSymbol(this, data) visitor.visitClassSymbol(this, data)
} }
interface IrScriptSymbol :
IrSymbol, IrBindableSymbol<ScriptDescriptor, IrScript> {
override fun <D, R> accept(visitor: IrSymbolVisitor<R, D>, data: D): R =
visitor.visitSymbol(this, data)
}
interface IrTypeParameterSymbol : interface IrTypeParameterSymbol :
IrClassifierSymbol, IrBindableSymbol<TypeParameterDescriptor, IrTypeParameter>, TypeParameterMarker { IrClassifierSymbol, IrBindableSymbol<TypeParameterDescriptor, IrTypeParameter>, TypeParameterMarker {
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2019 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.ir.symbols.impl
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.ir.declarations.IrScript
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
class IrScriptSymbolImpl(descriptor: ScriptDescriptor) :
IrScriptSymbol, IrBindableSymbolBase<ScriptDescriptor, IrScript>(descriptor)
@@ -345,6 +345,8 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
"FUN ${renderOriginIfNonTrivial()}" "FUN ${renderOriginIfNonTrivial()}"
} }
override fun visitScript(declaration: IrScript, data: Nothing?) = "SCRIPT"
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: Nothing?): String = override fun visitSimpleFunction(declaration: IrSimpleFunction, data: Nothing?): String =
declaration.runTrimEnd { declaration.runTrimEnd {
"FUN ${renderOriginIfNonTrivial()}" + "FUN ${renderOriginIfNonTrivial()}" +
@@ -192,7 +192,9 @@ open class SymbolTable : ReferenceSymbolTable {
currentScope?.dump() ?: "<none>" currentScope?.dump() ?: "<none>"
} }
private val externalPackageFragmentTable = FlatSymbolTable<PackageFragmentDescriptor, IrExternalPackageFragment, IrExternalPackageFragmentSymbol>() private val externalPackageFragmentTable =
FlatSymbolTable<PackageFragmentDescriptor, IrExternalPackageFragment, IrExternalPackageFragmentSymbol>()
private val scriptSymbolTable = FlatSymbolTable<ScriptDescriptor, IrScript, IrScriptSymbol>()
private val classSymbolTable = FlatSymbolTable<ClassDescriptor, IrClass, IrClassSymbol>() private val classSymbolTable = FlatSymbolTable<ClassDescriptor, IrClass, IrClassSymbol>()
private val constructorSymbolTable = FlatSymbolTable<ClassConstructorDescriptor, IrConstructor, IrConstructorSymbol>() private val constructorSymbolTable = FlatSymbolTable<ClassConstructorDescriptor, IrConstructor, IrConstructorSymbol>()
private val enumEntrySymbolTable = FlatSymbolTable<ClassDescriptor, IrEnumEntry, IrEnumEntrySymbol>() private val enumEntrySymbolTable = FlatSymbolTable<ClassDescriptor, IrEnumEntry, IrEnumEntrySymbol>()
@@ -232,6 +234,21 @@ open class SymbolTable : ReferenceSymbolTable {
IrAnonymousInitializerSymbolImpl(descriptor) IrAnonymousInitializerSymbolImpl(descriptor)
) )
fun listExistedScripts() = scriptSymbolTable.descriptorToSymbol.map { it.value }
fun declareScript(
descriptor: ScriptDescriptor,
scriptFactory: (IrScriptSymbol) -> IrScript = { symbol: IrScriptSymbol ->
IrScriptImpl(symbol, descriptor.name)
}
): IrScript {
return scriptSymbolTable.declare(
descriptor,
{ IrScriptSymbolImpl(descriptor) },
scriptFactory
)
}
fun declareClass( fun declareClass(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
modality: Modality = descriptor.modality, modality: Modality = descriptor.modality,
@@ -37,6 +37,7 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitDeclaration(declaration: IrDeclaration, data: D): IrStatement = override fun visitDeclaration(declaration: IrDeclaration, data: D): IrStatement =
declaration.also { it.transformChildren(this, data) } declaration.also { it.transformChildren(this, data) }
override fun visitScript(declaration: IrScript, data: D) = visitDeclaration(declaration, data)
override fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data) override fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data)
override fun visitFunction(declaration: IrFunction, data: D) = visitDeclaration(declaration, data) override fun visitFunction(declaration: IrFunction, data: D) = visitDeclaration(declaration, data)
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: D) = visitFunction(declaration, data) override fun visitSimpleFunction(declaration: IrSimpleFunction, data: D) = visitFunction(declaration, data)
@@ -46,6 +46,9 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitDeclaration(declaration: IrDeclaration): IrStatement = declaration.transformChildren() open fun visitDeclaration(declaration: IrDeclaration): IrStatement = declaration.transformChildren()
final override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): IrStatement = visitDeclaration(declaration) final override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): IrStatement = visitDeclaration(declaration)
open fun visitScript(declaration: IrScript) = visitDeclaration(declaration)
final override fun visitScript(declaration: IrScript, data: Nothing?) = visitScript(declaration)
open fun visitClass(declaration: IrClass) = visitDeclaration(declaration) open fun visitClass(declaration: IrClass) = visitDeclaration(declaration)
final override fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration) final override fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration)
@@ -26,6 +26,7 @@ interface IrElementVisitor<out R, in D> {
fun visitPackageFragment(declaration: IrPackageFragment, data: D) = visitElement(declaration, data) fun visitPackageFragment(declaration: IrPackageFragment, data: D) = visitElement(declaration, data)
fun visitFile(declaration: IrFile, data: D) = visitPackageFragment(declaration, data) fun visitFile(declaration: IrFile, data: D) = visitPackageFragment(declaration, data)
fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: D) = visitPackageFragment(declaration, data) fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: D) = visitPackageFragment(declaration, data)
fun visitScript(declaration: IrScript, data: D) = visitDeclaration(declaration, data)
fun visitDeclaration(declaration: IrDeclaration, data: D) = visitElement(declaration, data) fun visitDeclaration(declaration: IrDeclaration, data: D) = visitElement(declaration, data)
fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data) fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data)
@@ -43,6 +43,9 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitClass(declaration: IrClass) = visitDeclaration(declaration) fun visitClass(declaration: IrClass) = visitDeclaration(declaration)
override fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration) override fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration)
fun visitScript(declaration: IrScript) = visitDeclaration(declaration)
override fun visitScript(declaration: IrScript, data: Nothing?) = visitScript(declaration)
fun visitFunction(declaration: IrFunction) = visitDeclaration(declaration) fun visitFunction(declaration: IrFunction) = visitDeclaration(declaration)
override fun visitFunction(declaration: IrFunction, data: Nothing?) = visitFunction(declaration) override fun visitFunction(declaration: IrFunction, data: Nothing?) = visitFunction(declaration)