diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.java index bce8243b71c..c9e612057dd 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.java @@ -114,7 +114,7 @@ public class ReplInterpreter { FileScopeProvider.AdditionalScopes scopeProvider = new FileScopeProvider.AdditionalScopes() { @NotNull @Override - public List scopes(@NotNull JetFile file) { + public List getScopes() { return lastLineScope != null ? new SmartList(lastLineScope) : Collections.emptyList(); } }; diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/AdditionalScopesWithJavaSyntheticExtensions.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/AdditionalScopesWithJavaSyntheticExtensions.kt index 84bd1b1d6c6..af32c469e9e 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/AdditionalScopesWithJavaSyntheticExtensions.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/AdditionalScopesWithJavaSyntheticExtensions.kt @@ -16,12 +16,9 @@ package org.jetbrains.kotlin.synthetic -import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider import org.jetbrains.kotlin.storage.StorageManager class AdditionalScopesWithJavaSyntheticExtensions(storageManager: StorageManager) : FileScopeProvider.AdditionalScopes { - private val scopes = listOf(JavaSyntheticPropertiesScope(storageManager), SamAdapterFunctionsScope(storageManager)) - - override fun scopes(file: JetFile) = scopes + override val scopes = listOf(JavaSyntheticPropertiesScope(storageManager), SamAdapterFunctionsScope(storageManager)) } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProvider.kt index 29854c8b2dc..a7cc4558675 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProvider.kt @@ -29,7 +29,7 @@ public interface FileScopeProvider { } public interface AdditionalScopes { - public fun scopes(file: JetFile): List + public val scopes: List } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProviderImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProviderImpl.kt index 909a2a5b999..f2918f1c424 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProviderImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeProviderImpl.kt @@ -80,7 +80,7 @@ public class FileScopeProviderImpl( scopeChain.add(LazyImportScope(packageFragment, allUnderImportResolver, LazyImportScope.FilteringKind.VISIBLE_CLASSES, "All under imports in $debugName (visible classes)")) scopeChain.add(LazyImportScope(packageFragment, defaultAllUnderImportResolver, LazyImportScope.FilteringKind.VISIBLE_CLASSES, "Default all under imports in $debugName (visible classes)")) - scopeChain.addAll(additionalScopes.flatMap { it.scopes(file) }) + scopeChain.addAll(additionalScopes.flatMap { it.scopes }) scopeChain.add(LazyImportScope(packageFragment, allUnderImportResolver, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, "All under imports in $debugName (invisible classes only)")) scopeChain.add(LazyImportScope(packageFragment, defaultAllUnderImportResolver, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, "Default all under imports in $debugName (invisible classes only)")) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt index b32cea9a6bb..c32a575c2ac 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt @@ -38,12 +38,12 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider import org.jetbrains.kotlin.resolve.lazy.descriptors.ClassResolutionScopesSupport import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver import org.jetbrains.kotlin.resolve.scopes.utils.asJetScope import org.jetbrains.kotlin.resolve.scopes.utils.asLexicalScope -import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsFileScope import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices @@ -91,9 +91,9 @@ object ReplaceWithAnnotationAnalyzer { val explicitlyImportedSymbols = importFqNames.flatMap { resolutionFacade.resolveImportReference(symbolDescriptor.module, it) } - val symbolScope = getResolutionScope(symbolDescriptor) - val scope = LexicalChainedScope(symbolScope, symbolDescriptor, false, null, "ReplaceWith resolution scope", - ExplicitImportsScope(explicitlyImportedSymbols)) + val additionalScopes = resolutionFacade.getFrontendService(FileScopeProvider.AdditionalScopes::class.java) + val scope = getResolutionScope(symbolDescriptor, symbolDescriptor, + listOf(ExplicitImportsScope(explicitlyImportedSymbols)) + additionalScopes.scopes) var bindingContext = analyzeInContext(expression, symbolDescriptor, scope, resolutionFacade) @@ -137,7 +137,7 @@ object ReplaceWithAnnotationAnalyzer { else resolvedCall.getDispatchReceiver() if (receiver is ThisReceiver) { - val receiverExpression = receiver.asExpression(symbolScope.asJetScope(), psiFactory) + val receiverExpression = receiver.asExpression(scope.asJetScope(), psiFactory) if (receiverExpression != null) { receiversToAdd.add(expression to receiverExpression) } @@ -170,32 +170,31 @@ object ReplaceWithAnnotationAnalyzer { return traceContext.bindingContext } - private fun getResolutionScope(descriptor: DeclarationDescriptor): LexicalScope { + private fun getResolutionScope(descriptor: DeclarationDescriptor, ownerDescriptor: DeclarationDescriptor, additionalScopes: Collection): LexicalScope { return when (descriptor) { is PackageFragmentDescriptor -> { - val moduleDescriptor = descriptor.getContainingDeclaration() - getResolutionScope(moduleDescriptor.getPackage(descriptor.fqName)) + val moduleDescriptor = descriptor.containingDeclaration + getResolutionScope(moduleDescriptor.getPackage(descriptor.fqName), ownerDescriptor, additionalScopes) } is PackageViewDescriptor -> - descriptor.memberScope.memberScopeAsFileScope() + ChainedScope(ownerDescriptor, "ReplaceWith resolution scope", descriptor.memberScope, *additionalScopes.toTypedArray()).asLexicalScope() is ClassDescriptorWithResolutionScopes -> - descriptor.getScopeForMemberDeclarationResolution() + descriptor.scopeForMemberDeclarationResolution is ClassDescriptor -> { - val outerScope = getResolutionScope(descriptor.getContainingDeclaration()) - ClassResolutionScopesSupport(descriptor, LockBasedStorageManager.NO_LOCKS, { outerScope }) - .scopeForMemberDeclarationResolution() + val outerScope = getResolutionScope(descriptor.containingDeclaration, ownerDescriptor, additionalScopes) + ClassResolutionScopesSupport(descriptor, LockBasedStorageManager.NO_LOCKS, { outerScope }).scopeForMemberDeclarationResolution() } is FunctionDescriptor -> - FunctionDescriptorUtil.getFunctionInnerScope(getResolutionScope(descriptor.getContainingDeclaration()), + FunctionDescriptorUtil.getFunctionInnerScope(getResolutionScope(descriptor.containingDeclaration, ownerDescriptor, additionalScopes), descriptor, RedeclarationHandler.DO_NOTHING) is PropertyDescriptor -> JetScopeUtils.getPropertyDeclarationInnerScope(descriptor, - getResolutionScope(descriptor.getContainingDeclaration()), + getResolutionScope(descriptor.getContainingDeclaration(), ownerDescriptor, additionalScopes), RedeclarationHandler.DO_NOTHING) is LocalVariableDescriptor -> { val declaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as JetDeclaration diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyToSyntheticExtension.kt b/idea/testData/quickfix/deprecatedSymbolUsage/propertyToSyntheticExtension.kt new file mode 100644 index 00000000000..9736f3bdfd1 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyToSyntheticExtension.kt @@ -0,0 +1,11 @@ +// "Replace with 'absolutePath'" "true" +import java.io.File + +@deprecated("", ReplaceWith("absolutePath")) +val File.prop: String + get() = absolutePath + +fun foo(file: File) { + file.prop +} + diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyToSyntheticExtension.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/propertyToSyntheticExtension.kt.after new file mode 100644 index 00000000000..6843dd4c25c --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyToSyntheticExtension.kt.after @@ -0,0 +1,11 @@ +// "Replace with 'absolutePath'" "true" +import java.io.File + +@deprecated("", ReplaceWith("absolutePath")) +val File.prop: String + get() = absolutePath + +fun foo(file: File) { + file.absolutePath +} + diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 076e4b7b46e..e4b56a383d5 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -3121,6 +3121,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("propertyToSyntheticExtension.kt") + public void testPropertyToSyntheticExtension() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/propertyToSyntheticExtension.kt"); + doTest(fileName); + } + @TestMetadata("replaceCallWithArgument.kt") public void testReplaceCallWithArgument() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/replaceCallWithArgument.kt");