Reformat: ResolveElementCache
This commit is contained in:
@@ -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()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user