diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/PsiSourceManager.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/PsiSourceManager.kt index 19c62636ab7..c9830670331 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/PsiSourceManager.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/PsiSourceManager.kt @@ -62,6 +62,8 @@ class PsiSourceManager : SourceManager { fun getRecognizableName(): String = psiFileName + override val name: String get() = getRecognizableName() + override fun toString(): String = getRecognizableName() } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt index 81a46eb1cf1..14e481f5313 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt @@ -47,8 +47,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator { fun createEmptyIrFile(ktFile: KtFile): IrFileImpl { val fileEntry = context.sourceManager.getOrCreateFileEntry(ktFile) val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) - val fileName = fileEntry.getRecognizableName() - val irFile = IrFileImpl(fileEntry, fileName, packageFragmentDescriptor) + val irFile = IrFileImpl(fileEntry, packageFragmentDescriptor) context.sourceManager.putFileEntry(irFile, fileEntry) return irFile } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/SourceManager.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/SourceManager.kt index 8130953dfb3..ca2d17c5899 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/SourceManager.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/SourceManager.kt @@ -32,6 +32,7 @@ data class SourceRangeInfo( interface SourceManager { interface FileEntry { + val name: String val maxOffset: Int fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo fun getLineNumber(offset: Int): Int 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 b86760c944b..e33d5a0e950 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 @@ -18,17 +18,24 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.ClassDescriptor -interface IrClass : IrDeclaration { +interface IrClass : IrDeclaration, IrDeclarationContainer { override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.CLASS override val descriptor: ClassDescriptor - val members: List + interface Builder : IrDeclarationContainer.Builder { + val startOffset: Int + val endOffset: Int + var origin: IrDeclarationOrigin + val descriptor: ClassDescriptor + + override fun build(): IrClass + } } fun IrClass.getInstanceInitializerMembers() = - members.filter { + declarations.filter { when (it) { is IrAnonymousInitializer -> true diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt new file mode 100644 index 00000000000..da992d1b3b9 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt @@ -0,0 +1,29 @@ +/* + * 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 + +interface IrDeclarationContainer { + val declarations: List + + fun toBuilder(): Builder + + interface Builder { + val declarations: MutableList + + fun build(): IrDeclarationContainer + } +} \ No newline at end of file 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 cd1a91df20a..80d6c8d7913 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 @@ -21,11 +21,20 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.SourceManager -interface IrFile : IrElement { - val name: String +interface IrFile : IrElement, IrDeclarationContainer { val fileEntry: SourceManager.FileEntry val fileAnnotations: List val packageFragmentDescriptor: PackageFragmentDescriptor - val declarations: List + + override fun toBuilder(): Builder + + interface Builder : IrDeclarationContainer.Builder { + val fileEntry: SourceManager.FileEntry + val fileAnnotations: MutableList + val packageFragmentDescriptor: PackageFragmentDescriptor + + override fun build(): IrFile + } } +val IrFile.name: String get() = fileEntry.name \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt index a38e17b8cb9..ae131b5fc9c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* @@ -30,20 +31,36 @@ class IrClassImpl( origin: IrDeclarationOrigin, override val descriptor: ClassDescriptor ) : IrDeclarationBase(startOffset, endOffset, origin), IrClass { - override val members: MutableList = ArrayList() - - fun addMember(member: IrDeclaration) { - member.setTreeLocation(this, members.size) - members.add(member) + constructor( + startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, + members: List + ) : this(startOffset, endOffset, origin, descriptor) { + addAll(members) } + override val declarations: MutableList = ArrayList() + + fun addMember(member: IrDeclaration) { + member.setTreeLocation(this, declarations.size) + declarations.add(member) + } + + fun addAll(members: List) { + val originalSize = declarations.size + declarations.addAll(members) + members.forEachIndexed { i, irDeclaration -> irDeclaration.setTreeLocation(this, originalSize + i) } + } + + override fun toBuilder(): IrDeclarationContainer.Builder = + IrClassBuilderImpl(this) + override fun getChild(slot: Int): IrElement? = - members.getOrNull(slot) + declarations.getOrNull(slot) override fun replaceChild(slot: Int, newChild: IrElement) { - members.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot) - members[slot] = newChild.assertCast() + declarations.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot) + declarations[slot] = newChild.assertCast() newChild.setTreeLocation(this, slot) } @@ -51,6 +68,20 @@ class IrClassImpl( visitor.visitClass(this, data) override fun acceptChildren(visitor: IrElementVisitor, data: D) { - members.forEach { it.accept(visitor, data) } + declarations.forEach { it.accept(visitor, data) } } +} + +class IrClassBuilderImpl( + override val startOffset: Int, + override val endOffset: Int, + override var origin: IrDeclarationOrigin, + override val descriptor: ClassDescriptor, + override val declarations: MutableList +) : IrClass.Builder { + constructor(irClass: IrClass) : this(irClass.startOffset, irClass.endOffset, irClass.origin, irClass.descriptor, + irClass.declarations.toMutableList()) + + override fun build(): IrClass = + IrClassImpl(startOffset, endOffset, origin, descriptor, declarations) } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt index b1e974821f8..327ed101f49 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt @@ -27,15 +27,26 @@ import java.util.* class IrFileImpl( override val fileEntry: SourceManager.FileEntry, - override val name: String, override val packageFragmentDescriptor: PackageFragmentDescriptor ) : IrElementBase(0, fileEntry.maxOffset), IrFile { + constructor( + fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor, + fileAnnotations: List, declarations: List + ) : this(fileEntry, packageFragmentDescriptor) { + addAllAnnotations(fileAnnotations) + addAll(declarations) + } + override val fileAnnotations: MutableList = SmartList() fun addAnnotation(annotation: AnnotationDescriptor) { fileAnnotations.add(annotation) } + fun addAllAnnotations(annotations: List) { + fileAnnotations.addAll(annotations) + } + override val declarations: MutableList = ArrayList() fun addDeclaration(declaration: IrDeclaration) { @@ -43,6 +54,14 @@ class IrFileImpl( declarations.add(declaration) } + fun addAll(newDeclarations: List) { + val originalSize = declarations.size + declarations.addAll(newDeclarations) + newDeclarations.forEachIndexed { i, irDeclaration -> + irDeclaration.setTreeLocation(this, originalSize + i) + } + } + override fun getChild(slot: Int): IrElement? = declarations.getOrNull(slot) @@ -52,6 +71,9 @@ class IrFileImpl( newChild.setTreeLocation(this, slot) } + override fun toBuilder(): IrFile.Builder = + IrFileBuilderImpl(this) + override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitFile(this, data) @@ -60,4 +82,19 @@ class IrFileImpl( } +} + +class IrFileBuilderImpl( + override val fileEntry: SourceManager.FileEntry, + override val packageFragmentDescriptor: PackageFragmentDescriptor, + override val fileAnnotations: MutableList, + override val declarations: MutableList +) : IrFile.Builder { + constructor(irFile: IrFile) : this(irFile.fileEntry, + irFile.packageFragmentDescriptor, + irFile.fileAnnotations.toMutableList(), + irFile.declarations.toMutableList()) + + override fun build(): IrFile = + IrFileImpl(fileEntry, packageFragmentDescriptor, fileAnnotations, declarations) } \ No newline at end of file