From 986e703fad76a1ad9d62d4a4f5e8635b4017bdd5 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 16 Feb 2011 16:57:12 +0300 Subject: [PATCH] Working on overloads. The corresponding test fails. That's allright: the work is not finished yet. --- idea/src/org/jetbrains/jet/JetNodeTypes.java | 2 +- .../jet/lang/annotations/JetPsiChecker.java | 4 +- .../jet/lang/psi/JetCallExpression.java | 11 +- .../jetbrains/jet/lang/psi/JetFunction.java | 10 +- .../jet/lang/psi/JetPredicateExpression.java | 18 +++ .../jet/lang/psi/JetPridcateExpression.java | 13 -- .../jetbrains/jet/lang/psi/JetVisitor.java | 8 +- .../lang/resolve/ClassDescriptorResolver.java | 132 ++++++++++++++---- .../jetbrains/jet/lang/resolve/JetScope.java | 10 +- .../jet/lang/resolve/JetScopeAdapter.java | 17 ++- .../jet/lang/resolve/JetScopeImpl.java | 17 +-- .../jet/lang/resolve/OverloadDomain.java | 38 +++++ .../jet/lang/resolve/ScopeWithReceiver.java | 17 +-- .../jet/lang/resolve/SubstitutingScope.java | 15 +- .../jet/lang/resolve/TypeResolver.java | 2 +- .../lang/resolve/WritableFunctionGroup.java | 76 ++++++++++ .../jet/lang/resolve/WritableScope.java | 71 +++++++++- .../jetbrains/jet/lang/types/ErrorType.java | 16 +-- .../jet/lang/types/FunctionDescriptor.java | 110 +++++++++++++++ .../jet/lang/types/FunctionGroup.java | 33 +++++ .../jet/lang/types/JetStandardClasses.java | 9 +- .../jet/lang/types/JetTypeChecker.java | 98 ++++++++++++- .../jet/lang/types/MethodDescriptor.java | 7 - .../jet/lang/types/NamespaceDescriptor.java | 2 +- .../jet/lang/types/ParameterDescriptor.java | 26 ---- .../lang/types/PropertyDescriptorImpl.java | 4 - .../lang/types/ValueParameterDescriptor.java | 10 ++ .../types/ValueParameterDescriptorImpl.java | 30 ++++ .../jet/types/JetTypeCheckerTest.java | 11 ++ 29 files changed, 660 insertions(+), 157 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java delete mode 100644 idea/src/org/jetbrains/jet/lang/psi/JetPridcateExpression.java create mode 100644 idea/src/org/jetbrains/jet/lang/resolve/OverloadDomain.java create mode 100644 idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java create mode 100644 idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java create mode 100644 idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java delete mode 100644 idea/src/org/jetbrains/jet/lang/types/MethodDescriptor.java delete mode 100644 idea/src/org/jetbrains/jet/lang/types/ParameterDescriptor.java create mode 100644 idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java create mode 100644 idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 44bca5a4baa..2b546ab78dd 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -105,7 +105,7 @@ public interface JetNodeTypes { JetNodeType DOT_QIALIFIED_EXPRESSION = new JetNodeType("DOT_QIALIFIED_EXPRESSION", JetDotQualifiedExpression.class); JetNodeType HASH_QIALIFIED_EXPRESSION = new JetNodeType("HASH_QIALIFIED_EXPRESSION", JetHashQualifiedExpression.class); JetNodeType SAFE_ACCESS_EXPRESSION = new JetNodeType("SAFE_ACCESS_EXPRESSION", JetSafeQualifiedExpression.class); - JetNodeType PREDICATE_EXPRESSION = new JetNodeType("PREDICATE_EXPRESSION", JetPridcateExpression.class); + JetNodeType PREDICATE_EXPRESSION = new JetNodeType("PREDICATE_EXPRESSION", JetPredicateExpression.class); JetNodeType DECOMPOSER_PATTERN = new JetNodeType("DECOMPOSER_PATTERN"); JetNodeType TUPLE_PATTERN = new JetNodeType("TUPLE_PATTERN"); JetNodeType OBJECT_LITERAL = new JetNodeType("OBJECT_LITERAL", JetObjectLiteralExpression.class); diff --git a/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java b/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java index 1dc32aca633..6023040a07d 100644 --- a/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/lang/annotations/JetPsiChecker.java @@ -44,8 +44,8 @@ public class JetPsiChecker implements Annotator { } @Override - public void visitFunction(JetFunction fun) { - super.visitFunction(fun); //To change body of overridden methods use File | Settings | File Templates. + public void visitFunction(JetFunction function) { + super.visitFunction(function); //To change body of overridden methods use File | Settings | File Templates. } }); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetCallExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetCallExpression.java index 62f2a90c5aa..5102449b6f6 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetCallExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetCallExpression.java @@ -29,7 +29,7 @@ public class JetCallExpression extends JetExpression { } @Nullable - public JetArgumentList getArgumentList() { + public JetArgumentList getValueArgumentList() { return (JetArgumentList) findChildByType(JetNodeTypes.VALUE_ARGUMENT_LIST); } @@ -39,8 +39,13 @@ public class JetCallExpression extends JetExpression { } @NotNull - public List getArguments() { - JetArgumentList list = getArgumentList(); + public List getFunctionLiteralArguments() { + return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL); + } + + @NotNull + public List getValueArguments() { + JetArgumentList list = getValueArgumentList(); return list != null ? list.getArguments() : Collections.emptyList(); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java b/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java index a7b113d5cc1..eeddef516c7 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java @@ -25,13 +25,13 @@ public class JetFunction extends JetTypeParameterListOwner { } @Nullable @IfNotParsed - public JetParameterList getParameterList() { + public JetParameterList getValueParameterList() { return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST); } @NotNull - public List getParameters() { - JetParameterList list = getParameterList(); + public List getValueParameters() { + JetParameterList list = getValueParameterList(); return list != null ? list.getParameters() : Collections.emptyList(); } @@ -73,4 +73,8 @@ public class JetFunction extends JetTypeParameterListOwner { return null; } + + public boolean hasBlockBody() { + return findChildByType(JetTokens.EQ) != null; + } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java new file mode 100644 index 00000000000..63d73e4dd10 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.lang.psi; + +import com.intellij.lang.ASTNode; +import org.jetbrains.annotations.NotNull; + +/** + * @author abreslav + */ +public class JetPredicateExpression extends JetQualifiedExpression { + public JetPredicateExpression(@NotNull ASTNode node) { + super(node); + } + + @Override + public void accept(JetVisitor visitor) { + visitor.visitPredicateExpression(this); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetPridcateExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetPridcateExpression.java deleted file mode 100644 index bb183cee0fb..00000000000 --- a/idea/src/org/jetbrains/jet/lang/psi/JetPridcateExpression.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.jetbrains.jet.lang.psi; - -import com.intellij.lang.ASTNode; -import org.jetbrains.annotations.NotNull; - -/** - * @author abreslav - */ -public class JetPridcateExpression extends JetQualifiedExpression { - public JetPridcateExpression(@NotNull ASTNode node) { - super(node); - } -} diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java index 9022952736d..0b7bc6568d1 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java @@ -34,8 +34,8 @@ public class JetVisitor extends PsiElementVisitor { visitNamedDeclaration(extension); } - public void visitFunction(JetFunction fun) { - visitNamedDeclaration(fun); + public void visitFunction(JetFunction function) { + visitNamedDeclaration(function); } public void visitProperty(JetProperty property) { @@ -238,6 +238,10 @@ public class JetVisitor extends PsiElementVisitor { visitQualifiedExpression(expression); } + public void visitPredicateExpression(JetPredicateExpression expression) { + visitQualifiedExpression(expression); + } + public void visitSafeQualifiedExpression(JetSafeQualifiedExpression expression) { visitQualifiedExpression(expression); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index d4451ef9de1..9ea1e53a948 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -18,19 +18,19 @@ public class ClassDescriptorResolver { @Nullable public ClassDescriptor resolveClassDescriptor(@NotNull JetScope scope, @NotNull JetClass classElement) { - TypeParameterExtensibleScope typeParameterScope = new TypeParameterExtensibleScope(scope); + ParameterExtensibleScope parameterScope = new ParameterExtensibleScope(scope); - // This call has side-effects on the typeParameterScope (fills it in) + // This call has side-effects on the parameterScope (fills it in) List typeParameters - = resolveTypeParameters(typeParameterScope, classElement.getTypeParameters()); + = resolveTypeParameters(parameterScope, classElement.getTypeParameters()); List delegationSpecifiers = classElement.getDelegationSpecifiers(); // TODO : assuming that the hierarchy is acyclic Collection superclasses = delegationSpecifiers.isEmpty() ? Collections.singleton(JetStandardClasses.getAnyType()) - : resolveTypes(typeParameterScope, delegationSpecifiers); + : resolveTypes(parameterScope, delegationSpecifiers); boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); - WritableScope members = resolveMembers(classElement, typeParameters, scope, typeParameterScope, superclasses); + WritableScope members = resolveMembers(classElement, typeParameters, scope, parameterScope, superclasses); return new ClassDescriptor( AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()), @@ -46,31 +46,94 @@ public class ClassDescriptorResolver { final JetClass classElement, List typeParameters, final JetScope outerScope, - final TypeParameterExtensibleScope typeParameterScope, + final JetScope typeParameterScope, final Collection supertypes) { - WritableScope memberDeclarations = new WritableScope(); + final WritableScope memberDeclarations = new WritableScope(); List declarations = classElement.getDeclarations(); for (JetDeclaration declaration : declarations) { - if (declaration instanceof JetProperty) { - JetProperty property = (JetProperty) declaration; - - if (property.getPropertyTypeRef() != null) { - memberDeclarations.addPropertyDescriptor(resolvePropertyDescriptor(typeParameterScope, property)); - } else { - // TODO : Caution: a cyclic dependency possible - throw new UnsupportedOperationException(); + declaration.accept(new JetVisitor() { + @Override + public void visitProperty(JetProperty property) { + if (property.getPropertyTypeRef() != null) { + memberDeclarations.addPropertyDescriptor(resolvePropertyDescriptor(typeParameterScope, property)); + } else { + // TODO : Caution: a cyclic dependency possible + throw new UnsupportedOperationException(); + } } - } else { - throw new UnsupportedOperationException(); // TODO - } + + @Override + public void visitFunction(JetFunction function) { + if (function.getReturnTypeRef() != null) { + memberDeclarations.addFunctionDescriptor(resolveFunctionDescriptor(typeParameterScope, function)); + } else { + // TODO : Caution: a cyclic dependency possible + throw new UnsupportedOperationException(); + } + } + + @Override + public void visitJetElement(JetElement elem) { + throw new UnsupportedOperationException(elem.toString()); + } + }); } return memberDeclarations; } - private static List resolveTypeParameters(TypeParameterExtensibleScope extensibleScope, List typeParameters) { + private FunctionDescriptor resolveFunctionDescriptor(JetScope scope, JetFunction function) { + ParameterExtensibleScope parameterScope = new ParameterExtensibleScope(scope); + // The two calls below have side-effects on parameterScope + List typeParameterDescriptors = resolveTypeParameters(parameterScope, function.getTypeParameters()); + List valueParameterDescriptors = resolveValueParameters(parameterScope, function.getValueParameters()); + + Type returnType; + JetTypeReference returnTypeRef = function.getReturnTypeRef(); + if (returnTypeRef != null) { + returnType = TypeResolver.INSTANCE.resolveType(parameterScope, returnTypeRef); + // TODO : CHeck type of body + } else { + JetExpression bodyExpression = function.getBodyExpression(); + assert bodyExpression != null : "No type, no body"; // TODO + // TODO : Recursion possible + returnType = JetTypeChecker.INSTANCE.getType(parameterScope, bodyExpression, function.hasBlockBody()); + } + + return new FunctionDescriptor( + AttributeResolver.INSTANCE.resolveAttributes(function.getModifierList()), + function.getName(), + typeParameterDescriptors, + valueParameterDescriptors, + returnType + ); + } + + private List resolveValueParameters(ParameterExtensibleScope parameterScope, List valueParameters) { + List result = new ArrayList(); + for (JetParameter valueParameter : valueParameters) { + JetTypeReference typeReference = valueParameter.getTypeReference(); + + assert typeReference != null : "Parameters without type annotations are not supported"; // TODO + + ValueParameterDescriptor valueParameterDescriptor = new ValueParameterDescriptorImpl( + AttributeResolver.INSTANCE.resolveAttributes(valueParameter.getModifierList()), + valueParameter.getName(), + TypeResolver.INSTANCE.resolveType(parameterScope, typeReference), + valueParameter.getDefaultValue() != null + ); + + // TODO : Default values??? + + result.add(valueParameterDescriptor); + parameterScope.addPropertyDescriptor(valueParameterDescriptor); + } + return result; + } + + private static List resolveTypeParameters(ParameterExtensibleScope extensibleScope, List typeParameters) { // TODO : When-clause List result = new ArrayList(); for (JetTypeParameter typeParameter : typeParameters) { @@ -79,7 +142,7 @@ public class ClassDescriptorResolver { return result; } - private static TypeParameterDescriptor resolveTypeParameter(TypeParameterExtensibleScope extensibleScope, JetTypeParameter typeParameter) { + private static TypeParameterDescriptor resolveTypeParameter(ParameterExtensibleScope extensibleScope, JetTypeParameter typeParameter) { JetTypeReference extendsBound = typeParameter.getExtendsBound(); TypeParameterDescriptor typeParameterDescriptor = new TypeParameterDescriptor( AttributeResolver.INSTANCE.resolveAttributes(typeParameter.getModifierList()), @@ -93,7 +156,7 @@ public class ClassDescriptorResolver { return typeParameterDescriptor; } - private static Collection resolveTypes(TypeParameterExtensibleScope extensibleScope, List delegationSpecifiers) { + private static Collection resolveTypes(ParameterExtensibleScope extensibleScope, List delegationSpecifiers) { if (delegationSpecifiers.isEmpty()) { return Collections.emptyList(); } @@ -137,10 +200,12 @@ public class ClassDescriptorResolver { type); } - private static final class TypeParameterExtensibleScope extends JetScopeAdapter { + private static final class ParameterExtensibleScope extends JetScopeAdapter { private final Map typeParameterDescriptors = new HashMap(); - private TypeParameterExtensibleScope(JetScope scope) { + private final Map propertyDescriptors = new HashMap(); + + private ParameterExtensibleScope(JetScope scope) { super(scope); } @@ -153,12 +218,29 @@ public class ClassDescriptorResolver { } @Override - public TypeParameterDescriptor getTypeParameterDescriptor(String name) { + public TypeParameterDescriptor getTypeParameter(String name) { TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptors.get(name); if (typeParameterDescriptor != null) { return typeParameterDescriptor; } - return super.getTypeParameterDescriptor(name); + return super.getTypeParameter(name); + } + + public void addPropertyDescriptor(PropertyDescriptor descriptor) { + String name = descriptor.getName(); + if (propertyDescriptors.containsKey(name)) { + throw new UnsupportedOperationException(); // TODO + } + propertyDescriptors.put(name, descriptor); + } + + @Override + public PropertyDescriptor getProperty(String name) { + PropertyDescriptor PropertyDescriptor = propertyDescriptors.get(name); + if (PropertyDescriptor != null) { + return PropertyDescriptor; + } + return super.getProperty(name); } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java b/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java index 8acc3da532e..dd80b884f5d 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/JetScope.java @@ -4,17 +4,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.types.*; -import java.util.Collection; - /** * @author abreslav */ public interface JetScope { JetScope EMPTY = new JetScopeImpl() {}; - @NotNull - Collection getMethods(String name); - @Nullable ClassDescriptor getClass(String name); @@ -28,8 +23,11 @@ public interface JetScope { NamespaceDescriptor getNamespace(String name); @Nullable - TypeParameterDescriptor getTypeParameterDescriptor(String name); + TypeParameterDescriptor getTypeParameter(String name); @NotNull Type getThisType(); + + @NotNull + OverloadDomain getOverloadDomain(Type receiverType, String referencedName); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java index af741e9450f..f59087e3770 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java @@ -3,8 +3,6 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.types.*; -import java.util.Collection; - /** * @author abreslav */ @@ -22,8 +20,8 @@ public class JetScopeAdapter implements JetScope { } @Override - public TypeParameterDescriptor getTypeParameterDescriptor(String name) { - return scope.getTypeParameterDescriptor(name); + public TypeParameterDescriptor getTypeParameter(String name) { + return scope.getTypeParameter(name); } @Override @@ -31,11 +29,6 @@ public class JetScopeAdapter implements JetScope { return scope.getNamespace(name); } - @Override - public Collection getMethods(String name) { - return scope.getMethods(name); - } - @Override public ClassDescriptor getClass(String name) { return scope.getClass(name); @@ -50,4 +43,10 @@ public class JetScopeAdapter implements JetScope { public ExtensionDescriptor getExtension(String name) { return scope.getExtension(name); } + + @NotNull + @Override + public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) { + return scope.getOverloadDomain(receiverType, referencedName); + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java index cfd9db66d01..38240e783ca 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java @@ -3,19 +3,10 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.types.*; -import java.util.Collection; -import java.util.Collections; - /** * @author abreslav */ public abstract class JetScopeImpl implements JetScope { - @Override - @NotNull - public Collection getMethods(String name) { - return Collections.emptyList(); - } - @Override public ClassDescriptor getClass(String name) { return null; @@ -37,7 +28,7 @@ public abstract class JetScopeImpl implements JetScope { } @Override - public TypeParameterDescriptor getTypeParameterDescriptor(String name) { + public TypeParameterDescriptor getTypeParameter(String name) { return null; } @@ -46,4 +37,10 @@ public abstract class JetScopeImpl implements JetScope { public Type getThisType() { return JetStandardClasses.getNothingType(); } + + @NotNull + @Override + public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) { + return OverloadDomain.EMPTY; + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/OverloadDomain.java b/idea/src/org/jetbrains/jet/lang/resolve/OverloadDomain.java new file mode 100644 index 00000000000..a8b645821bf --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/resolve/OverloadDomain.java @@ -0,0 +1,38 @@ +package org.jetbrains.jet.lang.resolve; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.types.Type; + +import java.util.List; +import java.util.Map; + +/** + * @author abreslav + */ +public interface OverloadDomain { + OverloadDomain EMPTY = new OverloadDomain() { + @Nullable + @Override + public Type getReturnTypeForNamedArguments(@NotNull List typeArguments, @NotNull Map valueArgumentTypes, @Nullable Type functionLiteralArgumentType) { + return null; + } + + @Nullable + @Override + public Type getReturnTypeForPositionedArguments(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) { + return null; + } + }; + + @Nullable + Type getReturnTypeForNamedArguments( + @NotNull List typeArguments, + @NotNull Map valueArgumentTypes, + @Nullable Type functionLiteralArgumentType); + + @Nullable + Type getReturnTypeForPositionedArguments( + @NotNull List typeArguments, + @NotNull List positionedValueArgumentTypes); +} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java b/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java index 9372d623c92..c40355a27f8 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java @@ -3,8 +3,6 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.types.*; -import java.util.Collection; - /** * @author abreslav */ @@ -18,17 +16,6 @@ public class ScopeWithReceiver extends JetScopeImpl { this.receiverTypeScope = receiverType.getMemberScope(); } - @Override - public Collection getMethods(String name) { - return receiverTypeScope.getMethods(name); - // TODO : Extension methods -// Collection outerScopeMethods = outerScope.getMethods(name); -// for (MethodDescriptor method : outerScopeMethods) { -// check for extensions for receiver type -// method.hasReceiver() -// } - } - @Override public ClassDescriptor getClass(String name) { return super.getClass(name); // TODO @@ -51,8 +38,8 @@ public class ScopeWithReceiver extends JetScopeImpl { } @Override - public TypeParameterDescriptor getTypeParameterDescriptor(String name) { - return outerScope.getTypeParameterDescriptor(name); + public TypeParameterDescriptor getTypeParameter(String name) { + return outerScope.getTypeParameter(name); } @NotNull diff --git a/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java b/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java index 3614a312af9..35624b3c5e0 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/SubstitutingScope.java @@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.types.*; -import java.util.Collection; import java.util.Map; /** @@ -28,12 +27,6 @@ public class SubstitutingScope implements JetScope { return new LazySubstitutedPropertyDescriptorImpl(property, substitutionContext); } - @NotNull - @Override - public Collection getMethods(String name) { - throw new UnsupportedOperationException(); // TODO - } - @Override public ClassDescriptor getClass(String name) { throw new UnsupportedOperationException(); // TODO @@ -50,7 +43,7 @@ public class SubstitutingScope implements JetScope { } @Override - public TypeParameterDescriptor getTypeParameterDescriptor(String name) { + public TypeParameterDescriptor getTypeParameter(String name) { throw new UnsupportedOperationException(); // TODO } @@ -59,4 +52,10 @@ public class SubstitutingScope implements JetScope { public Type getThisType() { throw new UnsupportedOperationException(); // TODO } + + @NotNull + @Override + public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) { + throw new UnsupportedOperationException(); // TODO + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index a3a90993788..8b7a2d413f2 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -46,7 +46,7 @@ public class TypeResolver { ); } else if (type.getTypeArguments().isEmpty()) { - TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameterDescriptor(type.getReferencedName()); + TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameter(type.getReferencedName()); if (typeParameterDescriptor != null) { result[0] = new TypeImpl( attributes, diff --git a/idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java b/idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java new file mode 100644 index 00000000000..ebd6c2af005 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/resolve/WritableFunctionGroup.java @@ -0,0 +1,76 @@ +package org.jetbrains.jet.lang.resolve; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.types.FunctionDescriptor; +import org.jetbrains.jet.lang.types.FunctionGroup; +import org.jetbrains.jet.lang.types.Type; +import org.jetbrains.jet.lang.types.TypeParameterDescriptor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * @author abreslav + */ +public class WritableFunctionGroup implements FunctionGroup { + private final String name; + private Collection functionDescriptors; + + public WritableFunctionGroup(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return "FunctionGroup{" + + "name='" + name + '\'' + + '}'; + } + + public void addFunction(@NotNull FunctionDescriptor functionDescriptor) { + getFunctionDescriptors().add(functionDescriptor); + } + + @NotNull + private Collection getFunctionDescriptors() { + if (functionDescriptors == null) { + functionDescriptors = new ArrayList(); + } + return functionDescriptors; + } + + @NotNull + @Override + public Collection getPossiblyApplicableFunctions(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) { + int typeArgCount = typeArguments.size(); + int valueArgCount = positionedValueArgumentTypes.size(); + Collection result = new ArrayList(); + for (FunctionDescriptor functionDescriptor : getFunctionDescriptors()) { + // TODO : type argument inference breaks this logic + if (functionDescriptor.getTypeParameters().size() == typeArgCount) { + if (functionDescriptor.getMinimumArity() <= valueArgCount && valueArgCount <= functionDescriptor.getMaximumArity()) { + result.add(substituteFunctionDescriptor(typeArguments, functionDescriptor)); + } + } + } + return result; + } + + private FunctionDescriptor substituteFunctionDescriptor(List typeArguments, FunctionDescriptor functionDescriptor) { + return new FunctionDescriptor( + // TODO : substitute + functionDescriptor.getAttributes(), + functionDescriptor.getName(), + Collections.emptyList(), // TODO : questionable + functionDescriptor.getSubstitutedValueParameters(typeArguments), + functionDescriptor.getSubstitutedReturnType(typeArguments) + ); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java b/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java index 6416995ddc7..018feb706e0 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java @@ -1,35 +1,98 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.types.*; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; /** * @author abreslav */ public class WritableScope implements JetScope { + @Nullable private Map propertyDescriptors; + @Nullable + private Map functionGroups; - public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) { + @NotNull + private Map getPropertyDescriptors() { if (propertyDescriptors == null) { propertyDescriptors = new HashMap(); } + return propertyDescriptors; + } + + public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) { + Map propertyDescriptors = getPropertyDescriptors(); assert !propertyDescriptors.containsKey(propertyDescriptor.getName()) : "Property redeclared"; propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor); } @Override public PropertyDescriptor getProperty(String name) { + @NotNull + Map propertyDescriptors = getPropertyDescriptors(); return propertyDescriptors.get(name); } + @NotNull + private Map getFunctionGroups() { + if (functionGroups == null) { + functionGroups = new HashMap(); + } + return functionGroups; + } + + public void addFunctionDescriptor(FunctionDescriptor functionDescriptor) { + String name = functionDescriptor.getName(); + Map functionGroups = getFunctionGroups(); + + @Nullable + WritableFunctionGroup functionGroup = functionGroups.get(name); + if (functionGroup == null) { + functionGroup = new WritableFunctionGroup(name); + functionGroups.put(name, functionGroup); + } + functionGroup.addFunction(functionDescriptor); + } + + @NotNull + private FunctionGroup getFunctionGroup(String name) { + WritableFunctionGroup functionGroup = getFunctionGroups().get(name); + if (functionGroup == null) { + return FunctionGroup.EMPTY; + } + return functionGroup; + } + @NotNull @Override - public Collection getMethods(String name) { - throw new UnsupportedOperationException(); // TODO + public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) { + final FunctionGroup functionGroup = getFunctionGroups().get(referencedName); + if (functionGroup == null) { + return OverloadDomain.EMPTY; + } + + return new OverloadDomain() { + @Override + public Type getReturnTypeForPositionedArguments(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) { + Collection possiblyApplicableFunctions = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes); + if (possiblyApplicableFunctions.isEmpty()) { + return null; + } + + throw new UnsupportedOperationException(); + } + + @Override + public Type getReturnTypeForNamedArguments(@NotNull List typeArguments, @NotNull Map valueArgumentTypes, @Nullable Type functionLiteralArgumentType) { + throw new UnsupportedOperationException(); // TODO + } + }; } @Override @@ -48,7 +111,7 @@ public class WritableScope implements JetScope { } @Override - public TypeParameterDescriptor getTypeParameterDescriptor(String name) { + public TypeParameterDescriptor getTypeParameter(String name) { throw new UnsupportedOperationException(); // TODO } diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java index f9e894051b8..ad5b42c53a9 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java +++ b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java @@ -2,8 +2,8 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.JetScope; +import org.jetbrains.jet.lang.resolve.OverloadDomain; -import java.util.Collection; import java.util.Collections; import java.util.List; @@ -12,12 +12,6 @@ import java.util.List; */ public class ErrorType { private static final JetScope ERROR_SCOPE = new JetScope() { - @NotNull - @Override - public Collection getMethods(String name) { - throw new UnsupportedOperationException(); // TODO - } - @Override public ClassDescriptor getClass(String name) { throw new UnsupportedOperationException(); // TODO @@ -39,7 +33,7 @@ public class ErrorType { } @Override - public TypeParameterDescriptor getTypeParameterDescriptor(String name) { + public TypeParameterDescriptor getTypeParameter(String name) { throw new UnsupportedOperationException(); // TODO } @@ -48,6 +42,12 @@ public class ErrorType { public Type getThisType() { throw new UnsupportedOperationException(); // TODO } + + @NotNull + @Override + public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) { + throw new UnsupportedOperationException(); // TODO + } }; private ErrorType() {} diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java new file mode 100644 index 00000000000..50942f6f6f7 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptor.java @@ -0,0 +1,110 @@ +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.TypeResolver; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author abreslav + */ +public class FunctionDescriptor extends MemberDescriptorImpl { + @NotNull + private final List typeParameters; + @NotNull + private final List unsubstitutedValueParameters; + @NotNull + private final Type unsubstitutedReturnType; + + public FunctionDescriptor( + @NotNull List attributes, + String name, + @NotNull List typeParameters, + @NotNull List unsubstitutedValueParameters, + @NotNull Type unsubstitutedReturnType) { + super(attributes, name); + this.typeParameters = typeParameters; + this.unsubstitutedValueParameters = unsubstitutedValueParameters; + this.unsubstitutedReturnType = unsubstitutedReturnType; + } + + @NotNull + public List getTypeParameters() { + return typeParameters; + } + + @NotNull + public List getUnsubstitutedValueParameters() { + return unsubstitutedValueParameters; + } + + @NotNull + public Type getUnsubstitutedReturnType() { + return unsubstitutedReturnType; + } + + /** @return Minimal number of arguments to be passed */ + public int getMinimumArity() { + int result = 0; + for (ValueParameterDescriptor valueParameter : unsubstitutedValueParameters) { + if (valueParameter.hasDefaultValue()) { + break; + } + result++; + } + return result; + } + + /** + * @return Maximum number of arguments that can be passed. -1 if unbound (vararg) + */ + public int getMaximumArity() { + if (unsubstitutedValueParameters.isEmpty()) { + return 0; + } + // TODO : check somewhere that vararg is only the last one, and that varargs do not have default values + + ValueParameterDescriptor lastParameter = unsubstitutedValueParameters.get(unsubstitutedValueParameters.size() - 1); + if (lastParameter.isVararg()) { + return -1; + } + return unsubstitutedValueParameters.size(); + } + + @NotNull + public List getSubstitutedValueParameters(@NotNull List typeArguments) { + List result = new ArrayList(); + Map context = createSubstitutionContext(typeArguments); + for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) { + // TODO : Lazy? + result.add(new ValueParameterDescriptorImpl( + unsubstitutedValueParameter.getAttributes(), + unsubstitutedValueParameter.getName(), + TypeSubstitutor.INSTANCE.substitute(context, unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE), + unsubstitutedValueParameter.hasDefaultValue() + )); + } + return result; + } + + private Map createSubstitutionContext(List typeArguments) { + Map result = new HashMap(); + + int typeArgumentsSize = typeArguments.size(); + assert typeArgumentsSize == typeParameters.size(); + for (int i = 0; i < typeArgumentsSize; i++) { + TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i); + Type typeArgument = typeArguments.get(i); + result.put(typeParameterDescriptor.getTypeConstructor(), new TypeProjection(typeArgument)); + } + return result; + } + + @NotNull + public Type getSubstitutedReturnType(@NotNull List typeArguments) { + return TypeSubstitutor.INSTANCE.substitute(createSubstitutionContext(typeArguments), unsubstitutedReturnType, Variance.OUT_VARIANCE); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java b/idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java new file mode 100644 index 00000000000..19fac0d1b31 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/FunctionGroup.java @@ -0,0 +1,33 @@ +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * @author abreslav + */ +public interface FunctionGroup extends Named { + FunctionGroup EMPTY = new FunctionGroup() { + @Override + public String getName() { + return ""; + } + + @NotNull + @Override + public Collection getPossiblyApplicableFunctions(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes) { + return Collections.emptySet(); + } + }; + + + @NotNull + @Override + String getName(); + + @NotNull + Collection getPossiblyApplicableFunctions(@NotNull List typeArguments, @NotNull List positionedValueArgumentTypes); +} diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 21456a606c7..6d7fea52bcb 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -4,7 +4,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.JetScope; import org.jetbrains.jet.lang.resolve.JetScopeImpl; -import org.jetbrains.jet.lang.resolve.WritableScope; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -322,12 +321,12 @@ public class JetStandardClasses { return getTupleType(Collections.emptyList(), Arrays.asList(arguments)); } - public static Type getLabeledTupleType(List attributes, List arguments) { + public static Type getLabeledTupleType(List attributes, List arguments) { // TODO return getTupleType(attributes, toTypes(arguments)); } - public static Type getLabeledTupleType(List arguments) { + public static Type getLabeledTupleType(List arguments) { // TODO return getLabeledTupleType(Collections.emptyList(), arguments); } @@ -340,9 +339,9 @@ public class JetStandardClasses { return result; } - private static List toTypes(List labeledEntries) { + private static List toTypes(List labeledEntries) { List result = new ArrayList(); - for (ParameterDescriptor entry : labeledEntries) { + for (ValueParameterDescriptor entry : labeledEntries) { result.add(entry.getType()); } return result; diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index e71d70feaf4..f9bbf6471d9 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -265,6 +265,7 @@ public class JetTypeChecker { @Override public void visitDotQualifiedExpression(JetDotQualifiedExpression expression) { + // TODO : functions JetExpression receiverExpression = expression.getReceiverExpression(); JetExpression selectorExpression = expression.getSelectorExpression(); Type receiverType = getType(scope, receiverExpression, false); @@ -272,6 +273,96 @@ public class JetTypeChecker { result[0] = getType(compositeScope, selectorExpression, false); } + @Override + public void visitCallExpression(JetCallExpression expression) { + JetExpression calleeExpression = expression.getCalleeExpression(); + + // 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(); + boolean someNamed = false; + for (JetArgument argument : valueArguments) { + if (argument.isNamed()) { + someNamed = true; + break; + } + } + List functionLiteralArguments = expression.getFunctionLiteralArguments(); + + JetExpression functionLiteralArgument = functionLiteralArguments.isEmpty() ? null : functionLiteralArguments.get(0); + assert functionLiteralArguments.size() <= 1; + + OverloadDomain overloadDomain = getOverloadDomain(scope, calleeExpression); + if (someNamed) { + // TODO : check that all are named + throw new UnsupportedOperationException(); // TODO + +// result[0] = overloadDomain.getReturnTypeForNamedArguments(typeArguments, valueArguments, functionLiteralArgument); + } else { + throw new UnsupportedOperationException(); // TODO +// List positionedValueArguments = new ArrayList(); +// for (JetArgument argument : valueArguments) { +// positionedValueArguments.add(argument.getArgumentExpression()); +// } +// positionedValueArguments.addAll(functionLiteralArguments); +// result[0] = overloadDomain.getReturnTypeForPositionedArguments(typeArguments, positionedValueArguments); + } + } + + @Override + public void visitJetElement(JetElement elem) { + throw new IllegalArgumentException("Unsupported element: " + elem); + } + }); + return result[0]; + } + + private OverloadDomain getOverloadDomain(final JetScope scope, JetExpression calleeExpression) { + final OverloadDomain[] result = new OverloadDomain[1]; + calleeExpression.accept(new JetVisitor() { + + @Override + public void visitHashQualifiedExpression(JetHashQualifiedExpression expression) { + // a#b -- create a domain for all overloads of b in a + throw new UnsupportedOperationException(); // TODO + } + + @Override + public void visitPredicateExpression(JetPredicateExpression expression) { + // overload lookup for checking, but the type is receiver's type + nullable + throw new UnsupportedOperationException(); // TODO + } + + @Override + public void visitQualifiedExpression(JetQualifiedExpression expression) { + // . or ?. + JetExpression selectorExpression = expression.getSelectorExpression(); + if (selectorExpression instanceof JetReferenceExpression) { + JetReferenceExpression referenceExpression = (JetReferenceExpression) selectorExpression; + + Type receiverType = getType(scope, expression.getReceiverExpression(), false); + result[0] = scope.getOverloadDomain(receiverType, referenceExpression.getReferencedName()); + } else { + throw new UnsupportedOperationException(); // TODO + } + } + + @Override + public void visitReferenceExpression(JetReferenceExpression expression) { + // a -- create a hierarchical lookup domain for this.a + throw new UnsupportedOperationException(); // TODO + } + + @Override + public void visitExpression(JetExpression expression) { + // create a dummy domain for the type of e + throw new UnsupportedOperationException(); // TODO + } + @Override public void visitJetElement(JetElement elem) { throw new IllegalArgumentException("Unsupported element: " + elem); @@ -444,9 +535,7 @@ public class JetTypeChecker { Set commonSuperclasses = null; List order = null; - for (Iterator iterator = types.iterator(); iterator.hasNext();) { - Type type = iterator.next(); - + for (Type type : types) { Set visited = new HashSet(); order = dfs(type, visited, new DfsNodeHandler>() { @@ -477,7 +566,8 @@ public class JetTypeChecker { if (commonSuperclasses == null) { commonSuperclasses = visited; - } else { + } + else { commonSuperclasses.retainAll(visited); } } diff --git a/idea/src/org/jetbrains/jet/lang/types/MethodDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/MethodDescriptor.java deleted file mode 100644 index 6dd635bdae1..00000000000 --- a/idea/src/org/jetbrains/jet/lang/types/MethodDescriptor.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.jet.lang.types; - -/** - * @author abreslav - */ -public class MethodDescriptor { -} diff --git a/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java index 999531558d6..6ae9c0cf6a9 100644 --- a/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java @@ -12,7 +12,7 @@ public class NamespaceDescriptor implements NamespaceDomain { throw new UnsupportedOperationException(); // TODO } - public Collection getMethods(String name) { + public Collection getMethods(String name) { throw new UnsupportedOperationException(); // TODO } diff --git a/idea/src/org/jetbrains/jet/lang/types/ParameterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/ParameterDescriptor.java deleted file mode 100644 index a748636e0fb..00000000000 --- a/idea/src/org/jetbrains/jet/lang/types/ParameterDescriptor.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.jetbrains.jet.lang.types; - -import java.util.List; - -/** - * @author abreslav - */ -public class ParameterDescriptor extends AnnotatedImpl { - private final Type type; - private final String name; - - public ParameterDescriptor(List attributes, Type type, String name) { - super(attributes); - this.type = type; - this.name = name; - } - - public Type getType() { - return type; - } - - public String getName() { - return name; - } - -} diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java index 9f04bd494cc..97000f65e14 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java @@ -13,10 +13,6 @@ public class PropertyDescriptorImpl extends MemberDescriptorImpl implements Prop this.type = type; } - public PropertyDescriptorImpl(List attributes, String name) { - this(attributes, name, null); - } - @Override public Type getType() { return type; diff --git a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java new file mode 100644 index 00000000000..61f8d903c7c --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java @@ -0,0 +1,10 @@ +package org.jetbrains.jet.lang.types; + +/** + * @author abreslav + */ +public interface ValueParameterDescriptor extends PropertyDescriptor { + boolean hasDefaultValue(); + boolean isRef(); + boolean isVararg(); +} diff --git a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java new file mode 100644 index 00000000000..db385d8aa85 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java @@ -0,0 +1,30 @@ +package org.jetbrains.jet.lang.types; + +import java.util.List; + +/** + * @author abreslav + */ +public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl implements ValueParameterDescriptor { + private final boolean hasDefaultValue; + + public ValueParameterDescriptorImpl(List attributes, String name, Type type, boolean hasDefaultValue) { + super(attributes, name, type); + this.hasDefaultValue = hasDefaultValue; + } + + @Override + public boolean hasDefaultValue() { + return hasDefaultValue; + } + + @Override + public boolean isRef() { + throw new UnsupportedOperationException(); // TODO + } + + @Override + public boolean isVararg() { + throw new UnsupportedOperationException(); // TODO + } +} diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 8f9a6e5f1ad..8c7e873472f 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -317,6 +317,12 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { assertType("new Props().p.p", "Int"); } + public void testOverloads() throws Exception { + assertType("new Functions().f()", "Unit"); + assertType("new Functions().f(1)", "Int"); + assertType("new Functions().f(1d)", "Any"); + } + // public void testImplicitConversions() throws Exception { // assertConvertibleTo("1", JetStandardClasses.getByteType()); // } @@ -421,6 +427,11 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { "open class Derived_outT : Base_outT", "class Properties { val p : Int }", "class Props { val p : T }", + "class Functions { " + + "fun f() : Unit {} " + + "fun f(a : Int) : Int {} " + + "fun f(a : T) : Any {} " + + "}" }; public static JetScope BASIC_SCOPE = new JetScopeAdapter(JetStandardClasses.STANDARD_CLASSES) {