diff --git a/grammar/src/class.grm b/grammar/src/class.grm index 796d0ffee29..d30f6da5118 100644 --- a/grammar/src/class.grm +++ b/grammar/src/class.grm @@ -42,6 +42,6 @@ typeParameter ; typeConstraint - : userType ":" type - : "class" "object" userType ":" type + : attributes SimpleName ":" type + : attributes "class" "object" SimpleName ":" type ; \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java b/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java index 06c66de5699..f05a8465266 100644 --- a/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java +++ b/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java @@ -92,5 +92,15 @@ public abstract class JetDiagnostic { } } +// private final StackTraceElement[] stackTrace; +// +// protected JetDiagnostic() { +// stackTrace = Thread.currentThread().getStackTrace(); +// } +// +// public StackTraceElement[] getStackTrace() { +// return stackTrace; +// } + public abstract void acceptHandler(@NonNls ErrorHandler handler); } diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java index 37caa9600bc..418c2a2a4c0 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java @@ -33,7 +33,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements } public ConstructorDescriptor initialize(@NotNull List unsubstitutedValueParameters) { - super.initialize(null, Collections.emptyList(), unsubstitutedValueParameters, getContainingDeclaration().getDefaultType()); + super.initialize(null, Collections.emptyList(), unsubstitutedValueParameters, null); return this; } diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java index 02f7bf0f531..a8cfa9e5ce2 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorImpl.java @@ -52,7 +52,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements return this; } - public void setReturnType(JetType unsubstitutedReturnType) { + public void setReturnType(@NotNull JetType unsubstitutedReturnType) { this.unsubstitutedReturnType = unsubstitutedReturnType; } diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index e1eab068401..e6e7a91368c 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -29,6 +29,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme private final WritableScope scopeForSupertypeResolution; private MutableClassDescriptor classObjectDescriptor; private JetType classObjectType; + private JetType defaultType; public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) { super(containingDeclaration); @@ -66,6 +67,9 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { assert constructorDescriptor.getContainingDeclaration() == this; constructors.addFunction(constructorDescriptor); + if (defaultType != null) { + ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); + } } @Override @@ -115,10 +119,8 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme this.typeParameters.add(typeParameterDescriptor); scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor); } - scopeForMemberResolution.setThisType(getDefaultType()); } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -138,18 +140,24 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @NotNull @Override public TypeConstructor getTypeConstructor() { - if (typeConstructor == null) { - this.typeConstructor = new TypeConstructorImpl( - this, - Collections.emptyList(), // TODO : pass annotations from the class? - !open, - getName(), - typeParameters, - supertypes); - } return typeConstructor; } + public void createTypeConstructor() { + assert typeConstructor == null : typeConstructor; + this.typeConstructor = new TypeConstructorImpl( + this, + Collections.emptyList(), // TODO : pass annotations from the class? + !open, + getName(), + typeParameters, + supertypes); + scopeForMemberResolution.setThisType(getDefaultType()); + for (FunctionDescriptor functionDescriptor : constructors.getFunctionDescriptors()) { + ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); + } + } + @NotNull @Override public JetScope getMemberScope(List typeArguments) { @@ -164,7 +172,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @NotNull @Override public JetType getDefaultType() { - return TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup); + if (defaultType == null) { + defaultType = TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup); + } + return defaultType; } @NotNull @@ -226,6 +237,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @Override public String toString() { - return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; + return DescriptorRenderer.TEXT_FOR_DEBUG.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; } } diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java b/idea/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java index 830e90a96bd..99baf8e5dc5 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/TypeParameterDescriptor.java @@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.descriptors; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetTupleType; import org.jetbrains.jet.lang.resolve.JetScope; import org.jetbrains.jet.lang.resolve.LazyScopeAdapter; import org.jetbrains.jet.lang.types.*; @@ -68,7 +69,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement } public void addUpperBound(@NotNull JetType bound) { - upperBounds.add(bound); + upperBounds.add(bound); // TODO : Duplicates? } public Set getUpperBounds() { @@ -93,7 +94,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement assert upperBounds.size() > 0; boundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds); if (boundsAsType == null) { - boundsAsType = JetStandardClasses.getNothingType(); // TODO : some error message? + boundsAsType = JetStandardClasses.getNothingType(); } } return boundsAsType; @@ -145,6 +146,10 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement return true; } + public void addClassObjectBound(@NotNull JetType bound) { + classObjectUpperBounds.add(bound); // TODO : Duplicates? + } + public int getIndex() { return index; } diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 4b170ebf368..966d8adef6d 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -1170,20 +1170,25 @@ public class JetParsing extends AbstractJetParsing { /* * typeConstraint - * : userType ":" type - * : "class" "object" userType ":" type + * : attributes SimpleName ":" type + * : attributes "class" "object" SimpleName ":" type * ; */ private void parseTypeConstraint() { PsiBuilder.Marker constraint = mark(); + parseAttributeList(); + if (at(CLASS_KEYWORD)) { advance(); // CLASS_KEYWORD expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST); } - parseTypeRef(); + + PsiBuilder.Marker reference = mark(); + expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST)); + reference.done(REFERENCE_EXPRESSION); expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java b/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java index 6a1567075e5..2e6fcacf5d6 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java @@ -26,20 +26,12 @@ public class JetTypeConstraint extends JetElement { } @Nullable @IfNotParsed - public JetTypeReference getSubjectTypeReference() { - ASTNode node = getNode().getFirstChildNode(); - while (node != null) { - IElementType tt = node.getElementType(); - if (tt == JetTokens.COLON) break; - if (tt == JetNodeTypes.TYPE_REFERENCE) return (JetTypeReference) node.getPsi(); - node = node.getTreeNext(); - } - - return null; + public JetSimpleNameExpression getSubjectTypeParameterName() { + return (JetSimpleNameExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION); } @Nullable @IfNotParsed - public JetTypeReference getExtendsTypeReference() { + public JetTypeReference getBoundTypeReference() { boolean passedColon = false; ASTNode node = getNode().getFirstChildNode(); while (node != null) { diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java b/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java index 7ffadb377cc..4a96a97782b 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetTypeParameterListOwner.java @@ -21,6 +21,19 @@ public class JetTypeParameterListOwner extends JetNamedDeclaration { return (JetTypeParameterList) findChildByType(JetNodeTypes.TYPE_PARAMETER_LIST); } + @NotNull + public List getTypeConstaints() { + JetTypeParameterList typeParameterList = getTypeParameterList(); + if (typeParameterList == null) { + return Collections.emptyList(); + } + JetTypeConstraintList typeConstraintList = typeParameterList.getTypeConstraintList(); + if (typeConstraintList == null) { + return Collections.emptyList(); + } + return typeConstraintList.getConstraints(); + } + @NotNull public List getTypeParameters() { JetTypeParameterList list = getTypeParameterList(); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index a4c71c2949a..e58fdf6f44b 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -1,7 +1,9 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; @@ -134,9 +136,11 @@ public class ClassDescriptorResolver { public void resolveGenericBounds(@NotNull JetClass jetClass, @NotNull MutableClassDescriptor classDescriptor) { List typeParameters = jetClass.getTypeParameters(); List parameters = classDescriptor.getTypeConstructor().getParameters(); + Map parameterByName = Maps.newHashMap(); for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) { JetTypeParameter jetTypeParameter = typeParameters.get(i); TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); + parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor); JetTypeReference extendsBound = jetTypeParameter.getExtendsBound(); if (extendsBound != null) { typeParameterDescriptor.addUpperBound(typeResolverNotCheckingBounds.resolveType(classDescriptor.getScopeForSupertypeResolution(), extendsBound)); @@ -145,7 +149,48 @@ public class ClassDescriptorResolver { typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound()); } } - // TODO : Bounds from with + for (JetTypeConstraint constraint : jetClass.getTypeConstaints()) { + JetSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName(); + if (subjectTypeParameterName == null) { + continue; + } + String referencedName = subjectTypeParameterName.getReferencedName(); + if (referencedName == null) { + continue; + } + TypeParameterDescriptor typeParameterDescriptor = parameterByName.get(referencedName); + if (typeParameterDescriptor == null) { + // To tell the user that we look only for locally defined type parameters + ClassifierDescriptor classifier = classDescriptor.getScopeForSupertypeResolution().getClassifier(referencedName); + if (classifier != null) { + trace.getErrorHandler().genericError(subjectTypeParameterName.getNode(), referencedName + " does not refer to a type parameter of class " + classDescriptor.getName()); + trace.recordReferenceResolution(subjectTypeParameterName, classifier); + } + else { + trace.getErrorHandler().unresolvedReference(subjectTypeParameterName); + } + } + else { + JetTypeReference boundTypeReference = constraint.getBoundTypeReference(); + if (boundTypeReference != null) { + JetType bound = typeResolverNotCheckingBounds.resolveType(classDescriptor.getScopeForSupertypeResolution(), boundTypeReference); + if (constraint.isClassObjectContraint()) { + typeParameterDescriptor.addClassObjectBound(bound); + } + else { + typeParameterDescriptor.addUpperBound(bound); + } + } + } + } + for (TypeParameterDescriptor parameter : parameters) { + if (JetStandardClasses.isNothing(parameter.getBoundsAsType())) { + PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier(); + if (nameIdentifier != null) { + trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Upper bounds of " + parameter.getName() + " have empty intersection"); + } + } + } } public void resolveSupertypes(@NotNull JetClassOrObject jetClass, @NotNull MutableClassDescriptor descriptor) { diff --git a/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java b/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java index d538d04f420..b9ff1deb4ef 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java @@ -17,6 +17,11 @@ public interface JetScope { public DeclarationDescriptor getContainingDeclaration() { throw new UnsupportedOperationException(); // TODO } + + @Override + public String toString() { + return "EMPTY"; + } }; @Nullable diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 43d8b2cce86..27c01026b73 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -298,6 +298,11 @@ public class TopDownAnalyzer { JetClass jetClass = entry.getKey(); MutableClassDescriptor descriptor = entry.getValue(); classDescriptorResolver.resolveMutableClassDescriptor(jetClass, descriptor); + descriptor.createTypeConstructor(); + } + for (Map.Entry entry : objects.entrySet()) { + MutableClassDescriptor descriptor = entry.getValue(); + descriptor.createTypeConstructor(); } } @@ -439,8 +444,6 @@ public class TopDownAnalyzer { checkIfPrimaryConstructorIsNecessary(); bindOverrides(); - - checkGenericBoundsInClassHeaders(); } private void bindOverrides() { diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 252a4a17d82..5d7d9a41023 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -64,8 +64,7 @@ public class TypeResolver { typeParameterDescriptor.getTypeConstructor(), nullable || TypeUtils.hasNullableBound(typeParameterDescriptor), Collections.emptyList(), - // TODO : joint domain - JetStandardClasses.STUB + getScopeForTypeParameter(typeParameterDescriptor) ); } else if (classifierDescriptor instanceof ClassDescriptor) { @@ -160,6 +159,20 @@ public class TypeResolver { return result[0]; } + private JetScope getScopeForTypeParameter(final TypeParameterDescriptor typeParameterDescriptor) { + if (checkBounds) { + return typeParameterDescriptor.getBoundsAsType().getMemberScope(); + } + else { + return new LazyScopeAdapter(new LazyValue() { + @Override + protected JetScope compute() { + return typeParameterDescriptor.getBoundsAsType().getMemberScope(); + } + }); + } + } + private List resolveTypes(JetScope scope, List argumentElements) { final List arguments = new ArrayList(); for (JetTypeReference argumentElement : argumentElements) { diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 0d9046d3543..21136db418b 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -117,6 +117,7 @@ public class JavaDescriptorResolver { Collections.emptyList(), false); constructorDescriptor.initialize(Collections.emptyList()); + constructorDescriptor.setReturnType(classDescriptor.getDefaultType()); classDescriptor.addConstructor(constructorDescriptor); semanticServices.getTrace().recordDeclarationResolution(psiClass, constructorDescriptor); } @@ -128,12 +129,14 @@ public class JavaDescriptorResolver { Collections.emptyList(), // TODO false); constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters())); + constructorDescriptor.setReturnType(classDescriptor.getDefaultType()); classDescriptor.addConstructor(constructorDescriptor); semanticServices.getTrace().recordDeclarationResolution(constructor, constructorDescriptor); } } semanticServices.getTrace().recordDeclarationResolution(psiClass, classDescriptor); + return classDescriptor; } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index bdc22edb51b..c32f66c2ad9 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.ErrorHandler; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.JetScope; +import org.jetbrains.jet.lang.resolve.JetScopeImpl; import org.jetbrains.jet.lang.resolve.WritableScope; import org.jetbrains.jet.lang.resolve.WritableScopeImpl; @@ -74,7 +75,18 @@ public class JetStandardClasses { null ); - private static final JetType ANY_TYPE = new JetTypeImpl(ANY.getTypeConstructor(), JetScope.EMPTY); + private static final JetType ANY_TYPE = new JetTypeImpl(ANY.getTypeConstructor(), new JetScopeImpl() { + @NotNull + @Override + public DeclarationDescriptor getContainingDeclaration() { + return STANDARD_CLASSES_NAMESPACE; + } + + @Override + public String toString() { + return "Scope for Any"; + } + }); private static final JetType NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index f507edca665..dc6358d55c7 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -138,7 +138,7 @@ public class JetTypeChecker { } // TODO : attributes? - return new JetTypeImpl(Collections.emptyList(), constructor, nullable, newProjections, JetStandardClasses.STUB); + return new JetTypeImpl(Collections.emptyList(), constructor, nullable, newProjections, JetStandardClasses.STUB); // TODO : scope } @NotNull diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 0d7fcfa5468..540956a064c 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -640,6 +640,11 @@ public class JetTypeInferrer { } try { expression.accept(this); + // Some recursive definitions (object expressions) must put their types in the cache manually: + if (trace.isProcessed(expression)) { + return trace.getBindingContext().getExpressionType(expression); + } + if (result instanceof DeferredType) { result = ((DeferredType) result).getActualType(); } @@ -754,9 +759,14 @@ public class JetTypeInferrer { public void visitObjectLiteralExpression(final JetObjectLiteralExpression expression) { TopDownAnalyzer topDownAnalyzer = new TopDownAnalyzer(semanticServices, new BindingTraceAdapter(trace) { @Override - public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) { + public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull final DeclarationDescriptor descriptor) { if (declaration == expression.getObjectDeclaration()) { - JetType defaultType = ((ClassDescriptor) descriptor).getDefaultType(); + JetType defaultType = new DeferredType(new LazyValue() { + @Override + protected JetType compute() { + return ((ClassDescriptor) descriptor).getDefaultType(); + } + }); result = defaultType; if (!trace.isProcessed(expression)) { recordExpressionType(expression, defaultType); diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java index 6a4399d2ec3..c992424a5d1 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.Annotation; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.resolve.ChainedScope; import org.jetbrains.jet.lang.resolve.JetScope; import java.util.*; @@ -70,13 +71,27 @@ public class TypeUtils { } List noAnnotations = Collections.emptyList(); - TypeConstructor constructor = new TypeConstructorImpl(null, noAnnotations, false, debugName.toString(), Collections.emptyList(), types); + TypeConstructor constructor = new TypeConstructorImpl( + null, + noAnnotations, + false, + debugName.toString(), + Collections.emptyList(), + types); + + JetScope[] scopes = new JetScope[types.size()]; + int i = 0; + for (JetType type : types) { + scopes[i] = type.getMemberScope(); + i++; + } + return new JetTypeImpl( noAnnotations, constructor, nullable, Collections.emptyList(), - JetStandardClasses.STUB); + new ChainedScope(null, scopes)); // TODO : check intersectibility, don't use a chanied scope } private static boolean canHaveSubtypes(JetTypeChecker typeChecker, JetType type) { @@ -176,7 +191,7 @@ public class TypeUtils { private static List getArguments(@NotNull ClassDescriptor classDescriptor) { List result = new ArrayList(); for (TypeParameterDescriptor parameterDescriptor : classDescriptor.getTypeConstructor().getParameters()) { - result.add(new TypeProjection(new JetTypeImpl(parameterDescriptor.getTypeConstructor(), JetScope.EMPTY))); // TODO : scope? + result.add(new TypeProjection(parameterDescriptor.getDefaultType())); } return result; } diff --git a/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java b/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java index 7b25f7fd893..75a9d5b85a5 100644 --- a/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java +++ b/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java @@ -274,7 +274,7 @@ public class DescriptorRenderer { renderName(descriptor, builder); if (!descriptor.getUpperBounds().isEmpty()) { JetType bound = descriptor.getUpperBounds().iterator().next(); - if (bound != JetStandardClasses.getAnyType()) { + if (bound != JetStandardClasses.getDefaultBound()) { builder.append(" : ").append(renderType(bound)); if (descriptor.getUpperBounds().size() > 1) { builder.append(" (...)"); diff --git a/idea/testData/psi/TypeConstraints.txt b/idea/testData/psi/TypeConstraints.txt index af1e22f32be..4df16bb80c5 100644 --- a/idea/testData/psi/TypeConstraints.txt +++ b/idea/testData/psi/TypeConstraints.txt @@ -14,10 +14,8 @@ JetFile: TypeConstraints.jet PsiWhiteSpace(' ') TYPE_CONSTRAINT_LIST TYPE_CONSTRAINT - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiWhiteSpace(' ') PsiElement(COLON)(':') PsiWhiteSpace(' ') @@ -32,10 +30,8 @@ JetFile: TypeConstraints.jet PsiWhiteSpace(' ') PsiElement(object)('object') PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiWhiteSpace(' ') PsiElement(COLON)(':') PsiWhiteSpace(' ') diff --git a/idea/testData/psi/examples/PolymorphicClassObjects.txt b/idea/testData/psi/examples/PolymorphicClassObjects.txt index fd390c9840d..32eff251783 100644 --- a/idea/testData/psi/examples/PolymorphicClassObjects.txt +++ b/idea/testData/psi/examples/PolymorphicClassObjects.txt @@ -213,10 +213,8 @@ JetFile: PolymorphicClassObjects.jet PsiWhiteSpace('\n ') TYPE_CONSTRAINT_LIST TYPE_CONSTRAINT - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiWhiteSpace(' ') PsiElement(COLON)(':') PsiWhiteSpace(' ') @@ -239,10 +237,8 @@ JetFile: PolymorphicClassObjects.jet PsiWhiteSpace(' ') PsiElement(object)('object') PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiWhiteSpace(' ') PsiElement(COLON)(':') PsiWhiteSpace(' ')