KT-11588 Type aliases
Resolution & expansion for type aliases. NB: Nested type aliases capturing type parameters of outer classes are not supported yet.
This commit is contained in:
+3
-1
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.repl
|
||||
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
|
||||
open class DelegatePackageMemberDeclarationProvider(var delegate: PackageMemberDeclarationProvider) : PackageMemberDeclarationProvider {
|
||||
@@ -35,4 +35,6 @@ open class DelegatePackageMemberDeclarationProvider(var delegate: PackageMemberD
|
||||
override fun getPropertyDeclarations(name: Name) = delegate.getPropertyDeclarations(name)
|
||||
|
||||
override fun getClassOrObjectDeclarations(name: Name) = delegate.getClassOrObjectDeclarations(name)
|
||||
|
||||
override fun getTypeAliasDeclarations(name: Name) = delegate.getTypeAliasDeclarations(name)
|
||||
}
|
||||
|
||||
@@ -115,6 +115,11 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtParameter> REIFIED_TYPE_IN_CATCH_CLAUSE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtTypeParameterList> GENERIC_THROWABLE_SUBCLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<KtUserType, ClassifierDescriptor> RECURSIVE_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory3<KtUserType, KotlinType, KotlinType, ClassifierDescriptor> UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION =
|
||||
DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory1<KtUserType, KotlinType> CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Errors in declarations
|
||||
@@ -281,8 +286,8 @@ public interface Errors {
|
||||
DiagnosticFactory2<KtSimpleNameExpression, KtTypeConstraint, KtTypeParameterListOwner> NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER =
|
||||
DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtTypeParameter>
|
||||
VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY = DiagnosticFactory0.create(ERROR, VARIANCE_MODIFIER);
|
||||
DiagnosticFactory0<KtTypeParameter> VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, VARIANCE_MODIFIER);
|
||||
DiagnosticFactory0<KtTypeReference> BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtTypeParameterList> DEPRECATED_TYPE_PARAMETER_SYNTAX = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
|
||||
+9
-1
@@ -413,6 +413,13 @@ 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(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}'': " +
|
||||
"should be subtype of ''{0}'', substituted type is ''{1}''",
|
||||
RENDER_TYPE, RENDER_TYPE, NAME);
|
||||
MAP.put(CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION, "Conflicting projection in type alias expansion in intermediate type ''{0}''", RENDER_TYPE);
|
||||
|
||||
MAP.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", FQ_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(CONSTANT_EXPECTED_TYPE_MISMATCH, "The {0} literal does not conform to the expected type {1}", STRING, RENDER_TYPE);
|
||||
@@ -503,7 +510,8 @@ public class DefaultErrorMessages {
|
||||
|
||||
MAP.put(MISSING_CONSTRUCTOR_KEYWORD, "Use 'constructor' keyword after modifiers of primary constructor");
|
||||
|
||||
MAP.put(VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY, "Variance annotations are only allowed for type parameters of classes and interfaces");
|
||||
MAP.put(VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED, "Variance annotations are only allowed for type parameters of classes and interfaces");
|
||||
MAP.put(BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED, "Bounds are not allowed on type alias parameters");
|
||||
|
||||
MAP.put(DEPRECATED_TYPE_PARAMETER_SYNTAX, "Type parameters must be placed before the name of the function");
|
||||
|
||||
|
||||
@@ -216,10 +216,11 @@ public interface BindingContext {
|
||||
WritableSlice<KtParameter, VariableDescriptor> VALUE_PARAMETER = Slices.createSimpleSlice();
|
||||
WritableSlice<KtPropertyAccessor, PropertyAccessorDescriptor> PROPERTY_ACCESSOR = Slices.createSimpleSlice();
|
||||
WritableSlice<PsiElement, PropertyDescriptor> PRIMARY_CONSTRUCTOR_PARAMETER = Slices.createSimpleSlice();
|
||||
WritableSlice<KtTypeAlias, TypeAliasDescriptor> TYPE_ALIAS = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice[] DECLARATIONS_TO_DESCRIPTORS = new WritableSlice[] {
|
||||
CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR,
|
||||
PRIMARY_CONSTRUCTOR_PARAMETER, SCRIPT
|
||||
PRIMARY_CONSTRUCTOR_PARAMETER, SCRIPT, TYPE_ALIAS
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -20,10 +20,7 @@ import org.jetbrains.annotations.Mutable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ReadOnly;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes;
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor;
|
||||
@@ -49,6 +46,8 @@ public interface BodiesResolveContext {
|
||||
Map<KtProperty, PropertyDescriptor> getProperties();
|
||||
@Mutable
|
||||
Map<KtNamedFunction, SimpleFunctionDescriptor> getFunctions();
|
||||
@Mutable
|
||||
Map<KtTypeAlias, TypeAliasDescriptor> getTypeAliases();
|
||||
|
||||
@Nullable
|
||||
LexicalScope getDeclaringScope(@NotNull KtDeclaration declaration);
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.TypeAliasDescriptorImpl;
|
||||
import org.jetbrains.kotlin.resolve.scopes.*;
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
@@ -62,6 +63,7 @@ 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.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveModalityFromModifiers;
|
||||
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers;
|
||||
@@ -388,24 +390,29 @@ public class DescriptorResolver {
|
||||
return builtIns.getArrayType(Variance.OUT_VARIANCE, elementType);
|
||||
}
|
||||
|
||||
public List<TypeParameterDescriptorImpl> resolveTypeParametersForCallableDescriptor(
|
||||
public List<TypeParameterDescriptorImpl> resolveTypeParametersForDescriptor(
|
||||
DeclarationDescriptor containingDescriptor,
|
||||
LexicalWritableScope extensibleScope,
|
||||
LexicalScope scopeForAnnotationsResolve,
|
||||
List<KtTypeParameter> typeParameters,
|
||||
BindingTrace trace
|
||||
) {
|
||||
assert containingDescriptor instanceof FunctionDescriptor ||
|
||||
containingDescriptor instanceof PropertyDescriptor ||
|
||||
containingDescriptor instanceof TypeAliasDescriptor
|
||||
: "This method should be called for functions, properties, or type aliases, got " + containingDescriptor;
|
||||
|
||||
List<TypeParameterDescriptorImpl> result = new ArrayList<TypeParameterDescriptorImpl>();
|
||||
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
||||
KtTypeParameter typeParameter = typeParameters.get(i);
|
||||
result.add(resolveTypeParameterForCallableDescriptor(
|
||||
result.add(resolveTypeParameterForDescriptor(
|
||||
containingDescriptor, extensibleScope, scopeForAnnotationsResolve, typeParameter, i, trace));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private TypeParameterDescriptorImpl resolveTypeParameterForCallableDescriptor(
|
||||
DeclarationDescriptor containingDescriptor,
|
||||
private TypeParameterDescriptorImpl resolveTypeParameterForDescriptor(
|
||||
final DeclarationDescriptor containingDescriptor,
|
||||
LexicalWritableScope extensibleScope,
|
||||
LexicalScope scopeForAnnotationsResolve,
|
||||
final KtTypeParameter typeParameter,
|
||||
@@ -413,8 +420,7 @@ public class DescriptorResolver {
|
||||
final BindingTrace trace
|
||||
) {
|
||||
if (typeParameter.getVariance() != Variance.INVARIANT) {
|
||||
assert !(containingDescriptor instanceof ClassifierDescriptor) : "This method is intended for functions/properties";
|
||||
trace.report(VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY.on(typeParameter));
|
||||
trace.report(VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED.on(typeParameter));
|
||||
}
|
||||
|
||||
Annotations annotations =
|
||||
@@ -431,7 +437,9 @@ public class DescriptorResolver {
|
||||
new Function1<KotlinType, Void>() {
|
||||
@Override
|
||||
public Void invoke(KotlinType type) {
|
||||
trace.report(Errors.CYCLIC_GENERIC_UPPER_BOUND.on(typeParameter));
|
||||
if (!(containingDescriptor instanceof TypeAliasDescriptor)) {
|
||||
trace.report(Errors.CYCLIC_GENERIC_UPPER_BOUND.on(typeParameter));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
@@ -667,6 +675,65 @@ public class DescriptorResolver {
|
||||
return variableDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TypeAliasDescriptor resolveTypeAliasDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull KtTypeAlias typeAlias,
|
||||
@NotNull final BindingTrace trace
|
||||
) {
|
||||
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);
|
||||
TypeAliasDescriptorImpl typeAliasDescriptor = TypeAliasDescriptorImpl.create(
|
||||
containingDeclaration, allAnnotations, name, sourceElement, visibility);
|
||||
|
||||
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
|
||||
final LexicalScope scopeWithTypeParameters;
|
||||
{
|
||||
List<KtTypeParameter> typeParameters = typeAlias.getTypeParameters();
|
||||
if (typeParameters.isEmpty()) {
|
||||
scopeWithTypeParameters = scope;
|
||||
typeParameterDescriptors = Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
LexicalWritableScope writableScope = new LexicalWritableScope(
|
||||
scope, containingDeclaration, false, null, new TraceBasedLocalRedeclarationChecker(trace),
|
||||
LexicalScopeKind.TYPE_ALIAS_HEADER);
|
||||
typeParameterDescriptors = resolveTypeParametersForDescriptor(
|
||||
typeAliasDescriptor, writableScope, scope, typeParameters, trace);
|
||||
writableScope.freeze();
|
||||
checkNoGenericBoundsOnTypeAliasParameters(typeAlias, trace);
|
||||
resolveGenericBounds(typeAlias, typeAliasDescriptor, writableScope, typeParameterDescriptors, trace);
|
||||
scopeWithTypeParameters = writableScope;
|
||||
}
|
||||
}
|
||||
|
||||
final KtTypeReference typeReference = typeAlias.getTypeReference();
|
||||
|
||||
typeAliasDescriptor.initialize(typeParameterDescriptors, storageManager.createLazyValue(new Function0<KotlinType>() {
|
||||
@Override
|
||||
public KotlinType invoke() {
|
||||
return typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace, true);
|
||||
}
|
||||
}));
|
||||
|
||||
trace.record(TYPE_ALIAS, typeAlias, typeAliasDescriptor);
|
||||
return typeAliasDescriptor;
|
||||
}
|
||||
|
||||
private static void checkNoGenericBoundsOnTypeAliasParameters(@NotNull KtTypeAlias typeAlias, @NotNull BindingTrace trace) {
|
||||
for (KtTypeParameter typeParameter : typeAlias.getTypeParameters()) {
|
||||
KtTypeReference bound = typeParameter.getExtendsBound();
|
||||
if (bound != null) {
|
||||
trace.report(BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED.on(bound));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PropertyDescriptor resolvePropertyDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@@ -727,7 +794,7 @@ public class DescriptorResolver {
|
||||
LexicalWritableScope writableScope = new LexicalWritableScope(
|
||||
scope, containingDeclaration, false, null, new TraceBasedLocalRedeclarationChecker(trace, overloadChecker),
|
||||
LexicalScopeKind.PROPERTY_HEADER);
|
||||
typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(
|
||||
typeParameterDescriptors = resolveTypeParametersForDescriptor(
|
||||
propertyDescriptor, writableScope, scope, typeParameters, trace);
|
||||
writableScope.freeze();
|
||||
resolveGenericBounds(property, propertyDescriptor, writableScope, typeParameterDescriptors, trace);
|
||||
@@ -1092,6 +1159,27 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkBoundsInTypeAlias(
|
||||
@NotNull KtUserType typeAliasElement,
|
||||
@NotNull KotlinType typeArgument,
|
||||
@NotNull TypeParameterDescriptor typeParameterDescriptor,
|
||||
@NotNull TypeSubstitutor substitutor,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
|
||||
assert containingDeclaration instanceof ClassifierDescriptor :
|
||||
"Containing declaration of a type parameter should be a classifier, got " + containingDeclaration;
|
||||
ClassifierDescriptor containingClassifier = (ClassifierDescriptor) containingDeclaration;
|
||||
|
||||
for (KotlinType bound : typeParameterDescriptor.getUpperBounds()) {
|
||||
KotlinType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
|
||||
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(typeArgument, substitutedBound)) {
|
||||
trace.report(UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION.on(
|
||||
typeAliasElement, substitutedBound, typeArgument, containingClassifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkHasOuterClassInstance(
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull BindingTrace trace,
|
||||
|
||||
@@ -146,7 +146,7 @@ class FunctionDescriptorResolver(
|
||||
TraceBasedLocalRedeclarationChecker(trace, overloadChecker), LexicalScopeKind.FUNCTION_HEADER)
|
||||
|
||||
val typeParameterDescriptors = descriptorResolver.
|
||||
resolveTypeParametersForCallableDescriptor(functionDescriptor, innerScope, scope, function.typeParameters, trace)
|
||||
resolveTypeParametersForDescriptor(functionDescriptor, innerScope, scope, function.typeParameters, trace)
|
||||
descriptorResolver.resolveGenericBounds(function, functionDescriptor, innerScope, typeParameterDescriptors, trace)
|
||||
|
||||
val receiverTypeRef = function.receiverTypeReference
|
||||
|
||||
@@ -54,6 +54,7 @@ class LazyTopDownAnalyzer(
|
||||
|
||||
val properties = ArrayList<KtProperty>()
|
||||
val functions = ArrayList<KtNamedFunction>()
|
||||
val typeAliases = ArrayList<KtTypeAlias>()
|
||||
|
||||
// fill in the context
|
||||
for (declaration in declarations) {
|
||||
@@ -168,6 +169,10 @@ class LazyTopDownAnalyzer(
|
||||
override fun visitProperty(property: KtProperty) {
|
||||
properties.add(property)
|
||||
}
|
||||
|
||||
override fun visitTypeAlias(typeAlias: KtTypeAlias) {
|
||||
typeAliases.add(typeAlias)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -175,6 +180,8 @@ class LazyTopDownAnalyzer(
|
||||
|
||||
createPropertyDescriptors(c, topLevelFqNames, properties)
|
||||
|
||||
createTypeAliasDescriptors(c, topLevelFqNames, typeAliases)
|
||||
|
||||
resolveAllHeadersInClasses(c)
|
||||
|
||||
declarationResolver.checkRedeclarationsInPackages(topLevelDescriptorProvider, topLevelFqNames)
|
||||
@@ -199,6 +206,16 @@ class LazyTopDownAnalyzer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun createTypeAliasDescriptors(c: TopDownAnalysisContext, topLevelFqNames: Multimap<FqName, KtElement>, typeAliases: List<KtTypeAlias>) {
|
||||
for (typeAlias in typeAliases) {
|
||||
val descriptor = lazyDeclarationResolver.resolveToDescriptor(typeAlias) as TypeAliasDescriptor
|
||||
|
||||
c.typeAliases[typeAlias] = descriptor
|
||||
ForceResolveUtil.forceResolveAllContents(descriptor.annotations)
|
||||
registerTopLevelFqName(topLevelFqNames, typeAlias, descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPropertyDescriptors(c: TopDownAnalysisContext, topLevelFqNames: Multimap<FqName, KtElement>, properties: List<KtProperty>) {
|
||||
for (property in properties) {
|
||||
val descriptor = lazyDeclarationResolver.resolveToDescriptor(property) as PropertyDescriptor
|
||||
|
||||
@@ -370,8 +370,10 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
|
||||
|
||||
val nextPackageOrClassDescriptor =
|
||||
when (currentDescriptor) {
|
||||
is TypeAliasDescriptor -> // TODO type aliases as qualifiers? (would break some assumptions in TypeResolver)
|
||||
currentDescriptor.underlyingClassDescriptor.getContributedClassifier(qualifierPart)
|
||||
is ClassDescriptor ->
|
||||
currentDescriptor.unsubstitutedInnerClassesScope.getContributedClassifier(qualifierPart.name, qualifierPart.location)
|
||||
currentDescriptor.getContributedClassifier(qualifierPart)
|
||||
is PackageViewDescriptor -> {
|
||||
val packageView =
|
||||
if (qualifierPart.typeArguments == null) {
|
||||
@@ -404,6 +406,9 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
|
||||
return Pair(currentDescriptor, path.size)
|
||||
}
|
||||
|
||||
fun ClassDescriptor.getContributedClassifier(qualifierPart: QualifierPart) =
|
||||
unsubstitutedInnerClassesScope.getContributedClassifier(qualifierPart.name, qualifierPart.location)
|
||||
|
||||
fun resolveNameExpressionAsQualifierForDiagnostics(
|
||||
expression: KtSimpleNameExpression,
|
||||
receiver: Receiver?,
|
||||
|
||||
@@ -45,6 +45,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
private final Map<KtNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap();
|
||||
private final Map<KtProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
|
||||
private final Map<KtParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
|
||||
private final Map<KtTypeAlias, TypeAliasDescriptor> typeAliases = Maps.newLinkedHashMap();
|
||||
private Map<KtCallableDeclaration, CallableMemberDescriptor> members = null;
|
||||
|
||||
private final Map<KtScript, LazyScriptDescriptor> scripts = Maps.newLinkedHashMap();
|
||||
@@ -139,6 +140,11 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
return functions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<KtTypeAlias, TypeAliasDescriptor> getTypeAliases() {
|
||||
return typeAliases;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<KtCallableDeclaration, CallableMemberDescriptor> getMembers() {
|
||||
if (members == null) {
|
||||
|
||||
@@ -26,9 +26,14 @@ public class TypeResolutionContext {
|
||||
public final boolean allowBareTypes;
|
||||
public final boolean forceResolveLazyTypes;
|
||||
public final boolean isDebuggerContext;
|
||||
public final boolean abbreviated;
|
||||
|
||||
public TypeResolutionContext(@NotNull LexicalScope scope, @NotNull BindingTrace trace, boolean checkBounds, boolean allowBareTypes, boolean isDebuggerContext) {
|
||||
this(scope, trace, checkBounds, allowBareTypes, allowBareTypes, isDebuggerContext);
|
||||
this(scope, trace, checkBounds, allowBareTypes, allowBareTypes, isDebuggerContext, false);
|
||||
}
|
||||
|
||||
public TypeResolutionContext(@NotNull LexicalScope scope, @NotNull BindingTrace trace, boolean checkBounds, boolean allowBareTypes, boolean isDebuggerContext, boolean abbreviated) {
|
||||
this(scope, trace, checkBounds, allowBareTypes, allowBareTypes, isDebuggerContext, abbreviated);
|
||||
}
|
||||
|
||||
private TypeResolutionContext(
|
||||
@@ -37,7 +42,8 @@ public class TypeResolutionContext {
|
||||
boolean checkBounds,
|
||||
boolean allowBareTypes,
|
||||
boolean forceResolveLazyTypes,
|
||||
boolean isDebuggerContext
|
||||
boolean isDebuggerContext,
|
||||
boolean abbreviated
|
||||
) {
|
||||
this.scope = scope;
|
||||
this.trace = trace;
|
||||
@@ -45,9 +51,10 @@ public class TypeResolutionContext {
|
||||
this.allowBareTypes = allowBareTypes;
|
||||
this.forceResolveLazyTypes = forceResolveLazyTypes;
|
||||
this.isDebuggerContext = isDebuggerContext;
|
||||
this.abbreviated = abbreviated;
|
||||
}
|
||||
|
||||
public TypeResolutionContext noBareTypes() {
|
||||
return new TypeResolutionContext(scope, trace, checkBounds, false, forceResolveLazyTypes, isDebuggerContext);
|
||||
return new TypeResolutionContext(scope, trace, checkBounds, false, forceResolveLazyTypes, isDebuggerContext, abbreviated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.Variance.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.isArrayOfNothing
|
||||
import java.util.*
|
||||
|
||||
class TypeResolver(
|
||||
private val annotationResolver: AnnotationResolver,
|
||||
@@ -64,7 +65,11 @@ class TypeResolver(
|
||||
|
||||
fun resolveType(scope: LexicalScope, typeReference: KtTypeReference, trace: BindingTrace, checkBounds: Boolean): KotlinType {
|
||||
// bare types are not allowed
|
||||
return resolveType(TypeResolutionContext(scope, trace, checkBounds, false, typeReference.suppressDiagnosticsInDebugMode()), typeReference)
|
||||
return resolveType(TypeResolutionContext(scope, trace, checkBounds, false, typeReference.suppressDiagnosticsInDebugMode(), false), typeReference)
|
||||
}
|
||||
|
||||
fun resolveAbbreviatedType(scope: LexicalScope, typeReference: KtTypeReference, trace: BindingTrace, checkBounds: Boolean): KotlinType {
|
||||
return resolveType(TypeResolutionContext(scope, trace, checkBounds, false, typeReference.suppressDiagnosticsInDebugMode(), true), typeReference)
|
||||
}
|
||||
|
||||
private fun resolveType(c: TypeResolutionContext, typeReference: KtTypeReference): KotlinType {
|
||||
@@ -181,7 +186,10 @@ class TypeResolver(
|
||||
|
||||
type(resolveTypeForTypeParameter(c, annotations, classifierDescriptor, referenceExpression, type))
|
||||
}
|
||||
is ClassDescriptor -> resolveTypeForClass(c, annotations, classifierDescriptor, type, qualifierResolutionResults)
|
||||
is ClassDescriptor ->
|
||||
resolveTypeForClass(c, annotations, classifierDescriptor, type, qualifierResolutionResults)
|
||||
is TypeAliasDescriptor ->
|
||||
resolveTypeForTypeAlias(c, annotations, classifierDescriptor, type, qualifierResolutionResults)
|
||||
else -> error("Unexpected classifier type: ${classifierDescriptor.javaClass}")
|
||||
}
|
||||
}
|
||||
@@ -347,7 +355,7 @@ class TypeResolver(
|
||||
}
|
||||
|
||||
if (ErrorUtils.isError(classDescriptor)) {
|
||||
return createErrorTypeAndResolveArguments(c, projectionFromAllQualifierParts, "[Error type: $typeConstructor]")
|
||||
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
|
||||
}
|
||||
|
||||
val collectedArgumentAsTypeProjections =
|
||||
@@ -393,6 +401,264 @@ class TypeResolver(
|
||||
return type(resultingType)
|
||||
}
|
||||
|
||||
private fun resolveTypeForTypeAlias(
|
||||
c: TypeResolutionContext,
|
||||
annotations: Annotations,
|
||||
typeAliasDescriptor: TypeAliasDescriptor,
|
||||
type: KtUserType,
|
||||
qualifierResolutionResult: QualifiedExpressionResolver.TypeQualifierResolutionResult
|
||||
): PossiblyBareType {
|
||||
val typeAliasConstructor = typeAliasDescriptor.typeConstructor
|
||||
val projectionFromAllQualifierParts = qualifierResolutionResult.allProjections
|
||||
|
||||
if (ErrorUtils.isError(typeAliasDescriptor)) {
|
||||
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeAliasConstructor)
|
||||
}
|
||||
|
||||
// TODO type arguments substitution for type parameters of outer classes
|
||||
// TODO should we support type aliases as qualifiers? what about generics?
|
||||
|
||||
val typeAliasParameters = typeAliasDescriptor.declaredTypeParameters
|
||||
|
||||
val typeAliasQualifierPart = qualifierResolutionResult.qualifierParts.lastOrNull()
|
||||
?: return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeAliasConstructor)
|
||||
|
||||
// TODO appendDefaultArgumentsForInnerScope
|
||||
val typeAliasArguments = typeAliasQualifierPart.typeArguments?.arguments.orEmpty()
|
||||
|
||||
if (typeAliasParameters.size != typeAliasArguments.size) {
|
||||
c.trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeAliasQualifierPart.typeArguments ?: typeAliasQualifierPart.expression,
|
||||
typeAliasParameters.size, typeAliasDescriptor))
|
||||
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeAliasConstructor)
|
||||
}
|
||||
|
||||
return if (c.abbreviated) {
|
||||
val arguments = resolveTypeProjections(c, typeAliasDescriptor.typeConstructor, typeAliasArguments)
|
||||
val abbreviatedType = KotlinTypeImpl.create(annotations, typeAliasDescriptor.typeConstructor, false, arguments, MemberScope.Empty)
|
||||
type(abbreviatedType)
|
||||
}
|
||||
else {
|
||||
val typeAliasExpansion = createTypeAliasExpansionFromSource(c, type, typeAliasDescriptor, typeAliasArguments)
|
||||
val expandedType = expandTypeAlias(c, typeAliasExpansion, annotations)
|
||||
type(expandedType)
|
||||
}
|
||||
}
|
||||
|
||||
private class AbbreviatedTypeImpl(override val abbreviatedType: KotlinType): AbbreviatedType
|
||||
|
||||
private fun withAbbreviatedType(abbreviatedType: KotlinType): TypeCapabilities =
|
||||
SingletonTypeCapabilities(AbbreviatedType::class.java, AbbreviatedTypeImpl(abbreviatedType))
|
||||
|
||||
private class TypeAliasExpansionContext(
|
||||
val element: KtUserType,
|
||||
val argumentElements: Map<TypeParameterDescriptor, KtTypeProjection>
|
||||
)
|
||||
|
||||
private class TypeAliasExpansion(
|
||||
val context: TypeAliasExpansionContext,
|
||||
val parent: TypeAliasExpansion?,
|
||||
val descriptor: TypeAliasDescriptor,
|
||||
val arguments: List<TypeProjection>,
|
||||
val mapping: Map<TypeParameterDescriptor, TypeProjection>
|
||||
) {
|
||||
fun getReplacement(constructor: TypeConstructor): TypeProjection? {
|
||||
val descriptor = constructor.declarationDescriptor
|
||||
return if (descriptor is TypeParameterDescriptor)
|
||||
mapping[descriptor]
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
fun isRecursion(descriptor: TypeAliasDescriptor): Boolean =
|
||||
this.descriptor == descriptor || (parent?.isRecursion(descriptor) ?: false)
|
||||
}
|
||||
|
||||
private fun createTypeAliasExpansionFromSource(
|
||||
c: TypeResolutionContext,
|
||||
element: KtUserType,
|
||||
descriptor: TypeAliasDescriptor,
|
||||
argumentElements: List<KtTypeProjection>
|
||||
): TypeAliasExpansion {
|
||||
val typeAliasParameters = descriptor.typeConstructor.parameters
|
||||
val arguments = resolveTypeProjections(c, descriptor.typeConstructor, argumentElements)
|
||||
|
||||
val mappedArguments: Map<TypeParameterDescriptor, TypeProjection>
|
||||
val mappedElements: Map<TypeParameterDescriptor, KtTypeProjection>
|
||||
if (typeAliasParameters.isNotEmpty()) {
|
||||
val resultingArguments = HashMap<TypeParameterDescriptor, TypeProjection>()
|
||||
val resultingElements = HashMap<TypeParameterDescriptor, KtTypeProjection>()
|
||||
typeAliasParameters.forEachIndexed { i, typeParameterDescriptor ->
|
||||
resultingArguments[typeParameterDescriptor] = arguments[i]
|
||||
resultingElements[typeParameterDescriptor] = argumentElements[i]
|
||||
}
|
||||
mappedArguments = resultingArguments
|
||||
mappedElements = resultingElements
|
||||
}
|
||||
else {
|
||||
mappedArguments = emptyMap()
|
||||
mappedElements = emptyMap()
|
||||
}
|
||||
|
||||
return TypeAliasExpansion(TypeAliasExpansionContext(element, mappedElements), null, descriptor, arguments, mappedArguments)
|
||||
}
|
||||
|
||||
private fun createNestedTypeAliasExpansion(
|
||||
parent: TypeAliasExpansion,
|
||||
typeAliasDescriptor: TypeAliasDescriptor,
|
||||
expandedArguments: List<TypeProjection>
|
||||
): TypeAliasExpansion {
|
||||
val mappedArguments = HashMap<TypeParameterDescriptor, TypeProjection>()
|
||||
typeAliasDescriptor.typeConstructor.parameters.forEachIndexed { i, typeParameterDescriptor ->
|
||||
mappedArguments[typeParameterDescriptor] = expandedArguments[i]
|
||||
}
|
||||
|
||||
return TypeAliasExpansion(parent.context, parent, typeAliasDescriptor, expandedArguments, mappedArguments)
|
||||
}
|
||||
|
||||
private fun expandTypeAlias(
|
||||
c: TypeResolutionContext,
|
||||
typeAliasExpansion: TypeAliasExpansion,
|
||||
annotations: Annotations
|
||||
): KotlinType {
|
||||
val originalProjection = TypeProjectionImpl(Variance.INVARIANT, typeAliasExpansion.descriptor.underlyingType)
|
||||
val expandedProjection = expandTypeProjectionForTypeAlias(c, originalProjection, typeAliasExpansion, null, 1)
|
||||
|
||||
if (expandedProjection.type.isError) return expandedProjection.type
|
||||
|
||||
assert(expandedProjection.projectionKind == Variance.INVARIANT) {
|
||||
"Type alias expansion: result for ${typeAliasExpansion.descriptor} is ${expandedProjection.projectionKind}, should be invariant"
|
||||
}
|
||||
|
||||
val abbreviatedType = KotlinTypeImpl.create(annotations, typeAliasExpansion.descriptor.typeConstructor,
|
||||
originalProjection.type.isMarkedNullable,
|
||||
typeAliasExpansion.arguments, MemberScope.Empty)
|
||||
|
||||
return expandedProjection.type.replace(
|
||||
newAnnotations = annotations,
|
||||
newCapabilities = withAbbreviatedType(abbreviatedType))
|
||||
}
|
||||
|
||||
private fun expandTypeProjectionForTypeAlias(
|
||||
c: TypeResolutionContext,
|
||||
originalProjection: TypeProjection,
|
||||
typeAliasExpansion: TypeAliasExpansion,
|
||||
typeParameterDescriptor: TypeParameterDescriptor?,
|
||||
recursionDepth: Int
|
||||
): TypeProjection {
|
||||
assertRecursionDepth(recursionDepth) {
|
||||
"Too deep recursion while expanding type alias ${typeAliasExpansion.descriptor}"
|
||||
}
|
||||
|
||||
val originalType = originalProjection.type
|
||||
|
||||
val typeAliasArgument = typeAliasExpansion.getReplacement(originalType.constructor)
|
||||
|
||||
if (typeAliasArgument == null) {
|
||||
return substituteNonArgumentTypeForTypeAlias(c, originalProjection, typeAliasExpansion, recursionDepth)
|
||||
}
|
||||
|
||||
val originalVariance =
|
||||
if (originalProjection.projectionKind != Variance.INVARIANT)
|
||||
originalProjection.projectionKind
|
||||
else if (typeParameterDescriptor != null)
|
||||
typeParameterDescriptor.variance
|
||||
else
|
||||
Variance.INVARIANT
|
||||
|
||||
val argumentVariance = typeAliasArgument.projectionKind
|
||||
|
||||
val substitutedVariance =
|
||||
if (argumentVariance == Variance.INVARIANT)
|
||||
originalVariance
|
||||
else if (originalVariance == Variance.INVARIANT || originalVariance == argumentVariance)
|
||||
argumentVariance
|
||||
else if (typeAliasArgument.isStarProjection)
|
||||
argumentVariance
|
||||
else {
|
||||
if (originalVariance != argumentVariance && !typeAliasArgument.isStarProjection) {
|
||||
val argumentElement = typeParameterDescriptor?.let { typeAliasExpansion.context.argumentElements[it] }
|
||||
if (argumentElement != null && typeParameterDescriptor != null) {
|
||||
c.trace.report(CONFLICTING_PROJECTION.on(argumentElement, typeParameterDescriptor))
|
||||
}
|
||||
else {
|
||||
c.trace.report(CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION.on(
|
||||
typeAliasExpansion.context.element, typeAliasExpansion.descriptor.underlyingType))
|
||||
}
|
||||
}
|
||||
argumentVariance
|
||||
}
|
||||
|
||||
val substitutedType = TypeUtils.makeNullableIfNeeded(typeAliasArgument.type, originalType.isMarkedNullable)
|
||||
|
||||
return TypeProjectionImpl(substitutedVariance, substitutedType)
|
||||
}
|
||||
|
||||
private fun substituteNonArgumentTypeForTypeAlias(
|
||||
c: TypeResolutionContext,
|
||||
originalProjection: TypeProjection,
|
||||
typeAliasExpansion: TypeAliasExpansion,
|
||||
recursionDepth: Int
|
||||
): TypeProjection {
|
||||
val type = originalProjection.type
|
||||
val typeConstructor = type.constructor
|
||||
val typeDescriptor = typeConstructor.declarationDescriptor
|
||||
|
||||
when (typeDescriptor) {
|
||||
is TypeParameterDescriptor -> {
|
||||
return originalProjection
|
||||
}
|
||||
is TypeAliasDescriptor -> {
|
||||
if (typeAliasExpansion.isRecursion(typeDescriptor)) {
|
||||
c.trace.report(RECURSIVE_TYPEALIAS_EXPANSION.on(typeAliasExpansion.context.element, typeDescriptor))
|
||||
return TypeProjectionImpl(Variance.INVARIANT, ErrorUtils.createErrorType("Recursive type alias: ${typeDescriptor.name}"))
|
||||
}
|
||||
|
||||
val expandedArguments = type.arguments.mapIndexed { i, typeAliasArgument ->
|
||||
expandTypeProjectionForTypeAlias(c, typeAliasArgument, typeAliasExpansion, typeConstructor.parameters[i], recursionDepth)
|
||||
}
|
||||
|
||||
val nestedExpansion = createNestedTypeAliasExpansion(typeAliasExpansion, typeDescriptor, expandedArguments)
|
||||
|
||||
val expandedType = expandTypeAlias(c, nestedExpansion, type.annotations)
|
||||
|
||||
return TypeProjectionImpl(originalProjection.projectionKind,
|
||||
if (expandedType.isError) expandedType else expandedType.replace(newCapabilities = withAbbreviatedType(type)))
|
||||
}
|
||||
else -> {
|
||||
val substitutedArguments = type.arguments.mapIndexed { i, originalArgument ->
|
||||
expandTypeProjectionForTypeAlias(c, originalArgument, typeAliasExpansion, typeConstructor.parameters[i], recursionDepth + 1)
|
||||
}
|
||||
|
||||
checkTypeArgumentsSubstitutionInTypeAliasExpansion(c, type, substitutedArguments, typeAliasExpansion)
|
||||
|
||||
val substitutedType = type.replace(newArguments = substitutedArguments)
|
||||
|
||||
return TypeProjectionImpl(originalProjection.projectionKind, substitutedType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkTypeArgumentsSubstitutionInTypeAliasExpansion(
|
||||
c: TypeResolutionContext,
|
||||
type: KotlinType,
|
||||
substitutedArguments: List<TypeProjection>,
|
||||
typeAliasExpansion: TypeAliasExpansion
|
||||
) {
|
||||
val typeSubstitutor = TypeSubstitutor.create(type)
|
||||
|
||||
substitutedArguments.forEachIndexed { i, substitutedArgument ->
|
||||
val typeParameter = type.constructor.parameters[i]
|
||||
DescriptorResolver.checkBoundsInTypeAlias(typeAliasExpansion.context.element, substitutedArgument.type, typeParameter, typeSubstitutor, c.trace)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createErrorTypeForTypeConstructor(
|
||||
c: TypeResolutionContext,
|
||||
arguments: List<KtTypeProjection>,
|
||||
typeConstructor: TypeConstructor
|
||||
) =
|
||||
createErrorTypeAndResolveArguments(c, arguments, "[Error type: $typeConstructor]")
|
||||
|
||||
// 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
|
||||
// from enclosing functions. In such cases you can not specify any argument:
|
||||
@@ -583,6 +849,14 @@ class TypeResolver(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MAX_RECURSION_DEPTH = 100
|
||||
|
||||
private inline fun assertRecursionDepth(recursionDepth: Int, lazyMessage: () -> String) {
|
||||
if (recursionDepth > MAX_RECURSION_DEPTH) {
|
||||
throw AssertionError(lazyMessage())
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic fun resolveProjectionKind(projectionKind: KtProjectionKind): Variance {
|
||||
return when (projectionKind) {
|
||||
KtProjectionKind.IN -> IN_VARIANCE
|
||||
|
||||
@@ -160,7 +160,7 @@ open class FileScopeProviderImpl(
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
|
||||
if (name in excludedNames) return null
|
||||
val classifier = scope.getContributedClassifier(name, location) ?: return null
|
||||
val visible = Visibilities.isVisibleIgnoringReceiver(classifier as ClassDescriptor, fromDescriptor)
|
||||
val visible = Visibilities.isVisibleIgnoringReceiver(classifier as DeclarationDescriptorWithVisibility, fromDescriptor)
|
||||
return classifier.check { filteringKind == if (visible) FilteringKind.VISIBLE_CLASSES else FilteringKind.INVISIBLE_CLASSES }
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +224,14 @@ public class LazyDeclarationResolver {
|
||||
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor visitTypeAlias(@NotNull KtTypeAlias typeAlias, Void data) {
|
||||
LookupLocation location = lookupLocationFor(typeAlias, typeAlias.isTopLevel());
|
||||
MemberScope scopeForDeclaration = getMemberScopeDeclaredIn(typeAlias, location);
|
||||
scopeForDeclaration.getContributedClassifier(typeAlias.getNameAsSafeName(), location);
|
||||
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, typeAlias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor visitScript(@NotNull KtScript script, Void data) {
|
||||
return getScriptDescriptor(script, lookupLocationFor(script, true));
|
||||
|
||||
+21
-18
@@ -36,29 +36,29 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
||||
val functions = ArrayListMultimap.create<Name, KtNamedFunction>()
|
||||
val properties = ArrayListMultimap.create<Name, KtProperty>()
|
||||
val classesAndObjects = ArrayListMultimap.create<Name, KtClassLikeInfo>() // order matters here
|
||||
val typeAliases = ArrayListMultimap.create<Name, KtTypeAlias>()
|
||||
|
||||
fun putToIndex(declaration: KtDeclaration) {
|
||||
if (declaration is KtAnonymousInitializer || declaration is KtSecondaryConstructor) return
|
||||
|
||||
allDeclarations.add(declaration)
|
||||
if (declaration is KtNamedFunction) {
|
||||
functions.put(safeNameForLazyResolve(declaration), declaration)
|
||||
}
|
||||
else if (declaration is KtProperty) {
|
||||
properties.put(safeNameForLazyResolve(declaration), declaration)
|
||||
}
|
||||
else if (declaration is KtClassOrObject) {
|
||||
classesAndObjects.put(safeNameForLazyResolve(declaration.getNameAsName()), KtClassInfoUtil.createClassLikeInfo(declaration))
|
||||
}
|
||||
else if (declaration is KtScript) {
|
||||
val scriptInfo = KtScriptInfo(declaration)
|
||||
classesAndObjects.put(scriptInfo.script.nameAsName, scriptInfo)
|
||||
}
|
||||
else if (declaration is KtParameter || declaration is KtDestructuringDeclaration) {
|
||||
// Do nothing, just put it into allDeclarations is enough
|
||||
}
|
||||
else {
|
||||
throw IllegalArgumentException("Unknown declaration: " + declaration)
|
||||
when (declaration) {
|
||||
is KtNamedFunction ->
|
||||
functions.put(safeNameForLazyResolve(declaration), declaration)
|
||||
is KtProperty ->
|
||||
properties.put(safeNameForLazyResolve(declaration), declaration)
|
||||
is KtTypeAlias ->
|
||||
typeAliases.put(safeNameForLazyResolve(declaration.nameAsName), declaration)
|
||||
is KtClassOrObject ->
|
||||
classesAndObjects.put(safeNameForLazyResolve(declaration.nameAsName), KtClassInfoUtil.createClassLikeInfo(declaration))
|
||||
is KtScript -> {
|
||||
val scriptInfo = KtScriptInfo(declaration)
|
||||
classesAndObjects.put(scriptInfo.script.nameAsName, scriptInfo)
|
||||
}
|
||||
is KtParameter, is KtDestructuringDeclaration -> {
|
||||
// Do nothing, just put it into allDeclarations is enough
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unknown declaration: " + declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,4 +82,7 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
||||
|
||||
override fun getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo>
|
||||
= index().classesAndObjects[ResolveSessionUtils.safeNameForLazyResolve(name)]
|
||||
|
||||
override fun getTypeAliasDeclarations(name: Name): Collection<KtTypeAlias>
|
||||
= index().typeAliases[ResolveSessionUtils.safeNameForLazyResolve(name)]
|
||||
}
|
||||
|
||||
+2
@@ -32,4 +32,6 @@ class CombinedPackageMemberDeclarationProvider(val providers: Collection<Package
|
||||
override fun getPropertyDeclarations(name: Name) = providers.flatMap { it.getPropertyDeclarations(name) }
|
||||
|
||||
override fun getClassOrObjectDeclarations(name: Name) = providers.flatMap { it.getClassOrObjectDeclarations(name) }
|
||||
|
||||
override fun getTypeAliasDeclarations(name: Name) = providers.flatMap { it.getTypeAliasDeclarations(name) }
|
||||
}
|
||||
|
||||
+3
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtTypeAlias
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
|
||||
interface DeclarationProvider {
|
||||
@@ -31,4 +32,6 @@ interface DeclarationProvider {
|
||||
fun getPropertyDeclarations(name: Name): Collection<KtProperty>
|
||||
|
||||
fun getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo>
|
||||
|
||||
fun getTypeAliasDeclarations(name: Name): Collection<KtTypeAlias>
|
||||
}
|
||||
|
||||
+24
-5
@@ -50,6 +50,7 @@ protected constructor(
|
||||
private val classDescriptors: MemoizedFunctionToNotNull<Name, List<ClassDescriptor>> = storageManager.createMemoizedFunction { resolveClassDescriptor(it) }
|
||||
private val functionDescriptors: MemoizedFunctionToNotNull<Name, Collection<SimpleFunctionDescriptor>> = storageManager.createMemoizedFunction { doGetFunctions(it) }
|
||||
private val propertyDescriptors: MemoizedFunctionToNotNull<Name, Collection<PropertyDescriptor>> = storageManager.createMemoizedFunction { doGetProperties(it) }
|
||||
private val typeAliasDescriptors: MemoizedFunctionToNotNull<Name, Collection<TypeAliasDescriptor>> = storageManager.createMemoizedFunction { doGetTypeAliases(it) }
|
||||
|
||||
private fun resolveClassDescriptor(name: Name): List<ClassDescriptor> {
|
||||
return declarationProvider.getClassOrObjectDeclarations(name).map {
|
||||
@@ -60,9 +61,9 @@ protected constructor(
|
||||
}.toReadOnlyList()
|
||||
}
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassDescriptor? {
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
|
||||
recordLookup(name, location)
|
||||
return classDescriptors(name).firstOrNull()
|
||||
return classDescriptors(name).firstOrNull() ?: typeAliasDescriptors(name).firstOrNull()
|
||||
}
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
|
||||
@@ -120,6 +121,20 @@ protected constructor(
|
||||
|
||||
protected abstract fun getNonDeclaredProperties(name: Name, result: MutableSet<PropertyDescriptor>)
|
||||
|
||||
protected fun getContributedTypeAliasDescriptors(name: Name, location: LookupLocation): Collection<TypeAliasDescriptor> {
|
||||
recordLookup(name, location)
|
||||
return typeAliasDescriptors(name)
|
||||
}
|
||||
|
||||
private fun doGetTypeAliases(name: Name): Collection<TypeAliasDescriptor> =
|
||||
declarationProvider.getTypeAliasDeclarations(name).map { ktTypeAlias ->
|
||||
c.descriptorResolver.resolveTypeAliasDescriptor(
|
||||
thisDescriptor,
|
||||
getScopeForMemberDeclarationResolution(ktTypeAlias),
|
||||
ktTypeAlias,
|
||||
trace)
|
||||
}.toReadOnlyList()
|
||||
|
||||
protected fun computeDescriptorsFromDeclaredElements(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean,
|
||||
@@ -152,6 +167,12 @@ protected constructor(
|
||||
result.addAll(getContributedVariables(name, location))
|
||||
}
|
||||
}
|
||||
else if (declaration is KtTypeAlias) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedTypeAliasDescriptors(name, location))
|
||||
}
|
||||
}
|
||||
else if (declaration is KtScript) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
@@ -161,9 +182,7 @@ protected constructor(
|
||||
else if (declaration is KtDestructuringDeclaration) {
|
||||
// MultiDeclarations are not supported on global level
|
||||
}
|
||||
else {
|
||||
throw IllegalArgumentException("Unsupported declaration kind: " + declaration)
|
||||
}
|
||||
else throw IllegalArgumentException("Unsupported declaration kind: " + declaration)
|
||||
}
|
||||
return result.toReadOnlyList()
|
||||
}
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorNonRootImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.storage.NotNullLazyValue
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
class TypeAliasDescriptorImpl(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
annotations: Annotations,
|
||||
name: Name,
|
||||
sourceElement: SourceElement,
|
||||
private val fVisibility: Visibility
|
||||
) : DeclarationDescriptorNonRootImpl(containingDeclaration, annotations, name, sourceElement),
|
||||
TypeAliasDescriptor {
|
||||
|
||||
// TODO kotlinize some interfaces
|
||||
private lateinit var fDeclaredTypeParameters: List<TypeParameterDescriptor>
|
||||
private lateinit var lazyUnderlyingType: NotNullLazyValue<KotlinType>
|
||||
|
||||
override val underlyingType: KotlinType get() = lazyUnderlyingType()
|
||||
|
||||
fun initialize(declaredTypeParameters: List<TypeParameterDescriptor>, lazyUnderlyingType: NotNullLazyValue<KotlinType>) {
|
||||
this.fDeclaredTypeParameters = declaredTypeParameters
|
||||
this.lazyUnderlyingType = lazyUnderlyingType
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
|
||||
visitor.visitTypeAliasDescriptor(this, data)
|
||||
|
||||
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> =
|
||||
fDeclaredTypeParameters
|
||||
|
||||
override val underlyingClassDescriptor: ClassDescriptor
|
||||
get() = underlyingType.constructor.declarationDescriptor as ClassDescriptor // TODO
|
||||
|
||||
override fun getModality() = Modality.FINAL
|
||||
|
||||
override fun getVisibility() = fVisibility
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor =
|
||||
if (substitutor.isEmpty) this
|
||||
else TODO("typealias doSubstitute")
|
||||
|
||||
override fun getDefaultType(): KotlinType =
|
||||
TODO("typealias getDefaultType")
|
||||
|
||||
override fun getTypeConstructor(): TypeConstructor =
|
||||
typeConstructor
|
||||
|
||||
override fun toString(): String = "typealias ${name.asString()}"
|
||||
|
||||
private val typeConstructor = object : TypeConstructor {
|
||||
override fun getDeclarationDescriptor(): TypeAliasDescriptor =
|
||||
this@TypeAliasDescriptorImpl
|
||||
|
||||
override fun getParameters(): List<TypeParameterDescriptor> =
|
||||
declarationDescriptor.declaredTypeParameters // TODO type parameters of outer class
|
||||
|
||||
override fun getSupertypes(): Collection<KotlinType> =
|
||||
declarationDescriptor.underlyingType.constructor.supertypes
|
||||
|
||||
override fun isFinal(): Boolean =
|
||||
declarationDescriptor.underlyingType.constructor.isFinal
|
||||
|
||||
override fun isDenotable(): Boolean =
|
||||
true
|
||||
|
||||
override fun getBuiltIns(): KotlinBuiltIns =
|
||||
declarationDescriptor.builtIns
|
||||
|
||||
override fun getAnnotations(): Annotations =
|
||||
declarationDescriptor.annotations
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic fun create(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
annotations: Annotations,
|
||||
name: Name,
|
||||
sourceElement: SourceElement,
|
||||
visibility: Visibility
|
||||
): TypeAliasDescriptorImpl =
|
||||
TypeAliasDescriptorImpl(containingDeclaration, annotations, name, sourceElement, visibility)
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,8 @@ enum class LexicalScopeKind(val withLocalDescriptors: Boolean) {
|
||||
FUNCTION_HEADER(false),
|
||||
FUNCTION_INNER_SCOPE(true),
|
||||
|
||||
TYPE_ALIAS_HEADER(false),
|
||||
|
||||
CODE_BLOCK(true),
|
||||
|
||||
LEFT_BOOLEAN_EXPRESSION(true),
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
typealias S = String
|
||||
|
||||
val OK: S = "OK"
|
||||
|
||||
fun box(): S = OK
|
||||
@@ -0,0 +1,5 @@
|
||||
typealias WithVariance<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> X, <!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> Y> = Int
|
||||
typealias WithBounds1<T : <!BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED!>T<!>> = Int
|
||||
typealias WithBounds2<X : <!BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED!>Y<!>, Y : <!BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED!>X<!>> = Int
|
||||
|
||||
val x: WithVariance<Int, Int> = 0
|
||||
@@ -0,0 +1,6 @@
|
||||
package
|
||||
|
||||
public val x: WithVariance<kotlin.Int, kotlin.Int> [= kotlin.Int] = 0
|
||||
public typealias WithBounds1</*0*/ T : [ERROR : Cyclic upper bounds]> = kotlin.Int
|
||||
public typealias WithBounds2</*0*/ X : [ERROR : Cyclic upper bounds], /*1*/ Y : [ERROR : Cyclic upper bounds]> = kotlin.Int
|
||||
public typealias WithVariance</*0*/ in X, /*1*/ out Y> = kotlin.Int
|
||||
@@ -0,0 +1,8 @@
|
||||
class C<T>
|
||||
|
||||
typealias CA<T> = C<T>
|
||||
|
||||
val ca1: CA<Int> = C<Int>()
|
||||
val ca2: CA<CA<Int>> = C<C<Int>>()
|
||||
val ca3: CA<C<Int>> = C<C<Int>>()
|
||||
val ca4: CA<Int?> = C<Int?>()
|
||||
@@ -0,0 +1,14 @@
|
||||
package
|
||||
|
||||
public val ca1: CA<kotlin.Int> [= C<kotlin.Int>]
|
||||
public val ca2: CA<CA<kotlin.Int> [= C<kotlin.Int>]> [= C<CA<kotlin.Int> [= C<kotlin.Int>]>]
|
||||
public val ca3: CA<C<kotlin.Int>> [= C<C<kotlin.Int>>]
|
||||
public val ca4: CA<kotlin.Int?> [= C<kotlin.Int?>]
|
||||
|
||||
public final class C</*0*/ T> {
|
||||
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 typealias CA</*0*/ T> = C<T>
|
||||
@@ -0,0 +1,4 @@
|
||||
typealias A = B
|
||||
typealias B = A
|
||||
|
||||
val x: <!RECURSIVE_TYPEALIAS_EXPANSION!>A<!> = TODO()
|
||||
@@ -0,0 +1,5 @@
|
||||
package
|
||||
|
||||
public val x: [ERROR : Recursive type alias: A]
|
||||
public typealias A = B
|
||||
public typealias B = A
|
||||
@@ -0,0 +1,8 @@
|
||||
typealias S = String
|
||||
typealias SS = S
|
||||
typealias SSS = SS
|
||||
|
||||
val s1: SSS = ""
|
||||
val s2: SSS? = null
|
||||
val s3: List<SSS>? = null
|
||||
val s4: List<List<SSS>?>? = null
|
||||
@@ -0,0 +1,9 @@
|
||||
package
|
||||
|
||||
public val s1: SSS [= kotlin.String] = ""
|
||||
public val s2: SSS [= kotlin.String?] = null
|
||||
public val s3: kotlin.collections.List<SSS [= kotlin.String]>? = null
|
||||
public val s4: kotlin.collections.List<kotlin.collections.List<SSS [= kotlin.String]>?>? = null
|
||||
public typealias S = kotlin.String
|
||||
public typealias SS = S
|
||||
public typealias SSS = SS
|
||||
@@ -0,0 +1,20 @@
|
||||
class In<in T>
|
||||
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 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 Out4<T> = Out<*>
|
||||
|
||||
typealias Inv1<T> = Inv<T>
|
||||
typealias Inv2<T> = Inv<in T>
|
||||
typealias Inv3<T> = Inv<out T>
|
||||
typealias Inv4<T> = Inv<*>
|
||||
|
||||
val inv1: Inv1<Int> = Inv<Int>()
|
||||
@@ -0,0 +1,36 @@
|
||||
package
|
||||
|
||||
public val inv1: Inv1<kotlin.Int> [= Inv<kotlin.Int>]
|
||||
|
||||
public final class In</*0*/ in T> {
|
||||
public constructor In</*0*/ in 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 Inv</*0*/ T> {
|
||||
public constructor Inv</*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 Out</*0*/ out T> {
|
||||
public constructor Out</*0*/ out 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 typealias In1</*0*/ T> = In<T>
|
||||
public typealias In2</*0*/ T> = In<in T>
|
||||
public typealias In3</*0*/ T> = In<out T>
|
||||
public typealias In4</*0*/ T> = In<*>
|
||||
public typealias Inv1</*0*/ T> = Inv<T>
|
||||
public typealias Inv2</*0*/ T> = Inv<in T>
|
||||
public typealias Inv3</*0*/ T> = Inv<out T>
|
||||
public typealias Inv4</*0*/ T> = Inv<*>
|
||||
public typealias Out1</*0*/ T> = Out<T>
|
||||
public typealias Out2</*0*/ T> = Out<in T>
|
||||
public typealias Out3</*0*/ T> = Out<out T>
|
||||
public typealias Out4</*0*/ T> = Out<*>
|
||||
@@ -273,6 +273,14 @@ public class DescriptorValidator {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitTypeAliasDescriptor(
|
||||
TypeAliasDescriptor descriptor, DiagnosticCollector data
|
||||
) {
|
||||
// TODO typealias
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitModuleDeclaration(
|
||||
ModuleDescriptor descriptor, DiagnosticCollector collector
|
||||
@@ -436,6 +444,12 @@ public class DescriptorValidator {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeAliasDescriptor(TypeAliasDescriptor descriptor, MemberScope data) {
|
||||
// TODO typealias
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModuleDeclaration(
|
||||
ModuleDescriptor descriptor, MemberScope scope
|
||||
|
||||
@@ -109,6 +109,12 @@ public class RecursiveDescriptorProcessor {
|
||||
&& visitChildren(DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope()), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitTypeAliasDescriptor(TypeAliasDescriptor descriptor, D data) {
|
||||
// TODO typealias
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitModuleDeclaration(ModuleDescriptor descriptor, D data) {
|
||||
return applyWorker(descriptor, data)
|
||||
|
||||
@@ -19012,6 +19012,45 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/typealias")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Typealias extends AbstractDiagnosticsTest {
|
||||
public void testAllFilesPresentInTypealias() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/typealias"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("parameterRestrictions.kt")
|
||||
public void testParameterRestrictions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/parameterRestrictions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parameterSubstitution.kt")
|
||||
public void testParameterSubstitution() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/parameterSubstitution.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("recursive.kt")
|
||||
public void testRecursive() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/recursive.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleTypeAlias.kt")
|
||||
public void testSimpleTypeAlias() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/simpleTypeAlias.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("substitutionVariance.kt")
|
||||
public void testSubstitutionVariance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/substitutionVariance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/unit")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -14321,6 +14321,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/typealias")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Typealias extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInTypealias() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/typealias"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/unaryOp")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -129,6 +129,12 @@ public class RecursiveDescriptorProcessorTest extends KotlinTestWithEnvironment
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitTypeAliasDescriptor(TypeAliasDescriptor descriptor, Void data) {
|
||||
add(descriptor); // TODO typealias
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitModuleDeclaration(ModuleDescriptor descriptor, Void data) {
|
||||
add(descriptor);
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor, ClassOrPackageFragmentDescriptor {
|
||||
public interface ClassDescriptor extends ClassifierDescriptorWithTypeParameters, MemberDescriptor, ClassOrPackageFragmentDescriptor {
|
||||
@NotNull
|
||||
MemberScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments);
|
||||
|
||||
@@ -100,6 +100,7 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor,
|
||||
* captured parameters from outer declaration.
|
||||
* @return list of type parameters actually declared type parameters in current class
|
||||
*/
|
||||
@Override
|
||||
@ReadOnly
|
||||
@NotNull
|
||||
List<TypeParameterDescriptor> getDeclaredTypeParameters();
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.ReadOnly;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ClassifierDescriptorWithTypeParameters extends ClassifierDescriptor {
|
||||
@ReadOnly
|
||||
@NotNull
|
||||
List<TypeParameterDescriptor> getDeclaredTypeParameters();
|
||||
}
|
||||
+2
@@ -29,6 +29,8 @@ public interface DeclarationDescriptorVisitor<R, D> {
|
||||
|
||||
R visitClassDescriptor(ClassDescriptor descriptor, D data);
|
||||
|
||||
R visitTypeAliasDescriptor(TypeAliasDescriptor descriptor, D data);
|
||||
|
||||
R visitModuleDeclaration(ModuleDescriptor descriptor, D data);
|
||||
|
||||
R visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, D data);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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
|
||||
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
interface TypeAliasDescriptor : ClassifierDescriptorWithTypeParameters, MemberDescriptor {
|
||||
val underlyingType: KotlinType
|
||||
|
||||
val underlyingClassDescriptor: ClassDescriptor
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor
|
||||
}
|
||||
+5
@@ -53,6 +53,11 @@ public class DeclarationDescriptorVisitorEmptyBodies<R, D> implements Declaratio
|
||||
return visitDeclarationDescriptor(descriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R visitTypeAliasDescriptor(TypeAliasDescriptor descriptor, D data) {
|
||||
return visitDeclarationDescriptor(descriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R visitModuleDeclaration(ModuleDescriptor descriptor, D data) {
|
||||
return visitDeclarationDescriptor(descriptor, data);
|
||||
|
||||
@@ -128,6 +128,19 @@ internal class DescriptorRendererImpl(
|
||||
}
|
||||
|
||||
private fun renderNormalizedType(type: KotlinType): String {
|
||||
val abbreviated = type.getCapability(AbbreviatedType::class.java)?.abbreviatedType
|
||||
|
||||
if (abbreviated != null) {
|
||||
// TODO nullability is lost for abbreviated type?
|
||||
val abbreviatedRendered = renderNormalizedTypeAsIs(abbreviated)
|
||||
val unabbreviatedRendered = renderNormalizedTypeAsIs(type)
|
||||
return "$abbreviatedRendered [= $unabbreviatedRendered]"
|
||||
}
|
||||
|
||||
return renderNormalizedTypeAsIs(type)
|
||||
}
|
||||
|
||||
private fun renderNormalizedTypeAsIs(type: KotlinType): String {
|
||||
if (type is LazyType && debugMode) {
|
||||
return type.toString()
|
||||
}
|
||||
@@ -271,7 +284,7 @@ internal class DescriptorRendererImpl(
|
||||
override fun renderTypeConstructor(typeConstructor: TypeConstructor): String {
|
||||
val cd = typeConstructor.declarationDescriptor
|
||||
return when (cd) {
|
||||
is TypeParameterDescriptor, is ClassDescriptor -> renderClassifierName(cd)
|
||||
is TypeParameterDescriptor, is ClassDescriptor, is TypeAliasDescriptor -> renderClassifierName(cd)
|
||||
null -> typeConstructor.toString()
|
||||
else -> error("Unexpected classifier: " + cd.javaClass)
|
||||
}
|
||||
@@ -791,6 +804,15 @@ internal class DescriptorRendererImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderTypeAlias(typeAlias: TypeAliasDescriptor, builder: StringBuilder) {
|
||||
renderAnnotations(typeAlias, builder)
|
||||
renderVisibility(typeAlias.visibility, builder)
|
||||
builder.append(renderKeyword("typealias")).append(" ")
|
||||
renderName(typeAlias, builder)
|
||||
renderTypeParameters(typeAlias.declaredTypeParameters, builder, true)
|
||||
builder.append(" = ").append(renderType(typeAlias.underlyingType))
|
||||
}
|
||||
|
||||
/* CLASSES */
|
||||
private fun renderClass(klass: ClassDescriptor, builder: StringBuilder) {
|
||||
val isEnumEntry = klass.kind == ClassKind.ENUM_ENTRY
|
||||
@@ -961,6 +983,10 @@ internal class DescriptorRendererImpl(
|
||||
override fun visitClassDescriptor(descriptor: ClassDescriptor, builder: StringBuilder) {
|
||||
renderClass(descriptor, builder)
|
||||
}
|
||||
|
||||
override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, builder: StringBuilder) {
|
||||
renderTypeAlias(descriptor, builder)
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderSpaceIfNeeded(builder: StringBuilder) {
|
||||
|
||||
@@ -84,3 +84,13 @@ fun sameTypeConstructors(first: KotlinType, second: KotlinType): Boolean {
|
||||
return first.getCapability(typeRangeCapability)?.sameTypeConstructor(second) ?: false
|
||||
|| second.getCapability(typeRangeCapability)?.sameTypeConstructor(first) ?: false
|
||||
}
|
||||
|
||||
interface AbbreviatedType : TypeCapability {
|
||||
val abbreviatedType : KotlinType
|
||||
}
|
||||
|
||||
fun KotlinType.hasAbbreviatedType(): Boolean =
|
||||
getCapability(AbbreviatedType::class.java) != null
|
||||
|
||||
fun KotlinType.getAbbreviatedType(): KotlinType? =
|
||||
getCapability(AbbreviatedType::class.java)?.abbreviatedType
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
@@ -228,11 +229,11 @@ public class TypeUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static KotlinType makeUnsubstitutedType(ClassDescriptor classDescriptor, MemberScope unsubstitutedMemberScope) {
|
||||
if (ErrorUtils.isError(classDescriptor)) {
|
||||
return ErrorUtils.createErrorType("Unsubstituted type for " + classDescriptor);
|
||||
public static KotlinType makeUnsubstitutedType(ClassifierDescriptor classifierDescriptor, MemberScope unsubstitutedMemberScope) {
|
||||
if (ErrorUtils.isError(classifierDescriptor)) {
|
||||
return ErrorUtils.createErrorType("Unsubstituted type for " + classifierDescriptor);
|
||||
}
|
||||
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
|
||||
TypeConstructor typeConstructor = classifierDescriptor.getTypeConstructor();
|
||||
List<TypeProjection> arguments = getDefaultTypeProjections(typeConstructor.getParameters());
|
||||
return KotlinTypeImpl.create(
|
||||
Annotations.Companion.getEMPTY(),
|
||||
|
||||
@@ -561,6 +561,8 @@ class ResolveElementCache(
|
||||
|
||||
override fun getFunctions(): MutableMap<KtNamedFunction, SimpleFunctionDescriptor> = hashMapOf()
|
||||
|
||||
override fun getTypeAliases(): MutableMap<KtTypeAlias, TypeAliasDescriptor> = hashMapOf()
|
||||
|
||||
override fun getDeclaringScope(declaration: KtDeclaration): LexicalScope? = declaringScopes(declaration)
|
||||
|
||||
override fun getScripts(): MutableMap<KtScript, LazyScriptDescriptor> = hashMapOf()
|
||||
|
||||
@@ -105,7 +105,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
REDUNDANT_PROJECTION.registerFactory(RemoveModifierFix.createRemoveProjectionFactory(true))
|
||||
INCOMPATIBLE_MODIFIERS.registerFactory(RemoveModifierFix.createRemoveModifierFactory(false))
|
||||
VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY.registerFactory(RemoveModifierFix.createRemoveVarianceFactory())
|
||||
VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED.registerFactory(RemoveModifierFix.createRemoveVarianceFactory())
|
||||
|
||||
val removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OPEN_KEYWORD)
|
||||
NON_FINAL_MEMBER_IN_FINAL_CLASS.registerFactory(AddModifierFix.createFactory(OPEN_KEYWORD, KtClass::class.java),
|
||||
|
||||
Reference in New Issue
Block a user