Mutable declarations IR.

This commit is contained in:
Dmitry Petrov
2016-08-08 15:43:44 +03:00
committed by Dmitry Petrov
parent 64abecf996
commit cb79f377f0
21 changed files with 377 additions and 172 deletions
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBodyBase
import org.jetbrains.kotlin.ir.expressions.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.IrReturnExpressionImpl import org.jetbrains.kotlin.ir.expressions.IrReturnExpressionImpl
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -33,21 +35,23 @@ abstract class IrDeclarationGeneratorBase(
override val context: IrGeneratorContext, override val context: IrGeneratorContext,
override val irDeclaration: IrDeclaration, override val irDeclaration: IrDeclaration,
override val parent: IrDeclarationGenerator, override val parent: IrDeclarationGenerator,
val containingFile: PsiSourceManager.PsiFileEntry val fileElementFactory: IrFileElementFactory
) : IrDeclarationGenerator { ) : IrDeclarationGenerator {
val irExpressionGenerator = IrExpressionGenerator(context, containingFile) val irExpressionGenerator = IrExpressionGenerator(context, fileElementFactory)
val containingDeclaration: IrCompoundDeclaration get() = fileElementFactory.containingDeclaration
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) { fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
// TODO create IrAnnotation's for each KtAnnotationEntry // TODO create IrAnnotation's for each KtAnnotationEntry
} }
fun generateMemberDeclaration(ktDeclaration: KtDeclaration, containingDeclaration: IrCompoundDeclarationBase) { fun generateMemberDeclaration(ktDeclaration: KtDeclaration) {
// TODO visitor? // TODO visitor?
when (ktDeclaration) { when (ktDeclaration) {
is KtNamedFunction -> is KtNamedFunction ->
generateFunctionDeclaration(ktDeclaration, containingDeclaration) generateFunctionDeclaration(ktDeclaration)
is KtProperty -> is KtProperty ->
generatePropertyDeclaration(ktDeclaration, containingDeclaration) generatePropertyDeclaration(ktDeclaration)
is KtClassOrObject -> is KtClassOrObject ->
TODO("classOrObject") TODO("classOrObject")
is KtTypeAlias -> is KtTypeAlias ->
@@ -55,61 +59,47 @@ abstract class IrDeclarationGeneratorBase(
} }
} }
private fun loc(ktElement: KtElement) = containingFile.getSourceLocationForElement(ktElement) fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction) {
fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction, containingDeclaration: IrCompoundDeclarationBase) {
val sourceLocation = loc(ktNamedFunction)
val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) { "unresolved fun" } val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) { "unresolved fun" }
val body = generateExpressionBody(ktNamedFunction.bodyExpression ?: TODO("function without body expression")) val body = generateExpressionBody(ktNamedFunction.bodyExpression ?: TODO("function without body expression"))
val irFunction = IrFunctionImpl(sourceLocation, functionDescriptor, body).apply { parent = containingDeclaration } fileElementFactory.createFunction(ktNamedFunction, functionDescriptor, body)
containingDeclaration.childDeclarations.add(irFunction)
} }
fun generatePropertyDeclaration(ktProperty: KtProperty, containingDeclaration: IrCompoundDeclarationBase) { fun generatePropertyDeclaration(ktProperty: KtProperty) {
val sourceLocation = loc(ktProperty) val propertyDescriptor = getPropertyDescriptor(ktProperty)
val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) { "unresolved property" }
val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?")
if (ktProperty.hasDelegate()) TODO("handle delegated property") if (ktProperty.hasDelegate()) TODO("handle delegated property")
val initializer = ktProperty.initializer?.let { generateExpressionBody(it) } val initializer = ktProperty.initializer?.let { generateExpressionBody(it) }
val irProperty = IrSimplePropertyImpl(sourceLocation, propertyDescriptor, initializer) val irProperty = fileElementFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer)
val irGetter: IrPropertyGetter? = ktProperty.getter?.let { ktGetter -> ktProperty.getter?.let { ktGetter ->
val getterLocation = loc(ktGetter)
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) { "unresolved getter" } val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) { "unresolved getter" }
val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?") val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?")
val getterBody = generateExpressionBody(ktGetter.bodyExpression ?: TODO("default getter")) val getterBody = generateExpressionBody(ktGetter.bodyExpression ?: TODO("default getter"))
IrPropertyGetterImpl(getterLocation, getterDescriptor, getterBody).apply { fileElementFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody)
parent = irProperty
getterBody.parent = this
}
} }
val irSetter: IrPropertySetter? = ktProperty.setter?.let { ktSetter -> ktProperty.setter?.let { ktSetter ->
val getterLocation = loc(ktSetter)
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) { "unresolved setter" } val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) { "unresolved setter" }
val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?") val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?")
val setterBody = generateExpressionBody(ktSetter.bodyExpression ?: TODO("default setter")) val setterBody = generateExpressionBody(ktSetter.bodyExpression ?: TODO("default setter"))
IrPropertySetterImpl(getterLocation, setterDescriptor, setterBody).apply { fileElementFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody)
parent = irProperty
setterBody.parent = this
}
} }
irProperty.apply { }
parent = containingDeclaration
getter = irGetter private fun getPropertyDescriptor(ktProperty: KtProperty): PropertyDescriptor {
setter = irSetter val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) { "unresolved property" }
} val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?")
containingDeclaration.childDeclarations.add(irProperty) return propertyDescriptor
} }
fun generateExpressionBody(ktBody: KtExpression): IrBodyBase { fun generateExpressionBody(ktBody: KtExpression): IrBodyBase {
val sourceLocation = loc(ktBody) val sourceLocation = fileElementFactory.getLocationInFile(ktBody)
val irExpression = irExpressionGenerator.generateExpression(ktBody) val irExpression = irExpressionGenerator.generateExpression(ktBody)
val bodyExpression = val bodyExpression =
if (ktBody is KtBlockExpression) if (ktBody is KtBlockExpression)
irExpression irExpression
else else
IrReturnExpressionImpl(sourceLocation, irExpression.type, irExpression).apply { IrReturnExpressionImpl(sourceLocation, irExpression.type, irExpression).apply { irExpression.parent = this }
irExpression.parent = this
}
return IrExpressionBodyImpl(sourceLocation,bodyExpression) return IrExpressionBodyImpl(sourceLocation,bodyExpression)
} }
} }
@@ -1,36 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi2ir
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.IrModule
import org.jetbrains.kotlin.psi.KtFile
import java.util.*
class IrElementFactory(val irModule: IrModule, val sourceManager: PsiSourceManager) {
val ktFileToIrFile = LinkedHashMap<KtFile, IrFile>()
fun createIrFile(ktFile: KtFile, descriptor: PackageFragmentDescriptor): IrFileImpl {
val fileEntry = sourceManager.getOrCreateFileEntry(ktFile)
val irFile = IrFileImpl(fileEntry.getRootSourceLocation(), fileEntry.getRecognizableName(), fileEntry, descriptor)
irFile.parent = irModule
ktFileToIrFile.put(ktFile, irFile)
return irFile
}
}
@@ -24,12 +24,12 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat
class IrExpressionGenerator( class IrExpressionGenerator(
override val context: IrGeneratorContext, override val context: IrGeneratorContext,
val containingFile: PsiSourceManager.PsiFileEntry val fileElementFactory: IrFileElementFactory
) : KtVisitor<IrExpressionBase, Nothing?>(), IrGenerator { ) : KtVisitor<IrExpressionBase, Nothing?>(), IrGenerator {
fun generateExpression(ktExpression: KtExpression) = ktExpression.irExpr() fun generateExpression(ktExpression: KtExpression) = ktExpression.irExpr()
private fun KtElement.irExpr(): IrExpressionBase = accept(this@IrExpressionGenerator, null) private fun KtElement.irExpr(): IrExpressionBase = accept(this@IrExpressionGenerator, null)
private fun KtElement.loc() = this@IrExpressionGenerator.containingFile.getSourceLocationForElement(this) private fun KtElement.loc() = this@IrExpressionGenerator.fileElementFactory.getLocationInFile(this)
private fun KtExpression.type() = getType(this) ?: TODO("no type for expression") private fun KtExpression.type() = getType(this) ?: TODO("no type for expression")
override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpressionBase = override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpressionBase =
@@ -0,0 +1,81 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi2ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.psi.*
class IrFileElementFactory private constructor(
val fileEntry: PsiSourceManager.PsiFileEntry,
val irFileImpl: IrFileImpl,
val containingDeclaration: IrCompoundDeclaration
) {
fun createChild(containingDeclaration: IrCompoundDeclaration) =
IrFileElementFactory(fileEntry, irFileImpl, containingDeclaration)
fun getRootLocationInFile() =
fileEntry.getRootSourceLocation()
fun getLocationInFile(ktElement: KtElement) =
fileEntry.getSourceLocationForElement(ktElement)
private fun <D : IrMemberDeclaration> D.addToContainer(): D =
apply {
this@IrFileElementFactory.containingDeclaration.addChildDeclaration(this)
}
fun createFunction(ktFunction: KtFunction, functionDescriptor: FunctionDescriptor, body: IrBody): IrFunction =
IrFunctionImpl(getLocationInFile(ktFunction), IrDeclarationKind.DEFINED, functionDescriptor, body)
.addToContainer()
fun createSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor, valueInitializer: IrBody?): IrSimpleProperty =
IrSimplePropertyImpl(getLocationInFile(ktProperty), IrDeclarationKind.DEFINED, propertyDescriptor, valueInitializer)
.addToContainer()
fun createPropertyGetter(
ktPropertyAccessor: KtPropertyAccessor,
irProperty: IrProperty,
getterDescriptor: PropertyGetterDescriptor,
getterBody: IrBody
): IrPropertyGetter =
IrPropertyGetterImpl(getLocationInFile(ktPropertyAccessor), IrDeclarationKind.DEFINED, getterDescriptor, getterBody)
.apply { irProperty.getter = this }
.addToContainer()
fun createPropertySetter(
ktPropertyAccessor: KtPropertyAccessor,
irProperty: IrProperty,
setterDescriptor: PropertySetterDescriptor,
setterBody: IrBody
) : IrPropertySetter =
IrPropertySetterImpl(getLocationInFile(ktPropertyAccessor), IrDeclarationKind.DEFINED, setterDescriptor, setterBody)
.apply { irProperty.setter = this }
.addToContainer()
companion object {
fun create(irModule: IrModule, sourceManager: PsiSourceManager, ktFile: KtFile, descriptor: PackageFragmentDescriptor): IrFileElementFactory {
val fileEntry = sourceManager.getOrCreateFileEntry(ktFile)
val fileSourceLocation = fileEntry.getRootSourceLocation()
val fileName = fileEntry.getRecognizableName()
val irFile = IrFileImpl(fileSourceLocation, irModule, fileName, descriptor)
irModule.addFile(irFile)
return IrFileElementFactory(fileEntry, irFile, irFile)
}
}
}
@@ -20,16 +20,17 @@ import org.jetbrains.kotlin.ir.declarations.IrFileImpl
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
class IrFileGenerator( class IrFileGenerator(
private val ktFile: KtFile,
context: IrGeneratorContext, context: IrGeneratorContext,
val ktFile: KtFile, irDeclaration: IrFileImpl,
override val irDeclaration: IrFileImpl, parent: IrModuleGenerator,
override val parent: IrModuleGenerator fileFileElementFactory: IrFileElementFactory
) : IrDeclarationGeneratorBase(context, irDeclaration, parent, irDeclaration.fileEntry as PsiSourceManager.PsiFileEntry) { ) : IrDeclarationGeneratorBase(context, irDeclaration, parent, fileFileElementFactory) {
fun generateFileContent() { fun generateFileContent() {
generateAnnotationEntries(ktFile.annotationEntries) generateAnnotationEntries(ktFile.annotationEntries)
for (topLevelDeclaration in ktFile.declarations) { for (topLevelDeclaration in ktFile.declarations) {
generateMemberDeclaration(topLevelDeclaration, irDeclaration) generateMemberDeclaration(topLevelDeclaration)
} }
} }
} }
@@ -31,6 +31,5 @@ class IrGeneratorContext(
val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns
val sourceManager = PsiSourceManager() val sourceManager = PsiSourceManager()
val irElementFactory = IrElementFactory(irModule, sourceManager)
} }
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.psi2ir package org.jetbrains.kotlin.psi2ir
import org.jetbrains.kotlin.ir.declarations.IrModule import org.jetbrains.kotlin.ir.declarations.IrModule
import org.jetbrains.kotlin.ir.declarations.IrModuleImpl
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator { class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator {
@@ -27,9 +26,10 @@ class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclaratio
fun generateModuleContent() { fun generateModuleContent() {
for (ktFile in context.inputFiles) { for (ktFile in context.inputFiles) {
val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) { "no package fragment for file" } val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) { "no package fragment for file" }
val irFile = context.irElementFactory.createIrFile(ktFile, packageFragmentDescriptor) val irFileElementFactory = IrFileElementFactory.create(context.irModule, context.sourceManager, ktFile, packageFragmentDescriptor)
context.irModule.files.add(irFile) val irFile = irFileElementFactory.irFileImpl
val generator = IrFileGenerator(context, ktFile, irFile, this) context.irModule.addFile(irFile)
val generator = IrFileGenerator(ktFile, context, irFile, this, irFileElementFactory)
generator.generateFileContent() generator.generateFileContent()
} }
} }
@@ -19,8 +19,9 @@ package org.jetbrains.kotlin.ir
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrElement { interface IrElement {
val parent: IrElement?
val sourceLocation: SourceLocation val sourceLocation: SourceLocation
val parent: IrElement?
fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R
fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D): Unit fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D): Unit
} }
@@ -20,15 +20,22 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrClass : IrCompoundDeclaration { interface IrClass : IrCompoundDeclaration, IrMemberDeclaration {
override val descriptor: ClassDescriptor override val descriptor: ClassDescriptor
} }
class IrClassImpl( class IrClassImpl(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
override val descriptor: ClassDescriptor override val descriptor: ClassDescriptor
) : IrCompoundDeclarationBase(sourceLocation), IrClass { ) : IrCompoundDeclarationBase(sourceLocation, kind), IrClass {
override var parent: IrCompoundDeclaration? = null
override fun setTreeLocation(parent: IrCompoundDeclaration?, index: Int) {
this.parent = parent
this.index = index
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClass(this, data) visitor.visitClass(this, data)
} }
@@ -0,0 +1,90 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import java.util.*
interface IrCompoundDeclaration : IrDeclaration {
fun getChildDeclaration(index: Int): IrMemberDeclaration?
fun addChildDeclaration(child: IrMemberDeclaration)
fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: IrMemberDeclaration)
fun removeAllChildDeclarations()
// TODO This can be an expensive operation / prohibited for some children.
fun removeChildDeclaration(child: IrMemberDeclaration)
fun <D> acceptChildDeclarations(visitor: IrElementVisitor<Unit, D>, data: D)
}
interface IrMemberDeclaration : IrDeclaration {
fun setTreeLocation(parent: IrCompoundDeclaration?, index: Int)
}
// TODO synchronization?
abstract class IrCompoundDeclarationBase(
sourceLocation: SourceLocation,
kind: IrDeclarationKind
) : IrDeclarationBase(sourceLocation, kind), IrCompoundDeclaration {
protected val childDeclarations: MutableList<IrMemberDeclaration> = ArrayList()
override fun getChildDeclaration(index: Int): IrMemberDeclaration? =
childDeclarations.getOrNull(index)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
acceptChildDeclarations(visitor, data)
}
override fun <D> acceptChildDeclarations(visitor: IrElementVisitor<Unit, D>, data: D) {
childDeclarations.forEach { it.accept(visitor, data) }
}
override fun addChildDeclaration(child: IrMemberDeclaration) {
child.setTreeLocation(this, childDeclarations.size)
childDeclarations.add(child)
}
override fun removeChildDeclaration(child: IrMemberDeclaration) {
validateChild(child)
childDeclarations.removeAt(child.index)
for (i in child.index ..childDeclarations.size - 1) {
childDeclarations[i].setTreeLocation(this, i)
}
child.detach()
}
override fun removeAllChildDeclarations() {
childDeclarations.forEach { it.detach() }
childDeclarations.clear()
}
override fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: IrMemberDeclaration) {
validateChild(oldChild)
childDeclarations[oldChild.index] = newChild
newChild.setTreeLocation(this, oldChild.index)
oldChild.detach()
}
}
fun IrMemberDeclaration.detach() {
setTreeLocation(null, IrDeclaration.DETACHED_INDEX)
}
fun IrCompoundDeclaration.validateChild(child: IrMemberDeclaration) {
assert(child.parent == this && getChildDeclaration(child.index) == child) { "Invalid child: $child" }
}
@@ -17,41 +17,34 @@
package org.jetbrains.kotlin.ir.declarations package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrElementBase import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.SourceLocation
import java.util.*
interface IrDeclaration : IrElement { interface IrDeclaration : IrElement {
val descriptor: DeclarationDescriptor override val parent: IrCompoundDeclaration?
override val parent: IrDeclaration? val index: Int
}
interface IrCompoundDeclaration : IrDeclaration { val descriptor: DeclarationDescriptor?
val childDeclarations: List<IrDeclaration> val kind: IrDeclarationKind
}
interface IrDeclarationNonRoot : IrDeclaration { companion object {
override val parent: IrDeclaration const val DETACHED_INDEX = Int.MIN_VALUE
}
abstract class IrDeclarationBase(sourceLocation: SourceLocation) : IrElementBase(sourceLocation), IrDeclaration {
override var parent: IrDeclaration? = null
}
abstract class IrDeclarationNonRootBase(sourceLocation: SourceLocation) : IrElementBase(sourceLocation), IrDeclarationNonRoot
abstract class IrCompoundDeclarationBase(sourceLocation: SourceLocation) : IrDeclarationBase(sourceLocation), IrCompoundDeclaration {
override val childDeclarations: MutableList<IrDeclaration> = ArrayList()
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
childDeclarations.forEach { it.accept(visitor, data) }
} }
} }
enum class IrDeclarationKind {
DEFINED,
DEFAULT_PROPERTY_ACCESSOR,
}
abstract class IrDeclarationBase(
sourceLocation: SourceLocation,
override val kind: IrDeclarationKind
) : IrElementBase(sourceLocation), IrDeclaration {
override var index: Int = IrDeclaration.DETACHED_INDEX
}
val IrDeclaration.containingDeclaration: IrDeclaration? val IrDeclaration.containingDeclaration: IrDeclaration?
get() = parent get() = parent
val IrDeclarationNonRoot.continingDeclaration: IrDeclaration
get() = parent
@@ -18,21 +18,21 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.SourceLocationManager
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrFile : IrCompoundDeclaration { interface IrFile : IrCompoundDeclaration {
val name: String val name: String
val fileEntry: SourceLocationManager.FileEntry
override val descriptor: PackageFragmentDescriptor override val descriptor: PackageFragmentDescriptor
} }
class IrFileImpl( class IrFileImpl(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
val module: IrModule,
override val name: String, override val name: String,
override val fileEntry: SourceLocationManager.FileEntry,
override val descriptor: PackageFragmentDescriptor override val descriptor: PackageFragmentDescriptor
) : IrCompoundDeclarationBase(sourceLocation), IrFile { ) : IrCompoundDeclarationBase(sourceLocation, IrDeclarationKind.DEFINED), IrFile {
override val parent: IrCompoundDeclaration? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFile(this, data) visitor.visitFile(this, data)
} }
@@ -18,26 +18,37 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrFunction : IrDeclarationNonRoot { interface IrFunction : IrMemberDeclaration {
override val descriptor: FunctionDescriptor override val descriptor: FunctionDescriptor
val body: IrBody val body: IrBody
} }
abstract class IrFunctionBase(sourceLocation: SourceLocation) : IrDeclarationNonRootBase(sourceLocation), IrFunction { abstract class IrFunctionBase(
sourceLocation: SourceLocation,
kind: IrDeclarationKind
) : IrCompoundDeclarationBase(sourceLocation, kind), IrFunction {
override var parent: IrCompoundDeclaration? = null
override fun setTreeLocation(parent: IrCompoundDeclaration?, index: Int) {
this.parent = parent
this.index = index
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) { override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
super.acceptChildDeclarations(visitor, data)
body.accept(visitor, data) body.accept(visitor, data)
} }
} }
class IrFunctionImpl( class IrFunctionImpl(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
override val descriptor: FunctionDescriptor, override val descriptor: FunctionDescriptor,
override val body: IrBody override val body: IrBody
) : IrFunctionBase(sourceLocation) { ) : IrFunctionBase(sourceLocation, kind) {
override lateinit var parent: IrDeclaration
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFunction(this, data) visitor.visitFunction(this, data)
} }
@@ -17,19 +17,33 @@
package org.jetbrains.kotlin.ir.declarations package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.NO_LOCATION import org.jetbrains.kotlin.ir.NO_LOCATION
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import java.util.* import java.util.*
interface IrModule : IrCompoundDeclaration { interface IrModule : IrDeclaration {
override val descriptor: ModuleDescriptor override val descriptor: ModuleDescriptor
val files: List<IrFile> val files: List<IrFile>
fun addFile(file: IrFile)
} }
class IrModuleImpl(override val descriptor: ModuleDescriptor) : IrDeclarationBase(NO_LOCATION), IrModule { class IrModuleImpl(
override val descriptor: ModuleDescriptor
) : IrDeclarationBase(NO_LOCATION, IrDeclarationKind.DEFINED), IrModule {
init {
index = 0
}
override val parent: IrCompoundDeclaration? get() = null
override val files: MutableList<IrFile> = ArrayList() override val files: MutableList<IrFile> = ArrayList()
override val childDeclarations: List<IrDeclaration> get() = files
override fun addFile(file: IrFile) {
files.add(file)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitModule(this, data) visitor.visitModule(this, data)
@@ -18,12 +18,15 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrProperty : IrDeclarationNonRoot { interface IrProperty : IrMemberDeclaration {
override val descriptor: PropertyDescriptor override val descriptor: PropertyDescriptor
val getter: IrPropertyGetter? var getter: IrPropertyGetter?
val setter: IrPropertySetter? var setter: IrPropertySetter?
fun <D> acceptAccessors(visitor: IrElementVisitor<Unit, D>, data: D)
} }
interface IrSimpleProperty : IrProperty { interface IrSimpleProperty : IrProperty {
@@ -34,49 +37,61 @@ interface IrDelegatedProperty : IrProperty {
val delegateInitializer: IrBody val delegateInitializer: IrBody
} }
// TODO synchronization?
abstract class IrPropertyBase( abstract class IrPropertyBase(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
override val descriptor: PropertyDescriptor override val descriptor: PropertyDescriptor
) : IrDeclarationNonRootBase(sourceLocation), IrProperty { ) : IrDeclarationBase(sourceLocation, kind), IrProperty {
override lateinit var parent: IrDeclaration override var parent: IrCompoundDeclaration? = null
override var getter: IrPropertyGetter? = null
override var setter: IrPropertySetter? = null
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) { override fun setTreeLocation(parent: IrCompoundDeclaration?, index: Int) {
getter?.accept(visitor, data) this.parent = parent
setter?.accept(visitor, data) this.index = index
} }
fun initialize(getter: IrPropertyGetter?, setter: IrPropertySetter?) { override var getter: IrPropertyGetter? = null
this.getter = getter set(newGetter) {
this.setter = setter newGetter?.property = this
field = newGetter
}
override var setter: IrPropertySetter? = null
set(newSetter) {
newSetter?.property = this
field = newSetter
}
override fun <D> acceptAccessors(visitor: IrElementVisitor<Unit, D>, data: D) {
getter?.accept(visitor, data)
setter?.accept(visitor, data)
} }
} }
class IrSimplePropertyImpl( class IrSimplePropertyImpl(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
descriptor: PropertyDescriptor, descriptor: PropertyDescriptor,
override val valueInitializer: IrBody? override val valueInitializer: IrBody?
) : IrPropertyBase(sourceLocation, descriptor), IrSimpleProperty { ) : IrPropertyBase(sourceLocation, kind, descriptor), IrSimpleProperty {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitSimpleProperty(this, data) visitor.visitSimpleProperty(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) { override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
valueInitializer?.accept(visitor, data) valueInitializer?.accept(visitor, data)
super.acceptChildren(visitor, data)
} }
} }
class IrDelegatedPropertyImpl( class IrDelegatedPropertyImpl(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
descriptor: PropertyDescriptor, descriptor: PropertyDescriptor,
override val delegateInitializer: IrBody override val delegateInitializer: IrBody
) : IrPropertyBase(sourceLocation, descriptor), IrDelegatedProperty { ) : IrPropertyBase(sourceLocation, kind, descriptor), IrDelegatedProperty {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitDelegatedProperty(this, data) visitor.visitDelegatedProperty(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) { override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
delegateInitializer.accept(visitor, data) delegateInitializer.accept(visitor, data)
super.acceptChildren(visitor, data)
} }
} }
@@ -20,11 +20,12 @@ import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrPropertyAccessor : IrFunction { interface IrPropertyAccessor : IrFunction {
override val descriptor: PropertyAccessorDescriptor override val descriptor: PropertyAccessorDescriptor
override val parent: IrProperty var property: IrProperty?
} }
interface IrPropertyGetter : IrPropertyAccessor { interface IrPropertyGetter : IrPropertyAccessor {
@@ -37,25 +38,28 @@ interface IrPropertySetter : IrPropertyAccessor {
abstract class IrPropertyAccessorBase( abstract class IrPropertyAccessorBase(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
override val body: IrBody override val body: IrBody
) : IrFunctionBase(sourceLocation), IrPropertyAccessor { ) : IrFunctionBase(sourceLocation, kind), IrPropertyAccessor {
override lateinit var parent: IrProperty override var property: IrProperty? = null
} }
class IrPropertyGetterImpl( class IrPropertyGetterImpl(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
override val descriptor: PropertyGetterDescriptor, override val descriptor: PropertyGetterDescriptor,
body: IrBody body: IrBody
) : IrPropertyAccessorBase(sourceLocation, body), IrPropertyGetter { ) : IrPropertyAccessorBase(sourceLocation, kind, body), IrPropertyGetter {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitPropertyGetter(this, data) visitor.visitPropertyGetter(this, data)
} }
class IrPropertySetterImpl( class IrPropertySetterImpl(
sourceLocation: SourceLocation, sourceLocation: SourceLocation,
kind: IrDeclarationKind,
override val descriptor: PropertySetterDescriptor, override val descriptor: PropertySetterDescriptor,
body: IrBody body: IrBody
) : IrPropertyAccessorBase(sourceLocation, body), IrPropertySetter { ) : IrPropertyAccessorBase(sourceLocation, kind, body), IrPropertySetter {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitPropertySetter(this, data) visitor.visitPropertySetter(this, data)
} }
@@ -14,11 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.ir.declarations package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrElementBase import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.SourceLocation
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir.util
import java.util.*
class PairListImpl<T>(val first: T, val second: T) : AbstractList<T>() {
override val size: Int get() = 2
override fun get(index: Int): T =
when (index) {
0 -> first
1 -> second
else -> throw IndexOutOfBoundsException(index.toString())
}
}
fun <T> pairList(first: T, second: T): List<T> =
PairListImpl(first, second)
@@ -30,7 +30,7 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
"??? ${element.javaClass.simpleName}" "??? ${element.javaClass.simpleName}"
override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): String = override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): String =
"??? ${declaration.javaClass.simpleName} ${declaration.descriptor.name}" "??? ${declaration.javaClass.simpleName} ${declaration.descriptor?.name}"
override fun visitFile(declaration: IrFile, data: Nothing?): String = override fun visitFile(declaration: IrFile, data: Nothing?): String =
"IrFile ${declaration.name}" "IrFile ${declaration.name}"
@@ -39,13 +39,13 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
"IrFunction ${declaration.renderDescriptor()}" "IrFunction ${declaration.renderDescriptor()}"
override fun visitProperty(declaration: IrProperty, data: Nothing?): String = override fun visitProperty(declaration: IrProperty, data: Nothing?): String =
"IrProperty ${declaration.renderDescriptor()}" "IrProperty ${declaration.renderDescriptor()} getter=${declaration.getter?.name()} setter=${declaration.setter?.name()}"
override fun visitPropertyGetter(declaration: IrPropertyGetter, data: Nothing?): String = override fun visitPropertyGetter(declaration: IrPropertyGetter, data: Nothing?): String =
"IrPropertyGetter ${declaration.renderDescriptor()}" "IrPropertyGetter ${declaration.renderDescriptor()} property=${declaration.property?.name()}"
override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?): String = override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?): String =
"IrPropertySetter ${declaration.renderDescriptor()}" "IrPropertySetter ${declaration.renderDescriptor()} property=${declaration.property?.name()}"
override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String = override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String =
"IrExpressionBody" "IrExpressionBody"
@@ -72,7 +72,8 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
modifiers = DescriptorRendererModifier.ALL modifiers = DescriptorRendererModifier.ALL
} }
private fun IrDeclaration.renderDescriptor(): String = DESCRIPTOR_RENDERER.render(descriptor) private fun IrDeclaration.name(): String = descriptor?.let { it.name.toString() } ?: "<none>"
private fun IrDeclaration.renderDescriptor(): String = descriptor?.let { DESCRIPTOR_RENDERER.render(it) } ?: "<none>"
private fun IrExpression.renderType(): String = DESCRIPTOR_RENDERER.renderType(type) private fun IrExpression.renderType(): String = DESCRIPTOR_RENDERER.renderType(type)
} }
} }
@@ -24,8 +24,8 @@ interface IrElementVisitor<out R, in D> {
fun visitElement(element: IrElement, data: D): R fun visitElement(element: IrElement, data: D): R
fun visitDeclaration(declaration: IrDeclaration, data: D): R = visitElement(declaration, data) fun visitDeclaration(declaration: IrDeclaration, data: D): R = visitElement(declaration, data)
fun visitModule(declaration: IrModule, data: D): R = visitDeclaration(declaration, data)
fun visitCompoundDeclaration(declaration: IrCompoundDeclaration, data: D): R = visitDeclaration(declaration, data) fun visitCompoundDeclaration(declaration: IrCompoundDeclaration, data: D): R = visitDeclaration(declaration, data)
fun visitModule(declaration: IrModule, data: D): R = visitCompoundDeclaration(declaration, data)
fun visitFile(declaration: IrFile, data: D): R = visitCompoundDeclaration(declaration, data) fun visitFile(declaration: IrFile, data: D): R = visitCompoundDeclaration(declaration, data)
fun visitClass(declaration: IrClass, data: D): R = visitCompoundDeclaration(declaration, data) fun visitClass(declaration: IrClass, data: D): R = visitCompoundDeclaration(declaration, data)
fun visitFunction(declaration: IrFunction, data: D): R = visitDeclaration(declaration, data) fun visitFunction(declaration: IrFunction, data: D): R = visitDeclaration(declaration, data)
+15 -15
View File
@@ -4,24 +4,24 @@ IrFile /smoke.kt
IrBlockExpression type=kotlin.Nothing IrBlockExpression type=kotlin.Nothing
IrReturnExpression type=kotlin.Nothing IrReturnExpression type=kotlin.Nothing
IrLiteral String type=kotlin.String value='OK' IrLiteral String type=kotlin.String value='OK'
IrProperty public val testSimpleVal: kotlin.Int = 1 IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
IrExpressionBody IrExpressionBody
IrReturnExpression type=kotlin.Int IrReturnExpression type=kotlin.Int
IrLiteral Int type=kotlin.Int value='1' IrLiteral Int type=kotlin.Int value='1'
IrProperty public val testValWithGetter: kotlin.Int IrProperty public val testValWithGetter: kotlin.Int getter=<get-testValWithGetter> setter=null
IrPropertyGetter public fun <get-testValWithGetter>(): kotlin.Int IrPropertyGetter public fun <get-testValWithGetter>(): kotlin.Int property=testValWithGetter
IrExpressionBody IrExpressionBody
IrReturnExpression type=kotlin.Int IrReturnExpression type=kotlin.Int
IrLiteral Int type=kotlin.Int value='42' IrLiteral Int type=kotlin.Int value='42'
IrProperty public var testSimpleVar: kotlin.Int IrProperty public var testSimpleVar: kotlin.Int getter=null setter=null
IrExpressionBody IrExpressionBody
IrReturnExpression type=kotlin.Int IrReturnExpression type=kotlin.Int
IrLiteral Int type=kotlin.Int value='2' IrLiteral Int type=kotlin.Int value='2'
IrProperty public var testVarWithAccessors: kotlin.Int IrProperty public var testVarWithAccessors: kotlin.Int getter=<get-testVarWithAccessors> setter=<set-testVarWithAccessors>
IrPropertyGetter public fun <get-testVarWithAccessors>(): kotlin.Int IrPropertyGetter public fun <get-testVarWithAccessors>(): kotlin.Int property=testVarWithAccessors
IrExpressionBody IrExpressionBody
IrReturnExpression type=kotlin.Int IrReturnExpression type=kotlin.Int
IrLiteral Int type=kotlin.Int value='42' IrLiteral Int type=kotlin.Int value='42'
IrPropertySetter public fun <set-testVarWithAccessors>(/*0*/ v: kotlin.Int): kotlin.Unit IrPropertySetter public fun <set-testVarWithAccessors>(/*0*/ v: kotlin.Int): kotlin.Unit property=testVarWithAccessors
IrExpressionBody IrExpressionBody
IrBlockExpression type=kotlin.Unit IrBlockExpression type=kotlin.Unit