JVM: separate the two kinds of source mappers

* a writing source mapper has `mapLineNumber(line, file, class)` that
   inserts a new SMAP entry and returns a fake line number from it;
 * a copying source mapper has `mapLineNumber(line)` that uses an
   existing SMAP to resolve the line number and call the former method
   on a different source mapper;
 * those two types are disjoint.
This commit is contained in:
pyos
2020-04-01 07:59:01 +02:00
committed by max-kammerer
parent 143d8d1520
commit 1fe7ef6521
16 changed files with 90 additions and 179 deletions
@@ -148,7 +148,7 @@ abstract class ClassCodegen protected constructor(
if (writeSourceMap) {
visitor.visitSMAP(smap, !context.state.languageVersionSettings.supportsFeature(LanguageFeature.CorrectSourceMappingSyntax))
} else {
visitor.visitSource(smap.sourceInfo.source, null)
visitor.visitSource(smap.sourceInfo!!.source, null)
}
visitor.done()
@@ -269,7 +269,7 @@ abstract class ClassCodegen protected constructor(
protected abstract fun bindMethodMetadata(method: IrFunction, signature: Method)
private fun generateMethod(method: IrFunction, classSMAP: DefaultSourceMapper) {
private fun generateMethod(method: IrFunction, classSMAP: SourceMapper) {
if (method.isFakeOverride) {
jvmSignatureClashDetector.trackFakeOverrideMethod(method)
return
@@ -281,7 +281,7 @@ abstract class ClassCodegen protected constructor(
method.origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE
)
val mv = with(node) { visitor.newMethod(method.OtherOrigin, access, name, desc, signature, exceptions.toTypedArray()) }
val smapCopier = NestedSourceMapper(classSMAP, smap, sameFile = true)
val smapCopier = SourceMapCopier(classSMAP, smap, keepCallSites = true)
val smapCopyingVisitor = object : MethodVisitor(Opcodes.API_VERSION, mv) {
override fun visitLineNumber(line: Int, start: Label) =
super.visitLineNumber(smapCopier.mapLineNumber(line), start)
@@ -106,7 +106,7 @@ class ExpressionCodegen(
val mv: InstructionAdapter,
val classCodegen: ClassCodegen,
val inlinedInto: ExpressionCodegen?,
val smap: DefaultSourceMapper
val smap: SourceMapper
) : IrElementVisitor<PromisedValue, BlockInfo>, BaseExpressionCodegen {
var finallyDepth = 0
@@ -85,7 +85,7 @@ class IrSourceCompilerForInline(
)
}
override val lazySourceMapper: DefaultSourceMapper
override val lazySourceMapper: SourceMapper
get() = codegen.smap.also { codegen.classCodegen.writeSourceMap = true }
override fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode =
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper
import org.jetbrains.kotlin.codegen.inline.SourceMapper
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
@@ -80,14 +80,14 @@ val IrDeclaration.fileParent: IrFile
internal val DeclarationDescriptorWithSource.psiElement: PsiElement?
get() = (source as? PsiSourceElement)?.psi
fun JvmBackendContext.getSourceMapper(declaration: IrClass): DefaultSourceMapper {
fun JvmBackendContext.getSourceMapper(declaration: IrClass): SourceMapper {
val sourceManager = this.psiSourceManager
val fileEntry = sourceManager.getFileEntry(declaration.fileParent)
// NOTE: apparently inliner requires the source range to cover the
// whole file the class is declared in rather than the class only.
// TODO: revise
val endLineNumber = fileEntry?.getSourceRangeInfo(0, fileEntry.maxOffset)?.endLineNumber ?: 0
return DefaultSourceMapper(
return SourceMapper(
SourceInfo.createInfoForIr(
endLineNumber + 1,
typeMapper.mapClass(declaration).internalName,