JET-84 Support generic parameter constraints for class objects
Test for classes + small fixes
This commit is contained in:
@@ -183,6 +183,7 @@ public class ClassDescriptorResolver {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor parameter : parameters) {
|
||||
if (JetStandardClasses.isNothing(parameter.getBoundsAsType())) {
|
||||
PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier();
|
||||
@@ -652,7 +653,7 @@ public class ClassDescriptorResolver {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
public void checkBounds(JetTypeReference typeReference, JetType type) {
|
||||
public void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type) {
|
||||
if (ErrorUtils.isErrorType(type)) return;
|
||||
|
||||
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||
|
||||
@@ -325,15 +325,30 @@ public class TopDownAnalyzer {
|
||||
JetClass jetClass = entry.getKey();
|
||||
|
||||
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
||||
JetType type = trace.getBindingContext().resolveTypeReference(delegationSpecifier.getTypeReference());
|
||||
classDescriptorResolver.checkBounds(delegationSpecifier.getTypeReference(), type);
|
||||
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
JetType type = trace.getBindingContext().resolveTypeReference(typeReference);
|
||||
classDescriptorResolver.checkBounds(typeReference, type);
|
||||
}
|
||||
}
|
||||
|
||||
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
|
||||
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
||||
if (extendsBound != null) {
|
||||
JetType type = trace.getBindingContext().resolveTypeReference(extendsBound);
|
||||
classDescriptorResolver.checkBounds(extendsBound, type);
|
||||
if (type != null) {
|
||||
classDescriptorResolver.checkBounds(extendsBound, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (JetTypeConstraint constraint : jetClass.getTypeConstaints()) {
|
||||
JetTypeReference extendsBound = constraint.getBoundTypeReference();
|
||||
if (extendsBound != null) {
|
||||
JetType type = trace.getBindingContext().resolveTypeReference(extendsBound);
|
||||
if (type != null) {
|
||||
classDescriptorResolver.checkBounds(extendsBound, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ public class ErrorUtils {
|
||||
return typeConstructor == ERROR_CLASS.getTypeConstructor();
|
||||
}
|
||||
|
||||
public static boolean isErrorType(JetType type) {
|
||||
public static boolean isErrorType(@NotNull JetType type) {
|
||||
return (type instanceof DeferredType && ((DeferredType) type).getActualType() == null) ||
|
||||
type instanceof ErrorTypeImpl ||
|
||||
isError(type.getConstructor());
|
||||
|
||||
@@ -94,7 +94,7 @@ public class TypeUtils {
|
||||
new ChainedScope(null, scopes)); // TODO : check intersectibility, don't use a chanied scope
|
||||
}
|
||||
|
||||
private static boolean canHaveSubtypes(JetTypeChecker typeChecker, JetType type) {
|
||||
public static boolean canHaveSubtypes(JetTypeChecker typeChecker, JetType type) {
|
||||
if (type.isNullable()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
namespace Jet87
|
||||
|
||||
open class A() {
|
||||
fun foo() : Int
|
||||
}
|
||||
|
||||
open class B() {
|
||||
fun bar() : Double;
|
||||
}
|
||||
|
||||
class C() : A(), B()
|
||||
|
||||
class D() {
|
||||
class object : A(), B () {}
|
||||
}
|
||||
|
||||
class Test1<T : A>
|
||||
where
|
||||
T : B,
|
||||
<error>B</error> : T, // error
|
||||
class object T : A,
|
||||
class object T : B,
|
||||
class object <error>B</error> : T
|
||||
() {
|
||||
|
||||
fun test(t : T) {
|
||||
T.foo()
|
||||
T.bar()
|
||||
t.foo()
|
||||
t.bar()
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
new Test1<<error>B</error>>()
|
||||
new Test1<<error>A</error>>()
|
||||
new Test1<C>()
|
||||
}
|
||||
|
||||
class Foo() {}
|
||||
|
||||
class Bar<T : Foo>
|
||||
|
||||
class Buzz<T> where T : Bar<<error>Int</error>>, T : <error>nioho</error>
|
||||
|
||||
class X<T : Foo>
|
||||
class Y<<error>T</error> : Foo> where T : Bar<Foo>
|
||||
Reference in New Issue
Block a user