Treat unsupported or malformed type alias as a type alias with error types.

This commit is contained in:
Dmitry Petrov
2016-06-02 18:22:26 +03:00
parent 3500f5a96b
commit 772fe5badb
8 changed files with 68 additions and 32 deletions
@@ -678,21 +678,18 @@ public class DescriptorResolver {
return variableDescriptor;
}
@Nullable
@NotNull
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());
final Name name = KtPsiUtil.safeName(typeAlias.getName());
SourceElement sourceElement = KotlinSourceElementKt.toSourceElement(typeAlias);
final LazyTypeAliasDescriptor typeAliasDescriptor = LazyTypeAliasDescriptor.create(
storageManager, trace, containingDeclaration, allAnnotations, name, sourceElement, visibility);
@@ -718,26 +715,38 @@ public class DescriptorResolver {
}
}
if (!languageFeatureSettings.supportsFeature(LanguageFeature.TypeAliases)) {
typeResolver.resolveType(scopeWithTypeParameters, typeReference, trace, true);
trace.report(UNSUPPORTED_TYPEALIAS.on(typeAlias.getTypeAliasKeyword()));
return null;
final KtTypeReference typeReference = typeAlias.getTypeReference();
if (typeReference == null) {
typeAliasDescriptor.initialize(
typeParameterDescriptors,
ErrorUtils.createErrorType(name.asString()),
ErrorUtils.createErrorType(name.asString()));
}
else if (!languageFeatureSettings.supportsFeature(LanguageFeature.TypeAliases)) {
typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace, true);
PsiElement typeAliasKeyword = typeAlias.getTypeAliasKeyword();
trace.report(UNSUPPORTED_TYPEALIAS.on(typeAliasKeyword != null ? typeAliasKeyword : typeAlias));
typeAliasDescriptor.initialize(
typeParameterDescriptors,
ErrorUtils.createErrorType(name.asString()),
ErrorUtils.createErrorType(name.asString()));
}
else {
typeAliasDescriptor.initialize(
typeParameterDescriptors,
DeferredType.create(storageManager, trace, new Function0<KotlinType>() {
@Override
public KotlinType invoke() {
return typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace, true);
}
}),
DeferredType.create(storageManager, trace, new Function0<KotlinType>() {
@Override
public KotlinType invoke() {
return typeResolver.resolveExpandedTypeForTypeAlias(typeAliasDescriptor);
}
}));
}
typeAliasDescriptor.initialize(
typeParameterDescriptors,
DeferredType.create(storageManager, trace, new Function0<KotlinType>() {
@Override
public KotlinType invoke() {
return typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace, true);
}
}),
DeferredType.create(storageManager, trace, new Function0<KotlinType>() {
@Override
public KotlinType invoke() {
return typeResolver.resolveExpandedTypeForTypeAlias(typeAliasDescriptor);
}
}));
trace.record(TYPE_ALIAS, typeAlias, typeAliasDescriptor);
return typeAliasDescriptor;
@@ -17,6 +17,8 @@
package org.jetbrains.kotlin.resolve
import com.intellij.util.SmartList
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageFeatureSettings
import org.jetbrains.kotlin.context.TypeLazinessToken
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -55,7 +57,8 @@ class TypeResolver(
private val lazinessToken: TypeLazinessToken,
private val dynamicTypesSettings: DynamicTypesSettings,
private val dynamicCallableDescriptors: DynamicCallableDescriptors,
private val identifierChecker: IdentifierChecker
private val identifierChecker: IdentifierChecker,
private val languageFeatureSettings: LanguageFeatureSettings
) {
open class TypeTransformerForTests {
@@ -352,7 +355,7 @@ class TypeResolver(
type(resolveTypeForTypeParameter(c, annotations, descriptor, qualifierPart.expression, qualifierPart.typeArguments))
}
is ClassDescriptor -> resolveTypeForClass(c, annotations, descriptor, element, qualifierResolutionResult)
is TypeAliasDescriptor -> resolveTypeForTypeAlias(c, annotations, descriptor, element as KtUserType /* TODO */, qualifierResolutionResult)
is TypeAliasDescriptor -> resolveTypeForTypeAlias(c, annotations, descriptor, element as KtUserType, qualifierResolutionResult)
else -> error("Unexpected classifier type: ${descriptor.javaClass}")
}
}
@@ -440,6 +443,10 @@ class TypeResolver(
if (ErrorUtils.isError(descriptor)) {
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
}
if (!languageFeatureSettings.supportsFeature(LanguageFeature.TypeAliases)) {
c.trace.report(UNSUPPORTED_TYPEALIAS.on(type))
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
}
val parameters = typeConstructor.parameters
@@ -698,7 +705,7 @@ class TypeResolver(
typeConstructor: TypeConstructor
): PossiblyBareType =
type(ErrorUtils.createErrorTypeWithArguments(
"$typeConstructor",
typeConstructor.declarationDescriptor?.name?.asString() ?: typeConstructor.toString(),
resolveTypeProjectionsWithErrorConstructor(c, arguments)
))
@@ -124,7 +124,7 @@ protected constructor(
}
private fun doGetTypeAliases(name: Name): Collection<TypeAliasDescriptor> =
declarationProvider.getTypeAliasDeclarations(name).mapNotNull { ktTypeAlias ->
declarationProvider.getTypeAliasDeclarations(name).map { ktTypeAlias ->
c.descriptorResolver.resolveTypeAliasDescriptor(
thisDescriptor,
getScopeForMemberDeclarationResolution(ktTypeAlias),
@@ -0,0 +1,6 @@
typealias<!SYNTAX!><!>
<!SYNTAX!><!>typealias A1<!SYNTAX!><!>
<!SYNTAX!><!>typealias A2 =
<!SYNTAX!><!>
@@ -0,0 +1,5 @@
package
public typealias <no name provided> = [ERROR : No type element]
public typealias A1 = [ERROR : No type element]
public typealias A2 = [ERROR : No type element]
@@ -6,8 +6,8 @@ class C
<!UNSUPPORTED_TYPEALIAS!>typealias<!> L<T> = List<T>
<!UNSUPPORTED_TYPEALIAS!>typealias<!> CA = C
val test1: <!UNRESOLVED_REFERENCE!>S<!> = ""
val test1: <!UNSUPPORTED_TYPEALIAS!>S<!> = ""
fun test2(x: <!UNRESOLVED_REFERENCE!>L<!><<!UNRESOLVED_REFERENCE!>S<!>>) = <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>
fun test2(x: <!UNSUPPORTED_TYPEALIAS!>L<<!UNSUPPORTED_TYPEALIAS!>S<!>><!>) = <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>
class Test3 : <!UNRESOLVED_REFERENCE!>CA<!>()
class Test3 : <!UNSUPPORTED_TYPEALIAS!>CA<!>()
@@ -1,7 +1,10 @@
package
public typealias CA = [ERROR : CA]
public typealias L</*0*/ T> = [ERROR : L]
public typealias S = [ERROR : S]
public val test1: [ERROR : S]
public fun test2(/*0*/ x: [ERROR : L<S>]<[ERROR : S]>): [ERROR : L<S>]<[ERROR : S]>
public fun test2(/*0*/ x: [ERROR : L]<[ERROR : S]>): [ERROR : L]<[ERROR : S]>
public final class C {
public constructor C()
@@ -19344,6 +19344,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("noRHS.kt")
public void testNoRHS() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/noRHS.kt");
doTest(fileName);
}
@TestMetadata("parameterRestrictions.kt")
public void testParameterRestrictions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/parameterRestrictions.kt");