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; return variableDescriptor;
} }
@Nullable @NotNull
public TypeAliasDescriptor resolveTypeAliasDescriptor( public TypeAliasDescriptor resolveTypeAliasDescriptor(
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull LexicalScope scope, @NotNull LexicalScope scope,
@NotNull KtTypeAlias typeAlias, @NotNull KtTypeAlias typeAlias,
@NotNull final BindingTrace trace @NotNull final BindingTrace trace
) { ) {
final KtTypeReference typeReference = typeAlias.getTypeReference();
if (typeReference == null) return null;
KtModifierList modifierList = typeAlias.getModifierList(); KtModifierList modifierList = typeAlias.getModifierList();
Visibility visibility = resolveVisibilityFromModifiers(typeAlias, getDefaultVisibility(typeAlias, containingDeclaration)); Visibility visibility = resolveVisibilityFromModifiers(typeAlias, getDefaultVisibility(typeAlias, containingDeclaration));
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithArguments(scope, modifierList, trace); 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); SourceElement sourceElement = KotlinSourceElementKt.toSourceElement(typeAlias);
final LazyTypeAliasDescriptor typeAliasDescriptor = LazyTypeAliasDescriptor.create( final LazyTypeAliasDescriptor typeAliasDescriptor = LazyTypeAliasDescriptor.create(
storageManager, trace, containingDeclaration, allAnnotations, name, sourceElement, visibility); storageManager, trace, containingDeclaration, allAnnotations, name, sourceElement, visibility);
@@ -718,26 +715,38 @@ public class DescriptorResolver {
} }
} }
if (!languageFeatureSettings.supportsFeature(LanguageFeature.TypeAliases)) { final KtTypeReference typeReference = typeAlias.getTypeReference();
typeResolver.resolveType(scopeWithTypeParameters, typeReference, trace, true); if (typeReference == null) {
trace.report(UNSUPPORTED_TYPEALIAS.on(typeAlias.getTypeAliasKeyword())); typeAliasDescriptor.initialize(
return null; 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); trace.record(TYPE_ALIAS, typeAlias, typeAliasDescriptor);
return typeAliasDescriptor; return typeAliasDescriptor;
@@ -17,6 +17,8 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import com.intellij.util.SmartList 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.context.TypeLazinessToken
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -55,7 +57,8 @@ class TypeResolver(
private val lazinessToken: TypeLazinessToken, private val lazinessToken: TypeLazinessToken,
private val dynamicTypesSettings: DynamicTypesSettings, private val dynamicTypesSettings: DynamicTypesSettings,
private val dynamicCallableDescriptors: DynamicCallableDescriptors, private val dynamicCallableDescriptors: DynamicCallableDescriptors,
private val identifierChecker: IdentifierChecker private val identifierChecker: IdentifierChecker,
private val languageFeatureSettings: LanguageFeatureSettings
) { ) {
open class TypeTransformerForTests { open class TypeTransformerForTests {
@@ -352,7 +355,7 @@ class TypeResolver(
type(resolveTypeForTypeParameter(c, annotations, descriptor, qualifierPart.expression, qualifierPart.typeArguments)) type(resolveTypeForTypeParameter(c, annotations, descriptor, qualifierPart.expression, qualifierPart.typeArguments))
} }
is ClassDescriptor -> resolveTypeForClass(c, annotations, descriptor, element, qualifierResolutionResult) 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}") else -> error("Unexpected classifier type: ${descriptor.javaClass}")
} }
} }
@@ -440,6 +443,10 @@ class TypeResolver(
if (ErrorUtils.isError(descriptor)) { if (ErrorUtils.isError(descriptor)) {
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor) 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 val parameters = typeConstructor.parameters
@@ -698,7 +705,7 @@ class TypeResolver(
typeConstructor: TypeConstructor typeConstructor: TypeConstructor
): PossiblyBareType = ): PossiblyBareType =
type(ErrorUtils.createErrorTypeWithArguments( type(ErrorUtils.createErrorTypeWithArguments(
"$typeConstructor", typeConstructor.declarationDescriptor?.name?.asString() ?: typeConstructor.toString(),
resolveTypeProjectionsWithErrorConstructor(c, arguments) resolveTypeProjectionsWithErrorConstructor(c, arguments)
)) ))
@@ -124,7 +124,7 @@ protected constructor(
} }
private fun doGetTypeAliases(name: Name): Collection<TypeAliasDescriptor> = private fun doGetTypeAliases(name: Name): Collection<TypeAliasDescriptor> =
declarationProvider.getTypeAliasDeclarations(name).mapNotNull { ktTypeAlias -> declarationProvider.getTypeAliasDeclarations(name).map { ktTypeAlias ->
c.descriptorResolver.resolveTypeAliasDescriptor( c.descriptorResolver.resolveTypeAliasDescriptor(
thisDescriptor, thisDescriptor,
getScopeForMemberDeclarationResolution(ktTypeAlias), 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<!> L<T> = List<T>
<!UNSUPPORTED_TYPEALIAS!>typealias<!> CA = C <!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 package
public typealias CA = [ERROR : CA]
public typealias L</*0*/ T> = [ERROR : L]
public typealias S = [ERROR : S]
public val test1: [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 final class C {
public constructor C() public constructor C()
@@ -19344,6 +19344,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName); 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") @TestMetadata("parameterRestrictions.kt")
public void testParameterRestrictions() throws Exception { public void testParameterRestrictions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/parameterRestrictions.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/parameterRestrictions.kt");