Fixing replaceFileScope and other stuff

This commit is contained in:
Valentin Kipyatkov
2015-10-23 21:40:21 +03:00
parent 9eeb051bd4
commit 6252fb04c4
5 changed files with 65 additions and 64 deletions
@@ -26,17 +26,11 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.util.collectionUtils.concat import org.jetbrains.kotlin.util.collectionUtils.concat
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
@Deprecated("We probably don't need it at all") public val LexicalScope.parentsWithSelf: Sequence<LexicalScope>
public fun LexicalScope.getImportingScopeChain(): ImportingScope { get() = sequence(this) { it.parent }
var currentScope = this
while(currentScope.parent != null) { public val LexicalScope.parents: Sequence<LexicalScope>
currentScope = currentScope.parent!! get() = parentsWithSelf.drop(1)
}
assert(currentScope is ImportingScope) {
"Not FileScope without parent: $currentScope" // todo improve debug message
}
return currentScope as ImportingScope
}
/** /**
* Adds receivers to the list in order of locality, so that the closest (the most local) receiver goes first * Adds receivers to the list in order of locality, so that the closest (the most local) receiver goes first
@@ -84,25 +78,21 @@ public fun LexicalScope.getDescriptorsFiltered(
@Deprecated("Use getOwnProperties instead") @Deprecated("Use getOwnProperties instead")
public fun LexicalScope.getLocalVariable(name: Name): VariableDescriptor? { public fun LexicalScope.getLocalVariable(name: Name): VariableDescriptor? {
processForMeAndParent { return findFirstFromMeAndParent {
if (it is LexicalScopeWrapper) { when {
it.delegate.getLocalVariable(name)?.let { return it } it is LexicalScopeWrapper -> it.delegate.getLocalVariable(name)
}
else if (it is MemberScopeToImportingScopeAdapter) { // todo remove hack it is MemberScopeToImportingScopeAdapter -> it.memberScope.getLocalVariable(name) /* todo remove hack*/
it.memberScope.getLocalVariable(name)?.let { return it }
} it !is ImportingScope && it !is LexicalChainedScope -> it.getDeclaredVariables(name, NoLookupLocation.UNSORTED).singleOrNull() /* todo check this*/
else if (it !is ImportingScope && it !is LexicalChainedScope) { // todo check this
it.getDeclaredVariables(name, NoLookupLocation.UNSORTED).singleOrNull()?.let { return it } else -> null
} }
} }
return null
} }
public fun LexicalScope.getClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { public fun LexicalScope.getClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
processForMeAndParent { return findFirstFromMeAndParent { it.getDeclaredClassifier(name, location) }
it.getDeclaredClassifier(name, location)?.let { return it }
}
return null
} }
public fun LexicalScope.takeSnapshot(): LexicalScope = if (this is LexicalWritableScope) takeSnapshot() else this public fun LexicalScope.takeSnapshot(): LexicalScope = if (this is LexicalWritableScope) takeSnapshot() else this
@@ -131,10 +121,7 @@ private class LexicalToKtScopeAdapter(lexicalScope: LexicalScope): KtScope {
override fun getClassifier(name: Name, location: LookupLocation) = lexicalScope.getClassifier(name, location) override fun getClassifier(name: Name, location: LookupLocation) = lexicalScope.getClassifier(name, location)
override fun getPackage(name: Name): PackageViewDescriptor? { override fun getPackage(name: Name): PackageViewDescriptor? {
lexicalScope.processForMeAndParent { return lexicalScope.findFirstFromMeAndParent { (it as? ImportingScope)?.getPackage(name) }
(it as? ImportingScope)?.getPackage(name)?.let { return it }
}
return null
} }
override fun getProperties(name: Name, location: LookupLocation): Collection<VariableDescriptor> { override fun getProperties(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
@@ -245,7 +232,7 @@ private class MemberScopeToImportingScopeAdapter(override val parent: ImportingS
} }
} }
private inline fun LexicalScope.processForMeAndParent(process: (LexicalScope) -> Unit) { inline fun LexicalScope.processForMeAndParent(process: (LexicalScope) -> Unit) {
var currentScope = this var currentScope = this
process(currentScope) process(currentScope)
@@ -271,7 +258,7 @@ private inline fun <T: Any> LexicalScope.collectFromMeAndParent(
return result ?: emptyList() return result ?: emptyList()
} }
internal inline fun <T: Any> LexicalScope.collectAllFromMeAndParent( inline fun <T: Any> LexicalScope.collectAllFromMeAndParent(
collect: (LexicalScope) -> Collection<T> collect: (LexicalScope) -> Collection<T>
): Collection<T> { ): Collection<T> {
var result: Collection<T>? = null var result: Collection<T>? = null
@@ -279,32 +266,40 @@ internal inline fun <T: Any> LexicalScope.collectAllFromMeAndParent(
return result ?: emptySet() return result ?: emptySet()
} }
public fun LexicalScope.addImportScope(importScope: KtScope): LexicalScope { inline fun <T: Any> LexicalScope.findFirstFromMeAndParent(fetch: (LexicalScope) -> T?): T? {
val fileScope = getImportingScopeChain() processForMeAndParent { fetch(it)?.let { return it } }
val scopeWithAdditionImport = return null
LexicalChainedScope(fileScope, fileScope.ownerDescriptor, false, null, "Scope with addition import", importScope)
return replaceFileScope(scopeWithAdditionImport)
} }
//TODO!!! fun LexicalScope.addImportScope(importScope: KtScope): LexicalScope {
public fun LexicalScope.replaceFileScope(fileScopeReplace: LexicalScope): LexicalScope { if (this is ImportingScope) {
if (this is ImportingScope) return fileScopeReplace return importScope.memberScopeAsImportingScope(this)
}
return LexicalScopeWrapper(this, fileScopeReplace) else {
val lastNonImporting = parentsWithSelf.last { it !is ImportingScope }
val firstImporting = lastNonImporting.parent as ImportingScope?
val newImportingScope = importScope.memberScopeAsImportingScope(firstImporting)
return LexicalScopeWrapper(this, newImportingScope)
}
} }
public fun LexicalScope.withNoFileScope(): LexicalScope = replaceFileScope(MemberScopeToImportingScopeAdapter(null, KtScope.Empty)) fun LexicalScope.replaceImportingScopes(importingScopeChain: ImportingScope?): LexicalScope {
return if (this is ImportingScope)
importingScopeChain!!
else
LexicalScopeWrapper(this, importingScopeChain)
}
private class LexicalScopeWrapper(val delegate: LexicalScope, val fileScopeReplace: LexicalScope): LexicalScope by delegate { private class LexicalScopeWrapper(val delegate: LexicalScope, val newImportingScopeChain: ImportingScope?): LexicalScope by delegate {
override val parent: LexicalScope? by lazy(LazyThreadSafetyMode.NONE) { override val parent: LexicalScope? by lazy(LazyThreadSafetyMode.NONE) {
assert(delegate !is ImportingScope) { "We should replace FileScope($delegate) to $fileScopeReplace" } assert(delegate !is ImportingScope)
val parent = delegate.parent!!
if (parent is ImportingScope) { val parent = delegate.parent
fileScopeReplace if (parent == null || parent is ImportingScope) {
newImportingScopeChain
} }
else { else {
LexicalScopeWrapper(parent, fileScopeReplace) LexicalScopeWrapper(parent, newImportingScopeChain)
} }
} }
} }
@@ -40,9 +40,10 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
import org.jetbrains.kotlin.resolve.scopes.utils.findFirstFromMeAndParent
import org.jetbrains.kotlin.resolve.scopes.utils.getClassifier import org.jetbrains.kotlin.resolve.scopes.utils.getClassifier
import org.jetbrains.kotlin.resolve.scopes.utils.getImportingScopeChain
import java.util.* import java.util.*
public class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT }) { public class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT }) {
@@ -280,7 +281,7 @@ public class ShortenReferences(val options: (KtElement) -> Options = { Options.D
val targetByName = if (target is ClassifierDescriptor) val targetByName = if (target is ClassifierDescriptor)
scope.getClassifier(name, NoLookupLocation.FROM_IDE) scope.getClassifier(name, NoLookupLocation.FROM_IDE)
else else
scope.getImportingScopeChain().getPackage(name) scope.findFirstFromMeAndParent { (it as? ImportingScope)?.getPackage(name) }
val canShortenNow = targetByName?.asString() == target.asString() val canShortenNow = targetByName?.asString() == target.asString()
processQualifiedElement(type, target, canShortenNow) processQualifiedElement(type, target, canShortenNow)
@@ -40,10 +40,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.ImportPath import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
import org.jetbrains.kotlin.resolve.scopes.KtScope import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.utils.asKtScope import org.jetbrains.kotlin.resolve.scopes.utils.*
import org.jetbrains.kotlin.resolve.scopes.utils.getClassifier
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import org.jetbrains.kotlin.resolve.scopes.utils.withNoFileScope
import java.util.* import java.util.*
public class KotlinImportOptimizer() : ImportOptimizer { public class KotlinImportOptimizer() : ImportOptimizer {
@@ -137,7 +134,7 @@ public class KotlinImportOptimizer() : ImportOptimizer {
} }
val resolutionScope = place.getResolutionScope(bindingContext, place.getResolutionFacade()) val resolutionScope = place.getResolutionScope(bindingContext, place.getResolutionFacade())
val noImportsScope = resolutionScope.withNoFileScope() val noImportsScope = resolutionScope.replaceImportingScopes(null)
return isInScope(noImportsScope.asKtScope()) return isInScope(noImportsScope.asKtScope())
|| resolutionScope.getImplicitReceiversHierarchy().any { isInScope(it.type.memberScope) } || resolutionScope.getImplicitReceiversHierarchy().any { isInScope(it.type.memberScope) }
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.isAnnotatedAsHidden import org.jetbrains.kotlin.resolve.isAnnotatedAsHidden
import org.jetbrains.kotlin.resolve.scopes.ImportingScope import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
@@ -89,8 +90,12 @@ public class ConflictingExtensionPropertyInspection : AbstractKotlinInspection()
private fun conflictingSyntheticExtension(descriptor: PropertyDescriptor, importingScope: ImportingScope): SyntheticJavaPropertyDescriptor? { private fun conflictingSyntheticExtension(descriptor: PropertyDescriptor, importingScope: ImportingScope): SyntheticJavaPropertyDescriptor? {
val extensionReceiverType = descriptor.extensionReceiverParameter?.type ?: return null val extensionReceiverType = descriptor.extensionReceiverParameter?.type ?: return null
return importingScope return importingScope
.getSyntheticExtensionProperties(listOf(extensionReceiverType), descriptor.name, NoLookupLocation.FROM_IDE) .collectAllFromMeAndParent {
.firstIsInstanceOrNull() (it as? ImportingScope)
?.getSyntheticExtensionProperties(listOf(extensionReceiverType), descriptor.name, NoLookupLocation.FROM_IDE)
?: emptyList()
}
.firstIsInstanceOrNull<SyntheticJavaPropertyDescriptor>()
} }
private fun isSameAsSynthetic(declaration: KtProperty, syntheticProperty: SyntheticJavaPropertyDescriptor): Boolean { private fun isSameAsSynthetic(declaration: KtProperty, syntheticProperty: SyntheticJavaPropertyDescriptor): Boolean {
@@ -41,7 +41,8 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.utils.getImportingScopeChain import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.addToStdlib.check import org.jetbrains.kotlin.utils.addToStdlib.check
@@ -178,12 +179,14 @@ public class RedundantSamConstructorInspection : AbstractKotlinInspection() {
} }
// SAM adapters for member functions // SAM adapters for member functions
val resolutionScope = functionCall.getResolutionScope(bindingContext, functionCall.getResolutionFacade()).getImportingScopeChain() val resolutionScope = functionCall.getResolutionScope(bindingContext, functionCall.getResolutionFacade())
val syntheticExtensions = resolutionScope.getSyntheticExtensionFunctions( val syntheticExtensions = resolutionScope.collectAllFromMeAndParent {
containingClass.defaultType.singletonList(), (it as? ImportingScope)?.getSyntheticExtensionFunctions(
functionResolvedCall.resultingDescriptor.name, containingClass.defaultType.singletonList(),
NoLookupLocation.FROM_IDE functionResolvedCall.resultingDescriptor.name,
) NoLookupLocation.FROM_IDE
) ?: emptyList()
}
for (syntheticExtension in syntheticExtensions) { for (syntheticExtension in syntheticExtensions) {
val samAdapter = syntheticExtension as? SamAdapterExtensionFunctionDescriptor ?: continue val samAdapter = syntheticExtension as? SamAdapterExtensionFunctionDescriptor ?: continue
if (isSamAdapterSuitableForCall(samAdapter, originalFunctionDescriptor, samConstructorCalls.size())) { if (isSamAdapterSuitableForCall(samAdapter, originalFunctionDescriptor, samConstructorCalls.size())) {