Better error recovery

This commit is contained in:
Andrey Breslav
2011-09-05 20:41:52 +04:00
parent 8801cf37fe
commit abfbe52a5a
4 changed files with 60 additions and 52 deletions
@@ -325,6 +325,8 @@ public class ClassDescriptorResolver {
continue;
}
TypeParameterDescriptor typeParameterDescriptor = parameterByName.get(referencedName);
JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
JetType bound = boundTypeReference != null ? resolveAndCheckUpperBoundType(boundTypeReference, scope, constraint.isClassObjectContraint()) : null;
if (typeParameterDescriptor == null) {
// To tell the user that we look only for locally defined type parameters
ClassifierDescriptor classifier = scope.getClassifier(referencedName);
@@ -338,9 +340,7 @@ public class ClassDescriptorResolver {
}
else {
trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, typeParameterDescriptor);
JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
if (boundTypeReference != null) {
JetType bound = resolveAndCheckUpperBoundType(boundTypeReference, scope, constraint.isClassObjectContraint());
if (bound != null) {
if (constraint.isClassObjectContraint()) {
typeParameterDescriptor.addClassObjectBound(bound);
}
@@ -56,64 +56,68 @@ public class TypeResolver {
}
ClassifierDescriptor classifierDescriptor = resolveClass(scope, type);
if (classifierDescriptor != null) {
if (classifierDescriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
if (classifierDescriptor == null) {
resolveTypeProjections(scope, ErrorUtils.createErrorType("No type").getConstructor(), type.getTypeArguments());
return;
}
if (classifierDescriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, typeParameterDescriptor);
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, typeParameterDescriptor);
result[0] = new JetTypeImpl(
annotations,
typeParameterDescriptor.getTypeConstructor(),
nullable || TypeUtils.hasNullableBound(typeParameterDescriptor),
Collections.<TypeProjection>emptyList(),
getScopeForTypeParameter(typeParameterDescriptor)
);
resolveTypeProjections(scope, ErrorUtils.createErrorType("No type").getConstructor(), type.getTypeArguments());
}
else if (classifierDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) classifierDescriptor;
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
TypeConstructor typeConstructor = classifierDescriptor.getTypeConstructor();
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
List<TypeParameterDescriptor> parameters = typeConstructor.getParameters();
int expectedArgumentCount = parameters.size();
int actualArgumentCount = arguments.size();
if (ErrorUtils.isError(typeConstructor)) {
result[0] = new JetTypeImpl(
annotations,
typeParameterDescriptor.getTypeConstructor(),
nullable || TypeUtils.hasNullableBound(typeParameterDescriptor),
Collections.<TypeProjection>emptyList(),
getScopeForTypeParameter(typeParameterDescriptor)
typeConstructor,
nullable,
arguments, // TODO : review
classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList())
);
}
else if (classifierDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) classifierDescriptor;
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
TypeConstructor typeConstructor = classifierDescriptor.getTypeConstructor();
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
List<TypeParameterDescriptor> parameters = typeConstructor.getParameters();
int expectedArgumentCount = parameters.size();
int actualArgumentCount = arguments.size();
if (ErrorUtils.isError(typeConstructor)) {
else {
if (actualArgumentCount != expectedArgumentCount) {
String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected";
if (actualArgumentCount == 0) {
trace.getErrorHandler().genericError(type.getNode(), errorMessage);
} else {
trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
}
} else {
result[0] = new JetTypeImpl(
annotations,
typeConstructor,
nullable,
arguments, // TODO : review
classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList())
arguments,
classDescriptor.getMemberScope(arguments)
);
}
else {
if (actualArgumentCount != expectedArgumentCount) {
String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected";
if (actualArgumentCount == 0) {
trace.getErrorHandler().genericError(type.getNode(), errorMessage);
} else {
trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
}
} else {
result[0] = new JetTypeImpl(
annotations,
typeConstructor,
nullable,
arguments,
classDescriptor.getMemberScope(arguments)
);
if (checkBounds) {
TypeSubstitutor substitutor = TypeSubstitutor.create(result[0]);
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
TypeParameterDescriptor parameter = parameters.get(i);
JetType argument = arguments.get(i).getType();
JetTypeReference typeReference = type.getTypeArguments().get(i).getTypeReference();
if (checkBounds) {
TypeSubstitutor substitutor = TypeSubstitutor.create(result[0]);
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
TypeParameterDescriptor parameter = parameters.get(i);
JetType argument = arguments.get(i).getType();
JetTypeReference typeReference = type.getTypeArguments().get(i).getTypeReference();
if (typeReference != null) {
semanticServices.getClassDescriptorResolver(trace).checkBounds(typeReference, argument, parameter, substitutor);
}
if (typeReference != null) {
semanticServices.getClassDescriptorResolver(trace).checkBounds(typeReference, argument, parameter, substitutor);
}
}
}
+3 -3
View File
@@ -60,9 +60,9 @@ fun <T : A> test2(t : T)
t.bar()
}
val test1 = test2<<error>A</error>>(A())
val test2 = test2<<error>B</error>>(B())
val test3 = test2<C>(C())
val t1 = test2<<error>A</error>>(A())
val t2 = test2<<error>B</error>>(B())
val t3 = test2<C>(C())
class Test<<error>T</error>>
where
@@ -8,6 +8,10 @@ namespace a {
}
class Foo<T>() {
val x : T<Int>
}
namespace a {
import java.util.*