Reformat: ResolveElementCache

This commit is contained in:
Mikhail Glukhikh
2018-02-13 13:51:47 +03:00
parent ba71e732a9
commit 52166646bb
@@ -49,10 +49,10 @@ import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.* import java.util.*
class ResolveElementCache( class ResolveElementCache(
private val resolveSession: ResolveSession, private val resolveSession: ResolveSession,
private val project: Project, private val project: Project,
private val targetPlatform: TargetPlatform, private val targetPlatform: TargetPlatform,
private val codeFragmentAnalyzer: CodeFragmentAnalyzer private val codeFragmentAnalyzer: CodeFragmentAnalyzer
) : BodyResolveCache { ) : BodyResolveCache {
private class CachedFullResolve(val bindingContext: BindingContext, resolveElement: KtElement) { private class CachedFullResolve(val bindingContext: BindingContext, resolveElement: KtElement) {
private val modificationStamp: Long? = modificationStamp(resolveElement) private val modificationStamp: Long? = modificationStamp(resolveElement)
@@ -62,8 +62,8 @@ class ResolveElementCache(
private fun modificationStamp(resolveElement: KtElement): Long? { private fun modificationStamp(resolveElement: KtElement): Long? {
val file = resolveElement.containingFile val file = resolveElement.containingFile
return when { return when {
// for non-physical file we don't get OUT_OF_CODE_BLOCK_MODIFICATION_COUNT increased and must reset // for non-physical file we don't get OUT_OF_CODE_BLOCK_MODIFICATION_COUNT increased and must reset
// data on any modification of the file // data on any modification of the file
!file.isPhysical -> file.modificationStamp !file.isPhysical -> file.modificationStamp
resolveElement is KtDeclaration && KotlinCodeBlockModificationListener.isBlockDeclaration(resolveElement) -> resolveElement.getModificationStamp() resolveElement is KtDeclaration && KotlinCodeBlockModificationListener.isBlockDeclaration(resolveElement) -> resolveElement.getModificationStamp()
@@ -74,19 +74,23 @@ class ResolveElementCache(
} }
// drop whole cache after change "out of code block" // drop whole cache after change "out of code block"
private val fullResolveCache: CachedValue<MutableMap<KtElement, CachedFullResolve>> = CachedValuesManager.getManager(project).createCachedValue( private val fullResolveCache: CachedValue<MutableMap<KtElement, CachedFullResolve>> =
CachedValuesManager.getManager(project).createCachedValue(
CachedValueProvider<MutableMap<KtElement, ResolveElementCache.CachedFullResolve>> { CachedValueProvider<MutableMap<KtElement, ResolveElementCache.CachedFullResolve>> {
CachedValueProvider.Result.create(ContainerUtil.createConcurrentSoftValueMap<KtElement, CachedFullResolve>(), CachedValueProvider.Result.create(
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, ContainerUtil.createConcurrentSoftValueMap<KtElement, CachedFullResolve>(),
resolveSession.exceptionTracker) PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT,
resolveSession.exceptionTracker
)
}, },
false) false
)
private class CachedPartialResolve(val bindingContext: BindingContext, file: KtFile, val mode: BodyResolveMode) { private class CachedPartialResolve(val bindingContext: BindingContext, file: KtFile, val mode: BodyResolveMode) {
private val modificationStamp: Long? = modificationStamp(file) private val modificationStamp: Long? = modificationStamp(file)
fun isUpToDate(file: KtFile, newMode: BodyResolveMode) = fun isUpToDate(file: KtFile, newMode: BodyResolveMode) =
modificationStamp == modificationStamp(file) && mode.doesNotLessThan(newMode) modificationStamp == modificationStamp(file) && mode.doesNotLessThan(newMode)
private fun modificationStamp(file: KtFile): Long? { private fun modificationStamp(file: KtFile): Long? {
return if (!file.isPhysical) // for non-physical file we don't get MODIFICATION_COUNT increased and must reset data on any modification of the file return if (!file.isPhysical) // for non-physical file we don't get MODIFICATION_COUNT increased and must reset data on any modification of the file
@@ -97,13 +101,16 @@ class ResolveElementCache(
} }
private val partialBodyResolveCache: CachedValue<MutableMap<KtExpression, CachedPartialResolve>> = private val partialBodyResolveCache: CachedValue<MutableMap<KtExpression, CachedPartialResolve>> =
CachedValuesManager.getManager(project).createCachedValue( CachedValuesManager.getManager(project).createCachedValue(
CachedValueProvider<MutableMap<KtExpression, ResolveElementCache.CachedPartialResolve>> { CachedValueProvider<MutableMap<KtExpression, ResolveElementCache.CachedPartialResolve>> {
CachedValueProvider.Result.create(ContainerUtil.createConcurrentSoftValueMap<KtExpression, CachedPartialResolve>(), CachedValueProvider.Result.create(
PsiModificationTracker.MODIFICATION_COUNT, ContainerUtil.createConcurrentSoftValueMap<KtExpression, CachedPartialResolve>(),
resolveSession.exceptionTracker) PsiModificationTracker.MODIFICATION_COUNT,
}, resolveSession.exceptionTracker
false) )
},
false
)
private fun probablyNothingCallableNames(): ProbablyNothingCallableNames { private fun probablyNothingCallableNames(): ProbablyNothingCallableNames {
@@ -113,19 +120,31 @@ class ResolveElementCache(
} }
} }
override fun resolveFunctionBody(function: KtNamedFunction) override fun resolveFunctionBody(function: KtNamedFunction) = getElementsAdditionalResolve(function, null, BodyResolveMode.FULL)
= getElementsAdditionalResolve(function, null, BodyResolveMode.FULL)
fun resolvePrimaryConstructorParametersDefaultValues(ktClass: KtClass): BindingContext { fun resolvePrimaryConstructorParametersDefaultValues(ktClass: KtClass): BindingContext {
return constructorAdditionalResolve(resolveSession, ktClass, ktClass.containingKtFile, BindingTraceFilter.NO_DIAGNOSTICS).bindingContext return constructorAdditionalResolve(
resolveSession,
ktClass,
ktClass.containingKtFile,
BindingTraceFilter.NO_DIAGNOSTICS
).bindingContext
} }
@Deprecated("Use getElementsAdditionalResolve") @Deprecated("Use getElementsAdditionalResolve")
fun getElementAdditionalResolve(resolveElement: KtElement, contextElement: KtElement, bodyResolveMode: BodyResolveMode): BindingContext { fun getElementAdditionalResolve(
resolveElement: KtElement,
contextElement: KtElement,
bodyResolveMode: BodyResolveMode
): BindingContext {
return getElementsAdditionalResolve(resolveElement, listOf(contextElement), bodyResolveMode) return getElementsAdditionalResolve(resolveElement, listOf(contextElement), bodyResolveMode)
} }
fun getElementsAdditionalResolve(resolveElement: KtElement, contextElements: Collection<KtElement>?, bodyResolveMode: BodyResolveMode): BindingContext { fun getElementsAdditionalResolve(
resolveElement: KtElement,
contextElements: Collection<KtElement>?,
bodyResolveMode: BodyResolveMode
): BindingContext {
if (contextElements == null) { if (contextElements == null) {
assert(bodyResolveMode == BodyResolveMode.FULL) assert(bodyResolveMode == BodyResolveMode.FULL)
} }
@@ -136,8 +155,7 @@ class ResolveElementCache(
if (cachedFullResolve != null) { if (cachedFullResolve != null) {
if (cachedFullResolve.isUpToDate(resolveElement)) { if (cachedFullResolve.isUpToDate(resolveElement)) {
return cachedFullResolve.bindingContext return cachedFullResolve.bindingContext
} } else {
else {
fullResolveMap.remove(resolveElement) // remove outdated cache entry fullResolveMap.remove(resolveElement) // remove outdated cache entry
} }
} }
@@ -155,10 +173,16 @@ class ResolveElementCache(
} }
val file = resolveElement.getContainingKtFile() val file = resolveElement.getContainingKtFile()
val statementsToResolve = contextElements!!.map { PartialBodyResolveFilter.findStatementToResolve(it, resolveElement) }.distinct() val statementsToResolve =
contextElements!!.map { PartialBodyResolveFilter.findStatementToResolve(it, resolveElement) }.distinct()
val partialResolveMap = partialBodyResolveCache.value val partialResolveMap = partialBodyResolveCache.value
val cachedResults = statementsToResolve.map { partialResolveMap[it ?: resolveElement] } val cachedResults = statementsToResolve.map { partialResolveMap[it ?: resolveElement] }
if (cachedResults.all { it != null && it.isUpToDate(file, bodyResolveMode) }) { // partial resolve is already cached for these statements if (cachedResults.all {
it != null && it.isUpToDate(
file,
bodyResolveMode
)
}) { // partial resolve is already cached for these statements
return CompositeBindingContext.create(cachedResults.map { it!!.bindingContext }.distinct()) return CompositeBindingContext.create(cachedResults.map { it!!.bindingContext }.distinct())
} }
@@ -196,19 +220,17 @@ class ResolveElementCache(
if (elementOfAdditionalResolve !is KtParameter) { if (elementOfAdditionalResolve !is KtParameter) {
val bindingContext = getElementsAdditionalResolve(elementOfAdditionalResolve, contextElements, bodyResolveMode) val bindingContext = getElementsAdditionalResolve(elementOfAdditionalResolve, contextElements, bodyResolveMode)
bindingContexts.add(bindingContext) bindingContexts.add(bindingContext)
} } else {
else {
// Parameters for function literal could be met inside other parameters. We can't make resolveToDescriptors for internal elements. // Parameters for function literal could be met inside other parameters. We can't make resolveToDescriptors for internal elements.
declarationsToResolve.addIfNotNull(elementOfAdditionalResolve.getNonStrictParentOfType<KtDeclaration>()) declarationsToResolve.addIfNotNull(elementOfAdditionalResolve.getNonStrictParentOfType<KtDeclaration>())
addResolveSessionBindingContext = true addResolveSessionBindingContext = true
} }
} } else {
else {
contextElements contextElements
.mapNotNull { it.getNonStrictParentOfType<KtDeclaration>() } .mapNotNull { it.getNonStrictParentOfType<KtDeclaration>() }
.filterTo(declarationsToResolve) { .filterTo(declarationsToResolve) {
it !is KtAnonymousInitializer && it !is KtDestructuringDeclaration && it !is KtDestructuringDeclarationEntry it !is KtAnonymousInitializer && it !is KtDestructuringDeclaration && it !is KtDestructuringDeclarationEntry
} }
addResolveSessionBindingContext = true addResolveSessionBindingContext = true
} }
} }
@@ -224,21 +246,21 @@ class ResolveElementCache(
private fun findElementOfAdditionalResolve(element: KtElement): KtElement? { private fun findElementOfAdditionalResolve(element: KtElement): KtElement? {
val elementOfAdditionalResolve = KtPsiUtil.getTopmostParentOfTypes( val elementOfAdditionalResolve = KtPsiUtil.getTopmostParentOfTypes(
element, element,
KtNamedFunction::class.java, KtNamedFunction::class.java,
KtAnonymousInitializer::class.java, KtAnonymousInitializer::class.java,
KtPrimaryConstructor::class.java, KtPrimaryConstructor::class.java,
KtSecondaryConstructor::class.java, KtSecondaryConstructor::class.java,
KtProperty::class.java, KtProperty::class.java,
KtSuperTypeList::class.java, KtSuperTypeList::class.java,
KtInitializerList::class.java, KtInitializerList::class.java,
KtImportList::class.java, KtImportList::class.java,
KtAnnotationEntry::class.java, KtAnnotationEntry::class.java,
KtTypeParameter::class.java, KtTypeParameter::class.java,
KtTypeConstraint::class.java, KtTypeConstraint::class.java,
KtPackageDirective::class.java, KtPackageDirective::class.java,
KtCodeFragment::class.java, KtCodeFragment::class.java,
KtTypeAlias::class.java KtTypeAlias::class.java
) as KtElement? ) as KtElement?
when (elementOfAdditionalResolve) { when (elementOfAdditionalResolve) {
@@ -271,9 +293,9 @@ class ResolveElementCache(
} }
private fun performElementAdditionalResolve( private fun performElementAdditionalResolve(
resolveElement: KtElement, resolveElement: KtElement,
contextElements: Collection<KtElement>?, contextElements: Collection<KtElement>?,
bodyResolveMode: BodyResolveMode bodyResolveMode: BodyResolveMode
): Pair<BindingContext, StatementFilter> { ): Pair<BindingContext, StatementFilter> {
if (contextElements == null) { if (contextElements == null) {
assert(bodyResolveMode == BodyResolveMode.FULL) assert(bodyResolveMode == BodyResolveMode.FULL)
@@ -287,28 +309,70 @@ class ResolveElementCache(
assert(resolveElement is KtDeclaration) assert(resolveElement is KtDeclaration)
if (bodyResolveMode != BodyResolveMode.FULL) { if (bodyResolveMode != BodyResolveMode.FULL) {
statementFilterUsed = PartialBodyResolveFilter( statementFilterUsed = PartialBodyResolveFilter(
contextElements!!, contextElements!!,
resolveElement as KtDeclaration, resolveElement as KtDeclaration,
probablyNothingCallableNames(), probablyNothingCallableNames(),
bodyResolveMode == BodyResolveMode.PARTIAL_FOR_COMPLETION) bodyResolveMode == BodyResolveMode.PARTIAL_FOR_COMPLETION
)
} }
return statementFilterUsed return statementFilterUsed
} }
val trace: BindingTrace = when (resolveElement) { val trace: BindingTrace = when (resolveElement) {
is KtNamedFunction -> functionAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter) is KtNamedFunction -> functionAdditionalResolve(
resolveSession,
resolveElement,
file,
createStatementFilter(),
bodyResolveMode.bindingTraceFilter
)
is KtAnonymousInitializer -> initializerAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter) is KtAnonymousInitializer -> initializerAdditionalResolve(
resolveSession,
resolveElement,
file,
createStatementFilter(),
bodyResolveMode.bindingTraceFilter
)
is KtPrimaryConstructor -> constructorAdditionalResolve(resolveSession, resolveElement.parent as KtClassOrObject, file, bodyResolveMode.bindingTraceFilter) is KtPrimaryConstructor -> constructorAdditionalResolve(
resolveSession,
resolveElement.parent as KtClassOrObject,
file,
bodyResolveMode.bindingTraceFilter
)
is KtSecondaryConstructor -> secondaryConstructorAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter) is KtSecondaryConstructor -> secondaryConstructorAdditionalResolve(
resolveSession,
resolveElement,
file,
createStatementFilter(),
bodyResolveMode.bindingTraceFilter
)
is KtProperty -> propertyAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter) is KtProperty -> propertyAdditionalResolve(
resolveSession,
resolveElement,
file,
createStatementFilter(),
bodyResolveMode.bindingTraceFilter
)
is KtSuperTypeList -> delegationSpecifierAdditionalResolve(resolveSession, resolveElement, resolveElement.getParent() as KtClassOrObject, file, bodyResolveMode.bindingTraceFilter) is KtSuperTypeList -> delegationSpecifierAdditionalResolve(
resolveSession,
resolveElement,
resolveElement.getParent() as KtClassOrObject,
file,
bodyResolveMode.bindingTraceFilter
)
is KtInitializerList -> delegationSpecifierAdditionalResolve(resolveSession, resolveElement, resolveElement.getParent() as KtEnumEntry, file, bodyResolveMode.bindingTraceFilter) is KtInitializerList -> delegationSpecifierAdditionalResolve(
resolveSession,
resolveElement,
resolveElement.getParent() as KtEnumEntry,
file,
bodyResolveMode.bindingTraceFilter
)
is KtImportList -> { is KtImportList -> {
val resolver = resolveSession.fileScopeProvider.getImportResolver(resolveElement.getContainingKtFile()) val resolver = resolveSession.fileScopeProvider.getImportResolver(resolveElement.getContainingKtFile())
@@ -320,8 +384,7 @@ class ResolveElementCache(
val annotationEntry = resolveElement.annotationEntries.firstOrNull() val annotationEntry = resolveElement.annotationEntries.firstOrNull()
if (annotationEntry != null) { if (annotationEntry != null) {
annotationAdditionalResolve(resolveSession, annotationEntry) annotationAdditionalResolve(resolveSession, annotationEntry)
} } else {
else {
resolveSession.trace resolveSession.trace
} }
} }
@@ -341,24 +404,26 @@ class ResolveElementCache(
else -> { else -> {
if (resolveElement.getParentOfType<KtPackageDirective>(true) != null) { if (resolveElement.getParentOfType<KtPackageDirective>(true) != null) {
packageRefAdditionalResolve(resolveSession, resolveElement, bodyResolveMode.bindingTraceFilter) packageRefAdditionalResolve(resolveSession, resolveElement, bodyResolveMode.bindingTraceFilter)
} } else {
else {
error("Invalid type of the topmost parent: $resolveElement\n${resolveElement.getElementTextWithContext()}") error("Invalid type of the topmost parent: $resolveElement\n${resolveElement.getElementTextWithContext()}")
} }
} }
} }
val controlFlowTrace = DelegatingBindingTrace(trace.bindingContext, "Element control flow resolve", resolveElement, allowSliceRewrite = true) val controlFlowTrace =
DelegatingBindingTrace(trace.bindingContext, "Element control flow resolve", resolveElement, allowSliceRewrite = true)
ControlFlowInformationProvider( ControlFlowInformationProvider(
resolveElement, controlFlowTrace, resolveElement.languageVersionSettings, resolveSession.platformDiagnosticSuppressor resolveElement, controlFlowTrace, resolveElement.languageVersionSettings, resolveSession.platformDiagnosticSuppressor
).checkDeclaration() ).checkDeclaration()
controlFlowTrace.addOwnDataTo(trace, null, false) controlFlowTrace.addOwnDataTo(trace, null, false)
return Pair(trace.bindingContext, statementFilterUsed) return Pair(trace.bindingContext, statementFilterUsed)
} }
private fun packageRefAdditionalResolve(resolveSession: ResolveSession, ktElement: KtElement, private fun packageRefAdditionalResolve(
bindingTraceFilter: BindingTraceFilter): BindingTrace { resolveSession: ResolveSession, ktElement: KtElement,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(ktElement, bindingTraceFilter) val trace = createDelegatingTrace(ktElement, bindingTraceFilter)
if (ktElement is KtSimpleNameExpression) { if (ktElement is KtSimpleNameExpression) {
@@ -404,8 +469,7 @@ class ResolveElementCache(
val declaration = modifierList?.getParentOfType<KtDeclaration>(true) val declaration = modifierList?.getParentOfType<KtDeclaration>(true)
if (declaration != null) { if (declaration != null) {
doResolveAnnotations(getAnnotationsByDeclaration(resolveSession, modifierList, declaration)) doResolveAnnotations(getAnnotationsByDeclaration(resolveSession, modifierList, declaration))
} } else {
else {
val fileAnnotationList = ktAnnotationEntry.getParentOfType<KtFileAnnotationList>(true) val fileAnnotationList = ktAnnotationEntry.getParentOfType<KtFileAnnotationList>(true)
if (fileAnnotationList != null) { if (fileAnnotationList != null) {
doResolveAnnotations(resolveSession.getFileAnnotations(fileAnnotationList.containingKtFile)) doResolveAnnotations(resolveSession.getFileAnnotations(fileAnnotationList.containingKtFile))
@@ -422,12 +486,16 @@ class ResolveElementCache(
ForceResolveUtil.forceResolveAllContents(annotations) ForceResolveUtil.forceResolveAllContents(annotations)
} }
private fun getAnnotationsByDeclaration(resolveSession: ResolveSession, modifierList: KtModifierList, declaration: KtDeclaration): Annotations { private fun getAnnotationsByDeclaration(
resolveSession: ResolveSession,
modifierList: KtModifierList,
declaration: KtDeclaration
): Annotations {
var descriptor = resolveSession.resolveToDescriptor(declaration) var descriptor = resolveSession.resolveToDescriptor(declaration)
if (declaration is KtClass) { if (declaration is KtClass) {
if (modifierList == declaration.primaryConstructorModifierList) { if (modifierList == declaration.primaryConstructorModifierList) {
descriptor = (descriptor as ClassDescriptor).unsubstitutedPrimaryConstructor descriptor = (descriptor as ClassDescriptor).unsubstitutedPrimaryConstructor
?: error("No constructor found: ${declaration.getText()}") ?: error("No constructor found: ${declaration.getText()}")
} }
} }
@@ -445,9 +513,11 @@ class ResolveElementCache(
return resolveSession.trace return resolveSession.trace
} }
private fun delegationSpecifierAdditionalResolve(resolveSession: ResolveSession, ktElement: KtElement, private fun delegationSpecifierAdditionalResolve(
classOrObject: KtClassOrObject, file: KtFile, resolveSession: ResolveSession, ktElement: KtElement,
bindingTraceFilter: BindingTraceFilter): BindingTrace { classOrObject: KtClassOrObject, file: KtFile,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(ktElement, bindingTraceFilter) val trace = createDelegatingTrace(ktElement, bindingTraceFilter)
val descriptor = resolveSession.resolveToDescriptor(classOrObject) as LazyClassDescriptor val descriptor = resolveSession.resolveToDescriptor(classOrObject) as LazyClassDescriptor
@@ -455,20 +525,24 @@ class ResolveElementCache(
ForceResolveUtil.forceResolveAllContents(descriptor.typeConstructor.supertypes) ForceResolveUtil.forceResolveAllContents(descriptor.typeConstructor.supertypes)
val bodyResolver = createBodyResolver(resolveSession, trace, file, StatementFilter.NONE) val bodyResolver = createBodyResolver(resolveSession, trace, file, StatementFilter.NONE)
bodyResolver.resolveSuperTypeEntryList(DataFlowInfo.EMPTY, bodyResolver.resolveSuperTypeEntryList(
classOrObject, DataFlowInfo.EMPTY,
descriptor, classOrObject,
descriptor.unsubstitutedPrimaryConstructor, descriptor,
descriptor.scopeForConstructorHeaderResolution, descriptor.unsubstitutedPrimaryConstructor,
descriptor.scopeForMemberDeclarationResolution) descriptor.scopeForConstructorHeaderResolution,
descriptor.scopeForMemberDeclarationResolution
)
return trace return trace
} }
private fun propertyAdditionalResolve(resolveSession: ResolveSession, property: KtProperty, private fun propertyAdditionalResolve(
file: KtFile, resolveSession: ResolveSession, property: KtProperty,
statementFilter: StatementFilter, file: KtFile,
bindingTraceFilter: BindingTraceFilter): BindingTrace { statementFilter: StatementFilter,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(property, bindingTraceFilter) val trace = createDelegatingTrace(property, bindingTraceFilter)
val bodyResolver = createBodyResolver(resolveSession, trace, file, statementFilter) val bodyResolver = createBodyResolver(resolveSession, trace, file, statementFilter)
@@ -488,15 +562,17 @@ class ResolveElementCache(
for (accessor in property.accessors) { for (accessor in property.accessors) {
ControlFlowInformationProvider( ControlFlowInformationProvider(
accessor, trace, accessor.languageVersionSettings, resolveSession.platformDiagnosticSuppressor accessor, trace, accessor.languageVersionSettings, resolveSession.platformDiagnosticSuppressor
).checkDeclaration() ).checkDeclaration()
} }
return trace return trace
} }
private fun scriptAdditionalResolve(resolveSession: ResolveSession, script: KtScript, private fun scriptAdditionalResolve(
bindingTraceFilter: BindingTraceFilter): BindingTrace { resolveSession: ResolveSession, script: KtScript,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(script, bindingTraceFilter) val trace = createDelegatingTrace(script, bindingTraceFilter)
val scriptDescriptor = resolveSession.resolveToDescriptor(script) as ScriptDescriptor val scriptDescriptor = resolveSession.resolveToDescriptor(script) as ScriptDescriptor
ForceResolveUtil.forceResolveAllContents(scriptDescriptor) ForceResolveUtil.forceResolveAllContents(scriptDescriptor)
@@ -504,9 +580,11 @@ class ResolveElementCache(
return trace return trace
} }
private fun functionAdditionalResolve(resolveSession: ResolveSession, namedFunction: KtNamedFunction, file: KtFile, private fun functionAdditionalResolve(
statementFilter: StatementFilter, resolveSession: ResolveSession, namedFunction: KtNamedFunction, file: KtFile,
bindingTraceFilter: BindingTraceFilter): BindingTrace { statementFilter: StatementFilter,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(namedFunction, bindingTraceFilter) val trace = createDelegatingTrace(namedFunction, bindingTraceFilter)
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(namedFunction) val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(namedFunction)
@@ -521,9 +599,11 @@ class ResolveElementCache(
return trace return trace
} }
private fun secondaryConstructorAdditionalResolve(resolveSession: ResolveSession, constructor: KtSecondaryConstructor, private fun secondaryConstructorAdditionalResolve(
file: KtFile, statementFilter: StatementFilter, resolveSession: ResolveSession, constructor: KtSecondaryConstructor,
bindingTraceFilter: BindingTraceFilter): BindingTrace { file: KtFile, statementFilter: StatementFilter,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(constructor, bindingTraceFilter) val trace = createDelegatingTrace(constructor, bindingTraceFilter)
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(constructor) val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(constructor)
@@ -538,20 +618,33 @@ class ResolveElementCache(
return trace return trace
} }
private fun constructorAdditionalResolve(resolveSession: ResolveSession, klass: KtClassOrObject, file: KtFile, filter : BindingTraceFilter): BindingTrace { private fun constructorAdditionalResolve(
resolveSession: ResolveSession,
klass: KtClassOrObject,
file: KtFile,
filter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(klass, filter) val trace = createDelegatingTrace(klass, filter)
val classDescriptor = resolveSession.resolveToDescriptor(klass) as ClassDescriptor val classDescriptor = resolveSession.resolveToDescriptor(klass) as ClassDescriptor
val constructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor val constructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor
?: error("Can't get primary constructor for descriptor '$classDescriptor' " + ?: error(
"in from class '${klass.getElementTextWithContext()}'") "Can't get primary constructor for descriptor '$classDescriptor' " +
"in from class '${klass.getElementTextWithContext()}'"
)
ForceResolveUtil.forceResolveAllContents(constructorDescriptor) ForceResolveUtil.forceResolveAllContents(constructorDescriptor)
val primaryConstructor = klass.primaryConstructor val primaryConstructor = klass.primaryConstructor
if (primaryConstructor != null) { if (primaryConstructor != null) {
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(primaryConstructor) val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(primaryConstructor)
val bodyResolver = createBodyResolver(resolveSession, trace, file, StatementFilter.NONE) val bodyResolver = createBodyResolver(resolveSession, trace, file, StatementFilter.NONE)
bodyResolver.resolveConstructorParameterDefaultValues(DataFlowInfo.EMPTY, trace, primaryConstructor, constructorDescriptor, scope) bodyResolver.resolveConstructorParameterDefaultValues(
DataFlowInfo.EMPTY,
trace,
primaryConstructor,
constructorDescriptor,
scope
)
forceResolveAnnotationsInside(primaryConstructor) forceResolveAnnotationsInside(primaryConstructor)
} }
@@ -559,8 +652,10 @@ class ResolveElementCache(
return trace return trace
} }
private fun typealiasAdditionalResolve(resolveSession: ResolveSession, typeAlias: KtTypeAlias, private fun typealiasAdditionalResolve(
bindingTraceFilter: BindingTraceFilter): BindingTrace { resolveSession: ResolveSession, typeAlias: KtTypeAlias,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(typeAlias, bindingTraceFilter) val trace = createDelegatingTrace(typeAlias, bindingTraceFilter)
val typeAliasDescriptor = resolveSession.resolveToDescriptor(typeAlias) val typeAliasDescriptor = resolveSession.resolveToDescriptor(typeAlias)
ForceResolveUtil.forceResolveAllContents(typeAliasDescriptor) ForceResolveUtil.forceResolveAllContents(typeAliasDescriptor)
@@ -568,9 +663,11 @@ class ResolveElementCache(
return trace return trace
} }
private fun initializerAdditionalResolve(resolveSession: ResolveSession, anonymousInitializer: KtAnonymousInitializer, private fun initializerAdditionalResolve(
file: KtFile, statementFilter: StatementFilter, resolveSession: ResolveSession, anonymousInitializer: KtAnonymousInitializer,
bindingTraceFilter: BindingTraceFilter): BindingTrace { file: KtFile, statementFilter: StatementFilter,
bindingTraceFilter: BindingTraceFilter
): BindingTrace {
val trace = createDelegatingTrace(anonymousInitializer, bindingTraceFilter) val trace = createDelegatingTrace(anonymousInitializer, bindingTraceFilter)
val classOrObjectDescriptor = resolveSession.resolveToDescriptor(anonymousInitializer.containingDeclaration) as LazyClassDescriptor val classOrObjectDescriptor = resolveSession.resolveToDescriptor(anonymousInitializer.containingDeclaration) as LazyClassDescriptor
@@ -592,32 +689,39 @@ class ResolveElementCache(
} }
private fun createBodyResolver( private fun createBodyResolver(
resolveSession: ResolveSession, resolveSession: ResolveSession,
trace: BindingTrace, trace: BindingTrace,
file: KtFile, file: KtFile,
statementFilter: StatementFilter statementFilter: StatementFilter
): BodyResolver { ): BodyResolver {
val globalContext = SimpleGlobalContext(resolveSession.storageManager, resolveSession.exceptionTracker) val globalContext = SimpleGlobalContext(resolveSession.storageManager, resolveSession.exceptionTracker)
val module = resolveSession.moduleDescriptor val module = resolveSession.moduleDescriptor
return createContainerForBodyResolve( return createContainerForBodyResolve(
globalContext.withProject(file.project).withModule(module), globalContext.withProject(file.project).withModule(module),
trace, trace,
targetPlatform, targetPlatform,
statementFilter, statementFilter,
file.jvmTarget, file.jvmTarget,
file.languageVersionSettings file.languageVersionSettings
).get<BodyResolver>() ).get<BodyResolver>()
} }
// All additional resolve should be done to separate trace // All additional resolve should be done to separate trace
private fun createDelegatingTrace(resolveElement: KtElement, filter: BindingTraceFilter): BindingTrace { private fun createDelegatingTrace(resolveElement: KtElement, filter: BindingTraceFilter): BindingTrace {
return resolveSession.storageManager.createSafeTrace( return resolveSession.storageManager.createSafeTrace(
DelegatingBindingTrace(resolveSession.bindingContext, "trace to resolve element", resolveElement, filter, allowSliceRewrite = true)) DelegatingBindingTrace(
resolveSession.bindingContext,
"trace to resolve element",
resolveElement,
filter,
allowSliceRewrite = true
)
)
} }
private class BodyResolveContextForLazy( private class BodyResolveContextForLazy(
private val topDownAnalysisMode: TopDownAnalysisMode, private val topDownAnalysisMode: TopDownAnalysisMode,
private val declaringScopes: Function1<KtDeclaration, LexicalScope?> private val declaringScopes: Function1<KtDeclaration, LexicalScope?>
) : BodiesResolveContext { ) : BodiesResolveContext {
override fun getFiles(): Collection<KtFile> = setOf() override fun getFiles(): Collection<KtFile> = setOf()