Correct parameters of inner's class type constructor

Now it contains copies of outer's class constructor parameters
They are appended just after real type parameters
This commit is contained in:
Denis Zharkov
2015-11-03 14:12:36 +03:00
parent 7b4c0fb83a
commit 990bd7e71d
9 changed files with 88 additions and 4 deletions
@@ -642,6 +642,8 @@ public class JetTypeMapper {
List<TypeProjection> arguments = jetType.getArguments();
for (TypeParameterDescriptor parameter : jetType.getConstructor().getParameters()) {
if (parameter.isCopyFromOuterDeclaration()) continue;
TypeProjection argument = arguments.get(parameter.getIndex());
if (projectionsAllowed && argument.isStarProjection()) {
@@ -576,7 +576,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters = c.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
@Override
public List<TypeParameterDescriptor> invoke() {
return LazyClassDescriptor.this.getDeclaredTypeParameters();
return TypeParameterUtilsKt.computeConstructorTypeParameters(LazyClassDescriptor.this);
}
});
@@ -131,7 +131,7 @@ class LazyJavaClassDescriptor(
private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor() {
private val parameters = c.storageManager.createLazyValue {
this@LazyJavaClassDescriptor.declaredTypeParameters
this@LazyJavaClassDescriptor.computeConstructorTypeParameters()
}
override fun getParameters(): List<TypeParameterDescriptor> = parameters()
@@ -46,4 +46,15 @@ public interface TypeParameterDescriptor extends ClassifierDescriptor {
TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor);
int getIndex();
/**
* Is current parameter just a copy of another type parameter (getOriginal) from outer declaration
* to be used for type constructor of inner declaration (i.e. inner class).
*
* If this method returns true:
* 1. Containing declaration for current parameter is the inner one
* 2. 'getOriginal' returns original type parameter from outer declaration
* 3. 'getTypeConstructor' is the same as for original declaration (at least in means of 'equals')
*/
boolean isCapturedFromOuterDeclaration();
}
@@ -166,6 +166,11 @@ public abstract class AbstractTypeParameterDescriptor extends DeclarationDescrip
return index;
}
@Override
public boolean isCapturedFromOuterDeclaration() {
return false;
}
@NotNull
@Override
public List<KotlinType> getUpperBounds() {
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.descriptors.impl;
import kotlin.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
@@ -34,6 +36,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
private final TypeSubstitutor originalSubstitutor;
private TypeSubstitutor newSubstitutor;
private List<TypeParameterDescriptor> typeConstructorParameters;
private List<TypeParameterDescriptor> declaredTypeParameters;
private TypeConstructor typeConstructor;
public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, TypeSubstitutor substitutor) {
@@ -52,6 +55,13 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
newSubstitutor = DescriptorSubstitutor.substituteTypeParameters(
originalTypeParameters, originalSubstitutor.getSubstitution(), this, typeConstructorParameters
);
declaredTypeParameters = CollectionsKt.filter(typeConstructorParameters, new Function1<TypeParameterDescriptor, Boolean>() {
@Override
public Boolean invoke(TypeParameterDescriptor descriptor) {
return !descriptor.isCapturedFromOuterDeclaration();
}
});
}
}
return newSubstitutor;
@@ -253,6 +263,6 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
@Override
public List<TypeParameterDescriptor> getDeclaredTypeParameters() {
getSubstitutor();
return typeConstructorParameters;
return declaredTypeParameters;
}
}
@@ -0,0 +1,46 @@
/*
* 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.descriptors
fun ClassDescriptor.computeConstructorTypeParameters(): List<TypeParameterDescriptor> {
val declaredParameters = declaredTypeParameters
if (!isInner) return declaredParameters
val containingTypeConstructor = (containingDeclaration as? ClassDescriptor)?.typeConstructor ?: return emptyList()
val additional = containingTypeConstructor.parameters.map { it.capturedCopyForInnerDeclaration(this, declaredParameters.size) }
if (additional.isEmpty()) return declaredParameters
return declaredParameters + additional
}
private fun TypeParameterDescriptor.capturedCopyForInnerDeclaration(
declarationDescriptor: DeclarationDescriptor,
declaredTypeParametersCount: Int
) = CapturedTypeParameterDescriptor(this, declarationDescriptor, declaredTypeParametersCount)
private class CapturedTypeParameterDescriptor(
private val originalDescriptor: TypeParameterDescriptor,
private val declarationDescriptor: DeclarationDescriptor,
private val declaredTypeParametersCount: Int
) : TypeParameterDescriptor by originalDescriptor {
override fun isCapturedFromOuterDeclaration() = true
override fun getOriginal() = originalDescriptor.original
override fun getContainingDeclaration() = declarationDescriptor
override fun getIndex() = declaredTypeParametersCount + originalDescriptor.index
override fun toString() = originalDescriptor.toString() + "[inner-copy]"
}
@@ -28,6 +28,12 @@ import java.util.Collection;
import java.util.List;
public interface TypeConstructor extends Annotated {
/**
* It may differ from ClassDescriptor.declaredParameters if the class is inner, in such case
* it also contains additional parameters from outer declarations.
*
* @return list of parameters for type constructor, both from current declaration and the outer one
*/
@NotNull
@ReadOnly
List<TypeParameterDescriptor> getParameters();
@@ -173,7 +173,11 @@ public class DeserializedClassDescriptor(
computeSupertypes()
}
override fun getParameters() = c.typeDeserializer.ownTypeParameters
private val parameters = c.storageManager.createLazyValue {
this@DeserializedClassDescriptor.computeConstructorTypeParameters()
}
override fun getParameters() = parameters()
override fun getSupertypes() = supertypes()