diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index c57dcbe7c4f..52329447902 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -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); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 7ec333a5cc2..63ed59ab9c5 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -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.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 arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments()); + List 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.emptyList(), - getScopeForTypeParameter(typeParameterDescriptor) + typeConstructor, + nullable, + arguments, // TODO : review + classDescriptor.getMemberScope(Collections.emptyList()) ); } - else if (classifierDescriptor instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) classifierDescriptor; - - trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor); - TypeConstructor typeConstructor = classifierDescriptor.getTypeConstructor(); - List arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments()); - List 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.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); } } } diff --git a/idea/testData/checker/MultipleBounds.jet b/idea/testData/checker/MultipleBounds.jet index 126864510c1..3ae66e4ea89 100644 --- a/idea/testData/checker/MultipleBounds.jet +++ b/idea/testData/checker/MultipleBounds.jet @@ -60,9 +60,9 @@ fun test2(t : T) t.bar() } -val test1 = test2<A>(A()) -val test2 = test2<B>(B()) -val test3 = test2(C()) +val t1 = test2<A>(A()) +val t2 = test2<B>(B()) +val t3 = test2(C()) class Test<T> where diff --git a/idea/testData/checker/NamespaceQualified.jet b/idea/testData/checker/NamespaceQualified.jet index 2b8832aef89..81b0ed014c3 100644 --- a/idea/testData/checker/NamespaceQualified.jet +++ b/idea/testData/checker/NamespaceQualified.jet @@ -8,6 +8,10 @@ namespace a { } +class Foo() { + val x : T +} + namespace a { import java.util.*