diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetClass.java b/idea/src/org/jetbrains/jet/lang/psi/JetClass.java index edf9399f7d63016e66ceb5b567e83a05e19c45a9..6eaa974df5fe3b65bf6ef3e5f888eb6d3bdb026b 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetClass.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetClass.java @@ -24,6 +24,14 @@ public class JetClass extends JetTypeParameterListOwner implements JetClassOrObj return body.getDeclarations(); } + @NotNull + public List getSecondaryConstructors() { + JetClassBody body = (JetClassBody) findChildByType(JetNodeTypes.CLASS_BODY); + if (body == null) return Collections.emptyList(); + + return body.getSecondaryConstructors(); + } + @Override public void accept(@NotNull JetVisitor visitor) { visitor.visitClass(this); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetClassBody.java b/idea/src/org/jetbrains/jet/lang/psi/JetClassBody.java index 2b10b9bb5d3bfabf7a34c5176a1c4b82fd1f9ae9..3764491912bf738398850b4154dbc74303e999c6 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetClassBody.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetClassBody.java @@ -18,6 +18,10 @@ public class JetClassBody extends JetElement { return PsiTreeUtil.getChildrenOfTypeAsList(this, JetDeclaration.class); } + public List getSecondaryConstructors() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, JetConstructor.class); + } + @Override public void accept(@NotNull JetVisitor visitor) { visitor.visitClassBody(this); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java index 3b84c048c7f3d4f905731dd84088b365ab865ded..dc5a97ea35fd5823a6ed13a0517972d5b71b9283 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetNewExpression.java @@ -36,4 +36,10 @@ public class JetNewExpression extends JetExpression { JetArgumentList list = getArgumentList(); return list != null ? list.getArguments() : Collections.emptyList(); } + + @NotNull + public List getFunctionLiteralArguments() { + return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL); + } + } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 67dfc5f3df8f9a5ba5fc929a2de75cd7a3769325..942cefff9d0572956ef541e62cdd3d4ba44c973d 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -47,11 +47,20 @@ public class ClassDescriptorResolver { boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); WritableScope members = resolveMembers(classDescriptor, classElement, typeParameters, scope, parameterScope, superclasses); + WritableFunctionGroup constructors = new WritableFunctionGroup(""); + for (JetConstructor constructor : classElement.getSecondaryConstructors()) { + constructors.addFunction(resolveConstructorDescriptor(members, classDescriptor, constructor, false)); + } + ConstructorDescriptor primaryConstructorDescriptor = resolvePrimaryConstructor(scope, classDescriptor, classElement); + if (primaryConstructorDescriptor != null) { + constructors.addFunction(primaryConstructorDescriptor); + } return classDescriptor.initialize( !open, typeParameters, superclasses, - members + members, + constructors ); } @@ -298,4 +307,51 @@ public class ClassDescriptorResolver { property.getName(), type); } + + @NotNull + public ConstructorDescriptor resolveConstructorDescriptor(@NotNull JetScope scope, ClassDescriptor classDescriptor, JetConstructor constructor, boolean isPrimary) { + return createConstructorDescriptor(scope, classDescriptor, isPrimary, constructor.getModifierList(), constructor, constructor.getParameters()); + } + + @NotNull + private ConstructorDescriptor createConstructorDescriptor(JetScope scope, ClassDescriptor classDescriptor, boolean isPrimary, JetModifierList modifierList, JetDeclaration declarationToTrace, List valueParameters) { + ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl( + classDescriptor, + AttributeResolver.INSTANCE.resolveAttributes(modifierList), + isPrimary + ); + trace.recordDeclarationResolution(declarationToTrace, constructorDescriptor); + return constructorDescriptor.initialize( + resolveValueParameters( + constructorDescriptor, + semanticServices.createWritableScope(scope, classDescriptor), + valueParameters)); + } + + @Nullable + private ConstructorDescriptor resolvePrimaryConstructor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass classElement) { + JetParameterList primaryConstructorParameterList = classElement.getPrimaryConstructorParameterList(); + if (primaryConstructorParameterList != null) { + return createConstructorDescriptor( + scope, + classDescriptor, + true, + classElement.getModifierList(), // TODO + classElement, + primaryConstructorParameterList.getParameters()); + } + else { + List secondaryConstructors = classElement.getSecondaryConstructors(); + if (secondaryConstructors.isEmpty()) { + return createConstructorDescriptor( + scope, + classDescriptor, + true, + classElement.getModifierList(), // TODO + classElement, + Collections.emptyList()); + } + else return null; + } + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/LazySubstitutingClassDescriptor.java b/idea/src/org/jetbrains/jet/lang/resolve/LazySubstitutingClassDescriptor.java index 1b66444f6d80859497d7f32fb0d177f19d512449..38ab2483748a39e1212db96d367139da75a2869c 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/LazySubstitutingClassDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/LazySubstitutingClassDescriptor.java @@ -12,7 +12,7 @@ import java.util.Map; public class LazySubstitutingClassDescriptor implements ClassDescriptor { private final ClassDescriptor original; - private final Map substitutionContext; + private final Map substitutionContext; public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, Map substitutionContext) { this.original = descriptor; @@ -38,6 +38,12 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { return new SubstitutingScope(memberScope, substitutionContext); } + @NotNull + @Override + public FunctionGroup getConstructors(List typeArguments) { + throw new UnsupportedOperationException(); // TODO + } + @Override public List getAttributes() { throw new UnsupportedOperationException(); // TODO diff --git a/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java b/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java index 5e9231c0ab7b8ae6228caa63ef7830d8d6fc58a7..73e2d0aeb3e5ddfea536f305a134814a60bb2c5b 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/MutableClassDescriptor.java @@ -12,11 +12,15 @@ import java.util.Map; */ public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor { private final WritableScope unsubstitutedMemberScope; + private final WritableFunctionGroup constructors = new WritableFunctionGroup(""); + private final JetSemanticServices semanticServices; + private TypeConstructor typeConstructor; public MutableClassDescriptor(@NotNull JetSemanticServices semanticServices, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) { super(containingDeclaration); this.unsubstitutedMemberScope = semanticServices.createWritableScope(outerScope, this); + this.semanticServices = semanticServices; } @NotNull @@ -37,6 +41,23 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return new SubstitutingScope(unsubstitutedMemberScope, substitutionContext); } + public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { + assert constructorDescriptor.getContainingDeclaration() == this; + constructors.addFunction(constructorDescriptor); + } + + @NotNull + @Override + public FunctionGroup getConstructors(List typeArguments) { + // TODO : Duplicates ClassDescriptorImpl + assert typeArguments.size() == getTypeConstructor().getParameters().size(); + if (typeArguments.size() == 0) { + return constructors; + } + Map substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments); + return new LazySubstitutingFunctionGroup(substitutionContext, constructors); + } + @NotNull public WritableScope getUnsubstitutedMemberScope() { return unsubstitutedMemberScope; diff --git a/idea/src/org/jetbrains/jet/lang/resolve/MutableDeclarationDescriptor.java b/idea/src/org/jetbrains/jet/lang/resolve/MutableDeclarationDescriptor.java index 9eb337badd8ec65070bc6bc8a468415845c70ae2..636f3ce02c85e5a9b5c19a7da6f602d3cfa08ed9 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/MutableDeclarationDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/MutableDeclarationDescriptor.java @@ -38,6 +38,7 @@ public abstract class MutableDeclarationDescriptor implements DeclarationDescrip return this; } + @NotNull @Override public DeclarationDescriptor getContainingDeclaration() { return containingDeclaration; diff --git a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java index 0e4bf0886fe6e62f547a238679e8745bdfe36005..3f8fe463009395181b02282dcf99e27bc1816650 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java @@ -24,6 +24,11 @@ public class OverloadResolver { final FunctionGroup functionGroup = scope.getFunctionGroup(name); + return getOverloadDomain(functionGroup); + } + + @NotNull + public OverloadDomain getOverloadDomain(@NotNull final FunctionGroup functionGroup) { if (functionGroup.isEmpty()) { return OverloadDomain.EMPTY; } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index e0e62888281fe4dcc77c129112ec3cee0f8773c4..bb53f7822591ef00ab62da6048410a47b8314c9e 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -166,6 +166,17 @@ public class TopDownAnalyzer { processProperty(declaringScope, property); } + @Override + public void visitConstructor(JetConstructor constructor) { + DeclarationDescriptor containingDeclaration = declaringScope.getContainingDeclaration(); + if (containingDeclaration instanceof ClassDescriptor) { + processConstructor((MutableClassDescriptor) containingDeclaration, constructor); + } + else { + semanticServices.getErrorHandler().genericError(constructor.getNode(), "Constructors are only allowed inside classes"); + } + } + @Override public void visitDeclaration(JetDeclaration dcl) { throw new UnsupportedOperationException(); // TODO @@ -175,6 +186,10 @@ public class TopDownAnalyzer { } + private void processConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) { + classDescriptor.addConstructor(classDescriptorResolver.resolveConstructorDescriptor(classDescriptor.getUnsubstitutedMemberScope(), classDescriptor, constructor, false)); + } + private void processFunction(@NotNull WritableScope declaringScope, JetFunction function) { declaringScopes.put(function, declaringScope); FunctionDescriptor descriptor = classDescriptorResolver.resolveFunctionDescriptor(declaringScope.getContainingDeclaration(), declaringScope, function); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 9a21617c7b44dc39d7e067b756d18377e8d08ae0..f2f7ac8ba79feb300211e9bda835dfb2fc41879d 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -46,13 +46,17 @@ public class TypeResolver { trace.recordReferenceResolution(type.getReferenceExpression(), classDescriptor); TypeConstructor typeConstructor = classDescriptor.getTypeConstructor(); List arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments()); - result[0] = new JetTypeImpl( - attributes, - typeConstructor, - nullable, - arguments, - classDescriptor.getMemberScope(arguments) - ); + if (arguments.size() != typeConstructor.getParameters().size()) { + semanticServices.getErrorHandler().genericError(type.getNode(), typeConstructor.getParameters().size() + " type parameters expected"); // TODO : message + } else { + result[0] = new JetTypeImpl( + attributes, + typeConstructor, + nullable, + arguments, + classDescriptor.getMemberScope(arguments) + ); + } } else if (type.getTypeArguments().isEmpty()) { TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameter(type.getReferencedName()); 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 7f68fd975b25ea1de780e7fce2e60c22f2462cd4..a09f40c8f347470cbfb9e21d959635219cfd53fd 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -71,7 +71,25 @@ public class JavaDescriptorResolver { modifierList == null ? false : modifierList.hasModifierProperty(PsiModifier.FINAL), Collections.emptyList(), getSupertypes(psiClass), - new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false) + new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false), + new FunctionGroup() { + @NotNull + @Override + public String getName() { + throw new UnsupportedOperationException(); // TODO + } + + @NotNull + @Override + public Collection getPossiblyApplicableFunctions(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) { + throw new UnsupportedOperationException(); // TODO + } + + @Override + public boolean isEmpty() { + throw new UnsupportedOperationException(); // TODO + } + } ); semanticServices.getTrace().recordDeclarationResolution(psiClass, classDescriptor); return classDescriptor; diff --git a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java index 25dae46940b9f9e2c2d0c2180703bfa0e6b79786..ac15a99bdd9ab8c89ef15a2ddf6858507425e057 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java @@ -15,6 +15,9 @@ public interface ClassDescriptor extends DeclarationDescriptor { @NotNull JetScope getMemberScope(List typeArguments); + @NotNull + FunctionGroup getConstructors(List typeArguments); + @Override @NotNull DeclarationDescriptor getContainingDeclaration(); diff --git a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java index eec0c493bb196421576952d1eab1fb7374e33b90..2ebc609887dca22604b3e95757da6fa313c5bbe8 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java @@ -15,11 +15,12 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl private TypeConstructor typeConstructor; private JetScope memberDeclarations; + private FunctionGroup constructors; public ClassDescriptorImpl( @NotNull DeclarationDescriptor containingDeclaration, - List attributes, - String name) { + @NotNull List attributes, + @NotNull String name) { super(containingDeclaration, attributes, name); } @@ -31,10 +32,13 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl // } // public final ClassDescriptorImpl initialize(boolean sealed, - List typeParameters, - Collection superclasses, JetScope memberDeclarations) { + @NotNull List typeParameters, + @NotNull Collection superclasses, + @NotNull JetScope memberDeclarations, + @NotNull FunctionGroup constructors) { this.typeConstructor = new TypeConstructorImpl(this, getAttributes(), sealed, getName(), typeParameters, superclasses); this.memberDeclarations = memberDeclarations; + this.constructors = constructors; return this; } @@ -47,13 +51,25 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl @Override @NotNull public JetScope getMemberScope(List typeArguments) { + assert typeArguments.size() == typeConstructor.getParameters().size(); if (typeConstructor.getParameters().isEmpty()) { return memberDeclarations; } - Map substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(typeConstructor.getParameters(), typeArguments); + Map substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(typeConstructor.getParameters(), typeArguments); return new SubstitutingScope(memberDeclarations, substitutionContext); } + @NotNull + @Override + public FunctionGroup getConstructors(List typeArguments) { + assert typeArguments.size() == getTypeConstructor().getParameters().size(); + if (typeArguments.size() == 0) { + return constructors; + } + Map substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments); + return new LazySubstitutingFunctionGroup(substitutionContext, constructors); + } + @Override public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitClassDescriptor(this, data); diff --git a/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..5d1be022c42394c0fa03784a19f9820376251b17 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptor.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author abreslav + */ +public interface ConstructorDescriptor extends FunctionDescriptor { + /** + * @throws UnsupportedOperationException -- no type parameters supported for constructors + */ + @NotNull + @Override + List getTypeParameters(); + + /** + * @throws UnsupportedOperationException -- return type is not stored for constructors + */ + @NotNull + @Override + JetType getUnsubstitutedReturnType(); + + @NotNull + @Override + ClassDescriptor getContainingDeclaration(); + + /** + * @return "<init>" -- name is not stored for constructors + */ + @Override + String getName(); + + boolean isPrimary(); +} diff --git a/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptorImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..0ef331378e9219cb39dfc80b4960c968c5fffec4 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/ConstructorDescriptorImpl.java @@ -0,0 +1,69 @@ +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +/** + * @author abreslav + */ +public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements ConstructorDescriptor { + + private final boolean isPrimary; + + public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull List attributes, boolean isPrimary) { + super(containingDeclaration, attributes, ""); + this.isPrimary = isPrimary; + } + + public ConstructorDescriptorImpl(@NotNull ConstructorDescriptor original, @NotNull List attributes, boolean isPrimary) { + super(original, attributes, ""); + this.isPrimary = isPrimary; + } + + @Override + @Deprecated + public FunctionDescriptor initialize(@NotNull List typeParameters, @NotNull List unsubstitutedValueParameters, @NotNull JetType unsubstitutedReturnType) { + return super.initialize(typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType); + } + + public ConstructorDescriptor initialize(@NotNull List unsubstitutedValueParameters) { + super.initialize(Collections.emptyList(), unsubstitutedValueParameters, JetStandardClasses.getNothingType()); + return this; + } + + @NotNull + @Override + public ClassDescriptor getContainingDeclaration() { + return (ClassDescriptor) super.getContainingDeclaration(); + } + + @NotNull + @Override + public ConstructorDescriptor getOriginal() { + return (ConstructorDescriptor) super.getOriginal(); + } + + @Override + public R accept(DeclarationDescriptorVisitor visitor, D data) { + return visitor.visitConstructorDescriptor(this, data); + } + + @Override + public boolean isPrimary() { + return isPrimary; + } + + @NotNull + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + + @NotNull + @Override + public JetType getUnsubstitutedReturnType() { + return TypeUtils.makeUnsubstitutedType(getContainingDeclaration()); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorVisitor.java b/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorVisitor.java index 125c812ab15bfa53cb04a8c09e392c683b699a46..e2d608a37628daba31f8a16571966003f8b6c28b 100644 --- a/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorVisitor.java +++ b/idea/src/org/jetbrains/jet/lang/types/DeclarationDescriptorVisitor.java @@ -27,4 +27,8 @@ public class DeclarationDescriptorVisitor { public R visitModuleDeclaration(ModuleDescriptor moduleDescriptor, D data) { return null; } + + public R visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, D data) { + return visitFunctionDescriptor(constructorDescriptor, data); + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java index 893bff495ff1b16becbc0463b0f7a0412e167897..fae8ccf5338a9607d1b5bdbec85e624a4c95edd5 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java +++ b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java @@ -3,10 +3,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.JetScope; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * @author abreslav @@ -61,15 +58,6 @@ public class ErrorType { }; - private static final ClassDescriptor ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.emptyList(), "").initialize( - true, Collections.emptyList(), Collections.emptyList(), getErrorScope() - ); - - private static JetScope getErrorScope() { - return ERROR_SCOPE; - } - - private static final PropertyDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl(ERROR_CLASS, Collections.emptyList(), "", createErrorType("")); private static final FunctionGroup ERROR_FUNCTION_GROUP = new FunctionGroup() { @NotNull @Override @@ -80,28 +68,8 @@ public class ErrorType { @NotNull @Override public Collection getPossiblyApplicableFunctions(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) { - FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.emptyList(), ""); - return Collections.singletonList(functionDescriptor.initialize( - Collections.emptyList(), - getValueParameters(functionDescriptor, positionedValueArgumentTypes), - createErrorType("") - )); - } - - private List getValueParameters(FunctionDescriptor functionDescriptor, List argumentTypes) { - List result = new ArrayList(); - for (int i = 0, argumentTypesSize = argumentTypes.size(); i < argumentTypesSize; i++) { - JetType argumentType = argumentTypes.get(i); - result.add(new ValueParameterDescriptorImpl( - functionDescriptor, - i, - Collections.emptyList(), - "", - createErrorType(""), - false, - false)); - } - return result; + List typeParameters = Collections.emptyList(); + return createErrorFunction(typeParameters, positionedValueArgumentTypes); } @Override @@ -110,14 +78,58 @@ public class ErrorType { } }; - private ErrorType() {} + private static final ClassDescriptor ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.emptyList(), "").initialize( + true, Collections.emptyList(), Collections.emptyList(), getErrorScope(), ERROR_FUNCTION_GROUP); + + private static JetScope getErrorScope() { + return ERROR_SCOPE; + } + + private static final PropertyDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl(ERROR_CLASS, Collections.emptyList(), "", createErrorType("")); + + private static Collection createErrorFunction(List typeParameters, List positionedValueArgumentTypes) { + FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.emptyList(), ""); + return Collections.singletonList(functionDescriptor.initialize( + typeParameters, + getValueParameters(functionDescriptor, positionedValueArgumentTypes), + createErrorType("") + )); + } + + private static FunctionDescriptor createErrorFunction(int typeParameterCount, Map valueParameters) { + throw new UnsupportedOperationException(); // TODO + } + + private static FunctionDescriptor createErrorFunction(int typeParameterCount, List positionedValueParameterTypes) { + return new FunctionDescriptorImpl(ERROR_CLASS, Collections.emptyList(), "").initialize( + Collections.emptyList(), // TODO + Collections.emptyList(), // TODO + createErrorType("") + ); + } + + private static List getValueParameters(FunctionDescriptor functionDescriptor, List argumentTypes) { + List result = new ArrayList(); + for (int i = 0, argumentTypesSize = argumentTypes.size(); i < argumentTypesSize; i++) { + JetType argumentType = argumentTypes.get(i); + result.add(new ValueParameterDescriptorImpl( + functionDescriptor, + i, + Collections.emptyList(), + "", + createErrorType(""), + false, + false)); + } + return result; + } public static JetType createErrorType(String debugMessage) { return createErrorType(debugMessage, ERROR_SCOPE); } private static JetType createErrorType(String debugMessage, JetScope memberScope) { - return new ErrorTypeImpl(new TypeConstructorImpl(null, Collections.emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.emptyList(), Collections.emptyList()), memberScope); + return new ErrorTypeImpl(new TypeConstructorImpl(ERROR_CLASS, Collections.emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.emptyList(), Collections.emptyList()), memberScope); } public static JetType createWrongVarianceErrorType(TypeProjection value) { @@ -131,8 +143,8 @@ public class ErrorType { private static class ErrorTypeImpl implements JetType { private final TypeConstructor constructor; - private final JetScope memberScope; + private final JetScope memberScope; private ErrorTypeImpl(TypeConstructor constructor, JetScope memberScope) { this.constructor = constructor; this.memberScope = memberScope; @@ -165,5 +177,8 @@ public class ErrorType { public List getAttributes() { return Collections.emptyList(); } + } + + private ErrorType() {} } diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java index 05c6e25af04e854bb7ded0923125645fcb257d68..e3133c71c053db370d7811da465f2740364d943a 100644 --- a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorImpl.java @@ -32,7 +32,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements this.original = original; } - public final FunctionDescriptor initialize( + public FunctionDescriptor initialize( @NotNull List typeParameters, @NotNull List unsubstitutedValueParameters, @NotNull JetType unsubstitutedReturnType) { diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java index 9838ec78223ba7e6aa4af56977957502565b6b8d..d6da415cb93ce078b5245ccaed35b8d74f4fd1a7 100644 --- a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java +++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java @@ -39,6 +39,7 @@ public class FunctionDescriptorUtil { @NotNull public static List getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull List typeArguments) { + // TODO : Review, maybe duplicates LazySubstitutingFunctionDescriptor List result = new ArrayList(); Map context = createSubstitutionContext(functionDescriptor, typeArguments); List unsubstitutedValueParameters = functionDescriptor.getUnsubstitutedValueParameters(); @@ -59,7 +60,7 @@ public class FunctionDescriptorUtil { } private static Map createSubstitutionContext(@NotNull FunctionDescriptor functionDescriptor, List typeArguments) { - Map result = new HashMap(); + Map result = new HashMap(); int typeArgumentsSize = typeArguments.size(); List typeParameters = functionDescriptor.getTypeParameters(); @@ -74,6 +75,7 @@ public class FunctionDescriptorUtil { @NotNull public static JetType getSubstitutedReturnType(@NotNull FunctionDescriptor functionDescriptor, @NotNull List typeArguments) { + // TODO : Review, maybe duplicates LazySubstitutingFunctionDescriptor return TypeSubstitutor.INSTANCE.substitute(createSubstitutionContext(functionDescriptor, typeArguments), functionDescriptor.getUnsubstitutedReturnType(), Variance.OUT_VARIANCE); } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 71883f3809445a8afb93d5ac9f349a29f6dc65c0..1e67287c0082c76c63000f3b5a47bb18312b2ad1 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -25,7 +25,8 @@ public class JetStandardClasses { private static final ClassDescriptor NOTHING_CLASS = new ClassDescriptorImpl( STANDARD_CLASSES_NAMESPACE, Collections.emptyList(), - "Nothing").initialize( + "Nothing" + ).initialize( true, Collections.emptyList(), new AbstractCollection() { @@ -43,7 +44,9 @@ public class JetStandardClasses { public int size() { throw new UnsupportedOperationException(); } - }, JetScope.EMPTY + }, + JetScope.EMPTY, + FunctionGroup.EMPTY ); private static final JetType NOTHING_TYPE = new JetTypeImpl(getNothing()); @@ -63,7 +66,8 @@ public class JetStandardClasses { false, Collections.emptyList(), Collections.emptySet(), - JetScope.EMPTY + JetScope.EMPTY, + FunctionGroup.EMPTY ); private static final JetType ANY_TYPE = new JetTypeImpl(ANY.getTypeConstructor(), JetScope.EMPTY); @@ -72,6 +76,7 @@ public class JetStandardClasses { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static final JetScope STUB = JetScope.EMPTY; + public static final FunctionGroup STUB_FG = FunctionGroup.EMPTY; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -95,7 +100,9 @@ public class JetStandardClasses { TUPLE[i] = classDescriptor.initialize( true, parameters, - Collections.singleton(getAnyType()), STUB); + Collections.singleton(getAnyType()), + STUB, + STUB_FG); } } @@ -115,7 +122,7 @@ public class JetStandardClasses { FUNCTION[i] = function.initialize( false, createTypeParameters(i, function), - Collections.singleton(getAnyType()), STUB); + Collections.singleton(getAnyType()), STUB, STUB_FG); ClassDescriptorImpl receiverFunction = new ClassDescriptorImpl( STANDARD_CLASSES_NAMESPACE, @@ -130,7 +137,7 @@ public class JetStandardClasses { RECEIVER_FUNCTION[i] = receiverFunction.initialize( false, parameters, - Collections.singleton(getAnyType()), STUB); + Collections.singleton(getAnyType()), STUB, STUB_FG); } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index 347874d78e9fdb21dcc6c352bbda8346443e88d5..bcd37da59f110fce4841cea07f2e46e7abcfa7ef 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -274,7 +274,7 @@ public class JetTypeChecker { return; } handler.beforeChildren(current); - Map substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(current); + Map substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(current); for (JetType supertype : current.getConstructor().getSupertypes()) { TypeConstructor supertypeConstructor = supertype.getConstructor(); if (visited.contains(supertypeConstructor)) { diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 398f52c49dfdfd0bf9ee134301e3409ff332806f..087444ff0ffb0205c5be51311957bb4941bbf1b4 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -283,20 +283,22 @@ public class JetTypeInferrer { // TODO : other members // TODO : type substitutions??? String referencedName = expression.getReferencedName(); - PropertyDescriptor property = scope.getProperty(referencedName); - if (property != null) { - trace.recordReferenceResolution(expression, property); - result = property.getType(); - return; - } else { - NamespaceDescriptor namespace = scope.getNamespace(referencedName); - if (namespace != null) { - trace.recordReferenceResolution(expression, namespace); - result = namespace.getNamespaceType(); + if (referencedName != null) { + PropertyDescriptor property = scope.getProperty(referencedName); + if (property != null) { + trace.recordReferenceResolution(expression, property); + result = property.getType(); return; + } else { + NamespaceDescriptor namespace = scope.getNamespace(referencedName); + if (namespace != null) { + trace.recordReferenceResolution(expression, namespace); + result = namespace.getNamespaceType(); + return; + } } + semanticServices.getErrorHandler().unresolvedReference(expression); } - semanticServices.getErrorHandler().unresolvedReference(expression); } @Override @@ -451,7 +453,7 @@ public class JetTypeInferrer { JetUserType typeElement = (JetUserType) superTypeQualifier.getTypeElement(); ClassDescriptor superclass = typeResolver.resolveClass(scope, typeElement); Collection supertypes = thisType.getConstructor().getSupertypes(); - Map substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(thisType); + Map substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(thisType); for (JetType declaredSupertype : supertypes) { if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) { result = TypeSubstitutor.INSTANCE.substitute(substitutionContext, declaredSupertype, Variance.INVARIANT); @@ -499,15 +501,27 @@ public class JetTypeInferrer { public void visitIfExpression(JetIfExpression expression) { checkCondition(scope, expression.getCondition()); - // TODO : change types according to is and nullability checks + // TODO : change types according to is and null checks JetExpression elseBranch = expression.getElse(); - if (elseBranch == null) { - // TODO : type-check the branch - result = JetStandardClasses.getUnitType(); - } else { - JetType thenType = getType(scope, expression.getThen(), true); + JetExpression thenBranch = expression.getThen(); + JetType thenType = null; + if (thenBranch != null) { + thenType = getType(scope, thenBranch, true); + } + if (elseBranch != null) { JetType elseType = getType(scope, elseBranch, true); - result = semanticServices.getTypeChecker().commonSupertype(Arrays.asList(thenType, elseType)); + if (thenType == null) { + result = elseType; + } + else if (elseType == null) { + result = thenType; + } + else { + result = semanticServices.getTypeChecker().commonSupertype(Arrays.asList(thenType, elseType)); + } + } + else { + result = JetStandardClasses.getUnitType(); } } @@ -609,7 +623,38 @@ public class JetTypeInferrer { // TODO : type argument inference JetTypeReference typeReference = expression.getTypeReference(); if (typeReference != null) { - result = typeResolver.resolveType(scope, typeReference); + JetTypeElement typeElement = typeReference.getTypeElement(); + if (typeElement instanceof JetUserType) { + JetUserType userType = (JetUserType) typeElement; + // TODO : to infer constructor parameters, one will need to + // 1) resolve a _class_ from the typeReference + // 2) rely on the overload domain of constructors of this class to infer type arguments + // For now we assume that the type arguments are provided, and thus the typeReference can be + // resolved into a valid type + JetType receiverType = typeResolver.resolveType(scope, typeReference); + DeclarationDescriptor declarationDescriptor = receiverType.getConstructor().getDeclarationDescriptor(); + if (declarationDescriptor instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; + + JetSimpleNameExpression referenceExpression = userType.getReferenceExpression(); + if (referenceExpression != null) { + FunctionGroup constructors = classDescriptor.getConstructors(receiverType.getArguments()); + OverloadDomain constructorsOverloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(constructors); + result = resolveOverloads( + scope, + wrapForTracing(constructorsOverloadDomain, referenceExpression, true), + Collections.emptyList(), + expression.getArguments(), + expression.getFunctionLiteralArguments()); + } + } + else { + semanticServices.getErrorHandler().genericError(expression.getNode(), "Calling a constructor is only supported for ordinary classes"); // TODO : review the message + } + } + else { + semanticServices.getErrorHandler().genericError(typeElement.getNode(), "Calling a constructor is only supported for ordinary classes"); // TODO : Better message + } } } @@ -664,14 +709,29 @@ public class JetTypeInferrer { result = resolveOverloads(scope, expression, overloadDomain); } + @Nullable private JetType resolveOverloads(JetScope scope, JetCallExpression expression, OverloadDomain overloadDomain) { + List typeArguments = expression.getTypeArguments(); + List valueArguments = expression.getValueArguments(); + List functionLiteralArguments = expression.getFunctionLiteralArguments(); + return resolveOverloads(scope, overloadDomain, typeArguments, valueArguments, functionLiteralArguments); + } + + @Nullable + private JetType resolveOverloads( + @NotNull JetScope scope, + @NotNull OverloadDomain overloadDomain, + @NotNull List typeArguments, + @NotNull List valueArguments, + @NotNull List functionLiteralArguments) { // 1) ends with a name -> (scope, name) to look up // 2) ends with something else -> just check types - // TODO : check somewhere that these are NOT projections - List typeArguments = expression.getTypeArguments(); - - List valueArguments = expression.getValueArguments(); + for (JetTypeProjection typeArgument : typeArguments) { + if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) { + semanticServices.getErrorHandler().genericError(typeArgument.getNode(), "Projections are not allowed on type parameters for methods"); // TODO : better positioning + } + } boolean someNamed = false; for (JetArgument argument : valueArguments) { @@ -680,7 +740,6 @@ public class JetTypeInferrer { break; } } - List functionLiteralArguments = expression.getFunctionLiteralArguments(); // JetExpression functionLiteralArgument = functionLiteralArguments.isEmpty() ? null : functionLiteralArguments.get(0); // TODO : must be a check @@ -762,7 +821,10 @@ public class JetTypeInferrer { IElementType operationType = operationSign.getReferencedNameElementType(); if (operationType == JetTokens.IDENTIFIER) { - result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope, true); + String referencedName = operationSign.getReferencedName(); + if (referencedName != null) { + result = getTypeForBinaryCall(expression, referencedName, scope, true); + } } else if (binaryOperationNames.containsKey(operationType)) { result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope, true); @@ -879,16 +941,18 @@ public class JetTypeInferrer { } } + @Nullable protected JetType getTypeForBinaryCall(JetBinaryExpression expression, @NotNull String name, JetScope scope, boolean reportUnresolved) { JetExpression left = expression.getLeft(); JetExpression right = expression.getRight(); if (right == null) { - return ErrorType.createErrorType("No right argument"); // TODO + return null; } JetSimpleNameExpression operationSign = expression.getOperationReference(); return getTypeForBinaryCall(scope, left, operationSign, right, name, reportUnresolved); } + @Nullable private JetType getTypeForBinaryCall(JetScope scope, JetExpression left, JetSimpleNameExpression operationSign, @NotNull JetExpression right, String name, boolean reportUnresolved) { JetType leftType = safeGetType(scope, left, false); JetType rightType = safeGetType(scope, right, false); diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeProjection.java b/idea/src/org/jetbrains/jet/lang/types/TypeProjection.java index 164480697471c24671e6dde460070c08995ed756..d401d388834aa7ce54dc54e5ef2ed6923e83ba09 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeProjection.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeProjection.java @@ -18,10 +18,12 @@ public class TypeProjection { this(Variance.INVARIANT, type); } + @NotNull public Variance getProjectionKind() { return projection; } + @NotNull public JetType getType() { return type; } diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java b/idea/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java index a1c624b9b0e6552df34617d78b1f1925f3c86bff..e4756accb079d4da3d1154d34635d614288ebfb5 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.SubstitutingScope; import java.util.*; @@ -13,7 +14,7 @@ public class TypeSubstitutor { private TypeSubstitutor() {} public JetType substitute(@NotNull JetType context, @NotNull JetType subject, @NotNull Variance howThisTypeIsUsed) { - return substitute(getSubstitutionContext(context), subject, howThisTypeIsUsed); + return substitute(buildSubstitutionContext(context), subject, howThisTypeIsUsed); } @NotNull @@ -28,47 +29,34 @@ public class TypeSubstitutor { return value.getType(); } - return specializeType(type, substituteInArguments(substitutionContext, type)); + return specializeType(type, substitutionContext); } - public Map getSubstitutionContext(JetType context) { - List parameters = context.getConstructor().getParameters(); - List contextArguments = context.getArguments(); - - return buildSubstitutionContext(parameters, contextArguments); + private JetType specializeType(JetType subjectType, Map substitutionContext) { + return new JetTypeImpl( + subjectType.getAttributes(), + subjectType.getConstructor(), + subjectType.isNullable(), + substituteInArguments(substitutionContext, subjectType), + new SubstitutingScope(subjectType.getMemberScope(), substitutionContext)); } - public Map buildSubstitutionContext(List parameters, List contextArguments) { - Map parameterValues = new HashMap(); - for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) { - TypeParameterDescriptor parameter = parameters.get(i); - TypeProjection value = contextArguments.get(i); - parameterValues.put(parameter.getTypeConstructor(), value); + private List substituteInArguments(Map substitutionContext, JetType subjectType) { + List newArguments = new ArrayList(); + for (TypeProjection argument : subjectType.getArguments()) { + newArguments.add(substituteInProjection(substitutionContext, argument)); } - return parameterValues; + return newArguments; } @NotNull - private TypeProjection substituteInProjection(Map parameterValues, TypeProjection subject) { - @NotNull JetType subjectType = subject.getType(); - TypeProjection value = parameterValues.get(subjectType.getConstructor()); + private TypeProjection substituteInProjection(Map substitutionContext, TypeProjection subject) { + JetType subjectType = subject.getType(); + TypeProjection value = substitutionContext.get(subjectType.getConstructor()); if (value != null) { return value; } - List newArguments = substituteInArguments(parameterValues, subjectType); - return new TypeProjection(subject.getProjectionKind(), specializeType(subjectType, newArguments)); - } - - private List substituteInArguments(Map parameterValues, JetType subjectType) { - List newArguments = new ArrayList(); - for (TypeProjection argument : subjectType.getArguments()) { - newArguments.add(substituteInProjection(parameterValues, argument)); - } - return newArguments; - } - - private JetType specializeType(JetType type, List newArguments) { - return new JetTypeImpl(type.getAttributes(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberScope()); + return new TypeProjection(subject.getProjectionKind(), specializeType(subjectType, substitutionContext)); } public Set substituteInSet(Map substitutionContext, Set types, Variance howTheseTypesWillBeUsed) { @@ -78,4 +66,18 @@ public class TypeSubstitutor { } return result; } + + public Map buildSubstitutionContext(JetType context) { + return buildSubstitutionContext(context.getConstructor().getParameters(), context.getArguments()); + } + + public Map buildSubstitutionContext(List parameters, List contextArguments) { + Map parameterValues = new HashMap(); + for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) { + TypeParameterDescriptor parameter = parameters.get(i); + TypeProjection value = contextArguments.get(i); + parameterValues.put(parameter.getTypeConstructor(), value); + } + return parameterValues; + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java index 7a11c4babaff383d0c0bdcbf577630e5e5ec8ae5..03999b9ffebdffc6d83e0eb32cbd62c162501375 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -1,11 +1,10 @@ package org.jetbrains.jet.lang.types; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.JetScope; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author abreslav @@ -146,4 +145,25 @@ public class TypeUtils { } return type; } + + @NotNull + public static JetType makeUnsubstitutedType(ClassDescriptor classDescriptor) { + List arguments = getArguments(classDescriptor); + return new JetTypeImpl( + Collections.emptyList(), + classDescriptor.getTypeConstructor(), + false, + arguments, + classDescriptor.getMemberScope(arguments) + ); + } + + @NotNull + 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? + } + return result; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java b/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java index 4f44cc73f91576d5853780595a92769e407eea90..269577ed047c7f35c31cfe93050b46194f95d2e6 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/JetQuickDocumentationProvider.java @@ -4,13 +4,11 @@ import com.intellij.lang.documentation.QuickDocumentationProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.jet.lang.ErrorHandler; -import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.DeclarationDescriptor; -import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.resolve.DescriptorUtil; /** @@ -49,7 +47,7 @@ public class JetQuickDocumentationProvider extends QuickDocumentationProvider { private String render(DeclarationDescriptor declarationDescriptor) { String text = DescriptorUtil.renderPresentableText(declarationDescriptor); - text = text.replaceAll("<", "<"); +// text = text.replaceAll("<", "<"); return text; } diff --git a/idea/testData/resolve/Basic.jet b/idea/testData/resolve/Basic.jet index b34da0fa42c5290a238a730ce4572a414035f60c..0a1a623207d5949986aa08623f4e2ece01f6d10d 100644 --- a/idea/testData/resolve/Basic.jet +++ b/idea/testData/resolve/Basic.jet @@ -1,12 +1,12 @@ ~A~class A { ~B~class B { - + ~B()~this() {} } ~foo~fun foo(~foo.a~a : `std::Char`Char) = `foo.a`a`:std::Char` ~fooB~fun fooB() = `foo`foo('1')`:std::Char` ~foo.1~fun foo() : Int = (1.`std::Int.plus(Int)`plus(1))`:std::Int` - ~foo1~fun foo1() : `B`B = new `B`B()`:B` + ~foo1~fun foo1() : `B`B = new `B()`B()`:B` ~A.a~val a : `std::Int`Int } diff --git a/idea/testData/resolve/ResolveOfInfixExpressions.jet b/idea/testData/resolve/ResolveOfInfixExpressions.jet index 0719bac45549f6c93dfc3dbb88be6ecc80eceeb7..27626af2cf7d24c818bde44ab3429311de525082 100644 --- a/idea/testData/resolve/ResolveOfInfixExpressions.jet +++ b/idea/testData/resolve/ResolveOfInfixExpressions.jet @@ -2,6 +2,7 @@ import java.* import util.* ~X~class X<~T~T> { + ~X()~this() {} fun foo(a : `T`T) : `X`X<`T`T>{} ~plus~fun plus(t : `T`T) : Int {} ~minus~fun minus(t : String) : Int {} @@ -16,7 +17,7 @@ import util.* ~t~fun <~t.T~T> t(~t.t~t : `t.T`T) : `t.T`T { `t`t(1)`:std::Int` `t`t<`t.T`T>(`t.t`t)`:t.T` - new `X`X<`t.T`T>() + new `X()`X<`t.T`T>() 1 `std::Int.plus(Int)`+ 1 1 `std::Int.plus(Int)`+= 1 new X() `plus`+ "1" @@ -43,6 +44,7 @@ import util.* } ~Bar~class Bar : Foo { + ~Bar()~this() {} ~not~fun not() : String {} ~inc~fun inc() : Bar ~dec~fun dec() : Bar @@ -53,7 +55,7 @@ import util.* fun tt(t : T) : T { val x : List = 0 x`java::java.util.List.get()`[1] - val foo = new Bar() + val foo = new `Bar()`Bar() foo`!`[null, 1] foo`get2`[1, 1] foo`get1`[1] diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index cd64021c93f276a57aa73d9c82ae3bdfcc4cbb51..cc02fb4c00b366fb624e92eef2e143e463a726f2 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -331,9 +331,9 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { assertType("new Properties().p", "Int"); assertType("new Props().p", "Int"); assertType("new Props().p", "Int"); - assertErrorType("new Props().p"); - assertType("new Props().p.p", "Int"); + + assertErrorType("new Props().p"); } public void testOverloads() throws Exception {