JET-84 Support generic parameter constraints for class objects

Done for classes only, not for functions
This commit is contained in:
Andrey Breslav
2011-06-05 00:32:17 +04:00
parent a32c7a4d87
commit 4204db9cb0
21 changed files with 196 additions and 62 deletions
+2 -2
View File
@@ -42,6 +42,6 @@ typeParameter
; ;
typeConstraint typeConstraint
: userType ":" type : attributes SimpleName ":" type
: "class" "object" userType ":" type : attributes "class" "object" SimpleName ":" type
; ;
@@ -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); public abstract void acceptHandler(@NonNls ErrorHandler handler);
} }
@@ -33,7 +33,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
} }
public ConstructorDescriptor initialize(@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters) { public ConstructorDescriptor initialize(@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters) {
super.initialize(null, Collections.<TypeParameterDescriptor>emptyList(), unsubstitutedValueParameters, getContainingDeclaration().getDefaultType()); super.initialize(null, Collections.<TypeParameterDescriptor>emptyList(), unsubstitutedValueParameters, null);
return this; return this;
} }
@@ -52,7 +52,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
return this; return this;
} }
public void setReturnType(JetType unsubstitutedReturnType) { public void setReturnType(@NotNull JetType unsubstitutedReturnType) {
this.unsubstitutedReturnType = unsubstitutedReturnType; this.unsubstitutedReturnType = unsubstitutedReturnType;
} }
@@ -29,6 +29,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
private final WritableScope scopeForSupertypeResolution; private final WritableScope scopeForSupertypeResolution;
private MutableClassDescriptor classObjectDescriptor; private MutableClassDescriptor classObjectDescriptor;
private JetType classObjectType; private JetType classObjectType;
private JetType defaultType;
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) { public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
super(containingDeclaration); super(containingDeclaration);
@@ -66,6 +67,9 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
assert constructorDescriptor.getContainingDeclaration() == this; assert constructorDescriptor.getContainingDeclaration() == this;
constructors.addFunction(constructorDescriptor); constructors.addFunction(constructorDescriptor);
if (defaultType != null) {
((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType());
}
} }
@Override @Override
@@ -115,10 +119,8 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
this.typeParameters.add(typeParameterDescriptor); this.typeParameters.add(typeParameterDescriptor);
scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor); scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor);
} }
scopeForMemberResolution.setThisType(getDefaultType());
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
@@ -138,18 +140,24 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
@NotNull @NotNull
@Override @Override
public TypeConstructor getTypeConstructor() { public TypeConstructor getTypeConstructor() {
if (typeConstructor == null) {
this.typeConstructor = new TypeConstructorImpl(
this,
Collections.<Annotation>emptyList(), // TODO : pass annotations from the class?
!open,
getName(),
typeParameters,
supertypes);
}
return typeConstructor; return typeConstructor;
} }
public void createTypeConstructor() {
assert typeConstructor == null : typeConstructor;
this.typeConstructor = new TypeConstructorImpl(
this,
Collections.<Annotation>emptyList(), // TODO : pass annotations from the class?
!open,
getName(),
typeParameters,
supertypes);
scopeForMemberResolution.setThisType(getDefaultType());
for (FunctionDescriptor functionDescriptor : constructors.getFunctionDescriptors()) {
((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
}
}
@NotNull @NotNull
@Override @Override
public JetScope getMemberScope(List<TypeProjection> typeArguments) { public JetScope getMemberScope(List<TypeProjection> typeArguments) {
@@ -164,7 +172,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
@NotNull @NotNull
@Override @Override
public JetType getDefaultType() { public JetType getDefaultType() {
return TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup); if (defaultType == null) {
defaultType = TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup);
}
return defaultType;
} }
@NotNull @NotNull
@@ -226,6 +237,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
@Override @Override
public String toString() { 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) + "]";
} }
} }
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull; 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.JetScope;
import org.jetbrains.jet.lang.resolve.LazyScopeAdapter; import org.jetbrains.jet.lang.resolve.LazyScopeAdapter;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
@@ -68,7 +69,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
} }
public void addUpperBound(@NotNull JetType bound) { public void addUpperBound(@NotNull JetType bound) {
upperBounds.add(bound); upperBounds.add(bound); // TODO : Duplicates?
} }
public Set<JetType> getUpperBounds() { public Set<JetType> getUpperBounds() {
@@ -93,7 +94,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
assert upperBounds.size() > 0; assert upperBounds.size() > 0;
boundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds); boundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
if (boundsAsType == null) { if (boundsAsType == null) {
boundsAsType = JetStandardClasses.getNothingType(); // TODO : some error message? boundsAsType = JetStandardClasses.getNothingType();
} }
} }
return boundsAsType; return boundsAsType;
@@ -145,6 +146,10 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
return true; return true;
} }
public void addClassObjectBound(@NotNull JetType bound) {
classObjectUpperBounds.add(bound); // TODO : Duplicates?
}
public int getIndex() { public int getIndex() {
return index; return index;
} }
@@ -1170,20 +1170,25 @@ public class JetParsing extends AbstractJetParsing {
/* /*
* typeConstraint * typeConstraint
* : userType ":" type * : attributes SimpleName ":" type
* : "class" "object" userType ":" type * : attributes "class" "object" SimpleName ":" type
* ; * ;
*/ */
private void parseTypeConstraint() { private void parseTypeConstraint() {
PsiBuilder.Marker constraint = mark(); PsiBuilder.Marker constraint = mark();
parseAttributeList();
if (at(CLASS_KEYWORD)) { if (at(CLASS_KEYWORD)) {
advance(); // CLASS_KEYWORD advance(); // CLASS_KEYWORD
expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST); 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); expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST);
@@ -26,20 +26,12 @@ public class JetTypeConstraint extends JetElement {
} }
@Nullable @IfNotParsed @Nullable @IfNotParsed
public JetTypeReference getSubjectTypeReference() { public JetSimpleNameExpression getSubjectTypeParameterName() {
ASTNode node = getNode().getFirstChildNode(); return (JetSimpleNameExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION);
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;
} }
@Nullable @IfNotParsed @Nullable @IfNotParsed
public JetTypeReference getExtendsTypeReference() { public JetTypeReference getBoundTypeReference() {
boolean passedColon = false; boolean passedColon = false;
ASTNode node = getNode().getFirstChildNode(); ASTNode node = getNode().getFirstChildNode();
while (node != null) { while (node != null) {
@@ -21,6 +21,19 @@ public class JetTypeParameterListOwner extends JetNamedDeclaration {
return (JetTypeParameterList) findChildByType(JetNodeTypes.TYPE_PARAMETER_LIST); return (JetTypeParameterList) findChildByType(JetNodeTypes.TYPE_PARAMETER_LIST);
} }
@NotNull
public List<JetTypeConstraint> getTypeConstaints() {
JetTypeParameterList typeParameterList = getTypeParameterList();
if (typeParameterList == null) {
return Collections.emptyList();
}
JetTypeConstraintList typeConstraintList = typeParameterList.getTypeConstraintList();
if (typeConstraintList == null) {
return Collections.emptyList();
}
return typeConstraintList.getConstraints();
}
@NotNull @NotNull
public List<JetTypeParameter> getTypeParameters() { public List<JetTypeParameter> getTypeParameters() {
JetTypeParameterList list = getTypeParameterList(); JetTypeParameterList list = getTypeParameterList();
@@ -1,7 +1,9 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
@@ -134,9 +136,11 @@ public class ClassDescriptorResolver {
public void resolveGenericBounds(@NotNull JetClass jetClass, @NotNull MutableClassDescriptor classDescriptor) { public void resolveGenericBounds(@NotNull JetClass jetClass, @NotNull MutableClassDescriptor classDescriptor) {
List<JetTypeParameter> typeParameters = jetClass.getTypeParameters(); List<JetTypeParameter> typeParameters = jetClass.getTypeParameters();
List<TypeParameterDescriptor> parameters = classDescriptor.getTypeConstructor().getParameters(); List<TypeParameterDescriptor> parameters = classDescriptor.getTypeConstructor().getParameters();
Map<String, TypeParameterDescriptor> parameterByName = Maps.newHashMap();
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) { for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
JetTypeParameter jetTypeParameter = typeParameters.get(i); JetTypeParameter jetTypeParameter = typeParameters.get(i);
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound(); JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
if (extendsBound != null) { if (extendsBound != null) {
typeParameterDescriptor.addUpperBound(typeResolverNotCheckingBounds.resolveType(classDescriptor.getScopeForSupertypeResolution(), extendsBound)); typeParameterDescriptor.addUpperBound(typeResolverNotCheckingBounds.resolveType(classDescriptor.getScopeForSupertypeResolution(), extendsBound));
@@ -145,7 +149,48 @@ public class ClassDescriptorResolver {
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound()); 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) { public void resolveSupertypes(@NotNull JetClassOrObject jetClass, @NotNull MutableClassDescriptor descriptor) {
@@ -17,6 +17,11 @@ public interface JetScope {
public DeclarationDescriptor getContainingDeclaration() { public DeclarationDescriptor getContainingDeclaration() {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
@Override
public String toString() {
return "EMPTY";
}
}; };
@Nullable @Nullable
@@ -298,6 +298,11 @@ public class TopDownAnalyzer {
JetClass jetClass = entry.getKey(); JetClass jetClass = entry.getKey();
MutableClassDescriptor descriptor = entry.getValue(); MutableClassDescriptor descriptor = entry.getValue();
classDescriptorResolver.resolveMutableClassDescriptor(jetClass, descriptor); classDescriptorResolver.resolveMutableClassDescriptor(jetClass, descriptor);
descriptor.createTypeConstructor();
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
MutableClassDescriptor descriptor = entry.getValue();
descriptor.createTypeConstructor();
} }
} }
@@ -439,8 +444,6 @@ public class TopDownAnalyzer {
checkIfPrimaryConstructorIsNecessary(); checkIfPrimaryConstructorIsNecessary();
bindOverrides(); bindOverrides();
checkGenericBoundsInClassHeaders();
} }
private void bindOverrides() { private void bindOverrides() {
@@ -64,8 +64,7 @@ public class TypeResolver {
typeParameterDescriptor.getTypeConstructor(), typeParameterDescriptor.getTypeConstructor(),
nullable || TypeUtils.hasNullableBound(typeParameterDescriptor), nullable || TypeUtils.hasNullableBound(typeParameterDescriptor),
Collections.<TypeProjection>emptyList(), Collections.<TypeProjection>emptyList(),
// TODO : joint domain getScopeForTypeParameter(typeParameterDescriptor)
JetStandardClasses.STUB
); );
} }
else if (classifierDescriptor instanceof ClassDescriptor) { else if (classifierDescriptor instanceof ClassDescriptor) {
@@ -160,6 +159,20 @@ public class TypeResolver {
return result[0]; return result[0];
} }
private JetScope getScopeForTypeParameter(final TypeParameterDescriptor typeParameterDescriptor) {
if (checkBounds) {
return typeParameterDescriptor.getBoundsAsType().getMemberScope();
}
else {
return new LazyScopeAdapter(new LazyValue<JetScope>() {
@Override
protected JetScope compute() {
return typeParameterDescriptor.getBoundsAsType().getMemberScope();
}
});
}
}
private List<JetType> resolveTypes(JetScope scope, List<JetTypeReference> argumentElements) { private List<JetType> resolveTypes(JetScope scope, List<JetTypeReference> argumentElements) {
final List<JetType> arguments = new ArrayList<JetType>(); final List<JetType> arguments = new ArrayList<JetType>();
for (JetTypeReference argumentElement : argumentElements) { for (JetTypeReference argumentElement : argumentElements) {
@@ -117,6 +117,7 @@ public class JavaDescriptorResolver {
Collections.<Annotation>emptyList(), Collections.<Annotation>emptyList(),
false); false);
constructorDescriptor.initialize(Collections.<ValueParameterDescriptor>emptyList()); constructorDescriptor.initialize(Collections.<ValueParameterDescriptor>emptyList());
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor); classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().recordDeclarationResolution(psiClass, constructorDescriptor); semanticServices.getTrace().recordDeclarationResolution(psiClass, constructorDescriptor);
} }
@@ -128,12 +129,14 @@ public class JavaDescriptorResolver {
Collections.<Annotation>emptyList(), // TODO Collections.<Annotation>emptyList(), // TODO
false); false);
constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters())); constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()));
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor); classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().recordDeclarationResolution(constructor, constructorDescriptor); semanticServices.getTrace().recordDeclarationResolution(constructor, constructorDescriptor);
} }
} }
semanticServices.getTrace().recordDeclarationResolution(psiClass, classDescriptor); semanticServices.getTrace().recordDeclarationResolution(psiClass, classDescriptor);
return classDescriptor; return classDescriptor;
} }
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.ErrorHandler; import org.jetbrains.jet.lang.ErrorHandler;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.JetScope; 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.WritableScope;
import org.jetbrains.jet.lang.resolve.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.WritableScopeImpl;
@@ -74,7 +75,18 @@ public class JetStandardClasses {
null 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); private static final JetType NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -138,7 +138,7 @@ public class JetTypeChecker {
} }
// TODO : attributes? // TODO : attributes?
return new JetTypeImpl(Collections.<Annotation>emptyList(), constructor, nullable, newProjections, JetStandardClasses.STUB); return new JetTypeImpl(Collections.<Annotation>emptyList(), constructor, nullable, newProjections, JetStandardClasses.STUB); // TODO : scope
} }
@NotNull @NotNull
@@ -640,6 +640,11 @@ public class JetTypeInferrer {
} }
try { try {
expression.accept(this); 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) { if (result instanceof DeferredType) {
result = ((DeferredType) result).getActualType(); result = ((DeferredType) result).getActualType();
} }
@@ -754,9 +759,14 @@ public class JetTypeInferrer {
public void visitObjectLiteralExpression(final JetObjectLiteralExpression expression) { public void visitObjectLiteralExpression(final JetObjectLiteralExpression expression) {
TopDownAnalyzer topDownAnalyzer = new TopDownAnalyzer(semanticServices, new BindingTraceAdapter(trace) { TopDownAnalyzer topDownAnalyzer = new TopDownAnalyzer(semanticServices, new BindingTraceAdapter(trace) {
@Override @Override
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) { public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull final DeclarationDescriptor descriptor) {
if (declaration == expression.getObjectDeclaration()) { if (declaration == expression.getObjectDeclaration()) {
JetType defaultType = ((ClassDescriptor) descriptor).getDefaultType(); JetType defaultType = new DeferredType(new LazyValue<JetType>() {
@Override
protected JetType compute() {
return ((ClassDescriptor) descriptor).getDefaultType();
}
});
result = defaultType; result = defaultType;
if (!trace.isProcessed(expression)) { if (!trace.isProcessed(expression)) {
recordExpressionType(expression, defaultType); recordExpressionType(expression, defaultType);
@@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.Annotation; import org.jetbrains.jet.lang.descriptors.Annotation;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.ChainedScope;
import org.jetbrains.jet.lang.resolve.JetScope; import org.jetbrains.jet.lang.resolve.JetScope;
import java.util.*; import java.util.*;
@@ -70,13 +71,27 @@ public class TypeUtils {
} }
List<Annotation> noAnnotations = Collections.<Annotation>emptyList(); List<Annotation> noAnnotations = Collections.<Annotation>emptyList();
TypeConstructor constructor = new TypeConstructorImpl(null, noAnnotations, false, debugName.toString(), Collections.<TypeParameterDescriptor>emptyList(), types); TypeConstructor constructor = new TypeConstructorImpl(
null,
noAnnotations,
false,
debugName.toString(),
Collections.<TypeParameterDescriptor>emptyList(),
types);
JetScope[] scopes = new JetScope[types.size()];
int i = 0;
for (JetType type : types) {
scopes[i] = type.getMemberScope();
i++;
}
return new JetTypeImpl( return new JetTypeImpl(
noAnnotations, noAnnotations,
constructor, constructor,
nullable, nullable,
Collections.<TypeProjection>emptyList(), Collections.<TypeProjection>emptyList(),
JetStandardClasses.STUB); new ChainedScope(null, scopes)); // TODO : check intersectibility, don't use a chanied scope
} }
private static boolean canHaveSubtypes(JetTypeChecker typeChecker, JetType type) { private static boolean canHaveSubtypes(JetTypeChecker typeChecker, JetType type) {
@@ -176,7 +191,7 @@ public class TypeUtils {
private static List<TypeProjection> getArguments(@NotNull ClassDescriptor classDescriptor) { private static List<TypeProjection> getArguments(@NotNull ClassDescriptor classDescriptor) {
List<TypeProjection> result = new ArrayList<TypeProjection>(); List<TypeProjection> result = new ArrayList<TypeProjection>();
for (TypeParameterDescriptor parameterDescriptor : classDescriptor.getTypeConstructor().getParameters()) { 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; return result;
} }
@@ -274,7 +274,7 @@ public class DescriptorRenderer {
renderName(descriptor, builder); renderName(descriptor, builder);
if (!descriptor.getUpperBounds().isEmpty()) { if (!descriptor.getUpperBounds().isEmpty()) {
JetType bound = descriptor.getUpperBounds().iterator().next(); JetType bound = descriptor.getUpperBounds().iterator().next();
if (bound != JetStandardClasses.getAnyType()) { if (bound != JetStandardClasses.getDefaultBound()) {
builder.append(" : ").append(renderType(bound)); builder.append(" : ").append(renderType(bound));
if (descriptor.getUpperBounds().size() > 1) { if (descriptor.getUpperBounds().size() > 1) {
builder.append(" (...)"); builder.append(" (...)");
+4 -8
View File
@@ -14,10 +14,8 @@ JetFile: TypeConstraints.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
TYPE_CONSTRAINT_LIST TYPE_CONSTRAINT_LIST
TYPE_CONSTRAINT TYPE_CONSTRAINT
TYPE_REFERENCE REFERENCE_EXPRESSION
USER_TYPE PsiElement(IDENTIFIER)('T')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -32,10 +30,8 @@ JetFile: TypeConstraints.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
TYPE_REFERENCE REFERENCE_EXPRESSION
USER_TYPE PsiElement(IDENTIFIER)('T')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -213,10 +213,8 @@ JetFile: PolymorphicClassObjects.jet
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
TYPE_CONSTRAINT_LIST TYPE_CONSTRAINT_LIST
TYPE_CONSTRAINT TYPE_CONSTRAINT
TYPE_REFERENCE REFERENCE_EXPRESSION
USER_TYPE PsiElement(IDENTIFIER)('T')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -239,10 +237,8 @@ JetFile: PolymorphicClassObjects.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
TYPE_REFERENCE REFERENCE_EXPRESSION
USER_TYPE PsiElement(IDENTIFIER)('T')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')