Extract PsiSourceCompiler
This commit is contained in:
@@ -2288,10 +2288,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
FunctionDescriptor original =
|
FunctionDescriptor original =
|
||||||
unwrapInitialSignatureDescriptor(DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal()));
|
unwrapInitialSignatureDescriptor(DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal()));
|
||||||
if (isDefaultCompilation) {
|
if (isDefaultCompilation) {
|
||||||
return new InlineCodegenForDefaultBody(original, this, state, new SourceCompilerForInline(this));
|
return new InlineCodegenForDefaultBody(original, this, state, new PsiSourceCompilerForInline(this, callElement));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new PsiInlineCodegen(this, state, original, callElement, typeParameterMappings, new SourceCompilerForInline(this));
|
return new PsiInlineCodegen(this, state, original, typeParameterMappings, new PsiSourceCompilerForInline(this, callElement));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.codegen.intrinsics.classId
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnly
|
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnly
|
||||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
@@ -57,11 +56,10 @@ import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
|||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
abstract class InlineCodegen(
|
abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||||
protected val codegen: BaseExpressionCodegen,
|
protected val codegen: T,
|
||||||
protected val state: GenerationState,
|
protected val state: GenerationState,
|
||||||
function: FunctionDescriptor,
|
function: FunctionDescriptor,
|
||||||
private val callElement: KtElement,
|
|
||||||
private val typeParameterMappings: TypeParameterMappings,
|
private val typeParameterMappings: TypeParameterMappings,
|
||||||
protected val sourceCompiler: SourceCompilerForInline
|
protected val sourceCompiler: SourceCompilerForInline
|
||||||
) {
|
) {
|
||||||
@@ -96,7 +94,7 @@ abstract class InlineCodegen(
|
|||||||
|
|
||||||
protected var activeLambda: LambdaInfo? = null
|
protected var activeLambda: LambdaInfo? = null
|
||||||
|
|
||||||
private val sourceMapper = sourceCompiler.lazySourceMapper
|
private val defaultSourceMapper = sourceCompiler.lazySourceMapper
|
||||||
|
|
||||||
protected var delayedHiddenWriting: Function0<Unit>? = null
|
protected var delayedHiddenWriting: Function0<Unit>? = null
|
||||||
|
|
||||||
@@ -116,7 +114,7 @@ abstract class InlineCodegen(
|
|||||||
if (functionOrAccessorName != functionDescriptor.name.asString()) {
|
if (functionOrAccessorName != functionDescriptor.name.asString()) {
|
||||||
val scope = getMemberScope(functionDescriptor)
|
val scope = getMemberScope(functionDescriptor)
|
||||||
//Fake lookup to track track changes for property accessors and @JvmName functions/property accessors
|
//Fake lookup to track track changes for property accessors and @JvmName functions/property accessors
|
||||||
scope?.getContributedFunctions(Name.identifier(functionOrAccessorName), KotlinLookupLocation(callElement))
|
scope?.getContributedFunctions(Name.identifier(functionOrAccessorName), sourceCompiler.lookupLocation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +131,7 @@ abstract class InlineCodegen(
|
|||||||
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
||||||
(element?.text ?: "<no source>") +
|
(element?.text ?: "<no source>") +
|
||||||
if (generateNodeText) "\nCause: " + node.nodeText else "",
|
if (generateNodeText) "\nCause: " + node.nodeText else "",
|
||||||
e, callElement
|
e, sourceCompiler.callElement as? PsiElement
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +184,6 @@ abstract class InlineCodegen(
|
|||||||
|
|
||||||
protected fun inlineCall(nodeAndSmap: SMAPAndMethodNode, callDefault: Boolean): InlineResult {
|
protected fun inlineCall(nodeAndSmap: SMAPAndMethodNode, callDefault: Boolean): InlineResult {
|
||||||
assert(delayedHiddenWriting == null) { "'putHiddenParamsIntoLocals' should be called after 'processAndPutHiddenParameters(true)'" }
|
assert(delayedHiddenWriting == null) { "'putHiddenParamsIntoLocals' should be called after 'processAndPutHiddenParameters(true)'" }
|
||||||
val defaultSourceMapper = sourceMapper
|
|
||||||
defaultSourceMapper.callSiteMarker = CallSiteMarker(codegen.lastLineNumber)
|
defaultSourceMapper.callSiteMarker = CallSiteMarker(codegen.lastLineNumber)
|
||||||
val node = nodeAndSmap.node
|
val node = nodeAndSmap.node
|
||||||
if (callDefault) {
|
if (callDefault) {
|
||||||
@@ -212,13 +209,13 @@ abstract class InlineCodegen(
|
|||||||
|
|
||||||
val info = RootInliningContext(
|
val info = RootInliningContext(
|
||||||
expressionMap, state, codegen.inlineNameGenerator.subGenerator(jvmSignature.asmMethod.name),
|
expressionMap, state, codegen.inlineNameGenerator.subGenerator(jvmSignature.asmMethod.name),
|
||||||
callElement, sourceCompiler.inlineCallSiteInfo, reifiedTypeInliner, typeParameterMappings
|
sourceCompiler, sourceCompiler.inlineCallSiteInfo, reifiedTypeInliner, typeParameterMappings
|
||||||
)
|
)
|
||||||
|
|
||||||
val inliner = MethodInliner(
|
val inliner = MethodInliner(
|
||||||
node, parameters, info, FieldRemapper(null, null, parameters), isSameModule,
|
node, parameters, info, FieldRemapper(null, null, parameters), isSameModule,
|
||||||
"Method inlining " + callElement.text,
|
"Method inlining " + sourceCompiler.callElementText,
|
||||||
createNestedSourceMapper(nodeAndSmap, sourceMapper), info.callSiteInfo,
|
createNestedSourceMapper(nodeAndSmap, defaultSourceMapper), info.callSiteInfo,
|
||||||
if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null
|
if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null
|
||||||
) //with captured
|
) //with captured
|
||||||
|
|
||||||
@@ -231,8 +228,7 @@ abstract class InlineCodegen(
|
|||||||
val result = inliner.doInline(adapter, remapper, true, LabelOwner.SKIP_ALL)
|
val result = inliner.doInline(adapter, remapper, true, LabelOwner.SKIP_ALL)
|
||||||
result.reifiedTypeParametersUsages.mergeAll(reificationResult)
|
result.reifiedTypeParametersUsages.mergeAll(reificationResult)
|
||||||
|
|
||||||
val descriptor = sourceCompiler.getLabelOwnerDescriptor()
|
val labels = sourceCompiler.getContextLabels()
|
||||||
val labels = getDeclarationLabels(DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor)
|
|
||||||
|
|
||||||
val infos = MethodInliner.processReturns(adapter, LabelOwner { labels.contains(it) }, true, null)
|
val infos = MethodInliner.processReturns(adapter, LabelOwner { labels.contains(it) }, true, null)
|
||||||
sourceCompiler.generateAndInsertFinallyBlocks(
|
sourceCompiler.generateAndInsertFinallyBlocks(
|
||||||
@@ -580,10 +576,9 @@ class PsiInlineCodegen(
|
|||||||
codegen: ExpressionCodegen,
|
codegen: ExpressionCodegen,
|
||||||
state: GenerationState,
|
state: GenerationState,
|
||||||
function: FunctionDescriptor,
|
function: FunctionDescriptor,
|
||||||
callElement: KtElement,
|
|
||||||
typeParameterMappings: TypeParameterMappings,
|
typeParameterMappings: TypeParameterMappings,
|
||||||
sourceCompiler: SourceCompilerForInline
|
sourceCompiler: SourceCompilerForInline
|
||||||
) : InlineCodegen(codegen, state, function, callElement, typeParameterMappings, sourceCompiler), CallGenerator {
|
) : InlineCodegen<ExpressionCodegen>(codegen, state, function, typeParameterMappings, sourceCompiler), CallGenerator {
|
||||||
|
|
||||||
override fun genCallInner(
|
override fun genCallInner(
|
||||||
callableMethod: Callable,
|
callableMethod: Callable,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class RootInliningContext(
|
|||||||
expressionMap: Map<Int, LambdaInfo>,
|
expressionMap: Map<Int, LambdaInfo>,
|
||||||
state: GenerationState,
|
state: GenerationState,
|
||||||
nameGenerator: NameGenerator,
|
nameGenerator: NameGenerator,
|
||||||
val callElement: KtElement,
|
val sourceCompilerForInline: SourceCompilerForInline,
|
||||||
override val callSiteInfo: InlineCallSiteInfo,
|
override val callSiteInfo: InlineCallSiteInfo,
|
||||||
val inlineMethodReifier: ReifiedTypeInliner,
|
val inlineMethodReifier: ReifiedTypeInliner,
|
||||||
typeParameterMappings: TypeParameterMappings
|
typeParameterMappings: TypeParameterMappings
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
|
|||||||
val classBuilder = state.factory.newVisitor(
|
val classBuilder = state.factory.newVisitor(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN,
|
JvmDeclarationOrigin.NO_ORIGIN,
|
||||||
Type.getObjectType(transformationInfo.newClassName),
|
Type.getObjectType(transformationInfo.newClassName),
|
||||||
inliningContext.root.callElement.containingFile
|
inliningContext.root.sourceCompilerForInline.callsiteFile!!
|
||||||
)
|
)
|
||||||
|
|
||||||
return RemappingClassBuilder(
|
return RemappingClassBuilder(
|
||||||
|
|||||||
+82
-17
@@ -16,11 +16,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.context.*
|
import org.jetbrains.kotlin.codegen.context.*
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
@@ -37,16 +40,75 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
|||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
class SourceCompilerForInline(private val codegen: ExpressionCodegen) {
|
interface SourceCompilerForInline {
|
||||||
|
val state: GenerationState
|
||||||
|
|
||||||
val state = codegen.state
|
val callElement: Any
|
||||||
|
|
||||||
|
val lookupLocation: LookupLocation
|
||||||
|
|
||||||
|
val callElementText: String
|
||||||
|
|
||||||
|
val callsiteFile: PsiFile?
|
||||||
|
|
||||||
|
val contextKind: OwnerKind
|
||||||
|
|
||||||
|
val inlineCallSiteInfo: InlineCallSiteInfo
|
||||||
|
|
||||||
|
val lazySourceMapper: DefaultSourceMapper
|
||||||
|
|
||||||
|
fun generateLambdaBody(adapter: MethodVisitor,
|
||||||
|
jvmMethodSignature: JvmMethodSignature,
|
||||||
|
lambdaInfo: ExpressionLambda): SMAP
|
||||||
|
|
||||||
|
fun doCreateMethodNodeFromSource(
|
||||||
|
callableDescriptor: FunctionDescriptor,
|
||||||
|
jvmSignature: JvmMethodSignature,
|
||||||
|
callDefault: Boolean,
|
||||||
|
asmMethod: Method
|
||||||
|
): SMAPAndMethodNode
|
||||||
|
|
||||||
|
fun generateAndInsertFinallyBlocks(
|
||||||
|
intoNode: MethodNode,
|
||||||
|
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
|
||||||
|
offsetForFinallyLocalVar: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean
|
||||||
|
|
||||||
|
fun isFinallyMarkerRequired(): Boolean
|
||||||
|
|
||||||
|
val compilationContextDescriptor: DeclarationDescriptor
|
||||||
|
|
||||||
|
val compilationContextFunctionDescriptor: FunctionDescriptor
|
||||||
|
|
||||||
|
fun getContextLabels(): Set<String>
|
||||||
|
|
||||||
|
fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, override val callElement: KtElement): SourceCompilerForInline {
|
||||||
|
|
||||||
|
override val state = codegen.state
|
||||||
|
|
||||||
private var context by Delegates.notNull<CodegenContext<*>>()
|
private var context by Delegates.notNull<CodegenContext<*>>()
|
||||||
|
|
||||||
val contextKind
|
override val lookupLocation = KotlinLookupLocation(callElement)
|
||||||
|
|
||||||
|
|
||||||
|
override val callElementText by lazy {
|
||||||
|
callElement.text
|
||||||
|
}
|
||||||
|
|
||||||
|
override val callsiteFile by lazy {
|
||||||
|
callElement.containingFile
|
||||||
|
}
|
||||||
|
|
||||||
|
override val contextKind
|
||||||
get () = context.contextKind
|
get () = context.contextKind
|
||||||
|
|
||||||
val inlineCallSiteInfo: InlineCallSiteInfo
|
override val inlineCallSiteInfo: InlineCallSiteInfo
|
||||||
get() {
|
get() {
|
||||||
var context = codegen.getContext()
|
var context = codegen.getContext()
|
||||||
var parentCodegen = codegen.parentCodegen
|
var parentCodegen = codegen.parentCodegen
|
||||||
@@ -65,10 +127,10 @@ class SourceCompilerForInline(private val codegen: ExpressionCodegen) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val lazySourceMapper
|
override val lazySourceMapper
|
||||||
get() = codegen.parentCodegen.orCreateSourceMapper
|
get() = codegen.parentCodegen.orCreateSourceMapper
|
||||||
|
|
||||||
fun generateLambdaBody(adapter: MethodVisitor,
|
override fun generateLambdaBody(adapter: MethodVisitor,
|
||||||
jvmMethodSignature: JvmMethodSignature,
|
jvmMethodSignature: JvmMethodSignature,
|
||||||
lambdaInfo: ExpressionLambda): SMAP {
|
lambdaInfo: ExpressionLambda): SMAP {
|
||||||
val invokeMethodDescriptor = lambdaInfo.invokeMethodDescriptor
|
val invokeMethodDescriptor = lambdaInfo.invokeMethodDescriptor
|
||||||
@@ -179,6 +241,7 @@ class SourceCompilerForInline(private val codegen: ExpressionCodegen) {
|
|||||||
override fun getInlineNameGenerator(): NameGenerator {
|
override fun getInlineNameGenerator(): NameGenerator {
|
||||||
return delegate.inlineNameGenerator
|
return delegate.inlineNameGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
override //TODO: obtain name from context
|
override //TODO: obtain name from context
|
||||||
fun getClassName(): String {
|
fun getClassName(): String {
|
||||||
return className
|
return className
|
||||||
@@ -186,7 +249,7 @@ class SourceCompilerForInline(private val codegen: ExpressionCodegen) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doCreateMethodNodeFromSource(
|
override fun doCreateMethodNodeFromSource(
|
||||||
callableDescriptor: FunctionDescriptor,
|
callableDescriptor: FunctionDescriptor,
|
||||||
jvmSignature: JvmMethodSignature,
|
jvmSignature: JvmMethodSignature,
|
||||||
callDefault: Boolean,
|
callDefault: Boolean,
|
||||||
@@ -236,7 +299,7 @@ class SourceCompilerForInline(private val codegen: ExpressionCodegen) {
|
|||||||
return SMAPAndMethodNode(node, smap)
|
return SMAPAndMethodNode(node, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateAndInsertFinallyBlocks(
|
override fun generateAndInsertFinallyBlocks(
|
||||||
intoNode: MethodNode,
|
intoNode: MethodNode,
|
||||||
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
|
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
|
||||||
offsetForFinallyLocalVar: Int
|
offsetForFinallyLocalVar: Int
|
||||||
@@ -302,29 +365,31 @@ class SourceCompilerForInline(private val codegen: ExpressionCodegen) {
|
|||||||
//processor.substituteLocalVarTable(intoNode);
|
//processor.substituteLocalVarTable(intoNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor) : Boolean {
|
override fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean {
|
||||||
return JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory)
|
return JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isFinallyMarkerRequired(): Boolean = isFinallyMarkerRequired(codegen.getContext())
|
override fun isFinallyMarkerRequired(): Boolean = isFinallyMarkerRequired(codegen.getContext())
|
||||||
|
|
||||||
|
|
||||||
val compilationContextDescriptor
|
override val compilationContextDescriptor
|
||||||
get() = codegen.getContext().contextDescriptor
|
get() = codegen.getContext().contextDescriptor
|
||||||
|
|
||||||
val compilationContextFunctionDescriptor
|
override val compilationContextFunctionDescriptor
|
||||||
get() = codegen.getContext().functionDescriptor
|
get() = codegen.getContext().functionDescriptor
|
||||||
|
|
||||||
fun getLabelOwnerDescriptor(): CallableMemberDescriptor {
|
override fun getContextLabels(): Set<String> {
|
||||||
val context = codegen.getContext()
|
val context = codegen.getContext()
|
||||||
val parentContext = context.parentContext
|
val parentContext = context.parentContext
|
||||||
if (parentContext is ClosureContext && parentContext.originalSuspendLambdaDescriptor != null) {
|
val descriptor = if (parentContext is ClosureContext && parentContext.originalSuspendLambdaDescriptor != null) {
|
||||||
return parentContext.originalSuspendLambdaDescriptor!!
|
parentContext.originalSuspendLambdaDescriptor!!
|
||||||
}
|
}
|
||||||
return context.contextDescriptor
|
else context.contextDescriptor
|
||||||
|
|
||||||
|
return InlineCodegen.getDeclarationLabels(DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
|
override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
|
||||||
context = getContext(functionDescriptor, state, DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile)
|
context = getContext(functionDescriptor, state, DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user