Fixed containingDeclaration for descriptors inside init-blocks for the case of no primary constructor

KT-10226 Wrong Imports optimization ("Unresolved reference" is being added)

 #KT-10226 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-01-13 22:21:06 +03:00
parent f4613b8db1
commit 15930a42b8
5 changed files with 100 additions and 27 deletions
@@ -31,8 +31,7 @@ import java.util.*
class ClassResolutionScopesSupport(
private val classDescriptor: ClassDescriptor,
storageManager: StorageManager,
private val getOuterScope: () -> LexicalScope,
private val primaryConstructorParameters: List<KtParameter>? = null
private val getOuterScope: () -> LexicalScope
) {
private fun scopeWithGenerics(parent: LexicalScope): LexicalScopeImpl {
return LexicalScopeImpl(parent, classDescriptor, false, null, LexicalScopeKind.CLASS_HEADER) {
@@ -76,24 +75,6 @@ class ClassResolutionScopesSupport(
}
}
val scopeForInitializerResolution: () -> LexicalScope = storageManager.createLazyValue {
val primaryConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?:
return@createLazyValue scopeForMemberDeclarationResolution()
assert(primaryConstructorParameters != null) {
"primary constructor parameters must be not null, because primary constructor exist: $primaryConstructor"
}
LexicalScopeImpl(scopeForMemberDeclarationResolution(), primaryConstructor, false, null,
LexicalScopeKind.CLASS_INITIALIZER) {
primaryConstructorParameters!!.forEachIndexed {
index, parameter ->
if (!parameter.hasValOrVar()) {
addVariableDescriptor(primaryConstructor.valueParameters[index])
}
}
}
}
fun ClassDescriptor.getAllSuperclassesWithoutAny(): List<ClassDescriptor> {
val superClasses = SmartList<ClassDescriptor>()
var parent: ClassDescriptor? = getSuperClassNotAny()
@@ -151,3 +132,27 @@ class ClassResolutionScopesSupport(
private val createThrowingLexicalScope: (Boolean) -> LexicalScope = { ThrowingLexicalScope() }
}
}
fun scopeForInitializerResolution(
classDescriptor: LazyClassDescriptor,
parentDescriptor: DeclarationDescriptor,
primaryConstructorParameters: List<KtParameter>
): LexicalScope {
return LexicalScopeImpl(
classDescriptor.scopeForMemberDeclarationResolution,
parentDescriptor,
false,
null,
LexicalScopeKind.CLASS_INITIALIZER
) {
if (primaryConstructorParameters.isNotEmpty()) {
val parameterDescriptors = classDescriptor.unsubstitutedPrimaryConstructor!!.valueParameters
assert(parameterDescriptors.size == primaryConstructorParameters.size)
for ((parameter, descriptor) in primaryConstructorParameters.zip(parameterDescriptors)) {
if (!parameter.hasValOrVar()) {
addVariableDescriptor(descriptor)
}
}
}
}
}
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
@@ -54,10 +55,7 @@ import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
import org.jetbrains.kotlin.storage.NotNullLazyValue;
import org.jetbrains.kotlin.storage.NullableLazyValue;
import org.jetbrains.kotlin.storage.StorageManager;
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.*;
import java.util.ArrayList;
import java.util.Collection;
@@ -103,11 +101,13 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
private final ClassResolutionScopesSupport resolutionScopesSupport;
private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters;
private final NotNullLazyValue<LexicalScope> scopeForInitializerResolution;
public LazyClassDescriptor(
@NotNull final LazyClassContext c,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull KtClassLikeInfo classLikeInfo
@NotNull final KtClassLikeInfo classLikeInfo
) {
super(c.getStorageManager(), containingDeclaration, name,
KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject())
@@ -239,7 +239,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
public LexicalScope invoke() {
return getOuterScope();
}
}, classLikeInfo.getPrimaryConstructorParameters());
});
this.parameters = c.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
@Override
@@ -264,6 +264,48 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
}
});
this.scopeForInitializerResolution = storageManager.createLazyValue(new Function0<LexicalScope>() {
@Override
public LexicalScope invoke() {
return ClassResolutionScopesSupportKt.scopeForInitializerResolution(LazyClassDescriptor.this,
createInitializerScopeParent(),
classLikeInfo.getPrimaryConstructorParameters());
}
});
}
@NotNull
private DeclarationDescriptor createInitializerScopeParent() {
ConstructorDescriptor primaryConstructor = getUnsubstitutedPrimaryConstructor();
if (primaryConstructor != null) return primaryConstructor;
return new FunctionDescriptorImpl(LazyClassDescriptor.this, null, Annotations.Companion.getEMPTY(),
Name.special("<init-blocks>"),
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE) {
@NotNull
@Override
protected FunctionDescriptorImpl createSubstitutedCopy(
@NotNull DeclarationDescriptor newOwner,
@Nullable FunctionDescriptor original,
@NotNull Kind kind,
@Nullable Name newName,
boolean preserveSource
) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public FunctionDescriptor copy(
DeclarationDescriptor newOwner,
Modality modality,
Visibility visibility,
Kind kind,
boolean copyOverrides
) {
throw new UnsupportedOperationException();
}
};
}
// NOTE: Called from constructor!
@@ -319,7 +361,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@Override
@NotNull
public LexicalScope getScopeForInitializerResolution() {
return resolutionScopesSupport.getScopeForInitializerResolution().invoke();
return scopeForInitializerResolution.invoke();
}
@NotNull
+10
View File
@@ -0,0 +1,10 @@
import java.io.File
class C {
constructor(file: File)
init {
val xxx = 1
xxx.inc()
}
}
+10
View File
@@ -0,0 +1,10 @@
import java.io.File
class C {
constructor(file: File)
init {
val xxx = 1
xxx.inc()
}
}
@@ -137,6 +137,12 @@ public class OptimizeImportsTestGenerated extends AbstractOptimizeImportsTest {
doTest(fileName);
}
@TestMetadata("KT10226.kt")
public void testKT10226() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/KT10226.kt");
doTest(fileName);
}
@TestMetadata("KT9875.kt")
public void testKT9875() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/KT9875.kt");