KT-11588 Type aliases

- Nested type aliases
- UNSUPPORTED_TYPEALIAS error (language level < 1.1)
- tests for is/as/as? with type alias
This commit is contained in:
Dmitry Petrov
2016-05-26 17:29:04 +03:00
parent e979300579
commit 0319d5a5aa
34 changed files with 493 additions and 133 deletions
@@ -115,6 +115,7 @@ public interface Errors {
DiagnosticFactory0<KtParameter> REIFIED_TYPE_IN_CATCH_CLAUSE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtTypeParameterList> GENERIC_THROWABLE_SUBCLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> UNSUPPORTED_TYPEALIAS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<KtUserType, ClassifierDescriptor> RECURSIVE_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory3<KtElement, KotlinType, KotlinType, ClassifierDescriptor> UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION =
DiagnosticFactory3.create(ERROR);
@@ -417,6 +417,7 @@ public class DefaultErrorMessages {
MAP.put(USELESS_ELVIS_ON_LAMBDA_EXPRESSION, "Left operand of elvis operator (?:) is a lambda expression");
MAP.put(CONFLICTING_UPPER_BOUNDS, "Upper bounds of {0} have empty intersection", NAME);
MAP.put(UNSUPPORTED_TYPEALIAS, "Type aliases are unsupported (min Kotlin language level: 1.1)");
MAP.put(RECURSIVE_TYPEALIAS_EXPANSION, "Recursive type alias in expansion: {0}", NAME);
MAP.put(UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION,
"Type argument resulting from type alias expansion is not within required bounds for ''{2}'': " +
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.KotlinTypeAliasStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
@@ -31,6 +33,10 @@ class KtTypeAlias : KtTypeParameterListOwnerStub<KotlinTypeAliasStub>, KtNamedDe
fun isTopLevel(): Boolean =
stub?.isTopLevel() ?: parent is KtFile
@IfNotParsed
fun getTypeAliasKeyword(): PsiElement? =
findChildByType(KtTokens.TYPE_ALIAS_KEYWORD)
@IfNotParsed
fun getTypeReference(): KtTypeReference? =
findChildByType(KtNodeTypes.TYPE_REFERENCE)
@@ -29,6 +29,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageFeatureSettings;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
@@ -61,9 +63,7 @@ import java.util.*;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.lexer.KtTokens.*;
import static org.jetbrains.kotlin.resolve.BindingContext.CONSTRUCTOR;
import static org.jetbrains.kotlin.resolve.BindingContext.PACKAGE_TO_FILES;
import static org.jetbrains.kotlin.resolve.BindingContext.TYPE_ALIAS;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveModalityFromModifiers;
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers;
@@ -79,6 +79,7 @@ public class DescriptorResolver {
@NotNull private final VariableTypeResolver variableTypeResolver;
@NotNull private final ExpressionTypingServices expressionTypingServices;
@NotNull private final OverloadChecker overloadChecker;
@NotNull private final LanguageFeatureSettings languageFeatureSettings;
public DescriptorResolver(
@NotNull AnnotationResolver annotationResolver,
@@ -88,7 +89,8 @@ public class DescriptorResolver {
@NotNull SupertypeLoopChecker supertypeLoopsResolver,
@NotNull VariableTypeResolver variableTypeResolver,
@NotNull ExpressionTypingServices expressionTypingServices,
@NotNull OverloadChecker overloadChecker
@NotNull OverloadChecker overloadChecker,
@NotNull LanguageFeatureSettings languageFeatureSettings
) {
this.annotationResolver = annotationResolver;
this.builtIns = builtIns;
@@ -98,6 +100,7 @@ public class DescriptorResolver {
this.variableTypeResolver = variableTypeResolver;
this.expressionTypingServices = expressionTypingServices;
this.overloadChecker = overloadChecker;
this.languageFeatureSettings = languageFeatureSettings;
}
public List<KotlinType> resolveSupertypes(
@@ -675,21 +678,24 @@ public class DescriptorResolver {
return variableDescriptor;
}
@NotNull
@Nullable
public TypeAliasDescriptor resolveTypeAliasDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull LexicalScope scope,
@NotNull KtTypeAlias typeAlias,
@NotNull final BindingTrace trace
) {
final KtTypeReference typeReference = typeAlias.getTypeReference();
if (typeReference == null) return null;
KtModifierList modifierList = typeAlias.getModifierList();
Visibility visibility = resolveVisibilityFromModifiers(typeAlias, getDefaultVisibility(typeAlias, containingDeclaration));
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithArguments(scope, modifierList, trace);
Name name = KtPsiUtil.safeName(typeAlias.getName());
SourceElement sourceElement = KotlinSourceElementKt.toSourceElement(typeAlias);
LazyTypeAliasDescriptor typeAliasDescriptor = LazyTypeAliasDescriptor.create(
containingDeclaration, allAnnotations, name, sourceElement, visibility);
final LazyTypeAliasDescriptor typeAliasDescriptor = LazyTypeAliasDescriptor.create(
storageManager, trace, containingDeclaration, allAnnotations, name, sourceElement, visibility);
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
final LexicalScope scopeWithTypeParameters;
@@ -712,20 +718,25 @@ public class DescriptorResolver {
}
}
final KtTypeReference typeReference = typeAlias.getTypeReference();
if (!languageFeatureSettings.supportsFeature(LanguageFeature.TypeAliases)) {
typeResolver.resolveType(scopeWithTypeParameters, typeReference, trace, true);
trace.report(UNSUPPORTED_TYPEALIAS.on(typeAlias.getTypeAliasKeyword()));
return null;
}
typeAliasDescriptor.initialize(
typeParameterDescriptors,
storageManager.createLazyValue(new Function0<KotlinType>() {
DeferredType.create(storageManager, trace, new Function0<KotlinType>() {
@Override
public KotlinType invoke() {
return typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace, true);
}
}),
storageManager.createLazyValue(new Function0<KotlinType>() {
DeferredType.create(storageManager, trace, new Function0<KotlinType>() {
@Override
public KotlinType invoke() {
// TODO do not reparse
// TODO do not reparse type alias RHS, just expand it instead
// NB this messes up with diagnostics
return typeResolver.resolveType(scopeWithTypeParameters, typeReference, trace, true);
}
}));
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.resolve
import com.google.common.collect.HashMultimap
import com.google.common.collect.Multimap
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageFeatureSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
@@ -44,7 +46,8 @@ class LazyTopDownAnalyzer(
private val fileScopeProvider: FileScopeProvider,
private val declarationScopeProvider: DeclarationScopeProvider,
private val qualifiedExpressionResolver: QualifiedExpressionResolver,
private val identifierChecker: IdentifierChecker
private val identifierChecker: IdentifierChecker,
private val languageFeatureSettings: LanguageFeatureSettings
) {
fun analyzeDeclarations(topDownAnalysisMode: TopDownAnalysisMode, declarations: Collection<PsiElement>, outerDataFlowInfo: DataFlowInfo): TopDownAnalysisContext {
@@ -207,6 +210,8 @@ class LazyTopDownAnalyzer(
}
private fun createTypeAliasDescriptors(c: TopDownAnalysisContext, topLevelFqNames: Multimap<FqName, KtElement>, typeAliases: List<KtTypeAlias>) {
if (!languageFeatureSettings.supportsFeature(LanguageFeature.TypeAliases)) return
for (typeAlias in typeAliases) {
val descriptor = lazyDeclarationResolver.resolveToDescriptor(typeAlias) as TypeAliasDescriptor
@@ -369,8 +369,8 @@ class TypeResolver(
}
val collectedArgumentAsTypeProjections =
collectArgumentsForClassTypeConstructor(c, classDescriptor, qualifierResolutionResult.qualifierParts)
?: return createErrorTypeAndResolveArguments(c, projectionFromAllQualifierParts, typeConstructor.toString())
collectArgumentsForClassifierTypeConstructor(c, classDescriptor, qualifierResolutionResult.qualifierParts)
?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
assert(collectedArgumentAsTypeProjections.size <= parameters.size) {
"Collected arguments count should be not greater then parameters count," +
@@ -423,63 +423,70 @@ class TypeResolver(
private fun resolveTypeForTypeAlias(
c: TypeResolutionContext,
annotations: Annotations,
typeAliasDescriptor: TypeAliasDescriptor,
descriptor: TypeAliasDescriptor,
type: KtUserType,
qualifierResolutionResult: QualifiedExpressionResolver.TypeQualifierResolutionResult
): PossiblyBareType {
val typeAliasConstructor = typeAliasDescriptor.typeConstructor
val typeConstructor = descriptor.typeConstructor
val projectionFromAllQualifierParts = qualifierResolutionResult.allProjections
if (ErrorUtils.isError(typeAliasDescriptor)) {
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeAliasConstructor)
if (ErrorUtils.isError(descriptor)) {
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
}
// TODO type arguments substitution for type parameters of outer classes
// TODO should we support type aliases as qualifiers? what about generics?
val parameters = typeConstructor.parameters
val typeAliasParameters = typeAliasDescriptor.declaredTypeParameters
val typeAliasQualifierPart =
qualifierResolutionResult.qualifierParts.lastOrNull()
?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
val typeAliasQualifierPart = qualifierResolutionResult.qualifierParts.lastOrNull()
?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeAliasConstructor)
val argumentElementsFromUserType =
collectArgumentsForClassifierTypeConstructor(c, descriptor, qualifierResolutionResult.qualifierParts)
?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
// TODO appendDefaultArgumentsForInnerScope
val typeAliasArguments = typeAliasQualifierPart.typeArguments?.arguments.orEmpty()
val argumentsFromUserType = resolveTypeProjections(c, typeConstructor, argumentElementsFromUserType)
val arguments = argumentsFromUserType + appendDefaultArgumentsForInnerScope(argumentsFromUserType.size, parameters)
val reportStrategy = TracingTypeAliasExpansionReportStrategy(
c.trace,
type, typeAliasQualifierPart.typeArguments ?: typeAliasQualifierPart.expression,
typeAliasDescriptor, typeAliasDescriptor.declaredTypeParameters, typeAliasArguments)
descriptor, descriptor.declaredTypeParameters,
argumentElementsFromUserType // TODO arguments from inner scope
)
if (typeAliasParameters.size != typeAliasArguments.size) {
reportStrategy.wrongNumberOfTypeArguments(typeAliasDescriptor, typeAliasParameters.size)
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeAliasConstructor)
if (parameters.size != arguments.size) {
reportStrategy.wrongNumberOfTypeArguments(descriptor, parameters.size)
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
}
return if (c.abbreviated) {
val arguments = resolveTypeProjections(c, typeAliasDescriptor.typeConstructor, typeAliasArguments)
val abbreviatedType = KotlinTypeImpl.create(annotations, typeAliasDescriptor.typeConstructor, false, arguments, MemberScope.Empty)
val abbreviatedType = KotlinTypeImpl.create(annotations, descriptor.typeConstructor, false, arguments, MemberScope.Empty)
type(abbreviatedType)
}
else {
val arguments = resolveTypeProjections(c, typeAliasDescriptor.typeConstructor, typeAliasArguments)
val typeAliasExpansion = createTypeAliasExpansion(null, typeAliasDescriptor, arguments)
val expandedType = expandTypeAlias(c, typeAliasExpansion, reportStrategy, annotations, 0)
val typeAliasExpansion = createTypeAliasExpansion(null, descriptor, arguments)
val expandedType = expandTypeAlias(typeAliasExpansion, reportStrategy, annotations, 0)
type(expandedType)
}
}
private class TracingTypeAliasExpansionReportStrategy(
val trace: BindingTrace,
val type: KtUserType,
val typeArgumentsOrTypeName: KtElement,
val type: KtUserType?,
val typeArgumentsOrTypeName: KtElement?,
val typeAliasDescriptor: TypeAliasDescriptor,
val typeParameters: List<TypeParameterDescriptor>,
val typeArguments: List<KtTypeProjection>
typeParameters: List<TypeParameterDescriptor>,
typeArguments: List<KtTypeProjection>
) : TypeAliasExpansionReportStrategy {
constructor (trace: BindingTrace, typeAliasDescriptor: TypeAliasDescriptor) : this(trace, null, null, typeAliasDescriptor, emptyList(), emptyList())
private val mappedArguments = typeParameters.zip(typeArguments).toMap()
override fun wrongNumberOfTypeArguments(typeAlias: TypeAliasDescriptor, numberOfParameters: Int) {
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeArgumentsOrTypeName, numberOfParameters, typeAliasDescriptor))
if (typeArgumentsOrTypeName != null) {
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeArgumentsOrTypeName, numberOfParameters, typeAliasDescriptor))
}
}
override fun conflictingProjection(typeAlias: TypeAliasDescriptor, typeParameter: TypeParameterDescriptor?, expandingType: KotlinType) {
@@ -487,13 +494,15 @@ class TypeResolver(
if (argumentElement != null && typeParameter != null) {
trace.report(CONFLICTING_PROJECTION.on(argumentElement, typeParameter))
}
else {
else if (type != null) {
trace.report(CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION.on(type, typeAliasDescriptor.underlyingType))
}
}
override fun recursiveTypeAlias(typeAlias: TypeAliasDescriptor) {
trace.report(RECURSIVE_TYPEALIAS_EXPANSION.on(type, typeAlias))
if (type != null) {
trace.report(RECURSIVE_TYPEALIAS_EXPANSION.on(type, typeAlias))
}
}
override fun boundsViolationInSubstitution(bound: KotlinType, unsubstitutedArgument: KotlinType, argument: KotlinType, typeParameter: TypeParameterDescriptor) {
@@ -503,7 +512,7 @@ class TypeResolver(
if (argumentTypeReferenceElement != null) {
trace.report(UPPER_BOUND_VIOLATED.on(argumentTypeReferenceElement, bound, argument))
}
else {
else if (type != null) {
trace.report(UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION.on(type, bound, argument, typeParameter))
}
}
@@ -532,20 +541,19 @@ class TypeResolver(
typeAliasDescriptor: TypeAliasDescriptor,
arguments: List<TypeProjection>
): TypeAliasExpansion {
val typeParameters = typeAliasDescriptor.declaredTypeParameters // TODO inner type aliases
val typeParameters = typeAliasDescriptor.typeConstructor.parameters.map { it.original as TypeParameterDescriptor }
val mappedArguments = typeParameters.zip(arguments).toMap()
return TypeAliasExpansion(parent, typeAliasDescriptor, arguments, mappedArguments)
}
private fun expandTypeAlias(
c: TypeResolutionContext,
typeAliasExpansion: TypeAliasExpansion,
reportStrategy: TypeAliasExpansionReportStrategy,
annotations: Annotations,
recursionDepth: Int
): KotlinType {
val originalProjection = TypeProjectionImpl(Variance.INVARIANT, typeAliasExpansion.descriptor.underlyingType)
val expandedProjection = expandTypeProjectionForTypeAlias(c, originalProjection, typeAliasExpansion, null, reportStrategy, recursionDepth)
val expandedProjection = expandTypeProjectionForTypeAlias(originalProjection, typeAliasExpansion, null, reportStrategy, recursionDepth)
val expandedType = expandedProjection.type
if (expandedType.isError) return expandedType
@@ -564,7 +572,6 @@ class TypeResolver(
}
private fun expandTypeProjectionForTypeAlias(
c: TypeResolutionContext,
originalProjection: TypeProjection,
typeAliasExpansion: TypeAliasExpansion,
typeParameterDescriptor: TypeParameterDescriptor?,
@@ -580,7 +587,7 @@ class TypeResolver(
val typeAliasArgument = typeAliasExpansion.getReplacement(originalType.constructor)
if (typeAliasArgument == null) {
return substituteNonArgumentTypeForTypeAlias(c, originalProjection, typeAliasExpansion, reportStrategy, recursionDepth)
return substituteNonArgumentTypeForTypeAlias(originalProjection, typeAliasExpansion, reportStrategy, recursionDepth)
}
val originalVariance =
@@ -613,7 +620,6 @@ class TypeResolver(
}
private fun substituteNonArgumentTypeForTypeAlias(
c: TypeResolutionContext,
originalProjection: TypeProjection,
typeAliasExpansion: TypeAliasExpansion,
reportStrategy: TypeAliasExpansionReportStrategy,
@@ -634,18 +640,18 @@ class TypeResolver(
}
val expandedArguments = type.arguments.mapIndexed { i, typeAliasArgument ->
expandTypeProjectionForTypeAlias(c, typeAliasArgument, typeAliasExpansion, typeConstructor.parameters[i], reportStrategy, recursionDepth + 1)
expandTypeProjectionForTypeAlias(typeAliasArgument, typeAliasExpansion, typeConstructor.parameters[i], reportStrategy, recursionDepth + 1)
}
val nestedExpansion = createTypeAliasExpansion(typeAliasExpansion, typeDescriptor, expandedArguments)
val expandedType = expandTypeAlias(c, nestedExpansion, reportStrategy, type.annotations, recursionDepth + 1)
val expandedType = expandTypeAlias(nestedExpansion, reportStrategy, type.annotations, recursionDepth + 1)
return TypeProjectionImpl(originalProjection.projectionKind, expandedType.withAbbreviatedType(type))
}
else -> {
val substitutedArguments = type.arguments.mapIndexed { i, originalArgument ->
expandTypeProjectionForTypeAlias(c, originalArgument, typeAliasExpansion, typeConstructor.parameters[i], reportStrategy, recursionDepth + 1)
expandTypeProjectionForTypeAlias(originalArgument, typeAliasExpansion, typeConstructor.parameters[i], reportStrategy, recursionDepth + 1)
}
val substitutedType = type.replace(newArguments = substitutedArguments)
@@ -677,8 +683,11 @@ class TypeResolver(
c: TypeResolutionContext,
arguments: List<KtTypeProjection>,
typeConstructor: TypeConstructor
) =
createErrorTypeAndResolveArguments(c, arguments, "[Error type: $typeConstructor]")
): PossiblyBareType =
type(ErrorUtils.createErrorTypeWithArguments(
"$typeConstructor",
resolveTypeProjectionsWithErrorConstructor(c, arguments)
))
// Returns true in case when at least one argument for this class could be specified
// It could be always equal to 'typeConstructor.parameters.isNotEmpty()' unless local classes could captured type parameters
@@ -691,30 +700,30 @@ class TypeResolver(
// }
//
// It's needed to determine whether this particular type could be bare
private fun isPossibleToSpecifyTypeArgumentsFor(classDescriptor: ClassDescriptor): Boolean {
private fun isPossibleToSpecifyTypeArgumentsFor(classifierDescriptor: ClassifierDescriptorWithTypeParameters): Boolean {
// First parameter relates to the innermost declaration
// If it's declared in function there
val firstTypeParameter = classDescriptor.typeConstructor.parameters.firstOrNull() ?: return false
val firstTypeParameter = classifierDescriptor.typeConstructor.parameters.firstOrNull() ?: return false
return firstTypeParameter.original.containingDeclaration is ClassDescriptor
}
private fun collectArgumentsForClassTypeConstructor(
private fun collectArgumentsForClassifierTypeConstructor(
c: TypeResolutionContext,
classDescriptor: ClassDescriptor,
classifierDescriptor: ClassifierDescriptorWithTypeParameters,
qualifierParts: List<QualifiedExpressionResolver.QualifierPart>
): List<KtTypeProjection>? {
val classDescriptorChain = classDescriptor.classDescriptorChain()
val classifierDescriptorChain = classifierDescriptor.classifierDescriptorsFromInnerToOuter()
val reversedQualifierParts = qualifierParts.asReversed()
var wasStatic = false
var result = SmartList<KtTypeProjection>()
val result = SmartList<KtTypeProjection>()
val classChainLastIndex = Math.min(classDescriptorChain.size, reversedQualifierParts.size) - 1
val classifierChainLastIndex = Math.min(classifierDescriptorChain.size, reversedQualifierParts.size) - 1
for (index in 0..classChainLastIndex) {
for (index in 0..classifierChainLastIndex) {
val qualifierPart = reversedQualifierParts[index]
val currentArguments = qualifierPart.typeArguments?.arguments.orEmpty()
val declaredTypeParameters = classDescriptorChain[index].declaredTypeParameters
val declaredTypeParameters = classifierDescriptorChain[index].declaredTypeParameters
val currentParameters = if (wasStatic) emptyList() else declaredTypeParameters
if (wasStatic && currentArguments.isNotEmpty() && declaredTypeParameters.isNotEmpty()) {
@@ -725,7 +734,8 @@ class TypeResolver(
if (currentArguments.size != currentParameters.size) {
c.trace.report(
WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(
qualifierPart.typeArguments ?: qualifierPart.expression, currentParameters.size, classDescriptorChain[index]
qualifierPart.typeArguments ?: qualifierPart.expression,
currentParameters.size, classifierDescriptorChain[index]
)
)
return null
@@ -733,12 +743,12 @@ class TypeResolver(
result.addAll(currentArguments)
wasStatic = wasStatic || !classDescriptorChain[index].isInner
wasStatic = wasStatic || !classifierDescriptorChain[index].isInner
}
val nonClassQualifierParts =
reversedQualifierParts.subList(
Math.min(classChainLastIndex + 1, reversedQualifierParts.size),
Math.min(classifierChainLastIndex + 1, reversedQualifierParts.size),
reversedQualifierParts.size)
for (qualifierPart in nonClassQualifierParts) {
@@ -748,12 +758,12 @@ class TypeResolver(
}
}
val parameters = classDescriptor.typeConstructor.parameters
val parameters = classifierDescriptor.typeConstructor.parameters
if (result.size < parameters.size) {
val typeParametersToSpecify =
parameters.subList(result.size, parameters.size).takeWhile { it.original.containingDeclaration is ClassDescriptor }
if (typeParametersToSpecify.any { parameter -> !parameter.isDeclaredInScope(c) }) {
c.trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifierParts.last().expression, parameters.size, classDescriptor))
c.trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifierParts.last().expression, parameters.size, classifierDescriptor))
return null
}
}
@@ -761,11 +771,16 @@ class TypeResolver(
return result
}
private fun ClassifierDescriptor?.classDescriptorChain(): List<ClassDescriptor>
= generateSequence({ this as? ClassDescriptor }, { it.containingDeclaration as? ClassDescriptor }).toList()
private fun ClassifierDescriptor?.classifierDescriptorsFromInnerToOuter(): List<ClassifierDescriptorWithTypeParameters> =
generateSequence(
{ this as? ClassifierDescriptorWithTypeParameters },
{ it.containingDeclaration as? ClassifierDescriptorWithTypeParameters }
).toList()
private fun TypeParameterDescriptor.isDeclaredInScope(c: TypeResolutionContext): Boolean {
assert(containingDeclaration is ClassDescriptor) { "This function is implemented for classes only, but $containingDeclaration was given" }
assert(containingDeclaration is ClassifierDescriptorWithTypeParameters) {
"This function is implemented for ClassifierDescriptorWithTypeParameters only, but $containingDeclaration was given"
}
// This function checks whether this@TypeParameterDescriptor ()is reachable from current scope by it's name
// The only way it can be is that we are within class that contains it
@@ -776,11 +791,11 @@ class TypeResolver(
val contributedClassifier = c.scope.findClassifier(name, NoLookupLocation.WHEN_RESOLVING_DEFAULT_TYPE_ARGUMENTS) ?: return false
if (contributedClassifier.typeConstructor == typeConstructor) return true
return c.scope.ownerDescriptor.isInsideOfClass(original.containingDeclaration as ClassDescriptor)
return c.scope.ownerDescriptor.isInsideOfClass(original.containingDeclaration as ClassifierDescriptorWithTypeParameters)
}
private fun DeclarationDescriptor.isInsideOfClass(classDescriptor: ClassDescriptor)
= generateSequence(this, { it.containingDeclaration }).any { it.original == classDescriptor }
private fun DeclarationDescriptor.isInsideOfClass(classifierDescriptor: ClassifierDescriptorWithTypeParameters)
= generateSequence(this, { it.containingDeclaration }).any { it.original == classifierDescriptor }
private fun resolveTypeProjectionsWithErrorConstructor(
@@ -789,13 +804,6 @@ class TypeResolver(
message: String = "Error type for resolving type projections"
) = resolveTypeProjections(c, ErrorUtils.createErrorTypeConstructor(message), argumentElements)
private fun createErrorTypeAndResolveArguments(
c: TypeResolutionContext,
argumentElements: List<KtTypeProjection>,
message: String = ""
): PossiblyBareType
= type(ErrorUtils.createErrorTypeWithArguments(message, resolveTypeProjectionsWithErrorConstructor(c, argumentElements)))
// In cases like
// class Outer<F> {
// inner class Inner<E>
@@ -124,7 +124,7 @@ protected constructor(
}
private fun doGetTypeAliases(name: Name): Collection<TypeAliasDescriptor> =
declarationProvider.getTypeAliasDeclarations(name).map { ktTypeAlias ->
declarationProvider.getTypeAliasDeclarations(name).mapNotNull { ktTypeAlias ->
c.descriptorResolver.resolveTypeAliasDescriptor(
thisDescriptor,
getScopeForMemberDeclarationResolution(ktTypeAlias),
@@ -20,10 +20,16 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.DeferredType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
class LazyTypeAliasDescriptor(
private val storageManager: StorageManager,
private val trace: BindingTrace,
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
@@ -32,30 +38,50 @@ class LazyTypeAliasDescriptor(
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, sourceElement, visibility),
TypeAliasDescriptor {
private lateinit var underlyingTypeImpl: NotNullLazyValue<KotlinType>
private lateinit var expandedTypeImpl: NotNullLazyValue<KotlinType>
override lateinit var underlyingType: KotlinType private set
override lateinit var expandedType: KotlinType private set
override val underlyingType: KotlinType get() = underlyingTypeImpl()
override val expandedType: KotlinType get() = expandedTypeImpl()
private val lazyTypeConstructorParameters =
storageManager.createLazyValue { this.computeConstructorTypeParameters() }
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
lazyUnderlyingType: NotNullLazyValue<KotlinType>,
lazyExpandedType: NotNullLazyValue<KotlinType>
underlyingType: KotlinType,
expandedType: KotlinType
) {
super.initialize(declaredTypeParameters)
this.underlyingTypeImpl = lazyUnderlyingType
this.expandedTypeImpl = lazyExpandedType
this.underlyingType = underlyingType
this.expandedType = expandedType
}
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor {
if (substitutor.isEmpty) return this
val substituted = LazyTypeAliasDescriptor(storageManager, trace,
containingDeclaration, annotations, name, source, visibility)
substituted.initialize(declaredTypeParameters,
DeferredType.create(storageManager, trace) {
substitutor.substitute(underlyingType, Variance.INVARIANT)
},
DeferredType.create(storageManager, trace) {
substitutor.substitute(expandedType, Variance.INVARIANT)
})
return substituted
}
override fun getTypeConstructorTypeParameters(): List<TypeParameterDescriptor> =
lazyTypeConstructorParameters()
companion object {
@JvmStatic fun create(
storageManager: StorageManager,
trace: BindingTrace,
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
sourceElement: SourceElement,
visibility: Visibility
): LazyTypeAliasDescriptor =
LazyTypeAliasDescriptor(containingDeclaration, annotations, name, sourceElement, visibility)
LazyTypeAliasDescriptor(storageManager, trace,
containingDeclaration, annotations, name, sourceElement, visibility)
}
}
@@ -172,12 +172,17 @@ public class DescriptorSerializer {
}
for (DeclarationDescriptor descriptor : sort(DescriptorUtils.getAllDescriptors(classDescriptor.getUnsubstitutedInnerClassesScope()))) {
int name = getSimpleNameIndex(descriptor.getName());
if (isEnumEntry(descriptor)) {
builder.addEnumEntry(enumEntryProto((ClassDescriptor) descriptor));
if (descriptor instanceof TypeAliasDescriptor) {
builder.addTypeAlias(typeAliasProto((TypeAliasDescriptor) descriptor));
}
else {
builder.addNestedClassName(name);
int name = getSimpleNameIndex(descriptor.getName());
if (isEnumEntry(descriptor)) {
builder.addEnumEntry(enumEntryProto((ClassDescriptor) descriptor));
}
else {
builder.addNestedClassName(name);
}
}
}
@@ -520,9 +525,8 @@ public class DescriptorSerializer {
assert possiblyInnerType != null : "possiblyInnerType should not be null in case of class";
fillFromPossiblyInnerType(builder, possiblyInnerType);
}
if (descriptor instanceof TypeParameterDescriptor) {
else if (descriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) descriptor;
if (typeParameter.getContainingDeclaration() == containingDeclaration) {
builder.setTypeParameterName(getSimpleNameIndex(typeParameter.getName()));
@@ -533,7 +537,7 @@ public class DescriptorSerializer {
assert type.getArguments().isEmpty() : "Found arguments for type constructor build on type parameter: " + descriptor;
}
if (descriptor instanceof TypeAliasDescriptor) {
else if (descriptor instanceof TypeAliasDescriptor) {
PossiblyInnerType possiblyInnerType = TypeParameterUtilsKt.buildPossiblyInnerType(type);
assert possiblyInnerType != null : "possiblyInnerType should not be null in case of type alias";
fillFromPossiblyInnerType(builder, possiblyInnerType);
@@ -0,0 +1,5 @@
typealias S = String
fun test1(x: Any) = x is S
fun test2(x: Any) = x as S
fun test3(x: Any) = x as? S
@@ -0,0 +1,6 @@
package
public typealias S = kotlin.String
public fun test1(/*0*/ x: kotlin.Any): kotlin.Boolean
public fun test2(/*0*/ x: kotlin.Any): S [= kotlin.String]
public fun test3(/*0*/ x: kotlin.Any): S [= kotlin.String?]
+24
View File
@@ -0,0 +1,24 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
class Pair<T1, T2>(val x1: T1, val x2: T2)
class C {
typealias P2 = Pair<Int, Int>
fun p() = P2(1, 1)
fun first(p: P2) = p.x1
fun second(p: P2) = p.x2
}
val p1 = Pair(1, 1)
val test1: Int = C().first(p1)
val test2: Int = C().second(p1)
fun C.testExtFun1(x: C.P2) = x
fun C.testExtFun2(): C.P2 {
val x: C.P2 = p()
val y = C.P2(1, 1)
return x
}
@@ -0,0 +1,27 @@
package
public val p1: Pair<kotlin.Int, kotlin.Int>
public val test1: kotlin.Int
public val test2: kotlin.Int
public fun C.testExtFun1(/*0*/ x: C.P2 [= Pair<kotlin.Int, kotlin.Int>]): C.P2 [= Pair<kotlin.Int, kotlin.Int>]
public fun C.testExtFun2(): C.P2 [= Pair<kotlin.Int, kotlin.Int>]
public final class C {
public typealias P2 = Pair<kotlin.Int, kotlin.Int>
public constructor C()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun first(/*0*/ p: C.P2 [= Pair<kotlin.Int, kotlin.Int>]): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun p(): Pair<kotlin.Int, kotlin.Int>
public final fun second(/*0*/ p: C.P2 [= Pair<kotlin.Int, kotlin.Int>]): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Pair</*0*/ T1, /*1*/ T2> {
public constructor Pair</*0*/ T1, /*1*/ T2>(/*0*/ x1: T1, /*1*/ x2: T2)
public final val x1: T1
public final val x2: T2
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,21 @@
class Pair<T1, T2>(val x1: T1, val x2: T2)
class C<T> {
typealias P2 = Pair<T, T>
typealias PT2<T2> = Pair<T, T2>
fun first(p: P2) = p.x1
fun second(p: P2) = p.x2
fun <T2> first2(p: PT2<T2>) = p.x1
fun <T2> second2(p: PT2<T2>) = p.x2
}
val p1 = Pair(1, 1)
val p2 = Pair(1, "")
val test1: Int = C<Int>().first(p1)
val test2: Int = C<Int>().second(p1)
val test3: Int = C<Int>().first2(p2)
val test4: String = C<Int>().second2(p2)
@@ -0,0 +1,30 @@
package
public val p1: Pair<kotlin.Int, kotlin.Int>
public val p2: Pair<kotlin.Int, kotlin.String>
public val test1: kotlin.Int
public val test2: kotlin.Int
public val test3: kotlin.Int
public val test4: kotlin.String
public final class C</*0*/ T> {
public typealias P2 /*captured type parameters: /*0*/ T*/ = Pair<T, T>
public typealias PT2</*0*/ T2> /*captured type parameters: /*1*/ T*/ = Pair<T, T2>
public constructor C</*0*/ T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun first(/*0*/ p: C<T>.P2 [= Pair<T, T>]): T
public final fun </*0*/ T2> first2(/*0*/ p: C<T>.PT2<T2> [= Pair<T, T2>]): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun second(/*0*/ p: C<T>.P2 [= Pair<T, T>]): T
public final fun </*0*/ T2> second2(/*0*/ p: C<T>.PT2<T2> [= Pair<T, T2>]): T2
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Pair</*0*/ T1, /*1*/ T2> {
public constructor Pair</*0*/ T1, /*1*/ T2>(/*0*/ x1: T1, /*1*/ x2: T2)
public final val x1: T1
public final val x2: T2
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,9 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
class Pair<T1, T2>(val x1: T1, val x2: T2)
class C<T> {
typealias P2 = Pair<T, Int>
}
val p1: C<String>.P2 = Pair("", 1)
@@ -0,0 +1,20 @@
package
public val p1: C<kotlin.String>.P2 [= Pair<kotlin.String, kotlin.Int>]
public final class C</*0*/ T> {
public typealias P2 /*captured type parameters: /*0*/ T*/ = Pair<T, kotlin.Int>
public constructor C</*0*/ T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Pair</*0*/ T1, /*1*/ T2> {
public constructor Pair</*0*/ T1, /*1*/ T2>(/*0*/ x1: T1, /*1*/ x2: T2)
public final val x1: T1
public final val x2: T2
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
+2 -2
View File
@@ -1,4 +1,4 @@
typealias A = B
typealias B = A
typealias A = <!RECURSIVE_TYPEALIAS_EXPANSION!>B<!>
typealias B = <!RECURSIVE_TYPEALIAS_EXPANSION!>A<!>
val x: <!RECURSIVE_TYPEALIAS_EXPANSION!>A<!> = TODO()
@@ -3,13 +3,13 @@ class Out<out T>
class Inv<T>
typealias In1<T> = In<T>
typealias In2<T> = In<<!REDUNDANT_PROJECTION!>in<!> T>
typealias In3<T> = In<<!CONFLICTING_PROJECTION!>out<!> T>
typealias In2<T> = In<<!REDUNDANT_PROJECTION, REDUNDANT_PROJECTION!>in<!> T>
typealias In3<T> = In<<!CONFLICTING_PROJECTION, CONFLICTING_PROJECTION!>out<!> T>
typealias In4<T> = In<*>
typealias Out1<T> = Out<T>
typealias Out2<T> = Out<<!CONFLICTING_PROJECTION!>in<!> T>
typealias Out3<T> = Out<<!REDUNDANT_PROJECTION!>out<!> T>
typealias Out2<T> = Out<<!CONFLICTING_PROJECTION, CONFLICTING_PROJECTION!>in<!> T>
typealias Out3<T> = Out<<!REDUNDANT_PROJECTION, REDUNDANT_PROJECTION!>out<!> T>
typealias Out4<T> = Out<*>
typealias Inv1<T> = Inv<T>
@@ -0,0 +1,13 @@
// !LANGUAGE: -TypeAliases
class C
<!UNSUPPORTED_TYPEALIAS!>typealias<!> S = String
<!UNSUPPORTED_TYPEALIAS!>typealias<!> L<T> = List<T>
<!UNSUPPORTED_TYPEALIAS!>typealias<!> CA = C
val test1: <!UNRESOLVED_REFERENCE!>S<!> = ""
fun test2(x: <!UNRESOLVED_REFERENCE!>L<!><<!UNRESOLVED_REFERENCE!>S<!>>) = <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>
class Test3 : <!UNRESOLVED_REFERENCE!>CA<!>()
@@ -0,0 +1,18 @@
package
public val test1: [ERROR : S]
public fun test2(/*0*/ x: [ERROR : L<S>]<[ERROR : S]>): [ERROR : L<S>]<[ERROR : S]>
public final class C {
public constructor C()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test3 {
public constructor Test3()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,18 @@
//ALLOW_AST_ACCESS
package test
open class Pair<T1, T2>
open class Triple<T1, T2, T3>
class Outer<X> {
inner class InnerTest1<A>: Pair<X, A>()
typealias Test1<A> = Pair<X, A>
class Nested<Y> {
typealias Test2<B> = Pair<Y, B>
}
inner class Inner<Z> {
typealias Test3<C> = Triple<X, Z, C>
}
}
@@ -0,0 +1,28 @@
package test
public final class Outer</*0*/ X> {
public typealias Test1</*0*/ A> /*captured type parameters: /*1*/ X*/ = test.Pair<X, A>
/*primary*/ public constructor Outer</*0*/ X>()
public final inner class Inner</*0*/ Z> /*captured type parameters: /*1*/ X*/ {
public typealias Test3</*0*/ C> /*captured type parameters: /*1*/ Z, /*2*/ X*/ = test.Triple<X, Z, C>
/*primary*/ public constructor Inner</*0*/ Z>()
}
public final inner class InnerTest1</*0*/ A> /*captured type parameters: /*1*/ X*/ : test.Pair<X, A> {
/*primary*/ public constructor InnerTest1</*0*/ A>()
}
public final class Nested</*0*/ Y> {
public typealias Test2</*0*/ B> /*captured type parameters: /*1*/ Y*/ = test.Pair<Y, B>
/*primary*/ public constructor Nested</*0*/ Y>()
}
}
public open class Pair</*0*/ T1, /*1*/ T2> {
/*primary*/ public constructor Pair</*0*/ T1, /*1*/ T2>()
}
public open class Triple</*0*/ T1, /*1*/ T2, /*2*/ T3> {
/*primary*/ public constructor Triple</*0*/ T1, /*1*/ T2, /*2*/ T3>()
}
@@ -19167,6 +19167,30 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("isAsWithTypeAlias.kt")
public void testIsAsWithTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/isAsWithTypeAlias.kt");
doTest(fileName);
}
@TestMetadata("nested.kt")
public void testNested() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/nested.kt");
doTest(fileName);
}
@TestMetadata("nestedCapturingTypeParameters.kt")
public void testNestedCapturingTypeParameters() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/nestedCapturingTypeParameters.kt");
doTest(fileName);
}
@TestMetadata("nestedSubstituted.kt")
public void testNestedSubstituted() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/nestedSubstituted.kt");
doTest(fileName);
}
@TestMetadata("parameterRestrictions.kt")
public void testParameterRestrictions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/parameterRestrictions.kt");
@@ -19226,6 +19250,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasObjectWithInvoke.kt");
doTest(fileName);
}
@TestMetadata("unsupportedTypeAlias.kt")
public void testUnsupportedTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/unsupportedTypeAlias.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/diagnostics/tests/unit")
@@ -4815,6 +4815,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Generic.kt");
doTestCompiledKotlin(fileName);
}
@TestMetadata("Nested.kt")
public void testNested() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Nested.kt");
doTestCompiledKotlin(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/visibility")
@@ -3048,6 +3048,12 @@ public class LoadKotlinWithTypeTableTestGenerated extends AbstractLoadKotlinWith
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Generic.kt");
doTest(fileName);
}
@TestMetadata("Nested.kt")
public void testNested() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Nested.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/visibility")
@@ -3050,6 +3050,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Generic.kt");
doTest(fileName);
}
@TestMetadata("Nested.kt")
public void testNested() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Nested.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/visibility")
@@ -44,24 +44,19 @@ abstract class AbstractTypeAliasDescriptor(
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
visitor.visitTypeAliasDescriptor(this, data)
override fun isInner(): Boolean = false // TODO treat all nested type aliases as inner?
override fun isInner(): Boolean =
containingDeclaration !is PackageFragmentDescriptor
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> =
declaredTypeParametersImpl
override val classDescriptor: ClassDescriptor?
get() = expandedType.let { expandedType ->
if (expandedType.isError) null else expandedType.constructor.declarationDescriptor as? ClassDescriptor
}
get() = if (expandedType.isError) null else expandedType.constructor.declarationDescriptor as? ClassDescriptor
override fun getModality() = Modality.FINAL
override fun getVisibility() = visibilityImpl
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor =
if (substitutor.isEmpty) this
else TODO("typealias doSubstitute")
override fun getDefaultType(): KotlinType =
TODO("typealias getDefaultType")
@@ -70,12 +65,14 @@ abstract class AbstractTypeAliasDescriptor(
override fun toString(): String = "typealias ${name.asString()}"
protected abstract fun getTypeConstructorTypeParameters(): List<TypeParameterDescriptor>
private val typeConstructor = object : TypeConstructor {
override fun getDeclarationDescriptor(): TypeAliasDescriptor =
this@AbstractTypeAliasDescriptor
override fun getParameters(): List<TypeParameterDescriptor> =
declarationDescriptor.declaredTypeParameters // TODO type parameters of outer class
getTypeConstructorTypeParameters()
override fun getSupertypes(): Collection<KotlinType> =
declarationDescriptor.underlyingType.constructor.supertypes
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
fun ClassDescriptor.computeConstructorTypeParameters(): List<TypeParameterDescriptor> {
fun ClassifierDescriptorWithTypeParameters.computeConstructorTypeParameters(): List<TypeParameterDescriptor> {
val declaredParameters = declaredTypeParameters
if (!isInner && containingDeclaration !is CallableDescriptor) return declaredParameters
@@ -810,10 +810,24 @@ internal class DescriptorRendererImpl(
renderVisibility(typeAlias.visibility, builder)
builder.append(renderKeyword("typealias")).append(" ")
renderName(typeAlias, builder)
renderTypeParameters(typeAlias.declaredTypeParameters, builder, true)
renderCapturedTypeParametersIfRequired(typeAlias, builder)
builder.append(" = ").append(renderType(typeAlias.underlyingType))
}
private fun renderCapturedTypeParametersIfRequired(classifier: ClassifierDescriptorWithTypeParameters, builder: StringBuilder) {
val typeParameters = classifier.declaredTypeParameters
val typeConstructorParameters = classifier.typeConstructor.parameters
if (verbose && classifier.isInner && typeConstructorParameters.size > typeParameters.size) {
builder.append(" /*captured type parameters: ")
renderTypeParameterList(builder, typeConstructorParameters.subList(typeParameters.size, typeConstructorParameters.size))
builder.append("*/")
}
}
/* CLASSES */
private fun renderClass(klass: ClassDescriptor, builder: StringBuilder) {
val isEnumEntry = klass.kind == ClassKind.ENUM_ENTRY
@@ -844,14 +858,7 @@ internal class DescriptorRendererImpl(
val typeParameters = klass.declaredTypeParameters
renderTypeParameters(typeParameters, builder, false)
if (verbose && klass.isInner && klass.typeConstructor.parameters.size > typeParameters.size) {
builder.append(" /*captured type parameters: ")
val constructorTypeParameters = klass.typeConstructor.parameters
renderTypeParameterList(
builder, constructorTypeParameters.subList(typeParameters.size, constructorTypeParameters.size))
builder.append("*/")
}
renderCapturedTypeParametersIfRequired(klass, builder)
if (!klass.kind.isSingleton && classWithPrimaryConstructor) {
val primaryConstructor = klass.unsubstitutedPrimaryConstructor
@@ -17,16 +17,22 @@
package org.jetbrains.kotlin.resolve.scopes
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.Printer
class InnerClassesScopeWrapper(val workerScope: MemberScope) : MemberScopeImpl() {
override fun getContributedClassifier(name: Name, location: LookupLocation) = workerScope.getContributedClassifier(name, location) as? ClassDescriptor
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
workerScope.getContributedClassifier(name, location)?.let {
it as? ClassDescriptor ?: it as? TypeAliasDescriptor
}
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<ClassDescriptor> {
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<ClassifierDescriptor> {
val restrictedFilter = kindFilter.restrictedToKindsOrNull(DescriptorKindFilter.CLASSIFIERS_MASK) ?: return listOf()
return workerScope.getContributedDescriptors(restrictedFilter, nameFilter).filterIsInstance<ClassDescriptor>()
return workerScope.getContributedDescriptors(restrictedFilter, nameFilter).filterIsInstance<ClassifierDescriptorWithTypeParameters>()
}
override fun printScopeStructure(p: Printer) {
@@ -82,7 +82,7 @@ class TypeDeserializer(
proto.hasTypeParameterName() -> {
val container = c.containingDeclaration
val typeParameters = when (container) {
is ClassDescriptor -> container.typeConstructor.parameters
is ClassifierDescriptorWithTypeParameters -> container.typeConstructor.parameters
is CallableDescriptor -> container.typeParameters
else -> emptyList<TypeParameterDescriptor>()
}
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
interface DeserializedMemberDescriptor : MemberDescriptor {
val proto: MessageLite
@@ -146,11 +148,9 @@ class DeserializedTypeAliasDescriptor(
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility),
DeserializedMemberDescriptor {
private lateinit var underlyingTypeImpl: KotlinType
private lateinit var expandedTypeImpl: KotlinType
override val underlyingType: KotlinType get() = underlyingTypeImpl
override val expandedType: KotlinType get() = expandedTypeImpl
override lateinit var underlyingType: KotlinType private set
override lateinit var expandedType: KotlinType private set
private lateinit var typeConstructorParameters: List<TypeParameterDescriptor>
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
@@ -158,7 +158,22 @@ class DeserializedTypeAliasDescriptor(
expandedType: KotlinType
) {
initialize(declaredTypeParameters)
underlyingTypeImpl = underlyingType
expandedTypeImpl = expandedType
this.underlyingType = underlyingType
this.expandedType = expandedType
typeConstructorParameters = computeConstructorTypeParameters()
}
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor {
if (substitutor.isEmpty) return this
val substituted = DeserializedTypeAliasDescriptor(containingDeclaration, annotations, name, visibility, proto, nameResolver, typeTable, containerSource)
substituted.initialize(declaredTypeParameters,
substitutor.safeSubstitute(underlyingType, Variance.INVARIANT),
substitutor.safeSubstitute(expandedType, Variance.INVARIANT))
return substituted
}
override fun getTypeConstructorTypeParameters(): List<TypeParameterDescriptor> =
typeConstructorParameters
}
@@ -3048,6 +3048,12 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Generic.kt");
doTest(fileName);
}
@TestMetadata("Nested.kt")
public void testNested() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/typealias/Nested.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/visibility")