File class lowering
This commit is contained in:
committed by
Dmitry Petrov
parent
a25e781ee9
commit
5386d27284
@@ -11,5 +11,7 @@
|
|||||||
<orderEntry type="module" module-name="ir.tree" />
|
<orderEntry type="module" module-name="ir.tree" />
|
||||||
<orderEntry type="module" module-name="frontend" />
|
<orderEntry type="module" module-name="frontend" />
|
||||||
<orderEntry type="module" module-name="backend" />
|
<orderEntry type="module" module-name="backend" />
|
||||||
|
<orderEntry type="module" module-name="ir.psi2ir" />
|
||||||
|
<orderEntry type="module" module-name="frontend.java" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
|
import java.lang.AssertionError
|
||||||
|
|
||||||
|
class JvmBackend(context: JvmBackendContext) {
|
||||||
|
private val lower = JvmLower(context)
|
||||||
|
private val codegen = JvmCodegen(context)
|
||||||
|
|
||||||
|
fun generateFile(irFile: IrFile) {
|
||||||
|
val loweredFile = lower.lower(irFile)
|
||||||
|
|
||||||
|
for (loweredClass in loweredFile.declarations) {
|
||||||
|
if (loweredClass !is IrClass) {
|
||||||
|
throw AssertionError("File-level declaration should be IrClass after JvmLower, got: " + loweredClass.render())
|
||||||
|
}
|
||||||
|
|
||||||
|
codegen.generateClass(loweredClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.JvmFileClassProvider
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
|
||||||
|
class JvmBackendContext(
|
||||||
|
val state: GenerationState,
|
||||||
|
val jvmFileClassProvider: JvmFileClassProvider
|
||||||
|
)
|
||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.JvmFileClassProvider
|
||||||
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
|
|
||||||
object JvmBackendFacade {
|
object JvmBackendFacade {
|
||||||
fun compileCorrectFiles(state: GenerationState, errorHandler: CompilationErrorHandler) {
|
fun compileCorrectFiles(state: GenerationState, errorHandler: CompilationErrorHandler) {
|
||||||
@@ -30,6 +33,33 @@ object JvmBackendFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun doGenerateFiles(files: Collection<KtFile>, state: GenerationState, errorHandler: CompilationErrorHandler) {
|
fun doGenerateFiles(files: Collection<KtFile>, state: GenerationState, errorHandler: CompilationErrorHandler) {
|
||||||
// TODO
|
// TODO multifile classes support
|
||||||
|
|
||||||
|
val psi2ir = Psi2IrTranslator()
|
||||||
|
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext)
|
||||||
|
val jvmBackendContext = createJvmBackendContext(psi2ir, state)
|
||||||
|
|
||||||
|
val jvmBackend = JvmBackend(jvmBackendContext)
|
||||||
|
|
||||||
|
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files)
|
||||||
|
|
||||||
|
for (ktFile in irModuleFragment.files) {
|
||||||
|
try {
|
||||||
|
jvmBackend.generateFile(ktFile)
|
||||||
|
state.afterIndependentPart()
|
||||||
|
}
|
||||||
|
catch (e: Throwable) {
|
||||||
|
errorHandler.reportException(e, null) // TODO ktFile.virtualFile.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createJvmBackendContext(psi2ir: Psi2IrTranslator, state: GenerationState): JvmBackendContext {
|
||||||
|
val jvmFileClassProvider = JvmFileClassProvider()
|
||||||
|
psi2ir.add(jvmFileClassProvider)
|
||||||
|
|
||||||
|
val jvmBackendContext = JvmBackendContext(state, jvmFileClassProvider)
|
||||||
|
|
||||||
|
return jvmBackendContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
|
||||||
|
class JvmCodegen(val context: JvmBackendContext) {
|
||||||
|
fun generateClass(irClass: IrClass) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.FileClassLowering
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
|
||||||
|
class JvmLower(val context: JvmBackendContext) {
|
||||||
|
fun lower(irFile: IrFile): IrFile {
|
||||||
|
var newIrFile = irFile
|
||||||
|
|
||||||
|
newIrFile = FileClassLowering(context).lower(newIrFile)
|
||||||
|
|
||||||
|
return newIrFile
|
||||||
|
}
|
||||||
|
}
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.jvm.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
import org.jetbrains.kotlin.types.*
|
||||||
|
|
||||||
|
interface FileClassDescriptor : ClassDescriptor
|
||||||
|
|
||||||
|
class FileClassDescriptorImpl(
|
||||||
|
private val nameImpl: Name,
|
||||||
|
private val containingDeclarationImpl: PackageFragmentDescriptor,
|
||||||
|
private val sourceElement: SourceElement
|
||||||
|
) : FileClassDescriptor {
|
||||||
|
override fun getCompanionObjectDescriptor(): ClassDescriptor? = null
|
||||||
|
override fun getConstructors(): Collection<ConstructorDescriptor> = emptyList()
|
||||||
|
override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclarationImpl
|
||||||
|
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = emptyList()
|
||||||
|
override fun getDefaultType(): SimpleType = ErrorUtils.createErrorType("File class type for $nameImpl")
|
||||||
|
override fun getKind(): ClassKind = ClassKind.CLASS
|
||||||
|
override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope = error("File class has no member scope")
|
||||||
|
override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = error("File class has no member scope")
|
||||||
|
override fun getModality(): Modality = Modality.FINAL
|
||||||
|
override fun getOriginal(): ClassDescriptor = this
|
||||||
|
override fun getName(): Name = nameImpl
|
||||||
|
override fun getStaticScope(): MemberScope = error("File class has no static scope")
|
||||||
|
override fun getThisAsReceiverParameter(): ReceiverParameterDescriptor = error("File class has no instances")
|
||||||
|
override fun getUnsubstitutedInnerClassesScope(): MemberScope = error("File class has no inner classes scope")
|
||||||
|
override fun getUnsubstitutedMemberScope(): MemberScope = error("File class has no member scope")
|
||||||
|
override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = null
|
||||||
|
override fun getVisibility(): Visibility = Visibilities.PUBLIC
|
||||||
|
override fun isCompanionObject(): Boolean = false
|
||||||
|
override fun isData(): Boolean = false
|
||||||
|
override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor = error("File class can't be substituted")
|
||||||
|
override fun getSource(): SourceElement = sourceElement
|
||||||
|
override fun getTypeConstructor(): TypeConstructor = error("File class can't be used in types")
|
||||||
|
override fun isInner(): Boolean = false
|
||||||
|
|
||||||
|
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
|
||||||
|
return visitor.visitClassDescriptor(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>) {
|
||||||
|
visitor.visitClassDescriptor(this, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val annotations: Annotations
|
||||||
|
get() = TODO("not implemented")
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"IrFileClassDescriptor($fqNameUnsafe)"
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.jvm.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class FileClassLowering(val context: JvmBackendContext) {
|
||||||
|
fun lower(irFile: IrFile): IrFile {
|
||||||
|
val classes = ArrayList<IrClass>()
|
||||||
|
val fileClassMembers = ArrayList<IrDeclaration>()
|
||||||
|
|
||||||
|
irFile.declarations.forEach {
|
||||||
|
if (it is IrClass)
|
||||||
|
classes.add(it)
|
||||||
|
else
|
||||||
|
fileClassMembers.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileClassMembers.isEmpty()) return irFile
|
||||||
|
|
||||||
|
val fileClassDescriptor = context.jvmFileClassProvider.createFileClassDescriptor(irFile.fileEntry, irFile.packageFragmentDescriptor)
|
||||||
|
|
||||||
|
val irFileClass = IrClassImpl(0, irFile.fileEntry.maxOffset, IrDeclarationOrigin.DEFINED, fileClassDescriptor, fileClassMembers)
|
||||||
|
classes.add(irFileClass)
|
||||||
|
|
||||||
|
val newIrFile = irFile.toBuilder().apply { declarations.clear(); declarations.addAll(classes) }.build()
|
||||||
|
|
||||||
|
return newIrFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.jvm.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||||
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
||||||
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
|
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
|
import java.lang.AssertionError
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class JvmFileClassProvider : Psi2IrTranslator.PostprocessingStep {
|
||||||
|
override fun postprocess(context: GeneratorContext, irElement: IrElement) {
|
||||||
|
when (irElement) {
|
||||||
|
is IrModuleFragment ->
|
||||||
|
irElement.files.forEach { postprocess(context, it) }
|
||||||
|
is IrFile ->
|
||||||
|
recordFileClassInfo(context, irElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fileClassInfoByFileEntry = HashMap<SourceManager.FileEntry, JvmFileClassInfo>()
|
||||||
|
|
||||||
|
private fun recordFileClassInfo(context: GeneratorContext, irFile: IrFile) {
|
||||||
|
val jvmFileClassInfo = context.sourceManager.getFileClassInfo(irFile.fileEntry)
|
||||||
|
fileClassInfoByFileEntry[irFile.fileEntry] = jvmFileClassInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiSourceManager.getKtFile(fileEntry: SourceManager.FileEntry) =
|
||||||
|
getPsiFile(fileEntry as PsiSourceManager.PsiFileEntry) as KtFile
|
||||||
|
|
||||||
|
private fun PsiSourceManager.getFileClassInfo(fileEntry: SourceManager.FileEntry): JvmFileClassInfo =
|
||||||
|
JvmFileClassUtil.getFileClassInfoNoResolve(getKtFile(fileEntry))
|
||||||
|
|
||||||
|
fun createFileClassDescriptor(fileEntry: SourceManager.FileEntry, packageFragment: PackageFragmentDescriptor): FileClassDescriptor {
|
||||||
|
val fileClassInfo = fileClassInfoByFileEntry[fileEntry] ?: throw AssertionError("No file class info for ${fileEntry.name})")
|
||||||
|
return FileClassDescriptorImpl(fileClassInfo.fileClassFqName.shortName(), packageFragment, SourceElement.NO_SOURCE)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,5 +17,5 @@
|
|||||||
package org.jetbrains.kotlin.psi2ir
|
package org.jetbrains.kotlin.psi2ir
|
||||||
|
|
||||||
class Psi2IrConfiguration(
|
class Psi2IrConfiguration(
|
||||||
val ignoreErrors: Boolean
|
val ignoreErrors: Boolean = false
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir
|
package org.jetbrains.kotlin.psi2ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
@@ -25,23 +24,36 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
|||||||
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
|
import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
class Psi2IrTranslator(val configuration: Psi2IrConfiguration) {
|
class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfiguration()) {
|
||||||
fun generateModule(moduleDescriptor: ModuleDescriptor, ktFiles: List<KtFile>, bindingContext: BindingContext): IrModuleFragment {
|
interface PostprocessingStep {
|
||||||
val context = GeneratorContext(configuration, moduleDescriptor, bindingContext)
|
fun postprocess(context: GeneratorContext, irElement: IrElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val postprocessingSteps = SmartList<PostprocessingStep>()
|
||||||
|
|
||||||
|
fun add(step: PostprocessingStep) {
|
||||||
|
postprocessingSteps.add(step)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateModule(moduleDescriptor: ModuleDescriptor, ktFiles: Collection<KtFile>, bindingContext: BindingContext): IrModuleFragment {
|
||||||
|
val context = createGeneratorContext(moduleDescriptor, bindingContext)
|
||||||
|
return generateModuleFragment(context, ktFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createGeneratorContext(moduleDescriptor: ModuleDescriptor, bindingContext: BindingContext) =
|
||||||
|
GeneratorContext(configuration, moduleDescriptor, bindingContext)
|
||||||
|
|
||||||
|
fun generateModuleFragment(context: GeneratorContext, ktFiles: Collection<KtFile>): IrModuleFragment {
|
||||||
val irModule = ModuleGenerator(context).generateModuleFragment(ktFiles)
|
val irModule = ModuleGenerator(context).generateModuleFragment(ktFiles)
|
||||||
postprocess(irModule.descriptor.builtIns, irModule)
|
postprocess(context, irModule)
|
||||||
return irModule
|
return irModule
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateSingleFileFragment(moduleDescriptor: ModuleDescriptor, ktFile: KtFile, bindingContext: BindingContext): IrModuleFragment {
|
private fun postprocess(context: GeneratorContext, irElement: IrElement) {
|
||||||
val context = GeneratorContext(configuration, moduleDescriptor, bindingContext)
|
insertImplicitCasts(context.builtIns, irElement)
|
||||||
val irFileFragment = ModuleGenerator(context).generateSingleFileFragment(ktFile)
|
|
||||||
postprocess(moduleDescriptor.builtIns, irFileFragment)
|
|
||||||
return irFileFragment
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun postprocess(builtIns: KotlinBuiltIns, irElement: IrElement) {
|
postprocessingSteps.forEach { it.postprocess(context, irElement) }
|
||||||
insertImplicitCasts(builtIns, irElement)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,11 +69,13 @@ class PsiSourceManager : SourceManager {
|
|||||||
|
|
||||||
private val fileEntriesByPsiFile = HashMap<PsiFile, PsiFileEntry>()
|
private val fileEntriesByPsiFile = HashMap<PsiFile, PsiFileEntry>()
|
||||||
private val fileEntriesByIrFile = HashMap<IrFile, PsiFileEntry>()
|
private val fileEntriesByIrFile = HashMap<IrFile, PsiFileEntry>()
|
||||||
|
private val psiFileByFileEntry = HashMap<PsiFileEntry, PsiFile>()
|
||||||
|
|
||||||
fun createFileEntry(psiFile: PsiFile): PsiFileEntry {
|
fun createFileEntry(psiFile: PsiFile): PsiFileEntry {
|
||||||
if (psiFile in fileEntriesByPsiFile) error("PsiFileEntry is already created for $psiFile")
|
if (psiFile in fileEntriesByPsiFile) error("PsiFileEntry is already created for $psiFile")
|
||||||
val newEntry = PsiFileEntry(psiFile)
|
val newEntry = PsiFileEntry(psiFile)
|
||||||
fileEntriesByPsiFile[psiFile] = newEntry
|
fileEntriesByPsiFile[psiFile] = newEntry
|
||||||
|
psiFileByFileEntry[newEntry] = psiFile
|
||||||
return newEntry
|
return newEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +89,9 @@ class PsiSourceManager : SourceManager {
|
|||||||
fun getFileEntry(psiFile: PsiFile): PsiFileEntry? =
|
fun getFileEntry(psiFile: PsiFile): PsiFileEntry? =
|
||||||
fileEntriesByPsiFile[psiFile]
|
fileEntriesByPsiFile[psiFile]
|
||||||
|
|
||||||
|
fun getPsiFile(fileEntry: PsiFileEntry) =
|
||||||
|
psiFileByFileEntry[fileEntry]
|
||||||
|
|
||||||
override fun getFileEntry(irFile: IrFile): SourceManager.FileEntry =
|
override fun getFileEntry(irFile: IrFile): SourceManager.FileEntry =
|
||||||
fileEntriesByIrFile[irFile]!!
|
fileEntriesByIrFile[irFile]!!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ class GeneratorContext(
|
|||||||
val bindingContext: BindingContext
|
val bindingContext: BindingContext
|
||||||
) {
|
) {
|
||||||
val sourceManager = PsiSourceManager()
|
val sourceManager = PsiSourceManager()
|
||||||
val syntheticDescriptorsFactory = SyntheticDescriptorsFactory()
|
|
||||||
|
|
||||||
val reflectionTypes = ReflectionTypes(moduleDescriptor)
|
val reflectionTypes = ReflectionTypes(moduleDescriptor)
|
||||||
val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns
|
val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ package org.jetbrains.kotlin.ir.declarations
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.checkAnnotationName
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.SourceManager
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
interface IrFile : IrElement, IrDeclarationContainer {
|
interface IrFile : IrElement, IrDeclarationContainer {
|
||||||
val fileEntry: SourceManager.FileEntry
|
val fileEntry: SourceManager.FileEntry
|
||||||
@@ -37,4 +39,7 @@ interface IrFile : IrElement, IrDeclarationContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val IrFile.name: String get() = fileEntry.name
|
val IrFile.name: String get() = fileEntry.name
|
||||||
|
|
||||||
|
fun IrFile.findAnnotationsByFqName(fqName: FqName) =
|
||||||
|
fileAnnotations.filter { checkAnnotationName(it, fqName) }
|
||||||
@@ -73,10 +73,10 @@ class IrClassImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class IrClassBuilderImpl(
|
class IrClassBuilderImpl(
|
||||||
override val startOffset: Int,
|
override var startOffset: Int,
|
||||||
override val endOffset: Int,
|
override var endOffset: Int,
|
||||||
override var origin: IrDeclarationOrigin,
|
override var origin: IrDeclarationOrigin,
|
||||||
override val descriptor: ClassDescriptor,
|
override var descriptor: ClassDescriptor,
|
||||||
override val declarations: MutableList<IrDeclaration>
|
override val declarations: MutableList<IrDeclaration>
|
||||||
) : IrClass.Builder {
|
) : IrClass.Builder {
|
||||||
constructor(irClass: IrClass) : this(irClass.startOffset, irClass.endOffset, irClass.origin, irClass.descriptor,
|
constructor(irClass: IrClass) : this(irClass.startOffset, irClass.endOffset, irClass.origin, irClass.descriptor,
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ interface Annotations : Iterable<AnnotationDescriptor> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAnnotationName(annotation: AnnotationDescriptor, fqName: FqName): Boolean {
|
fun checkAnnotationName(annotation: AnnotationDescriptor, fqName: FqName): Boolean {
|
||||||
val descriptor = annotation.type.constructor.declarationDescriptor
|
val descriptor = annotation.type.constructor.declarationDescriptor
|
||||||
return descriptor is ClassDescriptor && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
|
return descriptor is ClassDescriptor && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -520,7 +520,11 @@ public class DescriptorUtils {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getJvmName(@NotNull Annotated annotated) {
|
public static String getJvmName(@NotNull Annotated annotated) {
|
||||||
AnnotationDescriptor jvmNameAnnotation = getAnnotationByFqName(annotated.getAnnotations(), JVM_NAME);
|
return getJvmName(getJvmNameAnnotation(annotated));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getJvmName(@Nullable AnnotationDescriptor jvmNameAnnotation) {
|
||||||
if (jvmNameAnnotation == null) return null;
|
if (jvmNameAnnotation == null) return null;
|
||||||
|
|
||||||
Map<ValueParameterDescriptor, ConstantValue<?>> arguments = jvmNameAnnotation.getAllValueArguments();
|
Map<ValueParameterDescriptor, ConstantValue<?>> arguments = jvmNameAnnotation.getAllValueArguments();
|
||||||
|
|||||||
Reference in New Issue
Block a user