diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt index aba30a53843..1b5eb9a0317 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor 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.psi.* import org.jetbrains.kotlin.resolve.BindingContext @@ -33,21 +35,23 @@ abstract class IrDeclarationGeneratorBase( override val context: IrGeneratorContext, override val irDeclaration: IrDeclaration, override val parent: IrDeclarationGenerator, - val containingFile: PsiSourceManager.PsiFileEntry + val fileElementFactory: IrFileElementFactory ) : IrDeclarationGenerator { - val irExpressionGenerator = IrExpressionGenerator(context, containingFile) + val irExpressionGenerator = IrExpressionGenerator(context, fileElementFactory) + + val containingDeclaration: IrCompoundDeclaration get() = fileElementFactory.containingDeclaration fun generateAnnotationEntries(annotationEntries: List) { // TODO create IrAnnotation's for each KtAnnotationEntry } - fun generateMemberDeclaration(ktDeclaration: KtDeclaration, containingDeclaration: IrCompoundDeclarationBase) { + fun generateMemberDeclaration(ktDeclaration: KtDeclaration) { // TODO visitor? when (ktDeclaration) { is KtNamedFunction -> - generateFunctionDeclaration(ktDeclaration, containingDeclaration) + generateFunctionDeclaration(ktDeclaration) is KtProperty -> - generatePropertyDeclaration(ktDeclaration, containingDeclaration) + generatePropertyDeclaration(ktDeclaration) is KtClassOrObject -> TODO("classOrObject") is KtTypeAlias -> @@ -55,61 +59,47 @@ abstract class IrDeclarationGeneratorBase( } } - private fun loc(ktElement: KtElement) = containingFile.getSourceLocationForElement(ktElement) - - fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction, containingDeclaration: IrCompoundDeclarationBase) { - val sourceLocation = loc(ktNamedFunction) + fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction) { val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) { "unresolved fun" } val body = generateExpressionBody(ktNamedFunction.bodyExpression ?: TODO("function without body expression")) - val irFunction = IrFunctionImpl(sourceLocation, functionDescriptor, body).apply { parent = containingDeclaration } - containingDeclaration.childDeclarations.add(irFunction) + fileElementFactory.createFunction(ktNamedFunction, functionDescriptor, body) } - fun generatePropertyDeclaration(ktProperty: KtProperty, containingDeclaration: IrCompoundDeclarationBase) { - val sourceLocation = loc(ktProperty) - val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) { "unresolved property" } - val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?") + fun generatePropertyDeclaration(ktProperty: KtProperty) { + val propertyDescriptor = getPropertyDescriptor(ktProperty) if (ktProperty.hasDelegate()) TODO("handle delegated property") val initializer = ktProperty.initializer?.let { generateExpressionBody(it) } - val irProperty = IrSimplePropertyImpl(sourceLocation, propertyDescriptor, initializer) - val irGetter: IrPropertyGetter? = ktProperty.getter?.let { ktGetter -> - val getterLocation = loc(ktGetter) + val irProperty = fileElementFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer) + ktProperty.getter?.let { ktGetter -> val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) { "unresolved getter" } val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?") val getterBody = generateExpressionBody(ktGetter.bodyExpression ?: TODO("default getter")) - IrPropertyGetterImpl(getterLocation, getterDescriptor, getterBody).apply { - parent = irProperty - getterBody.parent = this - } + fileElementFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody) } - val irSetter: IrPropertySetter? = ktProperty.setter?.let { ktSetter -> - val getterLocation = loc(ktSetter) + ktProperty.setter?.let { ktSetter -> val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) { "unresolved setter" } val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?") val setterBody = generateExpressionBody(ktSetter.bodyExpression ?: TODO("default setter")) - IrPropertySetterImpl(getterLocation, setterDescriptor, setterBody).apply { - parent = irProperty - setterBody.parent = this - } + fileElementFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody) } - irProperty.apply { - parent = containingDeclaration - getter = irGetter - setter = irSetter - } - containingDeclaration.childDeclarations.add(irProperty) + } + + private fun getPropertyDescriptor(ktProperty: KtProperty): PropertyDescriptor { + val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) { "unresolved property" } + val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?") + return propertyDescriptor } fun generateExpressionBody(ktBody: KtExpression): IrBodyBase { - val sourceLocation = loc(ktBody) + val sourceLocation = fileElementFactory.getLocationInFile(ktBody) val irExpression = irExpressionGenerator.generateExpression(ktBody) + val bodyExpression = if (ktBody is KtBlockExpression) irExpression else - IrReturnExpressionImpl(sourceLocation, irExpression.type, irExpression).apply { - irExpression.parent = this - } + IrReturnExpressionImpl(sourceLocation, irExpression.type, irExpression).apply { irExpression.parent = this } + return IrExpressionBodyImpl(sourceLocation,bodyExpression) } } \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrElementFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrElementFactory.kt deleted file mode 100644 index fd0154749ad..00000000000 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrElementFactory.kt +++ /dev/null @@ -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() - - 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 - } -} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt index 49c61c269d8..d16ae400bd1 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt @@ -24,12 +24,12 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat class IrExpressionGenerator( override val context: IrGeneratorContext, - val containingFile: PsiSourceManager.PsiFileEntry + val fileElementFactory: IrFileElementFactory ) : KtVisitor(), IrGenerator { fun generateExpression(ktExpression: KtExpression) = ktExpression.irExpr() 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") override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpressionBase = diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileElementFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileElementFactory.kt new file mode 100644 index 00000000000..f33476ceab6 --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileElementFactory.kt @@ -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.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) + } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt index 73a05c05e0f..ef24bea6170 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt @@ -20,16 +20,17 @@ import org.jetbrains.kotlin.ir.declarations.IrFileImpl import org.jetbrains.kotlin.psi.KtFile class IrFileGenerator( + private val ktFile: KtFile, context: IrGeneratorContext, - val ktFile: KtFile, - override val irDeclaration: IrFileImpl, - override val parent: IrModuleGenerator -) : IrDeclarationGeneratorBase(context, irDeclaration, parent, irDeclaration.fileEntry as PsiSourceManager.PsiFileEntry) { + irDeclaration: IrFileImpl, + parent: IrModuleGenerator, + fileFileElementFactory: IrFileElementFactory +) : IrDeclarationGeneratorBase(context, irDeclaration, parent, fileFileElementFactory) { fun generateFileContent() { generateAnnotationEntries(ktFile.annotationEntries) for (topLevelDeclaration in ktFile.declarations) { - generateMemberDeclaration(topLevelDeclaration, irDeclaration) + generateMemberDeclaration(topLevelDeclaration) } } } \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt index 354f302a951..f376ce89a54 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt @@ -31,6 +31,5 @@ class IrGeneratorContext( val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns val sourceManager = PsiSourceManager() - val irElementFactory = IrElementFactory(irModule, sourceManager) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt index 2196ef3ea12..b4a598ac85c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.psi2ir import org.jetbrains.kotlin.ir.declarations.IrModule -import org.jetbrains.kotlin.ir.declarations.IrModuleImpl import org.jetbrains.kotlin.resolve.BindingContext class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator { @@ -27,9 +26,10 @@ class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclaratio fun generateModuleContent() { for (ktFile in context.inputFiles) { val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) { "no package fragment for file" } - val irFile = context.irElementFactory.createIrFile(ktFile, packageFragmentDescriptor) - context.irModule.files.add(irFile) - val generator = IrFileGenerator(context, ktFile, irFile, this) + val irFileElementFactory = IrFileElementFactory.create(context.irModule, context.sourceManager, ktFile, packageFragmentDescriptor) + val irFile = irFileElementFactory.irFileImpl + context.irModule.addFile(irFile) + val generator = IrFileGenerator(ktFile, context, irFile, this, irFileElementFactory) generator.generateFileContent() } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt index 30886f5fda7..2ac4fbf76a3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt @@ -19,8 +19,9 @@ package org.jetbrains.kotlin.ir import org.jetbrains.kotlin.ir.visitors.IrElementVisitor interface IrElement { - val parent: IrElement? val sourceLocation: SourceLocation + val parent: IrElement? + fun accept(visitor: IrElementVisitor, data: D): R fun acceptChildren(visitor: IrElementVisitor, data: D): Unit } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt index bd60bbcda01..7b400358e63 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt @@ -20,15 +20,22 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -interface IrClass : IrCompoundDeclaration { +interface IrClass : IrCompoundDeclaration, IrMemberDeclaration { override val descriptor: ClassDescriptor } class IrClassImpl( sourceLocation: SourceLocation, + kind: IrDeclarationKind, 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 accept(visitor: IrElementVisitor, data: D): R = visitor.visitClass(this, data) } - diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrCompoundDeclaration.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrCompoundDeclaration.kt new file mode 100644 index 00000000000..de0c6e32aab --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrCompoundDeclaration.kt @@ -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 acceptChildDeclarations(visitor: IrElementVisitor, 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 = ArrayList() + + override fun getChildDeclaration(index: Int): IrMemberDeclaration? = + childDeclarations.getOrNull(index) + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + acceptChildDeclarations(visitor, data) + } + + override fun acceptChildDeclarations(visitor: IrElementVisitor, 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" } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt index 982008b38f6..ffd95257b87 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt @@ -17,41 +17,34 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElementBase -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import java.util.* +import org.jetbrains.kotlin.ir.SourceLocation interface IrDeclaration : IrElement { - val descriptor: DeclarationDescriptor - override val parent: IrDeclaration? -} + override val parent: IrCompoundDeclaration? + val index: Int -interface IrCompoundDeclaration : IrDeclaration { - val childDeclarations: List -} + val descriptor: DeclarationDescriptor? + val kind: IrDeclarationKind -interface IrDeclarationNonRoot : IrDeclaration { - override val parent: IrDeclaration -} - -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 = ArrayList() - - override fun acceptChildren(visitor: IrElementVisitor, data: D) { - childDeclarations.forEach { it.accept(visitor, data) } + companion object { + const val DETACHED_INDEX = Int.MIN_VALUE } } +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? get() = parent -val IrDeclarationNonRoot.continingDeclaration: IrDeclaration - get() = parent diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt index e5ed3264b8e..2f04ef242af 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt @@ -18,21 +18,21 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.ir.SourceLocation -import org.jetbrains.kotlin.ir.SourceLocationManager import org.jetbrains.kotlin.ir.visitors.IrElementVisitor interface IrFile : IrCompoundDeclaration { val name: String - val fileEntry: SourceLocationManager.FileEntry override val descriptor: PackageFragmentDescriptor } class IrFileImpl( sourceLocation: SourceLocation, + val module: IrModule, override val name: String, - override val fileEntry: SourceLocationManager.FileEntry, override val descriptor: PackageFragmentDescriptor -) : IrCompoundDeclarationBase(sourceLocation), IrFile { +) : IrCompoundDeclarationBase(sourceLocation, IrDeclarationKind.DEFINED), IrFile { + override val parent: IrCompoundDeclaration? = null + override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitFile(this, data) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt index bf2e3fa76f1..70d74459fce 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt @@ -18,26 +18,37 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -interface IrFunction : IrDeclarationNonRoot { +interface IrFunction : IrMemberDeclaration { override val descriptor: FunctionDescriptor 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 acceptChildren(visitor: IrElementVisitor, data: D) { + super.acceptChildDeclarations(visitor, data) body.accept(visitor, data) } } class IrFunctionImpl( sourceLocation: SourceLocation, + kind: IrDeclarationKind, override val descriptor: FunctionDescriptor, override val body: IrBody -) : IrFunctionBase(sourceLocation) { - override lateinit var parent: IrDeclaration - +) : IrFunctionBase(sourceLocation, kind) { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitFunction(this, data) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModule.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModule.kt index 3f2adb1eb15..c53431307d3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModule.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModule.kt @@ -17,19 +17,33 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.NO_LOCATION import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* -interface IrModule : IrCompoundDeclaration { +interface IrModule : IrDeclaration { override val descriptor: ModuleDescriptor val files: List + + 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 = ArrayList() - override val childDeclarations: List get() = files + + override fun addFile(file: IrFile) { + files.add(file) + } override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitModule(this, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt index d70c4a07bfc..a03bdf33aa4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt @@ -18,12 +18,15 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -interface IrProperty : IrDeclarationNonRoot { +interface IrProperty : IrMemberDeclaration { override val descriptor: PropertyDescriptor - val getter: IrPropertyGetter? - val setter: IrPropertySetter? + var getter: IrPropertyGetter? + var setter: IrPropertySetter? + + fun acceptAccessors(visitor: IrElementVisitor, data: D) } interface IrSimpleProperty : IrProperty { @@ -34,49 +37,61 @@ interface IrDelegatedProperty : IrProperty { val delegateInitializer: IrBody } +// TODO synchronization? abstract class IrPropertyBase( sourceLocation: SourceLocation, + kind: IrDeclarationKind, override val descriptor: PropertyDescriptor -) : IrDeclarationNonRootBase(sourceLocation), IrProperty { - override lateinit var parent: IrDeclaration - override var getter: IrPropertyGetter? = null - override var setter: IrPropertySetter? = null +) : IrDeclarationBase(sourceLocation, kind), IrProperty { + override var parent: IrCompoundDeclaration? = null - override fun acceptChildren(visitor: IrElementVisitor, data: D) { - getter?.accept(visitor, data) - setter?.accept(visitor, data) + override fun setTreeLocation(parent: IrCompoundDeclaration?, index: Int) { + this.parent = parent + this.index = index } - fun initialize(getter: IrPropertyGetter?, setter: IrPropertySetter?) { - this.getter = getter - this.setter = setter + override var getter: IrPropertyGetter? = null + set(newGetter) { + newGetter?.property = this + field = newGetter + } + + override var setter: IrPropertySetter? = null + set(newSetter) { + newSetter?.property = this + field = newSetter + } + + override fun acceptAccessors(visitor: IrElementVisitor, data: D) { + getter?.accept(visitor, data) + setter?.accept(visitor, data) } } class IrSimplePropertyImpl( sourceLocation: SourceLocation, + kind: IrDeclarationKind, descriptor: PropertyDescriptor, override val valueInitializer: IrBody? -) : IrPropertyBase(sourceLocation, descriptor), IrSimpleProperty { +) : IrPropertyBase(sourceLocation, kind, descriptor), IrSimpleProperty { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitSimpleProperty(this, data) override fun acceptChildren(visitor: IrElementVisitor, data: D) { valueInitializer?.accept(visitor, data) - super.acceptChildren(visitor, data) } } class IrDelegatedPropertyImpl( sourceLocation: SourceLocation, + kind: IrDeclarationKind, descriptor: PropertyDescriptor, override val delegateInitializer: IrBody -) : IrPropertyBase(sourceLocation, descriptor), IrDelegatedProperty { +) : IrPropertyBase(sourceLocation, kind, descriptor), IrDelegatedProperty { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitDelegatedProperty(this, data) override fun acceptChildren(visitor: IrElementVisitor, data: D) { delegateInitializer.accept(visitor, data) - super.acceptChildren(visitor, data) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt index 64bae584981..40c8f746c99 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt @@ -20,11 +20,12 @@ import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.visitors.IrElementVisitor interface IrPropertyAccessor : IrFunction { override val descriptor: PropertyAccessorDescriptor - override val parent: IrProperty + var property: IrProperty? } interface IrPropertyGetter : IrPropertyAccessor { @@ -37,25 +38,28 @@ interface IrPropertySetter : IrPropertyAccessor { abstract class IrPropertyAccessorBase( sourceLocation: SourceLocation, + kind: IrDeclarationKind, override val body: IrBody -) : IrFunctionBase(sourceLocation), IrPropertyAccessor { - override lateinit var parent: IrProperty +) : IrFunctionBase(sourceLocation, kind), IrPropertyAccessor { + override var property: IrProperty? = null } class IrPropertyGetterImpl( sourceLocation: SourceLocation, + kind: IrDeclarationKind, override val descriptor: PropertyGetterDescriptor, body: IrBody -) : IrPropertyAccessorBase(sourceLocation, body), IrPropertyGetter { +) : IrPropertyAccessorBase(sourceLocation, kind, body), IrPropertyGetter { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitPropertyGetter(this, data) } class IrPropertySetterImpl( sourceLocation: SourceLocation, + kind: IrDeclarationKind, override val descriptor: PropertySetterDescriptor, body: IrBody -) : IrPropertyAccessorBase(sourceLocation, body), IrPropertySetter { +) : IrPropertyAccessorBase(sourceLocation, kind, body), IrPropertySetter { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitPropertySetter(this, data) } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrBody.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt similarity index 93% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrBody.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt index 80807acd428..924c528c875 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrBody.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt @@ -14,11 +14,12 @@ * 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.IrElementBase 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.visitors.IrElementVisitor diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/PairList.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/PairList.kt new file mode 100644 index 00000000000..923ff32824e --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/PairList.kt @@ -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(val first: T, val second: T) : AbstractList() { + override val size: Int get() = 2 + + override fun get(index: Int): T = + when (index) { + 0 -> first + 1 -> second + else -> throw IndexOutOfBoundsException(index.toString()) + } +} + +fun pairList(first: T, second: T): List = + PairListImpl(first, second) \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index a4f48213b06..5136717c75c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -30,7 +30,7 @@ class RenderIrElementVisitor : IrElementVisitor { "??? ${element.javaClass.simpleName}" 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 = "IrFile ${declaration.name}" @@ -39,13 +39,13 @@ class RenderIrElementVisitor : IrElementVisitor { "IrFunction ${declaration.renderDescriptor()}" 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 = - "IrPropertyGetter ${declaration.renderDescriptor()}" + "IrPropertyGetter ${declaration.renderDescriptor()} property=${declaration.property?.name()}" 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 = "IrExpressionBody" @@ -72,7 +72,8 @@ class RenderIrElementVisitor : IrElementVisitor { modifiers = DescriptorRendererModifier.ALL } - private fun IrDeclaration.renderDescriptor(): String = DESCRIPTOR_RENDERER.render(descriptor) + private fun IrDeclaration.name(): String = descriptor?.let { it.name.toString() } ?: "" + private fun IrDeclaration.renderDescriptor(): String = descriptor?.let { DESCRIPTOR_RENDERER.render(it) } ?: "" private fun IrExpression.renderType(): String = DESCRIPTOR_RENDERER.renderType(type) } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt index 87fa4f04617..28f3472e0dd 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt @@ -24,8 +24,8 @@ interface IrElementVisitor { fun visitElement(element: IrElement, data: D): R 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 visitModule(declaration: IrModule, 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 visitFunction(declaration: IrFunction, data: D): R = visitDeclaration(declaration, data) diff --git a/compiler/testData/ir/irText/smoke.txt b/compiler/testData/ir/irText/smoke.txt index ad3a0e026e7..3274804b7e3 100644 --- a/compiler/testData/ir/irText/smoke.txt +++ b/compiler/testData/ir/irText/smoke.txt @@ -4,24 +4,24 @@ IrFile /smoke.kt IrBlockExpression type=kotlin.Nothing IrReturnExpression type=kotlin.Nothing 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 IrReturnExpression type=kotlin.Int IrLiteral Int type=kotlin.Int value='1' - IrProperty public val testValWithGetter: kotlin.Int - IrPropertyGetter public fun (): kotlin.Int - IrExpressionBody - IrReturnExpression type=kotlin.Int - IrLiteral Int type=kotlin.Int value='42' - IrProperty public var testSimpleVar: kotlin.Int + IrProperty public val testValWithGetter: kotlin.Int getter= setter=null + IrPropertyGetter public fun (): kotlin.Int property=testValWithGetter + IrExpressionBody + IrReturnExpression type=kotlin.Int + IrLiteral Int type=kotlin.Int value='42' + IrProperty public var testSimpleVar: kotlin.Int getter=null setter=null IrExpressionBody IrReturnExpression type=kotlin.Int IrLiteral Int type=kotlin.Int value='2' - IrProperty public var testVarWithAccessors: kotlin.Int - IrPropertyGetter public fun (): kotlin.Int - IrExpressionBody - IrReturnExpression type=kotlin.Int - IrLiteral Int type=kotlin.Int value='42' - IrPropertySetter public fun (/*0*/ v: kotlin.Int): kotlin.Unit - IrExpressionBody - IrBlockExpression type=kotlin.Unit + IrProperty public var testVarWithAccessors: kotlin.Int getter= setter= + IrPropertyGetter public fun (): kotlin.Int property=testVarWithAccessors + IrExpressionBody + IrReturnExpression type=kotlin.Int + IrLiteral Int type=kotlin.Int value='42' + IrPropertySetter public fun (/*0*/ v: kotlin.Int): kotlin.Unit property=testVarWithAccessors + IrExpressionBody + IrBlockExpression type=kotlin.Unit