K2 IC: refactor and optimize lookup tracking
- encapsulate semantic more into helpers - allow lazy scopes iteration - simplify reporting code in tower resolver - fix some inconsistencies and wrong lookups - remove redundant lookup recordings - remove lookup scopes for non-star imports The commit is a refactoring and doesn't change the behaviour of neither IC nor CRI. Changes in the lookups are mostly due to the previous obviously wrong lookups (see changed test data).
This commit is contained in:
committed by
Space Team
parent
fe4e0e9c2e
commit
a823bfd600
+1
-1
@@ -353,7 +353,7 @@ fun FirDeclarationCollector<FirBasedSymbol<*>>.collectTopLevel(file: FirFile, pa
|
|||||||
conflictingFile
|
conflictingFile
|
||||||
)
|
)
|
||||||
|
|
||||||
session.lookupTracker?.recordLookup(declarationName, file.packageFqName.asString(), declaration.source, file.source)
|
session.lookupTracker?.recordNameLookup(declarationName, file.packageFqName.asString(), declaration.source, file.source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.getLineAndColumnInPsiFil
|
|||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.incremental.components.Position
|
import org.jetbrains.kotlin.incremental.components.Position
|
||||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ class IncrementalPassThroughLookupTrackerComponent(
|
|||||||
private val requiresPosition = lookupTracker.requiresPosition
|
private val requiresPosition = lookupTracker.requiresPosition
|
||||||
private val sourceToFilePathsCache = ConcurrentHashMap<KtSourceElement, String>()
|
private val sourceToFilePathsCache = ConcurrentHashMap<KtSourceElement, String>()
|
||||||
|
|
||||||
override fun recordLookup(name: Name, inScopes: List<String>, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
override fun recordLookup(name: String, inScopes: Iterable<String>, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||||
// finding file for a source only possible for PSI, here it means
|
// finding file for a source only possible for PSI, here it means
|
||||||
// that we allow null for file source only for PSI-only "sources", currently - java ones, ignoring the other cases
|
// that we allow null for file source only for PSI-only "sources", currently - java ones, ignoring the other cases
|
||||||
// TODO: although there are valid use cases for missing fileSource, the ignore may hide some possible bugs; consider stricter implementation
|
// TODO: although there are valid use cases for missing fileSource, the ignore may hide some possible bugs; consider stricter implementation
|
||||||
@@ -38,11 +37,11 @@ class IncrementalPassThroughLookupTrackerComponent(
|
|||||||
} else Position.NO_POSITION
|
} else Position.NO_POSITION
|
||||||
|
|
||||||
for (scope in inScopes) {
|
for (scope in inScopes) {
|
||||||
lookupTracker.record(path, position, scope, ScopeKind.PACKAGE, name.asString())
|
lookupTracker.record(path, position, scope, ScopeKind.PACKAGE, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun recordLookup(name: Name, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
override fun recordLookup(name: String, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||||
recordLookup(name, SmartList(inScope), source, fileSource)
|
recordLookup(name, SmartList(inScope), source, fileSource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -132,8 +132,6 @@ class FirSignatureEnhancement(
|
|||||||
symbol = FirEnumEntrySymbol(firElement.symbol.callableId)
|
symbol = FirEnumEntrySymbol(firElement.symbol.callableId)
|
||||||
returnTypeRef = newReturnTypeRef
|
returnTypeRef = newReturnTypeRef
|
||||||
origin = FirDeclarationOrigin.Enhancement
|
origin = FirDeclarationOrigin.Enhancement
|
||||||
}.apply {
|
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(newReturnTypeRef, this.source, null)
|
|
||||||
}.symbol
|
}.symbol
|
||||||
}
|
}
|
||||||
is FirField -> {
|
is FirField -> {
|
||||||
|
|||||||
-4
@@ -19,8 +19,4 @@ class FirExplicitSimpleImportingScope(
|
|||||||
imports.filterIsInstance<FirResolvedImport>()
|
imports.filterIsInstance<FirResolvedImport>()
|
||||||
.filter { !it.isAllUnder && it.importedName != null }
|
.filter { !it.isAllUnder && it.importedName != null }
|
||||||
.groupBy { it.aliasName ?: it.importedName!! }
|
.groupBy { it.aliasName ?: it.importedName!! }
|
||||||
|
|
||||||
override val scopeOwnerLookupNames: List<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
|
||||||
simpleImports.values.flatMapTo(LinkedHashSet()) { it.map { it.packageFqName.asString() } }.toList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -476,18 +476,13 @@ private fun Candidate.prepareExpectedType(
|
|||||||
getExpectedTypeWithSAMConversion(session, scopeSession, argument, basicExpectedType, context)?.also {
|
getExpectedTypeWithSAMConversion(session, scopeSession, argument, basicExpectedType, context)?.also {
|
||||||
session.lookupTracker?.let { lookupTracker ->
|
session.lookupTracker?.let { lookupTracker ->
|
||||||
parameter.returnTypeRef.coneType.lowerBoundIfFlexible().classId?.takeIf { !it.isLocal }?.let { classId ->
|
parameter.returnTypeRef.coneType.lowerBoundIfFlexible().classId?.takeIf { !it.isLocal }?.let { classId ->
|
||||||
lookupTracker.recordLookup(
|
lookupTracker.recordClassMemberLookup(
|
||||||
SAM_LOOKUP_NAME,
|
SAM_LOOKUP_NAME.asString(),
|
||||||
classId.asString(),
|
classId,
|
||||||
callInfo.callSite.source,
|
|
||||||
callInfo.containingFile.source
|
|
||||||
)
|
|
||||||
lookupTracker.recordLookup(
|
|
||||||
classId.shortClassName,
|
|
||||||
classId.packageFqName.asString(),
|
|
||||||
callInfo.callSite.source,
|
callInfo.callSite.source,
|
||||||
callInfo.containingFile.source
|
callInfo.containingFile.source
|
||||||
)
|
)
|
||||||
|
lookupTracker.recordClassLikeLookup(classId, callInfo.callSite.source, callInfo.containingFile.source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-40
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry
|
|||||||
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers
|
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
|
||||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||||
|
|
||||||
enum class ProcessResult {
|
enum class ProcessResult {
|
||||||
@@ -277,17 +276,16 @@ class MemberScopeTowerLevel(
|
|||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
val lookupTracker = session.lookupTracker
|
val lookupTracker = session.lookupTracker
|
||||||
return processMembers(info, processor) { consumer ->
|
return processMembers(info, processor) { consumer ->
|
||||||
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
|
||||||
this.processFunctionsAndConstructorsByName(
|
this.processFunctionsAndConstructorsByName(
|
||||||
info, session, bodyResolveComponents,
|
info, session, bodyResolveComponents,
|
||||||
ConstructorFilter.OnlyInner,
|
ConstructorFilter.OnlyInner,
|
||||||
processor = {
|
processor = {
|
||||||
lookupCtx.recordCallableMemberLookup(it)
|
lookupTracker?.recordCallableCandidateAsLookup(it, info.callSite.source, info.containingFile.source)
|
||||||
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
|
||||||
consumer(it as FirFunctionSymbol<*>)
|
consumer(it as FirFunctionSymbol<*>)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,12 +295,10 @@ class MemberScopeTowerLevel(
|
|||||||
): ProcessResult {
|
): ProcessResult {
|
||||||
val lookupTracker = session.lookupTracker
|
val lookupTracker = session.lookupTracker
|
||||||
return processMembers(info, processor) { consumer ->
|
return processMembers(info, processor) { consumer ->
|
||||||
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
|
||||||
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
|
this.processPropertiesByName(info.name) {
|
||||||
this.processPropertiesByName(info.name) {
|
lookupTracker?.recordCallableCandidateAsLookup(it, info.callSite.source, info.containingFile.source)
|
||||||
lookupCtx.recordCallableMemberLookup(it)
|
consumer(it)
|
||||||
consumer(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,28 +310,6 @@ class MemberScopeTowerLevel(
|
|||||||
return ProcessResult.FOUND
|
return ProcessResult.FOUND
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun withMemberCallLookup(
|
|
||||||
lookupTracker: FirLookupTrackerComponent?,
|
|
||||||
info: CallInfo,
|
|
||||||
body: (Triple<FirLookupTrackerComponent?, SmartList<String>, CallInfo>) -> Unit
|
|
||||||
) {
|
|
||||||
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
|
|
||||||
val lookupScopes = SmartList<String>()
|
|
||||||
body(Triple(lookupTracker, lookupScopes, info))
|
|
||||||
if (lookupScopes.isNotEmpty()) {
|
|
||||||
lookupTracker?.recordCallLookup(info, lookupScopes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Triple<FirLookupTrackerComponent?, SmartList<String>, CallInfo>.recordCallableMemberLookup(callable: FirCallableSymbol<*>) {
|
|
||||||
first?.run {
|
|
||||||
recordTypeResolveAsLookup(callable.fir.returnTypeRef, third.callSite.source, third.containingFile.source)
|
|
||||||
callable.callableId.classId?.takeIf { !it.isLocal }?.let { lookupScope ->
|
|
||||||
second.add(lookupScope.asFqNameString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirCallableSymbol<*>.hasConsistentExtensionReceiver(givenExtensionReceivers: List<FirExpression>): Boolean {
|
private fun FirCallableSymbol<*>.hasConsistentExtensionReceiver(givenExtensionReceivers: List<FirExpression>): Boolean {
|
||||||
return givenExtensionReceivers.isNotEmpty() == hasExtensionReceiver()
|
return givenExtensionReceivers.isNotEmpty() == hasExtensionReceiver()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-7
@@ -5,17 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirImport
|
import org.jetbrains.kotlin.fir.declarations.FirImport
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
|
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
|
||||||
import org.jetbrains.kotlin.fir.lookupTracker
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.withFileAnalysisExceptionWrapping
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
class FirImportResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(
|
class FirImportResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(
|
||||||
@@ -61,11 +58,10 @@ open class FirImportResolveTransformer protected constructor(
|
|||||||
return transformImportForFqName(fqName, import)
|
return transformImportForFqName(fqName, import)
|
||||||
}
|
}
|
||||||
|
|
||||||
val parentFqName = fqName.parent()
|
|
||||||
currentFile?.let {
|
currentFile?.let {
|
||||||
session.lookupTracker?.recordLookup(fqName.shortName(), parentFqName.asString(), import.source, it.source)
|
session.lookupTracker?.recordFqNameLookup(fqName, import.source, it.source)
|
||||||
}
|
}
|
||||||
return transformImportForFqName(parentFqName, import)
|
return transformImportForFqName(fqName.parent(), import)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open val FqName.isAcceptable: Boolean
|
protected open val FqName.isAcceptable: Boolean
|
||||||
|
|||||||
+2
-4
@@ -87,8 +87,7 @@ class FirSpecificTypeResolverTransformer(
|
|||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
override fun transformTypeRef(typeRef: FirTypeRef, data: ScopeClassDeclaration): FirResolvedTypeRef {
|
override fun transformTypeRef(typeRef: FirTypeRef, data: ScopeClassDeclaration): FirResolvedTypeRef {
|
||||||
val scopeOwnerLookupNames = data.scopes.flatMap { it.scopeOwnerLookupNames }
|
session.lookupTracker?.recordTypeLookup(typeRef, data.scopes.flatMap { it.scopeOwnerLookupNames }, currentFile?.source)
|
||||||
session.lookupTracker?.recordTypeLookup(typeRef, scopeOwnerLookupNames, currentFile?.source)
|
|
||||||
withBareTypes(allowed = false) {
|
withBareTypes(allowed = false) {
|
||||||
typeRef.transformChildren(this, data)
|
typeRef.transformChildren(this, data)
|
||||||
}
|
}
|
||||||
@@ -102,8 +101,7 @@ class FirSpecificTypeResolverTransformer(
|
|||||||
data: ScopeClassDeclaration
|
data: ScopeClassDeclaration
|
||||||
): FirResolvedTypeRef {
|
): FirResolvedTypeRef {
|
||||||
functionTypeRef.transformChildren(this, data)
|
functionTypeRef.transformChildren(this, data)
|
||||||
val scopeOwnerLookupNames = data.scopes.flatMap { it.scopeOwnerLookupNames }
|
session.lookupTracker?.recordTypeLookup(functionTypeRef, data.scopes.flatMap { it.scopeOwnerLookupNames }, currentFile?.source)
|
||||||
session.lookupTracker?.recordTypeLookup(functionTypeRef, scopeOwnerLookupNames, currentFile?.source)
|
|
||||||
val resolvedTypeWithDiagnostic = resolveType(functionTypeRef, data)
|
val resolvedTypeWithDiagnostic = resolveType(functionTypeRef, data)
|
||||||
val resolvedType = resolvedTypeWithDiagnostic.type.takeIfAcceptable()
|
val resolvedType = resolvedTypeWithDiagnostic.type.takeIfAcceptable()
|
||||||
val diagnostic = resolvedTypeWithDiagnostic.diagnostic
|
val diagnostic = resolvedTypeWithDiagnostic.diagnostic
|
||||||
|
|||||||
+1
-1
@@ -453,8 +453,8 @@ open class FirSupertypeResolverVisitor(
|
|||||||
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
|
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
|
||||||
session.lookupTracker?.let {
|
session.lookupTracker?.let {
|
||||||
val fileSource = getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)?.source
|
val fileSource = getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)?.source
|
||||||
|
val scopeOwnerLookupNames = scopeDeclaration.scopes.flatMap { scope -> scope.scopeOwnerLookupNames }
|
||||||
for (supertypeRef in supertypeRefs) {
|
for (supertypeRef in supertypeRefs) {
|
||||||
val scopeOwnerLookupNames = scopeDeclaration.scopes.flatMap { scope -> scope.scopeOwnerLookupNames }
|
|
||||||
it.recordTypeLookup(supertypeRef, scopeOwnerLookupNames, fileSource)
|
it.recordTypeLookup(supertypeRef, scopeOwnerLookupNames, fileSource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -255,7 +255,7 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
|
|||||||
calleeReference: FirSimpleNamedReference,
|
calleeReference: FirSimpleNamedReference,
|
||||||
calleeSymbol: FirEnumEntrySymbol
|
calleeSymbol: FirEnumEntrySymbol
|
||||||
) {
|
) {
|
||||||
session.lookupTracker?.recordLookup(
|
session.lookupTracker?.recordNameLookup(
|
||||||
calleeReference.name,
|
calleeReference.name,
|
||||||
calleeSymbol.dispatchReceiverType?.classId?.asFqNameString() ?: calleeSymbol.callableId.packageName.asString(),
|
calleeSymbol.dispatchReceiverType?.classId?.asFqNameString() ?: calleeSymbol.callableId.packageName.asString(),
|
||||||
this.source,
|
this.source,
|
||||||
|
|||||||
@@ -7,36 +7,74 @@ package org.jetbrains.kotlin.fir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.AbstractCallInfo
|
import org.jetbrains.kotlin.fir.resolve.calls.AbstractCallInfo
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.name.SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
abstract class FirLookupTrackerComponent : FirSessionComponent {
|
abstract class FirLookupTrackerComponent : FirSessionComponent {
|
||||||
|
|
||||||
abstract fun recordLookup(name: Name, inScopes: List<String>, source: KtSourceElement?, fileSource: KtSourceElement?)
|
abstract fun recordLookup(name: String, inScopes: Iterable<String>, source: KtSourceElement?, fileSource: KtSourceElement?)
|
||||||
|
|
||||||
abstract fun recordLookup(name: Name, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?)
|
abstract fun recordLookup(name: String, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inType: ConeKotlinType) {
|
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inType: ConeKotlinType) {
|
||||||
val classId = inType.classId
|
val classId = inType.classId ?: return
|
||||||
if (classId?.isLocal == true) return
|
if (classId.isLocal) return
|
||||||
val scopes = SmartList(inType.renderForDebugging().replace('/', '.'))
|
val scopes = SmartList(classId.asFqNameString())
|
||||||
if (classId != null && classId.shortClassName.asString() == "Companion") {
|
if (classId.shortClassName == DEFAULT_NAME_FOR_COMPANION_OBJECT) {
|
||||||
classId.outerClassId?.asString()?.replace('/', '.')?.let {
|
classId.outerClassId?.asFqNameString()?.also {
|
||||||
scopes.add(it)
|
scopes.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recordLookup(callInfo.name, scopes, callInfo.callSite.source, callInfo.containingFile.source)
|
recordNameLookup(callInfo.name, scopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inScopes: List<String>) {
|
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inScopes: Iterable<String>) {
|
||||||
recordLookup(callInfo.name, inScopes, callInfo.callSite.source, callInfo.containingFile.source)
|
recordNameLookup(callInfo.name, inScopes, callInfo.callSite.source, callInfo.containingFile.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirLookupTrackerComponent.recordTypeLookup(typeRef: FirTypeRef, inScopes: List<String>, fileSource: KtSourceElement?) {
|
fun FirLookupTrackerComponent.recordTypeLookup(typeRef: FirTypeRef, inScopes: Iterable<String>, fileSource: KtSourceElement?) {
|
||||||
if (typeRef is FirUserTypeRef) recordLookup(typeRef.qualifier.first().name, inScopes, typeRef.source, fileSource)
|
if (typeRef is FirUserTypeRef) recordNameLookup(typeRef.qualifier.first().name, inScopes, typeRef.source, fileSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirLookupTrackerComponent.recordClassLikeLookup(classId: ClassId, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||||
|
if (!classId.isLocal && classId !in StandardClassIds.allBuiltinTypes) {
|
||||||
|
recordLookup(classId.relativeClassName.asString(), classId.packageFqName.asString(), source, fileSource)
|
||||||
|
if (classId.shortClassName == DEFAULT_NAME_FOR_COMPANION_OBJECT) {
|
||||||
|
recordLookup(
|
||||||
|
classId.outerClassId!!.relativeClassName.asString(),
|
||||||
|
classId.outerClassId!!.packageFqName.asString(),
|
||||||
|
source, fileSource
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirLookupTrackerComponent.recordClassMemberLookup(
|
||||||
|
memberName: String, classId: ClassId, source: KtSourceElement?, fileSource: KtSourceElement?
|
||||||
|
) {
|
||||||
|
recordLookup(memberName, classId.asFqNameString(), source, fileSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirLookupTrackerComponent.recordFqNameLookup(fqName: FqName, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||||
|
recordLookup(fqName.shortName().asString(), fqName.parent().asString(), source, fileSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirLookupTrackerComponent.recordNameLookup(
|
||||||
|
name: Name, inScopes: Iterable<String>, source: KtSourceElement?, fileSource: KtSourceElement?
|
||||||
|
) {
|
||||||
|
recordLookup(name.asString(), inScopes, source, fileSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirLookupTrackerComponent.recordNameLookup(name: Name, inScope: String, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||||
|
recordLookup(name.asString(), inScope, source, fileSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirLookupTrackerComponent.recordTypeResolveAsLookup(typeRef: FirTypeRef, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
fun FirLookupTrackerComponent.recordTypeResolveAsLookup(typeRef: FirTypeRef, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||||
@@ -44,23 +82,26 @@ fun FirLookupTrackerComponent.recordTypeResolveAsLookup(typeRef: FirTypeRef, sou
|
|||||||
recordTypeResolveAsLookup(typeRef.type, source, fileSource)
|
recordTypeResolveAsLookup(typeRef.type, source, fileSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: review all places that record resolved type as lookup and consider minimize the number of them; see #KT-66366
|
||||||
fun FirLookupTrackerComponent.recordTypeResolveAsLookup(type: ConeKotlinType?, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
fun FirLookupTrackerComponent.recordTypeResolveAsLookup(type: ConeKotlinType?, source: KtSourceElement?, fileSource: KtSourceElement?) {
|
||||||
if (type == null) return
|
if (type == null) return
|
||||||
if (source == null && fileSource == null) return // TODO: investigate all cases
|
if (source == null && fileSource == null) return // TODO: investigate all cases
|
||||||
if (type is ConeErrorType) return // TODO: investigate whether some cases should be recorded, e.g. unresolved
|
if (type is ConeErrorType) return // TODO: investigate whether some cases should be recorded, e.g. unresolved
|
||||||
type.classId?.let {
|
type.classId?.let { classId ->
|
||||||
if (!it.isLocal && it !in StandardClassIds.allBuiltinTypes) {
|
recordClassLikeLookup(classId, source, fileSource)
|
||||||
if (it.shortClassName.asString() != "Companion") {
|
|
||||||
recordLookup(it.shortClassName, it.packageFqName.asString(), source, fileSource)
|
|
||||||
} else {
|
|
||||||
recordLookup(it.outerClassId!!.shortClassName, it.outerClassId!!.packageFqName.asString(), source, fileSource)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
type.typeArguments.forEach {
|
type.typeArguments.forEach {
|
||||||
if (it is ConeKotlinType) recordTypeResolveAsLookup(it, source, fileSource)
|
if (it is ConeKotlinType) recordTypeResolveAsLookup(it, source, fileSource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirLookupTrackerComponent.recordCallableCandidateAsLookup(
|
||||||
|
callableSymbol: FirCallableSymbol<*>, source: KtSourceElement?, fileSource: KtSourceElement?
|
||||||
|
) {
|
||||||
|
if (!callableSymbol.callableId.isLocal && callableSymbol !is FirConstructorSymbol) {
|
||||||
|
recordTypeResolveAsLookup(callableSymbol.fir.returnTypeRef, source, fileSource)
|
||||||
|
recordFqNameLookup(callableSymbol.callableId.asSingleFqName(), source, fileSource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val FirSession.lookupTracker: FirLookupTrackerComponent? by FirSession.nullableSessionComponentAccessor()
|
val FirSession.lookupTracker: FirLookupTrackerComponent? by FirSession.nullableSessionComponentAccessor()
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import bar.*
|
|||||||
/*p:foo p:foo.A(c)*/A().c
|
/*p:foo p:foo.A(c)*/A().c
|
||||||
/*p:foo p:foo.A(d)*/A().d = "new value"
|
/*p:foo p:foo.A(d)*/A().d = "new value"
|
||||||
/*p:foo p:foo.A(foo)*/A().foo()
|
/*p:foo p:foo.A(foo)*/A().foo()
|
||||||
/*p:foo p:foo(B) p:foo.A.B(a)*/A.B().a
|
/*p:foo p:foo.A.B(a)*/A.B().a
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
||||||
/*p:foo*/A
|
/*p:foo*/A
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import bar.*
|
|||||||
/*p:foo p:foo.A(c)*/A().c
|
/*p:foo p:foo.A(c)*/A().c
|
||||||
/*p:foo p:foo.A(d)*/A().d = "new value"
|
/*p:foo p:foo.A(d)*/A().d = "new value"
|
||||||
/*p:foo p:foo.A(foo)*/A().foo()
|
/*p:foo p:foo.A(foo)*/A().foo()
|
||||||
/*p:foo p:foo(B) p:foo.A.B(a)*/A.B().a
|
/*p:foo p:foo.A.B(a)*/A.B().a
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
||||||
/*p:foo*/A
|
/*p:foo*/A
|
||||||
|
|||||||
+13
-13
@@ -3,28 +3,28 @@ package foo.bar
|
|||||||
/*p:kotlin.reflect(KProperty)*/import kotlin.reflect.KProperty
|
/*p:kotlin.reflect(KProperty)*/import kotlin.reflect.KProperty
|
||||||
|
|
||||||
/*p:foo.bar*/class D1 {
|
/*p:foo.bar*/class D1 {
|
||||||
operator fun getValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>) = 1
|
operator fun getValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>) = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo.bar*/operator fun /*p:foo.bar p:kotlin.reflect*/D1.setValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>, v: /*p:foo.bar p:kotlin.reflect*/Int) {}
|
/*p:foo.bar*/operator fun /*p:foo.bar*/D1.setValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>, v: /*p:foo.bar*/Int) {}
|
||||||
|
|
||||||
/*p:foo.bar(D2)*/open class D2 {
|
/*p:foo.bar(D2)*/open class D2 {
|
||||||
operator fun setValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>, v: /*p:foo.bar p:kotlin.reflect*/Int) {}
|
operator fun setValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>, v: /*p:foo.bar*/Int) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo.bar*/operator fun /*p:foo.bar p:kotlin.reflect*/D2.getValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>) = 1
|
/*p:foo.bar*/operator fun /*p:foo.bar*/D2.getValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>) = 1
|
||||||
/*p:foo.bar*/operator fun /*p:foo.bar p:kotlin.reflect*/D2.provideDelegate(p: /*p:foo.bar p:kotlin.reflect*/Any?, k: /*p:foo.bar p:kotlin.reflect*/Any) = this
|
/*p:foo.bar*/operator fun /*p:foo.bar*/D2.provideDelegate(p: /*p:foo.bar*/Any?, k: /*p:foo.bar*/Any) = this
|
||||||
|
|
||||||
/*p:foo.bar*/class D3 : /*p:foo.bar p:kotlin.reflect*/D2() {
|
/*p:foo.bar*/class D3 : /*p:foo.bar*/D2() {
|
||||||
operator fun provideDelegate(p: /*p:foo.bar p:kotlin.reflect*/Any?, k: /*p:foo.bar p:kotlin.reflect*/Any) = this
|
operator fun provideDelegate(p: /*p:foo.bar*/Any?, k: /*p:foo.bar*/Any) = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*p:foo.bar*/val x1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:kotlin.reflect p:kotlin.reflect(KProperty0) p:kotlin.reflect(provideDelegate)*/D1()
|
/*p:foo.bar*/val x1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:kotlin.reflect(KProperty0)*/D1()
|
||||||
/*p:foo.bar*/var y1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar(setValue) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:foo.bar.D1(setValue) p:kotlin.reflect p:kotlin.reflect(KMutableProperty0) p:kotlin.reflect(provideDelegate) p:kotlin.reflect(setValue)*/D1()
|
/*p:foo.bar*/var y1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar(setValue) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:foo.bar.D1(setValue) p:kotlin.reflect(KMutableProperty0)*/D1()
|
||||||
|
|
||||||
/*p:foo.bar*/val x2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:kotlin.reflect p:kotlin.reflect(KProperty0) p:kotlin.reflect(getValue) p:kotlin.reflect(provideDelegate)*/D2()
|
/*p:foo.bar*/val x2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:kotlin.reflect(KProperty0)*/D2()
|
||||||
/*p:foo.bar*/var y2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:foo.bar.D2(setValue) p:kotlin.reflect p:kotlin.reflect(KMutableProperty0) p:kotlin.reflect(getValue) p:kotlin.reflect(provideDelegate)*/D2()
|
/*p:foo.bar*/var y2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:foo.bar.D2(setValue) p:kotlin.reflect(KMutableProperty0)*/D2()
|
||||||
|
|
||||||
/*p:foo.bar*/val x3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:kotlin.reflect p:kotlin.reflect(KProperty0) p:kotlin.reflect(getValue)*/D3()
|
/*p:foo.bar*/val x3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:kotlin.reflect(KProperty0)*/D3()
|
||||||
/*p:foo.bar*/var y3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D2(setValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:foo.bar.D3(setValue) p:kotlin.reflect p:kotlin.reflect(KMutableProperty0) p:kotlin.reflect(getValue)*/D3()
|
/*p:foo.bar*/var y3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D2(setValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:foo.bar.D3(setValue) p:kotlin.reflect(KMutableProperty0)*/D3()
|
||||||
|
|||||||
+1
-1
@@ -12,5 +12,5 @@ package foo.bar
|
|||||||
val (/*p:foo.bar(A) p:foo.bar.A(component1)*/h, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/t) = a;
|
val (/*p:foo.bar(A) p:foo.bar.A(component1)*/h, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/t) = a;
|
||||||
|
|
||||||
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next)*/a);
|
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next)*/a);
|
||||||
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar(iterator) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next) p:foo.bar.A?(iterator)*/na);
|
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar(iterator) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next)*/na);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -5,11 +5,11 @@ package foo
|
|||||||
/*p:foo*/fun <T> identity(): (/*p:foo*/T) -> /*p:foo*/T = null as (/*p:foo*/T) -> /*p:foo*/T
|
/*p:foo*/fun <T> identity(): (/*p:foo*/T) -> /*p:foo*/T = null as (/*p:foo*/T) -> /*p:foo*/T
|
||||||
|
|
||||||
/*p:foo*/fun <T> compute(f: () -> /*p:foo*/T) {
|
/*p:foo*/fun <T> compute(f: () -> /*p:foo*/T) {
|
||||||
val result = /*p:kotlin(Function0) p:kotlin.Function0(invoke) p:kotlin.Function0<T>(invoke)*/f()
|
val result = /*p:kotlin(Function0) p:kotlin.Function0(invoke)*/f()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo*/class Bar<T>(val t: /*p:foo*/T) {
|
/*p:foo*/class Bar<T>(val t: /*p:foo*/T) {
|
||||||
init {
|
init {
|
||||||
val a = /*p:foo.Bar p:foo.Bar<T>*/t
|
val a = /*p:foo.Bar*/t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ import bar.*
|
|||||||
}
|
}
|
||||||
|
|
||||||
localFun()
|
localFun()
|
||||||
/*p:IOT(localExtFun)*/1.localExtFun()
|
1.localExtFun()
|
||||||
|
|
||||||
val c = LocalC()
|
val c = LocalC()
|
||||||
c.a
|
c.a
|
||||||
|
|||||||
+8
-8
@@ -3,15 +3,15 @@ package foo
|
|||||||
import bar.*
|
import bar.*
|
||||||
/*p:baz(C)*/import baz.C
|
/*p:baz(C)*/import baz.C
|
||||||
|
|
||||||
/*p:foo*/val a = /*p:bar p:baz p:foo*/A()
|
/*p:foo*/val a = /*p:bar p:foo*/A()
|
||||||
/*p:foo*/var b: /*p:bar p:baz p:foo*/baz.B = /*p:bar p:baz p:baz(B) p:foo*/baz.B()
|
/*p:foo*/var b: /*p:bar p:foo*/baz.B = /*p:bar p:baz(B) p:foo*/baz.B()
|
||||||
|
|
||||||
/*p:foo*/fun function(p: /*p:bar p:baz p:foo*/B): /*p:bar p:baz p:foo*/B {
|
/*p:foo*/fun function(p: /*p:bar p:foo*/B): /*p:bar p:foo*/B {
|
||||||
/*p:baz p:foo*/a
|
/*p:foo*/a
|
||||||
return /*p:bar p:baz p:foo*/B()
|
return /*p:bar p:foo*/B()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo*/fun /*p:bar p:baz p:foo*/MyClass.extFunc(p: /**p:foo p:bar*//*p:bar p:baz p:foo*/Array</*p:bar p:baz p:foo*/B>, e: /*p:bar p:baz p:foo*/MyEnum, c: /**???*//*p:bar p:baz p:foo*/C): /*p:bar p:baz p:foo*/MyInterface {
|
/*p:foo*/fun /*p:bar p:foo*/MyClass.extFunc(p: /**p:foo p:bar*//*p:bar p:foo*/Array</*p:bar p:foo*/B>, e: /*p:bar p:foo*/MyEnum, c: /**???*//*p:bar p:foo*/C): /*p:bar p:foo*/MyInterface {
|
||||||
/*p:bar p:baz p:foo p:foo.MyClass*/b
|
/*p:bar p:foo p:foo.MyClass*/b
|
||||||
return /*p:bar p:baz p:foo p:foo.MyClass*/MyClass()
|
return /*p:bar p:foo p:foo.MyClass*/MyClass()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package foo
|
|||||||
/*p:bar(C)*/import bar.C
|
/*p:bar(C)*/import bar.C
|
||||||
/*p:bar(SAMInterface)*/import bar.SAMInterface
|
/*p:bar(SAMInterface)*/import bar.SAMInterface
|
||||||
|
|
||||||
/*p:foo*/fun foo(c: /*p:bar p:foo*/C) {
|
/*p:foo*/fun foo(c: /*p:foo*/C) {
|
||||||
/*p:bar(foo) p:bar.C(foo) p:foo(foo)*/c.foo()
|
/*p:bar.C(foo) p:foo(foo)*/c.foo()
|
||||||
/*p:bar(SAMInterface) p:bar.C(foo) p:bar/SAMInterface(<SAM-CONSTRUCTOR>)*/c.foo /*p:kotlin(Function1)*/{ }
|
/*p:bar(SAMInterface) p:bar.C(foo) p:bar.SAMInterface(<SAM-CONSTRUCTOR>)*/c.foo /*p:kotlin(Function1)*/{ }
|
||||||
|
|
||||||
/*p:bar p:bar(bar) p:bar.C(bar) p:foo p:foo(bar)*/C.bar()
|
/*p:bar.C(bar) p:foo p:foo(bar)*/C.bar()
|
||||||
/*p:bar p:bar(SAMInterface) p:bar.C(bar) p:bar/SAMInterface(<SAM-CONSTRUCTOR>) p:foo*/C.bar /*p:kotlin(Function1)*/{}
|
/*p:bar(SAMInterface) p:bar.C(bar) p:bar.SAMInterface(<SAM-CONSTRUCTOR>) p:foo*/C.bar /*p:kotlin(Function1)*/{}
|
||||||
|
|
||||||
/*p:bar p:foo*/SAMInterface()
|
/*p:bar p:foo*/SAMInterface()
|
||||||
/*p:bar*/SAMInterface /*p:kotlin(Function1)*/{}
|
/*p:bar*/SAMInterface /*p:kotlin(Function1)*/{}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import bar.*
|
|||||||
/*p:foo p:foo.A(c)*/A().c
|
/*p:foo p:foo.A(c)*/A().c
|
||||||
/*p:foo p:foo.A(d)*/A().d = "new value"
|
/*p:foo p:foo.A(d)*/A().d = "new value"
|
||||||
/*p:foo p:foo.A(foo)*/A().foo()
|
/*p:foo p:foo.A(foo)*/A().foo()
|
||||||
/*p:foo p:foo(B) p:foo.A.B(a)*/A.B().a
|
/*p:foo p:foo.A.B(a)*/A.B().a
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
||||||
/*p:foo*/A
|
/*p:foo*/A
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import bar.*
|
|||||||
/*p:foo p:foo.A(c)*/A().c
|
/*p:foo p:foo.A(c)*/A().c
|
||||||
/*p:foo p:foo.A(d)*/A().d = "new value"
|
/*p:foo p:foo.A(d)*/A().d = "new value"
|
||||||
/*p:foo p:foo.A(foo)*/A().foo()
|
/*p:foo p:foo.A(foo)*/A().foo()
|
||||||
/*p:foo p:foo(B) p:foo.A.B(a)*/A.B().a
|
/*p:foo p:foo.A.B(a)*/A.B().a
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.bar(1)
|
||||||
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
/*p:bar(bar) p:foo p:foo(bar) p:foo.A.B.CO(bar)*/A.B.CO.bar(1)
|
||||||
/*p:foo*/A
|
/*p:foo*/A
|
||||||
|
|||||||
+13
-13
@@ -3,28 +3,28 @@ package foo.bar
|
|||||||
/*p:kotlin.reflect(KProperty)*/import kotlin.reflect.KProperty
|
/*p:kotlin.reflect(KProperty)*/import kotlin.reflect.KProperty
|
||||||
|
|
||||||
/*p:foo.bar*/class D1 {
|
/*p:foo.bar*/class D1 {
|
||||||
operator fun getValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>) = 1
|
operator fun getValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>) = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo.bar*/operator fun /*p:foo.bar p:kotlin.reflect*/D1.setValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>, v: /*p:foo.bar p:kotlin.reflect*/Int) {}
|
/*p:foo.bar*/operator fun /*p:foo.bar*/D1.setValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>, v: /*p:foo.bar*/Int) {}
|
||||||
|
|
||||||
/*p:foo.bar(D2)*/open class D2 {
|
/*p:foo.bar(D2)*/open class D2 {
|
||||||
operator fun setValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>, v: /*p:foo.bar p:kotlin.reflect*/Int) {}
|
operator fun setValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>, v: /*p:foo.bar*/Int) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo.bar*/operator fun /*p:foo.bar p:kotlin.reflect*/D2.getValue(t: /*p:foo.bar p:kotlin.reflect*/Any?, p: /*p:foo.bar p:kotlin.reflect*/KProperty<*>) = 1
|
/*p:foo.bar*/operator fun /*p:foo.bar*/D2.getValue(t: /*p:foo.bar*/Any?, p: /*p:foo.bar*/KProperty<*>) = 1
|
||||||
/*p:foo.bar*/operator fun /*p:foo.bar p:kotlin.reflect*/D2.provideDelegate(p: /*p:foo.bar p:kotlin.reflect*/Any?, k: /*p:foo.bar p:kotlin.reflect*/Any) = this
|
/*p:foo.bar*/operator fun /*p:foo.bar*/D2.provideDelegate(p: /*p:foo.bar*/Any?, k: /*p:foo.bar*/Any) = this
|
||||||
|
|
||||||
/*p:foo.bar*/class D3 : /*p:foo.bar p:kotlin.reflect*/D2() {
|
/*p:foo.bar*/class D3 : /*p:foo.bar*/D2() {
|
||||||
operator fun provideDelegate(p: /*p:foo.bar p:kotlin.reflect*/Any?, k: /*p:foo.bar p:kotlin.reflect*/Any) = this
|
operator fun provideDelegate(p: /*p:foo.bar*/Any?, k: /*p:foo.bar*/Any) = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*p:foo.bar*/val x1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:kotlin.reflect p:kotlin.reflect(KProperty0) p:kotlin.reflect(provideDelegate)*/D1()
|
/*p:foo.bar*/val x1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:kotlin.reflect(KProperty0)*/D1()
|
||||||
/*p:foo.bar*/var y1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar(setValue) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:foo.bar.D1(setValue) p:kotlin.reflect p:kotlin.reflect(KMutableProperty0) p:kotlin.reflect(provideDelegate) p:kotlin.reflect(setValue)*/D1()
|
/*p:foo.bar*/var y1 by /*p:foo.bar p:foo.bar(D2) p:foo.bar(provideDelegate) p:foo.bar(setValue) p:foo.bar.D1(getValue) p:foo.bar.D1(provideDelegate) p:foo.bar.D1(setValue) p:kotlin.reflect(KMutableProperty0)*/D1()
|
||||||
|
|
||||||
/*p:foo.bar*/val x2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:kotlin.reflect p:kotlin.reflect(KProperty0) p:kotlin.reflect(getValue) p:kotlin.reflect(provideDelegate)*/D2()
|
/*p:foo.bar*/val x2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:kotlin.reflect(KProperty0)*/D2()
|
||||||
/*p:foo.bar*/var y2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:foo.bar.D2(setValue) p:kotlin.reflect p:kotlin.reflect(KMutableProperty0) p:kotlin.reflect(getValue) p:kotlin.reflect(provideDelegate)*/D2()
|
/*p:foo.bar*/var y2 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar(provideDelegate) p:foo.bar.D2(getValue) p:foo.bar.D2(provideDelegate) p:foo.bar.D2(setValue) p:kotlin.reflect(KMutableProperty0)*/D2()
|
||||||
|
|
||||||
/*p:foo.bar*/val x3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:kotlin.reflect p:kotlin.reflect(KProperty0) p:kotlin.reflect(getValue)*/D3()
|
/*p:foo.bar*/val x3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:kotlin.reflect(KProperty0)*/D3()
|
||||||
/*p:foo.bar*/var y3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D2(setValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:foo.bar.D3(setValue) p:kotlin.reflect p:kotlin.reflect(KMutableProperty0) p:kotlin.reflect(getValue)*/D3()
|
/*p:foo.bar*/var y3 by /*p:foo.bar p:foo.bar(getValue) p:foo.bar.D2(setValue) p:foo.bar.D3(getValue) p:foo.bar.D3(provideDelegate) p:foo.bar.D3(setValue) p:kotlin.reflect(KMutableProperty0)*/D3()
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ package foo.bar
|
|||||||
val (/*p:foo.bar(A) p:foo.bar.A(component1)*/h, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/t) = a;
|
val (/*p:foo.bar(A) p:foo.bar.A(component1)*/h, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/t) = a;
|
||||||
|
|
||||||
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next)*/a);
|
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next)*/a);
|
||||||
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar(iterator) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next) p:foo.bar.A?(iterator)*/na);
|
for ((/*p:foo.bar(A) p:foo.bar.A(component1)*/f, /*p:foo.bar(A) p:foo.bar(component2) p:foo.bar.A(component2)*/s) in /*p:foo.bar(A) p:foo.bar(hasNext) p:foo.bar(iterator) p:foo.bar.A(hasNext) p:foo.bar.A(iterator) p:foo.bar.A(next)*/na);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -5,11 +5,11 @@ package foo
|
|||||||
/*p:foo*/fun <T> identity(): (/*p:foo*/T) -> /*p:foo*/T = null as (/*p:foo*/T) -> /*p:foo*/T
|
/*p:foo*/fun <T> identity(): (/*p:foo*/T) -> /*p:foo*/T = null as (/*p:foo*/T) -> /*p:foo*/T
|
||||||
|
|
||||||
/*p:foo*/fun <T> compute(f: () -> /*p:foo*/T) {
|
/*p:foo*/fun <T> compute(f: () -> /*p:foo*/T) {
|
||||||
val result = /*p:kotlin(Function0) p:kotlin.Function0(invoke) p:kotlin.Function0<T>(invoke)*/f()
|
val result = /*p:kotlin(Function0) p:kotlin.Function0(invoke)*/f()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo*/class Bar<T>(val t: /*p:foo*/T) {
|
/*p:foo*/class Bar<T>(val t: /*p:foo*/T) {
|
||||||
init {
|
init {
|
||||||
val a = /*p:foo.Bar p:foo.Bar<T>*/t
|
val a = /*p:foo.Bar*/t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,37 +9,37 @@ import baz.*
|
|||||||
/*p:bar.C(field)*/c.field
|
/*p:bar.C(field)*/c.field
|
||||||
/*p:bar.C(field)*/c.field = 2
|
/*p:bar.C(field)*/c.field = 2
|
||||||
/*p:bar.C(func)*/c.func()
|
/*p:bar.C(func)*/c.func()
|
||||||
/*p:bar(B) p:bar.C(B) p:bar.C.B(B)*/c.B()
|
/*p:bar(C.B) p:bar.C(B)*/c.B()
|
||||||
|
|
||||||
/*p:bar p:bar.C(sfield) p:baz p:foo*/C.sfield
|
/*p:bar.C(sfield) p:baz p:foo*/C.sfield
|
||||||
/*p:bar p:bar.C(sfield) p:baz p:foo*/C.sfield = "new"
|
/*p:bar.C(sfield) p:baz p:foo*/C.sfield = "new"
|
||||||
/*p:bar p:bar.C(sfunc) p:baz p:foo*/C.sfunc()
|
/*p:bar.C(sfunc) p:baz p:foo*/C.sfunc()
|
||||||
/*p:bar p:bar(S) p:bar.C(S) p:baz p:foo*/C.S()
|
/*p:bar p:bar.C(S) p:baz p:foo*/C.S()
|
||||||
|
|
||||||
// inherited from I
|
// inherited from I
|
||||||
/*p:bar.C(ifunc)*/c.ifunc()
|
/*p:bar.C(ifunc)*/c.ifunc()
|
||||||
/*p:bar p:bar.C(isfield) p:baz p:foo*/C.isfield
|
/*p:bar.C(isfield) p:baz p:foo*/C.isfield
|
||||||
// expected error: Unresolved reference: IS
|
// expected error: Unresolved reference: IS
|
||||||
/*p:bar p:bar(IS) p:bar.C(IS) p:baz p:baz(IS) p:foo p:foo(IS)*/C.IS()
|
/*p:bar.C(IS) p:baz p:baz(IS) p:foo p:foo(IS)*/C.IS()
|
||||||
|
|
||||||
|
|
||||||
val i: /*p:bar p:baz p:foo*/I = c
|
val i: /*p:baz p:foo*/I = c
|
||||||
/*p:foo.I(ifunc)*/i.ifunc()
|
/*p:foo.I(ifunc)*/i.ifunc()
|
||||||
|
|
||||||
/*p:bar p:baz p:foo p:foo.I(isfield)*/I.isfield
|
/*p:baz p:foo p:foo.I(isfield)*/I.isfield
|
||||||
/*p:bar p:baz p:foo p:foo(IS) p:foo.I(IS)*/I.IS()
|
/*p:baz p:foo p:foo.I(IS)*/I.IS()
|
||||||
|
|
||||||
/*p:bar p:baz p:baz.E(F) p:foo*/E.F
|
/*p:baz p:baz.E(F) p:foo*/E.F
|
||||||
/*p:bar p:baz p:baz.E(F) p:baz.E(field) p:foo*/E.F.field
|
/*p:baz p:baz.E(F) p:baz.E(field) p:foo*/E.F.field
|
||||||
/*p:bar p:baz p:baz.E(S) p:baz.E(func) p:foo*/E.S.func()
|
/*p:baz p:baz.E(S) p:baz.E(func) p:foo*/E.S.func()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun classifiers(
|
fun classifiers(
|
||||||
c: /*p:bar p:baz p:foo*/C,
|
c: /*p:baz p:foo*/C,
|
||||||
b: /*p:bar p:baz p:foo*/C.B,
|
b: /*p:baz p:foo*/C.B,
|
||||||
s: /*p:bar p:baz p:foo*/C.S,
|
s: /*p:baz p:foo*/C.S,
|
||||||
cis: /*p:bar p:baz p:foo*/C.IS,
|
cis: /*p:baz p:foo*/C.IS,
|
||||||
i: /*p:bar p:baz p:foo*/I,
|
i: /*p:baz p:foo*/I,
|
||||||
iis: /*p:bar p:baz p:foo*/I.IS,
|
iis: /*p:baz p:foo*/I.IS,
|
||||||
e: /*p:bar p:baz p:foo*/E
|
e: /*p:baz p:foo*/E
|
||||||
) {}
|
) {}
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ import bar.*
|
|||||||
}
|
}
|
||||||
|
|
||||||
localFun()
|
localFun()
|
||||||
/*p:IOT(localExtFun)*/1.localExtFun()
|
1.localExtFun()
|
||||||
|
|
||||||
val c = LocalC()
|
val c = LocalC()
|
||||||
c.a
|
c.a
|
||||||
|
|||||||
+8
-8
@@ -3,15 +3,15 @@ package foo
|
|||||||
import bar.*
|
import bar.*
|
||||||
/*p:baz(C)*/import baz.C
|
/*p:baz(C)*/import baz.C
|
||||||
|
|
||||||
/*p:foo*/val a = /*p:bar p:baz p:foo*/A()
|
/*p:foo*/val a = /*p:bar p:foo*/A()
|
||||||
/*p:foo*/var b: /*p:bar p:baz p:foo*/baz.B = /*p:bar p:baz p:baz(B) p:foo*/baz.B()
|
/*p:foo*/var b: /*p:bar p:foo*/baz.B = /*p:bar p:baz(B) p:foo*/baz.B()
|
||||||
|
|
||||||
/*p:foo*/fun function(p: /*p:bar p:baz p:foo*/B): /*p:bar p:baz p:foo*/B {
|
/*p:foo*/fun function(p: /*p:bar p:foo*/B): /*p:bar p:foo*/B {
|
||||||
/*p:baz p:foo*/a
|
/*p:foo*/a
|
||||||
return /*p:bar p:baz p:foo*/B()
|
return /*p:bar p:foo*/B()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*p:foo*/fun /*p:bar p:baz p:foo*/MyClass.extFunc(p: /**p:foo p:bar*//*p:bar p:baz p:foo*/Array</*p:bar p:baz p:foo*/B>, e: /*p:bar p:baz p:foo*/MyEnum, c: /**???*//*p:bar p:baz p:foo*/C): /*p:bar p:baz p:foo*/MyInterface {
|
/*p:foo*/fun /*p:bar p:foo*/MyClass.extFunc(p: /**p:foo p:bar*//*p:bar p:foo*/Array</*p:bar p:foo*/B>, e: /*p:bar p:foo*/MyEnum, c: /*p:bar p:foo*/C): /*p:bar p:foo*/MyInterface {
|
||||||
/*p:bar p:baz p:foo p:foo.MyClass*/b
|
/*p:bar p:foo p:foo.MyClass*/b
|
||||||
return /*p:bar p:baz p:foo p:foo.MyClass*/MyClass()
|
return /*p:bar p:foo p:foo.MyClass*/MyClass()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package foo
|
|||||||
|
|
||||||
/*p:<root>(JavaClass)*/import JavaClass
|
/*p:<root>(JavaClass)*/import JavaClass
|
||||||
|
|
||||||
/*p:foo*/class KotlinClass : /*p:<root> p:foo*/JavaClass() {
|
/*p:foo*/class KotlinClass : /*p:foo*/JavaClass() {
|
||||||
override fun getFoo() = 2
|
override fun getFoo() = 2
|
||||||
fun setFoo(i: /*p:<root> p:foo*/Int) {}
|
fun setFoo(i: /*p:foo*/Int) {}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -4,11 +4,11 @@ package foo.bar
|
|||||||
/*p:foo(KotlinClass)*/import foo.KotlinClass
|
/*p:foo(KotlinClass)*/import foo.KotlinClass
|
||||||
|
|
||||||
/*p:foo.bar*/fun test() {
|
/*p:foo.bar*/fun test() {
|
||||||
val j = /*p:<root> p:foo*/JavaClass()
|
val j = /*p:<root>*/JavaClass()
|
||||||
val k = /*p:<root> p:foo*/KotlinClass()
|
val k = /*p:foo*/KotlinClass()
|
||||||
|
|
||||||
/*p:JavaClass(getFoo)*/j.getFoo()
|
/*p:JavaClass(getFoo)*/j.getFoo()
|
||||||
/*p:<root>(setFoo) p:JavaClass(setFoo) p:foo(setFoo) p:foo.bar(setFoo)*/j.setFoo(2)
|
/*p:JavaClass(setFoo) p:foo.bar(setFoo)*/j.setFoo(2)
|
||||||
/*p:JavaClass(foo)*/j.foo = 2
|
/*p:JavaClass(foo)*/j.foo = 2
|
||||||
/*p:JavaClass(foo)*/j.foo
|
/*p:JavaClass(foo)*/j.foo
|
||||||
/*p:JavaClass(bar)*/j.bar
|
/*p:JavaClass(bar)*/j.bar
|
||||||
@@ -16,7 +16,7 @@ package foo.bar
|
|||||||
/*p:JavaClass(bazBaz)*/j.bazBaz
|
/*p:JavaClass(bazBaz)*/j.bazBaz
|
||||||
/*p:JavaClass(bazBaz)*/j.bazBaz = ""
|
/*p:JavaClass(bazBaz)*/j.bazBaz = ""
|
||||||
/*p:JavaClass(setBoo)*/j.setBoo(2)
|
/*p:JavaClass(setBoo)*/j.setBoo(2)
|
||||||
/*p:<root>(boo) p:JavaClass(boo) p:foo(boo) p:foo.bar(boo)*/j.boo = 2
|
/*p:JavaClass(boo) p:foo.bar(boo)*/j.boo = 2
|
||||||
/*p:foo.KotlinClass(getFoo)*/k.getFoo() // getFoo may be an inner class in JavaClass
|
/*p:foo.KotlinClass(getFoo)*/k.getFoo() // getFoo may be an inner class in JavaClass
|
||||||
/*p:foo.KotlinClass(setFoo)*/k.setFoo(2)
|
/*p:foo.KotlinClass(setFoo)*/k.setFoo(2)
|
||||||
/*p:foo.KotlinClass(foo)*/k.foo = 2
|
/*p:foo.KotlinClass(foo)*/k.foo = 2
|
||||||
@@ -26,5 +26,5 @@ package foo.bar
|
|||||||
/*p:JavaClass(bazBaz) p:foo.KotlinClass(bazBaz)*/k.bazBaz
|
/*p:JavaClass(bazBaz) p:foo.KotlinClass(bazBaz)*/k.bazBaz
|
||||||
/*p:JavaClass(bazBaz) p:foo.KotlinClass(bazBaz)*/k.bazBaz = ""
|
/*p:JavaClass(bazBaz) p:foo.KotlinClass(bazBaz)*/k.bazBaz = ""
|
||||||
/*p:JavaClass(setBoo) p:foo.KotlinClass(setBoo)*/k.setBoo(2)
|
/*p:JavaClass(setBoo) p:foo.KotlinClass(setBoo)*/k.setBoo(2)
|
||||||
/*p:<root>(boo) p:foo(boo) p:foo.KotlinClass(boo) p:foo.bar(boo)*/k.boo = 2
|
/*p:foo.KotlinClass(boo) p:foo.bar(boo)*/k.boo = 2
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user