Type bounds check for class headers moved to DeclarationsChecker
This commit is contained in:
@@ -21,6 +21,7 @@ import com.google.common.collect.Sets;
|
|||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -66,6 +67,7 @@ public class DeclarationsChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkSupertypesForConsistency(classDescriptor);
|
checkSupertypesForConsistency(classDescriptor);
|
||||||
|
checkTypesInClassHeader(classOrObject);
|
||||||
|
|
||||||
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
|
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
|
||||||
}
|
}
|
||||||
@@ -124,6 +126,32 @@ public class DeclarationsChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkTypesInClassHeader(@NotNull JetClassOrObject classOrObject) {
|
||||||
|
for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) {
|
||||||
|
checkBoundsForTypeInClassHeader(delegationSpecifier.getTypeReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(classOrObject instanceof JetClass)) return;
|
||||||
|
JetClass jetClass = (JetClass) classOrObject;
|
||||||
|
|
||||||
|
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
|
||||||
|
checkBoundsForTypeInClassHeader(jetTypeParameter.getExtendsBound());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JetTypeConstraint constraint : jetClass.getTypeConstraints()) {
|
||||||
|
checkBoundsForTypeInClassHeader(constraint.getBoundTypeReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBoundsForTypeInClassHeader(@Nullable JetTypeReference typeReference) {
|
||||||
|
if (typeReference != null) {
|
||||||
|
JetType type = trace.getBindingContext().get(TYPE, typeReference);
|
||||||
|
if (type != null) {
|
||||||
|
DescriptorResolver.checkBounds(typeReference, type, trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkSupertypesForConsistency(@NotNull ClassDescriptor classDescriptor) {
|
private void checkSupertypesForConsistency(@NotNull ClassDescriptor classDescriptor) {
|
||||||
Multimap<TypeConstructor, TypeProjection> multimap = SubstitutionUtils
|
Multimap<TypeConstructor, TypeProjection> multimap = SubstitutionUtils
|
||||||
.buildDeepSubstitutionMultimap(classDescriptor.getDefaultType());
|
.buildDeepSubstitutionMultimap(classDescriptor.getDefaultType());
|
||||||
|
|||||||
@@ -136,10 +136,6 @@ public class TypeHierarchyResolver {
|
|||||||
|
|
||||||
// Detect and disconnect all loops in the hierarchy
|
// Detect and disconnect all loops in the hierarchy
|
||||||
detectAndDisconnectLoops(c);
|
detectAndDisconnectLoops(c);
|
||||||
|
|
||||||
// At this point, there are no loops in the type hierarchy
|
|
||||||
|
|
||||||
checkTypesInClassHeaders(c); // Check bounds in the types used in generic bounds and supertype lists
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -319,34 +315,6 @@ public class TypeHierarchyResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTypesInClassHeaders(@NotNull TopDownAnalysisContext c) {
|
|
||||||
for (JetClassOrObject classOrObject : c.getClasses().keySet()) {
|
|
||||||
for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) {
|
|
||||||
checkBoundsForTypeInClassHeader(delegationSpecifier.getTypeReference());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(classOrObject instanceof JetClass)) continue;
|
|
||||||
JetClass jetClass = (JetClass) classOrObject;
|
|
||||||
|
|
||||||
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
|
|
||||||
checkBoundsForTypeInClassHeader(jetTypeParameter.getExtendsBound());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JetTypeConstraint constraint : jetClass.getTypeConstraints()) {
|
|
||||||
checkBoundsForTypeInClassHeader(constraint.getBoundTypeReference());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkBoundsForTypeInClassHeader(@Nullable JetTypeReference typeReference) {
|
|
||||||
if (typeReference != null) {
|
|
||||||
JetType type = trace.getBindingContext().get(TYPE, typeReference);
|
|
||||||
if (type != null) {
|
|
||||||
DescriptorResolver.checkBounds(typeReference, type, trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ClassifierCollector extends JetVisitorVoid {
|
private class ClassifierCollector extends JetVisitorVoid {
|
||||||
private final TopDownAnalysisContext c;
|
private final TopDownAnalysisContext c;
|
||||||
private final JetScope outerScope;
|
private final JetScope outerScope;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
class Other
|
||||||
|
trait Trait
|
||||||
|
trait WithBounds<T: Trait>
|
||||||
|
class Test1<T> where <!UNSUPPORTED!>class object T: WithBounds<<!UPPER_BOUND_VIOLATED!>Other<!>><!>
|
||||||
@@ -219,6 +219,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest("compiler/testData/diagnostics/tests/Dollar.kt");
|
doTest("compiler/testData/diagnostics/tests/Dollar.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FinalClassObjectBound.kt")
|
||||||
|
public void testFinalClassObjectBound() throws Exception {
|
||||||
|
doTest("compiler/testData/diagnostics/tests/FinalClassObjectBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ForRangeConventions.kt")
|
@TestMetadata("ForRangeConventions.kt")
|
||||||
public void testForRangeConventions() throws Exception {
|
public void testForRangeConventions() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/ForRangeConventions.kt");
|
doTest("compiler/testData/diagnostics/tests/ForRangeConventions.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user