NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER check for classes is moved to DescriptorResolver

This commit is contained in:
Andrey Breslav
2014-03-05 20:48:05 +04:00
parent 39de1f131b
commit 9964ecc883
7 changed files with 58 additions and 19 deletions
@@ -263,6 +263,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setTrace(bindingTrace);
functionAnalyzerExtension.setTrace(bindingTrace);
@@ -169,6 +169,7 @@ public class InjectorForBodyResolve {
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setTrace(bindingTrace);
functionAnalyzerExtension.setTrace(bindingTrace);
@@ -209,6 +209,7 @@ public class InjectorForTopDownAnalyzerBasic {
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setTrace(bindingTrace);
functionAnalyzerExtension.setTrace(bindingTrace);
@@ -41,6 +41,8 @@ public class DeclarationsChecker {
private BindingTrace trace;
@NotNull
private ModifiersChecker modifiersChecker;
@NotNull
private DescriptorResolver descriptorResolver;
@Inject
public void setTrace(@NotNull BindingTrace trace) {
@@ -48,6 +50,11 @@ public class DeclarationsChecker {
this.modifiersChecker = new ModifiersChecker(trace);
}
@Inject
public void setDescriptorResolver(@NotNull DescriptorResolver descriptorResolver) {
this.descriptorResolver = descriptorResolver;
}
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
for (JetFile file : bodiesResolveContext.getFiles()) {
checkModifiersAndAnnotationsInPackageDirective(file);
@@ -59,16 +66,19 @@ public class DeclarationsChecker {
ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue();
if (!bodiesResolveContext.completeAnalysisNeeded(classOrObject)) continue;
checkSupertypesForConsistency(classDescriptor);
checkTypesInClassHeader(classOrObject);
if (classOrObject instanceof JetClass) {
checkClass((JetClass) classOrObject, classDescriptor);
JetClass jetClass = (JetClass) classOrObject;
checkClass(jetClass, classDescriptor);
descriptorResolver.checkNamesInConstraints(
jetClass, classDescriptor, classDescriptor.getScopeForClassHeaderResolution(), trace);
}
else if (classOrObject instanceof JetObjectDeclaration) {
checkObject((JetObjectDeclaration) classOrObject);
}
checkSupertypesForConsistency(classDescriptor);
checkTypesInClassHeader(classOrObject);
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
}
@@ -306,7 +306,7 @@ public class DescriptorResolver {
List<TypeParameterDescriptorImpl> typeParameterDescriptors =
resolveTypeParametersForCallableDescriptor(functionDescriptor, innerScope, function.getTypeParameters(), trace);
innerScope.changeLockLevel(WritableScope.LockLevel.BOTH);
resolveGenericBounds(function, innerScope, typeParameterDescriptors, trace);
resolveGenericBounds(function, functionDescriptor, innerScope, typeParameterDescriptors, trace);
JetType receiverType = null;
JetTypeReference receiverTypeRef = function.getReceiverTypeRef();
@@ -627,6 +627,7 @@ public class DescriptorResolver {
public void resolveGenericBounds(
@NotNull JetTypeParameterListOwner declaration,
@NotNull DeclarationDescriptor descriptor,
JetScope scope,
List<TypeParameterDescriptorImpl> parameters,
BindingTrace trace
@@ -665,18 +666,7 @@ public class DescriptorResolver {
.add(new UpperBoundCheckerTask(boundTypeReference, bound, constraint.isClassObjectConstraint()));
}
if (typeParameterDescriptor == null) {
// To tell the user that we look only for locally defined type parameters
ClassifierDescriptor classifier = scope.getClassifier(referencedName);
if (classifier != null) {
trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(subjectTypeParameterName, constraint, declaration));
trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, classifier);
}
else {
trace.report(UNRESOLVED_REFERENCE.on(subjectTypeParameterName, subjectTypeParameterName));
}
}
else {
if (typeParameterDescriptor != null) {
trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, typeParameterDescriptor);
if (bound != null) {
if (constraint.isClassObjectConstraint()) {
@@ -713,6 +703,41 @@ public class DescriptorResolver {
for (UpperBoundCheckerTask checkerTask : deferredUpperBoundCheckerTasks) {
checkUpperBoundType(checkerTask.upperBound, checkerTask.upperBoundType, checkerTask.isClassObjectConstraint, trace);
}
if (!(declaration instanceof JetClass)) {
checkNamesInConstraints(declaration, descriptor, scope, trace);
}
}
public void checkNamesInConstraints(
@NotNull JetTypeParameterListOwner declaration,
@NotNull DeclarationDescriptor descriptor,
@NotNull JetScope scope,
@NotNull BindingTrace trace
) {
for (JetTypeConstraint constraint : declaration.getTypeConstraints()) {
JetSimpleNameExpression nameExpression = constraint.getSubjectTypeParameterName();
if (nameExpression == null) continue;
Name name = nameExpression.getReferencedNameAsName();
ClassifierDescriptor classifier = scope.getClassifier(name);
if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == descriptor) continue;
if (classifier != null) {
// To tell the user that we look only for locally defined type parameters
trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(nameExpression, constraint, declaration));
trace.record(BindingContext.REFERENCE_TARGET, nameExpression, classifier);
}
else {
trace.report(UNRESOLVED_REFERENCE.on(nameExpression, nameExpression));
}
JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
if (boundTypeReference != null) {
typeResolver.resolveType(scope, boundTypeReference, trace, true);
}
}
}
public static void reportUnsupportedClassObjectConstraint(BindingTrace trace, JetTypeConstraint constraint) {
@@ -877,7 +902,7 @@ public class DescriptorResolver {
typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(containingDeclaration, writableScope, typeParameters,
trace);
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
resolveGenericBounds(property, writableScope, typeParameterDescriptors, trace);
resolveGenericBounds(property, propertyDescriptor, writableScope, typeParameterDescriptors, trace);
scopeWithTypeParameters = writableScope;
}
@@ -208,7 +208,7 @@ public class TypeHierarchyResolver {
if (classOrObject instanceof JetClass) {
ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
//noinspection unchecked
descriptorResolver.resolveGenericBounds((JetClass) classOrObject, descriptor.getScopeForClassHeaderResolution(),
descriptorResolver.resolveGenericBounds((JetClass) classOrObject, descriptor, descriptor.getScopeForClassHeaderResolution(),
(List) descriptor.getTypeConstructor().getParameters(), trace);
}
}
@@ -209,6 +209,7 @@ public class InjectorForTopDownAnalyzerForJs {
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setTrace(bindingTrace);
functionAnalyzerExtension.setTrace(bindingTrace);