IR: move PsiFileEntry to ir.tree, rename to PsiIrFileEntry

This commit is contained in:
Alexander Udalov
2021-02-22 11:20:22 +01:00
parent 1f8de46b3c
commit bec4d1903b
6 changed files with 79 additions and 72 deletions
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.signaturer.FirMangler import org.jetbrains.kotlin.fir.signaturer.FirMangler
import org.jetbrains.kotlin.fir.symbols.FirBuiltinSymbols import org.jetbrains.kotlin.fir.symbols.FirBuiltinSymbols
import org.jetbrains.kotlin.ir.PsiIrFileEntry
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
@@ -29,7 +30,6 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
import org.jetbrains.kotlin.psi2ir.generators.generateTypicalIrProviderList import org.jetbrains.kotlin.psi2ir.generators.generateTypicalIrProviderList
@@ -57,7 +57,7 @@ class Fir2IrConverter(
fun registerFileAndClasses(file: FirFile): IrFile { fun registerFileAndClasses(file: FirFile): IrFile {
val irFile = IrFileImpl( val irFile = IrFileImpl(
PsiSourceManager.PsiFileEntry(file.psi as KtFile), PsiIrFileEntry(file.psi as KtFile),
moduleDescriptor.getPackage(file.packageFqName).fragments.first() moduleDescriptor.getPackage(file.packageFqName).fragments.first()
) )
declarationStorage.registerFile(file, irFile) declarationStorage.registerFile(file, irFile)
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.PsiIrFileEntry
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.builders.Scope
@@ -45,7 +46,6 @@ import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME
@@ -399,4 +399,4 @@ fun IrClass.getSingleAbstractMethod(): IrSimpleFunction? =
functions.singleOrNull { it.modality == Modality.ABSTRACT } functions.singleOrNull { it.modality == Modality.ABSTRACT }
fun IrFile.getKtFile(): KtFile? = fun IrFile.getKtFile(): KtFile? =
(fileEntry as? PsiSourceManager.PsiFileEntry)?.psiFile as KtFile? (fileEntry as? PsiIrFileEntry)?.psiFile as KtFile?
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.JvmSimpleFileClassInfo import org.jetbrains.kotlin.fileClasses.JvmSimpleFileClassInfo
import org.jetbrains.kotlin.ir.PsiIrFileEntry
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
@@ -35,10 +36,8 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.util.*
internal val fileClassPhase = makeIrModulePhase( internal val fileClassPhase = makeIrModulePhase(
::FileClassLowering, ::FileClassLowering,
@@ -80,7 +79,7 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
private fun createFileClass(irFile: IrFile, fileClassMembers: List<IrDeclaration>): IrClass { private fun createFileClass(irFile: IrFile, fileClassMembers: List<IrDeclaration>): IrClass {
val fileEntry = irFile.fileEntry val fileEntry = irFile.fileEntry
val fileClassInfo = when (fileEntry) { val fileClassInfo = when (fileEntry) {
is PsiSourceManager.PsiFileEntry -> is PsiIrFileEntry ->
JvmFileClassUtil.getFileClassInfoNoResolve(fileEntry.psiFile as KtFile) JvmFileClassUtil.getFileClassInfoNoResolve(fileEntry.psiFile as KtFile)
is NaiveSourceBasedFileEntryImpl -> is NaiveSourceBasedFileEntryImpl ->
JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(irFile.fqName, fileEntry.name), false) JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(irFile.fqName, fileEntry.name), false)
@@ -17,81 +17,21 @@
package org.jetbrains.kotlin.psi2ir package org.jetbrains.kotlin.psi2ir
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.PsiIrFileEntry
import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.util.fileOrNull import org.jetbrains.kotlin.ir.util.fileOrNull
import kotlin.reflect.KClass import kotlin.reflect.KClass
object PsiSourceManager { object PsiSourceManager {
class PsiFileEntry(val psiFile: PsiFile) : IrFileEntry {
private val psiFileName = psiFile.virtualFile?.path ?: psiFile.name
override val maxOffset: Int
private val lineStartOffsets: IntArray
private val fileViewProvider = psiFile.viewProvider
init {
val document = fileViewProvider.document ?: throw AssertionError("No document for $psiFile")
maxOffset = document.textLength
lineStartOffsets = IntArray(document.lineCount) { document.getLineStartOffset(it) }
}
override fun getLineNumber(offset: Int): Int {
if (offset < 0) return -1
val index = lineStartOffsets.binarySearch(offset)
return if (index >= 0) index else -index - 2
}
override fun getColumnNumber(offset: Int): Int {
if (offset < 0) return -1
val lineNumber = getLineNumber(offset)
return offset - lineStartOffsets[lineNumber]
}
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo =
SourceRangeInfo(
filePath = getRecognizableName(),
startOffset = beginOffset,
startLineNumber = getLineNumber(beginOffset),
startColumnNumber = getColumnNumber(beginOffset),
endOffset = endOffset,
endLineNumber = getLineNumber(endOffset),
endColumnNumber = getColumnNumber(endOffset)
)
private fun getRecognizableName(): String = psiFileName
override val name: String get() = getRecognizableName()
override fun toString(): String = getRecognizableName()
fun findPsiElement(irElement: IrElement): PsiElement? {
var psiElement = fileViewProvider.findElementAt(irElement.startOffset)
while (psiElement != null) {
if (irElement.endOffset == psiElement.textRange?.endOffset) break
psiElement = psiElement.parent
}
return psiElement
}
fun <E : PsiElement> findPsiElement(irElement: IrElement, psiElementClass: KClass<E>): E? =
findPsiElement(irElement)?.let {
PsiTreeUtil.getParentOfType(it, psiElementClass.java, false)
}
}
fun <E : PsiElement> findPsiElement(irElement: IrElement, irFile: IrFile, psiElementClass: KClass<E>): E? { fun <E : PsiElement> findPsiElement(irElement: IrElement, irFile: IrFile, psiElementClass: KClass<E>): E? {
val psiFileEntry = irFile.fileEntry as? PsiFileEntry ?: return null val psiFileEntry = irFile.fileEntry as? PsiIrFileEntry ?: return null
return psiFileEntry.findPsiElement(irElement, psiElementClass) return psiFileEntry.findPsiElement(irElement, psiElementClass)
} }
fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
val psiFileEntry = irFile.fileEntry as? PsiFileEntry ?: return null val psiFileEntry = irFile.fileEntry as? PsiIrFileEntry ?: return null
return psiFileEntry.findPsiElement(irElement) return psiFileEntry.findPsiElement(irElement)
} }
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.PsiIrFileEntry
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
@@ -31,7 +32,6 @@ import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
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.resolve.lazy.descriptors.findPackageFragmentForFile import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
@@ -102,7 +102,7 @@ class ModuleGenerator(
} }
private fun createEmptyIrFile(ktFile: KtFile): IrFileImpl { private fun createEmptyIrFile(ktFile: KtFile): IrFileImpl {
val fileEntry = PsiSourceManager.PsiFileEntry(ktFile) val fileEntry = PsiIrFileEntry(ktFile)
val packageFragmentDescriptor = context.moduleDescriptor.findPackageFragmentForFile(ktFile)!! val packageFragmentDescriptor = context.moduleDescriptor.findPackageFragmentForFile(ktFile)!!
return IrFileImpl(fileEntry, packageFragmentDescriptor).apply { return IrFileImpl(fileEntry, packageFragmentDescriptor).apply {
metadata = DescriptorMetadataSource.File(CodegenUtil.getMemberDescriptorsToGenerate(ktFile, context.bindingContext)) metadata = DescriptorMetadataSource.File(CodegenUtil.getMemberDescriptorsToGenerate(ktFile, context.bindingContext))
@@ -0,0 +1,68 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import kotlin.reflect.KClass
class PsiIrFileEntry(val psiFile: PsiFile) : IrFileEntry {
private val psiFileName = psiFile.virtualFile?.path ?: psiFile.name
override val maxOffset: Int
private val lineStartOffsets: IntArray
private val fileViewProvider = psiFile.viewProvider
init {
val document = fileViewProvider.document ?: throw AssertionError("No document for $psiFile")
maxOffset = document.textLength
lineStartOffsets = IntArray(document.lineCount) { document.getLineStartOffset(it) }
}
override fun getLineNumber(offset: Int): Int {
if (offset < 0) return -1
val index = lineStartOffsets.binarySearch(offset)
return if (index >= 0) index else -index - 2
}
override fun getColumnNumber(offset: Int): Int {
if (offset < 0) return -1
val lineNumber = getLineNumber(offset)
return offset - lineStartOffsets[lineNumber]
}
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo =
SourceRangeInfo(
filePath = getRecognizableName(),
startOffset = beginOffset,
startLineNumber = getLineNumber(beginOffset),
startColumnNumber = getColumnNumber(beginOffset),
endOffset = endOffset,
endLineNumber = getLineNumber(endOffset),
endColumnNumber = getColumnNumber(endOffset)
)
private fun getRecognizableName(): String = psiFileName
override val name: String get() = getRecognizableName()
override fun toString(): String = getRecognizableName()
fun findPsiElement(irElement: IrElement): PsiElement? {
var psiElement = fileViewProvider.findElementAt(irElement.startOffset)
while (psiElement != null) {
if (irElement.endOffset == psiElement.textRange?.endOffset) break
psiElement = psiElement.parent
}
return psiElement
}
fun <E : PsiElement> findPsiElement(irElement: IrElement, psiElementClass: KClass<E>): E? =
findPsiElement(irElement)?.let {
PsiTreeUtil.getParentOfType(it, psiElementClass.java, false)
}
}