From d32ba08cb7456dcd9b5a0323daab6afe23b8ac79 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 10 Jul 2015 21:53:02 +0300 Subject: [PATCH] KT-8394 ReplaceWith for Delegates.lazy fails outside of stdlib #KT-8394 Fixed --- .../ClassDescriptorWithResolutionScopes.java | 3 - .../impl/MutableClassDescriptor.java | 8 +-- .../kotlin/resolve/DeclarationResolver.kt | 2 +- .../ClassResolutionScopesSupport.kt | 68 ++++++++++++++++++ .../lazy/descriptors/LazyClassDescriptor.java | 71 +++++-------------- .../LazyScriptClassDescriptor.java | 4 +- .../lazy/descriptors/LazyScriptDescriptor.kt | 2 +- .../descriptors/LazyJavaClassDescriptor.kt | 10 +-- .../functions/FunctionClassDescriptor.kt | 2 +- .../kotlin/descriptors/ClassDescriptor.java | 3 + .../impl/AbstractClassDescriptor.java | 11 ++- .../descriptors/impl/ClassDescriptorImpl.java | 10 +-- .../EnumEntrySyntheticClassDescriptor.java | 2 +- .../impl/LazySubstitutingClassDescriptor.java | 10 +++ .../DeserializedClassDescriptor.kt | 2 +- .../textBuilder/missingDependencies.kt | 2 +- .../quickfix/ReplaceWithAnnotationAnalyzer.kt | 11 ++- .../deprecatedMemberInCompiledClass.kt | 7 ++ .../deprecatedMemberInCompiledClass.kt.after | 7 ++ .../quickfix/DeprecatedInCompiledClassTest.kt | 54 ++++++++++++++ 20 files changed, 199 insertions(+), 90 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt create mode 100644 idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt create mode 100644 idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt.after create mode 100644 idea/tests/org/jetbrains/kotlin/idea/quickfix/DeprecatedInCompiledClassTest.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/ClassDescriptorWithResolutionScopes.java b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/ClassDescriptorWithResolutionScopes.java index 07d1e710ccb..b8c9e4d3ec4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/ClassDescriptorWithResolutionScopes.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/ClassDescriptorWithResolutionScopes.java @@ -33,9 +33,6 @@ public interface ClassDescriptorWithResolutionScopes extends ClassDescriptor { @NotNull JetScope getScopeForInitializerResolution(); - @NotNull - JetScope getScopeForMemberLookup(); - @Nullable @Override ClassDescriptorWithResolutionScopes getCompanionObjectDescriptor(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java index 785f195b879..700b51a6a35 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java @@ -51,7 +51,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class // This scope contains type parameters but does not contain inner classes private final WritableScope scopeForSupertypeResolution; private JetScope scopeForInitializers; //contains members + primary constructor value parameters + map for backing fields - private final JetScope scopeForMemberLookup; + private final JetScope unsubstitutedMemberScope; private final JetScope staticScope = new StaticScopeForKotlinClass(this); public MutableClassDescriptor( @@ -70,7 +70,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING; - this.scopeForMemberLookup = new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, redeclarationHandler, "MemberLookup", null, this) + this.unsubstitutedMemberScope = new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, redeclarationHandler, "MemberLookup", null, this) .changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution") .changeLockLevel(WritableScope.LockLevel.BOTH); @@ -256,8 +256,8 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class @Override @NotNull - public JetScope getScopeForMemberLookup() { - return scopeForMemberLookup; + public JetScope getUnsubstitutedMemberScope() { + return unsubstitutedMemberScope; } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt index 880909bc1f5..b03e082fb3b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationResolver.kt @@ -61,7 +61,7 @@ public class DeclarationResolver { public fun checkRedeclarations(c: TopDownAnalysisContext) { for (classDescriptor in c.getDeclaredClasses().values()) { val descriptorMap = HashMultimap.create() - for (desc in classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors()) { + for (desc in classDescriptor.getUnsubstitutedMemberScope().getOwnDeclaredDescriptors()) { if (desc is ClassDescriptor || desc is PropertyDescriptor) { descriptorMap.put(desc.getName(), desc) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt new file mode 100644 index 00000000000..6a0ea715837 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.lazy.descriptors + +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.resolve.scopes.* +import org.jetbrains.kotlin.storage.StorageManager + +class ClassResolutionScopesSupport( + private val classDescriptor: ClassDescriptor, + storageManager: StorageManager, + private val getOuterScope: () -> JetScope +) { + private val staticScope = StaticScopeForKotlinClass(classDescriptor) + + private val scopeForClassHeaderResolution = storageManager.createLazyValue { computeScopeForClassHeaderResolution() } + private val scopeForMemberDeclarationResolution = storageManager.createLazyValue { computeScopeForMemberDeclarationResolution() } + + fun getStaticScope(): JetScope = staticScope + + fun getScopeForClassHeaderResolution(): JetScope = scopeForClassHeaderResolution() + + fun getScopeForMemberDeclarationResolution(): JetScope = scopeForMemberDeclarationResolution() + + private fun computeScopeForClassHeaderResolution(): JetScope { + val scope = WritableScopeImpl(JetScope.Empty, classDescriptor, RedeclarationHandler.DO_NOTHING, "Scope with type parameters for " + classDescriptor.getName()) + for (typeParameterDescriptor in classDescriptor.getTypeConstructor().getParameters()) { + scope.addClassifierDescriptor(typeParameterDescriptor) + } + scope.changeLockLevel(WritableScope.LockLevel.READING) + + return ChainedScope(classDescriptor, "ScopeForClassHeaderResolution: " + classDescriptor.getName(), scope, getOuterScope()) + } + + private fun computeScopeForMemberDeclarationResolution(): JetScope { + val thisScope = WritableScopeImpl(JetScope.Empty, classDescriptor, RedeclarationHandler.DO_NOTHING, + "Scope with 'this' for " + classDescriptor.getName(), classDescriptor.getThisAsReceiverParameter(), classDescriptor) + thisScope.changeLockLevel(WritableScope.LockLevel.READING) + + return ChainedScope( + classDescriptor, + "ScopeForMemberDeclarationResolution: " + classDescriptor.getName(), + thisScope, + classDescriptor.getUnsubstitutedMemberScope(), + getScopeForClassHeaderResolution(), + getCompanionObjectScope(), + classDescriptor.getStaticScope()) + } + + private fun getCompanionObjectScope(): JetScope { + val companionObjectDescriptor = classDescriptor.getCompanionObjectDescriptor() + return if ((companionObjectDescriptor != null)) CompanionObjectMixinScope(companionObjectDescriptor) else JetScope.Empty + } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index c6d1f72fd60..7426c82f89a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -87,15 +87,14 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes private final MemoizedFunctionToNotNull extraCompanionObjectDescriptors; private final LazyClassMemberScope unsubstitutedMemberScope; - private final JetScope staticScope = new StaticScopeForKotlinClass(this); - private final NotNullLazyValue scopeForClassHeaderResolution; - private final NotNullLazyValue scopeForMemberDeclarationResolution; private final NotNullLazyValue scopeForPropertyInitializerResolution; private final NullableLazyValue forceResolveAllContents; private final boolean isCompanionObject; + private final ClassResolutionScopesSupport resolutionScopesSupport; + public LazyClassDescriptor( @NotNull LazyClassContext c, @NotNull DeclarationDescriptor containingDeclaration, @@ -193,18 +192,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes return computeCompanionObjectDescriptor(companionObject); } }); - this.scopeForClassHeaderResolution = storageManager.createLazyValue(new Function0() { - @Override - public JetScope invoke() { - return computeScopeForClassHeaderResolution(); - } - }); - this.scopeForMemberDeclarationResolution = storageManager.createLazyValue(new Function0() { - @Override - public JetScope invoke() { - return computeScopeForMemberDeclarationResolution(); - } - }); this.scopeForPropertyInitializerResolution = storageManager.createLazyValue(new Function0() { @Override public JetScope invoke() { @@ -218,6 +205,13 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes return null; } }, null); + + this.resolutionScopesSupport = new ClassResolutionScopesSupport(this, storageManager, new Function0() { + @Override + public JetScope invoke() { + return getOuterScope(); + } + }); } // NOTE: Called from constructor! @@ -231,25 +225,14 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes @NotNull @Override - public JetScope getScopeForMemberLookup() { + public JetScope getUnsubstitutedMemberScope() { return unsubstitutedMemberScope; } @Override @NotNull public JetScope getScopeForClassHeaderResolution() { - return scopeForClassHeaderResolution.invoke(); - } - - @NotNull - private JetScope computeScopeForClassHeaderResolution() { - WritableScopeImpl scope = new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, RedeclarationHandler.DO_NOTHING, "Scope with type parameters for " + getName()); - for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) { - scope.addClassifierDescriptor(typeParameterDescriptor); - } - scope.changeLockLevel(WritableScope.LockLevel.READING); - - return new ChainedScope(this, "ScopeForClassHeaderResolution: " + getName(), scope, getOuterScope()); + return resolutionScopesSupport.getScopeForClassHeaderResolution(); } @NotNull @@ -260,29 +243,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes @Override @NotNull public JetScope getScopeForMemberDeclarationResolution() { - return scopeForMemberDeclarationResolution.invoke(); - } - - @NotNull - private JetScope computeScopeForMemberDeclarationResolution() { - WritableScopeImpl thisScope = new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, RedeclarationHandler.DO_NOTHING, - "Scope with 'this' for " + getName(), this.getThisAsReceiverParameter(), this); - thisScope.changeLockLevel(WritableScope.LockLevel.READING); - - return new ChainedScope( - this, - "ScopeForMemberDeclarationResolution: " + getName(), - thisScope, - getScopeForMemberLookup(), - getScopeForClassHeaderResolution(), - getCompanionObjectScope(), - getStaticScope() - ); - } - - private JetScope getCompanionObjectScope() { - ClassDescriptor companionObjectDescriptor = getCompanionObjectDescriptor(); - return (companionObjectDescriptor != null) ? new CompanionObjectMixinScope(companionObjectDescriptor) : JetScope.Empty.INSTANCE$; + return resolutionScopesSupport.getScopeForMemberDeclarationResolution(); } @Override @@ -331,7 +292,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes @NotNull @Override public JetScope getStaticScope() { - return staticScope; + return resolutionScopesSupport.getStaticScope(); } @NotNull @@ -388,7 +349,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes } Name name = ((JetClassOrObjectInfo) companionObjectInfo).getName(); assert name != null; - getScopeForMemberLookup().getClassifier(name); + getUnsubstitutedMemberScope().getClassifier(name); ClassDescriptor companionObjectDescriptor = c.getTrace().get(BindingContext.CLASS, companionObject); if (companionObjectDescriptor instanceof LazyClassDescriptor) { assert DescriptorUtils.isCompanionObject(companionObjectDescriptor) : "Not a companion object: " + companionObjectDescriptor; @@ -481,7 +442,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes ForceResolveUtil.forceResolveAllContents(getConstructors()); ForceResolveUtil.forceResolveAllContents(getDescriptorsForExtraCompanionObjects()); - ForceResolveUtil.forceResolveAllContents(getScopeForMemberLookup()); + ForceResolveUtil.forceResolveAllContents(getUnsubstitutedMemberScope()); ForceResolveUtil.forceResolveAllContents(getTypeConstructor()); } @@ -503,7 +464,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes getOriginal(); getScopeForClassHeaderResolution(); getScopeForMemberDeclarationResolution(); - getScopeForMemberLookup().getAllDescriptors(); + getUnsubstitutedMemberScope().getAllDescriptors(); getScopeForInitializerResolution(); getUnsubstitutedInnerClassesScope(); getTypeConstructor().getSupertypes(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java index 1a81b679724..996e919fd50 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java @@ -54,8 +54,8 @@ public class LazyScriptClassDescriptor extends LazyClassDescriptor { @NotNull @Override - public LazyScriptClassMemberScope getScopeForMemberLookup() { - return (LazyScriptClassMemberScope) super.getScopeForMemberLookup(); + public LazyScriptClassMemberScope getUnsubstitutedMemberScope() { + return (LazyScriptClassMemberScope) super.getUnsubstitutedMemberScope(); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt index 75693de7bc1..fb05f3d224f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt @@ -65,7 +65,7 @@ public class LazyScriptDescriptor( override fun getClassDescriptor() = resolveSession.getClassDescriptorForScript(jetScript) as LazyScriptClassDescriptor - override fun getScriptResultProperty(): PropertyDescriptor = getClassDescriptor().getScopeForMemberLookup().getScriptResultProperty() + override fun getScriptResultProperty(): PropertyDescriptor = getClassDescriptor().getUnsubstitutedMemberScope().getScriptResultProperty() private val scriptCodeDescriptor = resolveSession.getStorageManager().createLazyValue { val result = ScriptCodeDescriptor(this) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt index b80311bb371..8dab34fbd9c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -77,10 +77,10 @@ class LazyJavaClassDescriptor( private val typeConstructor = c.storageManager.createLazyValue { LazyJavaClassTypeConstructor() } override fun getTypeConstructor(): TypeConstructor = typeConstructor() - private val scopeForMemberLookup = LazyJavaClassMemberScope(c, this, jClass) - override fun getScopeForMemberLookup() = scopeForMemberLookup + private val unsubstitutedMemberScope = LazyJavaClassMemberScope(c, this, jClass) + override fun getUnsubstitutedMemberScope() = unsubstitutedMemberScope - private val innerClassesScope = InnerClassesScopeWrapper(getScopeForMemberLookup()) + private val innerClassesScope = InnerClassesScopeWrapper(getUnsubstitutedMemberScope()) override fun getUnsubstitutedInnerClassesScope(): JetScope = innerClassesScope private val staticScope = LazyJavaStaticClassScope(c, jClass, this) @@ -90,14 +90,14 @@ class LazyJavaClassDescriptor( override fun getCompanionObjectDescriptor(): ClassDescriptor? = null - override fun getConstructors() = scopeForMemberLookup.constructors() + override fun getConstructors() = unsubstitutedMemberScope.constructors() private val annotations = c.storageManager.createLazyValue { c.resolveAnnotations(jClass) } override fun getAnnotations() = annotations() private val functionTypeForSamInterface = c.storageManager.createNullableLazyValue { c.samConversionResolver.resolveFunctionTypeIfSamInterface(this) { method -> - scopeForMemberLookup.resolveMethodToFunctionDescriptor(method, false) + unsubstitutedMemberScope.resolveMethodToFunctionDescriptor(method, false) } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt index 9ca51bc7e48..5b013d923de 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt @@ -71,7 +71,7 @@ public class FunctionClassDescriptor( override fun getTypeConstructor(): TypeConstructor = typeConstructor - override fun getScopeForMemberLookup() = memberScope + override fun getUnsubstitutedMemberScope() = memberScope override fun getCompanionObjectDescriptor() = null override fun getConstructors() = emptyList() diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java index 8a5b89a5d8a..7d5c79af2c8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java @@ -31,6 +31,9 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor, @NotNull JetScope getMemberScope(@NotNull List typeArguments); + @NotNull + JetScope getUnsubstitutedMemberScope(); + @NotNull JetScope getUnsubstitutedInnerClassesScope(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java index 21c4b60d743..5ed6bfc0e36 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/AbstractClassDescriptor.java @@ -41,13 +41,13 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { this.defaultType = storageManager.createLazyValue(new Function0() { @Override public JetType invoke() { - return TypeUtils.makeUnsubstitutedType(AbstractClassDescriptor.this, getScopeForMemberLookup()); + return TypeUtils.makeUnsubstitutedType(AbstractClassDescriptor.this, getUnsubstitutedMemberScope()); } }); this.unsubstitutedInnerClassesScope = storageManager.createLazyValue(new Function0() { @Override public JetScope invoke() { - return new InnerClassesScopeWrapper(getScopeForMemberLookup()); + return new InnerClassesScopeWrapper(getUnsubstitutedMemberScope()); } }); this.thisAsReceiverParameter = storageManager.createLazyValue(new Function0() { @@ -70,9 +70,6 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { return this; } - @NotNull - protected abstract JetScope getScopeForMemberLookup(); - @NotNull @Override public JetScope getUnsubstitutedInnerClassesScope() { @@ -91,13 +88,13 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor { assert typeArguments.size() == getTypeConstructor().getParameters().size() : "Illegal number of type arguments: expected " + getTypeConstructor().getParameters().size() + " but was " + typeArguments.size() + " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters(); - if (typeArguments.isEmpty()) return getScopeForMemberLookup(); + if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope(); List typeParameters = getTypeConstructor().getParameters(); Map substitutionContext = TypeSubstitutor.buildSubstitutionContext(typeParameters, typeArguments); TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext); - return new SubstitutingScope(getScopeForMemberLookup(), substitutor); + return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor); } @NotNull diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java index 430f05928eb..f67ab43650a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java @@ -37,7 +37,7 @@ public class ClassDescriptorImpl extends ClassDescriptorBase { private final TypeConstructor typeConstructor; private final JetScope staticScope = new StaticScopeForKotlinClass(this); - private JetScope scopeForMemberLookup; + private JetScope unsubstitutedMemberScope; private Set constructors; private ConstructorDescriptor primaryConstructor; @@ -56,11 +56,11 @@ public class ClassDescriptorImpl extends ClassDescriptorBase { } public final void initialize( - @NotNull JetScope scopeForMemberLookup, + @NotNull JetScope unsubstitutedMemberScope, @NotNull Set constructors, @Nullable ConstructorDescriptor primaryConstructor ) { - this.scopeForMemberLookup = scopeForMemberLookup; + this.unsubstitutedMemberScope = unsubstitutedMemberScope; this.constructors = constructors; this.primaryConstructor = primaryConstructor; } @@ -89,8 +89,8 @@ public class ClassDescriptorImpl extends ClassDescriptorBase { @NotNull @Override - protected JetScope getScopeForMemberLookup() { - return scopeForMemberLookup; + public JetScope getUnsubstitutedMemberScope() { + return unsubstitutedMemberScope; } @NotNull diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java index d8090db79f1..7fe50931fc8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java @@ -91,7 +91,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { @NotNull @Override - protected JetScope getScopeForMemberLookup() { + public JetScope getUnsubstitutedMemberScope() { return scope; } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java index 224498d01e7..6783de5f75e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java @@ -97,6 +97,16 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { return new SubstitutingScope(memberScope, getSubstitutor()); } + @NotNull + @Override + public JetScope getUnsubstitutedMemberScope() { + JetScope memberScope = original.getUnsubstitutedMemberScope(); + if (originalSubstitutor.isEmpty()) { + return memberScope; + } + return new SubstitutingScope(memberScope, getSubstitutor()); + } + @NotNull @Override public JetScope getStaticScope() { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index f9bb831697b..bbbf6233675 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -91,7 +91,7 @@ public class DeserializedClassDescriptor( override fun getAnnotations() = annotations - override fun getScopeForMemberLookup() = memberScope + override fun getUnsubstitutedMemberScope() = memberScope override fun getStaticScope() = staticScope diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/missingDependencies.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/missingDependencies.kt index cef52d9312f..dbfd26ea74f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/missingDependencies.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/missingDependencies.kt @@ -77,7 +77,7 @@ private class MissingDependencyErrorClassDescriptor( override fun substitute(substitutor: TypeSubstitutor) = this - override fun getScopeForMemberLookup() = scope + override fun getUnsubstitutedMemberScope() = scope override fun getMemberScope(typeArguments: List) = scope } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt index 9b3abd6a43b..33eeed65747 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceWithAnnotationAnalyzer.kt @@ -42,11 +42,11 @@ import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.module +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.utils.Printer +import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.utils.addIfNotNull -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import java.util.ArrayList import java.util.LinkedHashSet @@ -172,13 +172,18 @@ object ReplaceWithAnnotationAnalyzer { is ClassDescriptorWithResolutionScopes -> descriptor.getScopeForMemberDeclarationResolution() + is ClassDescriptor -> { + val outerScope = getResolutionScope(descriptor.getContainingDeclaration()) + ClassResolutionScopesSupport(descriptor, LockBasedStorageManager.NO_LOCKS, { outerScope }).getScopeForMemberDeclarationResolution() + } + is FunctionDescriptor -> FunctionDescriptorUtil.getFunctionInnerScope(getResolutionScope(descriptor.getContainingDeclaration()), descriptor, RedeclarationHandler.DO_NOTHING) is PropertyDescriptor -> JetScopeUtils.getPropertyDeclarationInnerScope(descriptor, - getResolutionScope(descriptor.getContainingDeclaration()!!), + getResolutionScope(descriptor.getContainingDeclaration()), RedeclarationHandler.DO_NOTHING) is LocalVariableDescriptor -> { val declaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as JetDeclaration diff --git a/idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt b/idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt new file mode 100644 index 00000000000..110af59ade9 --- /dev/null +++ b/idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt @@ -0,0 +1,7 @@ +// "Replace with 'matches(input)'" "true" + +import kotlin.text.Regex + +fun foo(regex: Regex) { + regex.hasMatch("") +} \ No newline at end of file diff --git a/idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt.after b/idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt.after new file mode 100644 index 00000000000..14508d63305 --- /dev/null +++ b/idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt.after @@ -0,0 +1,7 @@ +// "Replace with 'matches(input)'" "true" + +import kotlin.text.Regex + +fun foo(regex: Regex) { + regex.matches("") +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/DeprecatedInCompiledClassTest.kt b/idea/tests/org/jetbrains/kotlin/idea/quickfix/DeprecatedInCompiledClassTest.kt new file mode 100644 index 00000000000..d6272ee856f --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/DeprecatedInCompiledClassTest.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix; + +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.TestDataPath +import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.idea.util.application.executeWriteCommand +import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.psi.JetSimpleNameExpression +import org.jetbrains.kotlin.psi.psiUtil.parents +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners +import org.jetbrains.kotlin.test.JetTestUtils +import org.jetbrains.kotlin.test.TestMetadata +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance +import org.junit.runner.RunWith + +TestMetadata("idea/testData/quickfix.special") +TestDataPath("\$PROJECT_ROOT") +RunWith(JUnit3RunnerWithInners::class) +public class QuickFixSpecialTest : JetLightCodeInsightFixtureTestCase() { + override fun getTestDataPath() = JetTestUtils.getHomeDirectory() + override fun getProjectDescriptor() = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE + + TestMetadata("deprecatedMemberInCompiledClass.kt") + public fun testDeprecatedMemberInCompiledClass() { + val testPath = JetTestUtils.navigationMetadata("idea/testData/quickfix.special/deprecatedMemberInCompiledClass.kt") + myFixture.configureByFile(testPath) + + val offset = getEditor().getCaretModel().getOffset() + val element = getFile().findElementAt(offset) + val nameExpression = element!!.parents.firstIsInstance() + getProject().executeWriteCommand("") { + DeprecatedSymbolUsageFix(nameExpression, ReplaceWith("matches(input)")).invoke(getProject(), getEditor(), getFile()) + } + + myFixture.checkResultByFile("$testPath.after") + } +}