提交 986e703f 编写于 作者: A Andrey Breslav

Working on overloads. The corresponding test fails. That's allright: the work is not finished yet.

上级 3184d972
......@@ -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);
......
......@@ -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.
}
});
}
......
......@@ -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<JetArgument> getArguments() {
JetArgumentList list = getArgumentList();
public List<JetExpression> getFunctionLiteralArguments() {
return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL);
}
@NotNull
public List<JetArgument> getValueArguments() {
JetArgumentList list = getValueArgumentList();
return list != null ? list.getArguments() : Collections.<JetArgument>emptyList();
}
......
......@@ -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<JetParameter> getParameters() {
JetParameterList list = getParameterList();
public List<JetParameter> getValueParameters() {
JetParameterList list = getValueParameterList();
return list != null ? list.getParameters() : Collections.<JetParameter>emptyList();
}
......@@ -73,4 +73,8 @@ public class JetFunction extends JetTypeParameterListOwner {
return null;
}
public boolean hasBlockBody() {
return findChildByType(JetTokens.EQ) != null;
}
}
......@@ -6,8 +6,13 @@ import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class JetPridcateExpression extends JetQualifiedExpression {
public JetPridcateExpression(@NotNull ASTNode node) {
public class JetPredicateExpression extends JetQualifiedExpression {
public JetPredicateExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public void accept(JetVisitor visitor) {
visitor.visitPredicateExpression(this);
}
}
......@@ -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);
}
......
......@@ -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<TypeParameterDescriptor> typeParameters
= resolveTypeParameters(typeParameterScope, classElement.getTypeParameters());
= resolveTypeParameters(parameterScope, classElement.getTypeParameters());
List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers();
// TODO : assuming that the hierarchy is acyclic
Collection<? extends Type> 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<TypeParameterDescriptor> typeParameters,
final JetScope outerScope,
final TypeParameterExtensibleScope typeParameterScope,
final JetScope typeParameterScope,
final Collection<? extends Type> supertypes) {
WritableScope memberDeclarations = new WritableScope();
final WritableScope memberDeclarations = new WritableScope();
List<JetDeclaration> 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<TypeParameterDescriptor> resolveTypeParameters(TypeParameterExtensibleScope extensibleScope, List<JetTypeParameter> typeParameters) {
private FunctionDescriptor resolveFunctionDescriptor(JetScope scope, JetFunction function) {
ParameterExtensibleScope parameterScope = new ParameterExtensibleScope(scope);
// The two calls below have side-effects on parameterScope
List<TypeParameterDescriptor> typeParameterDescriptors = resolveTypeParameters(parameterScope, function.getTypeParameters());
List<ValueParameterDescriptor> 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<ValueParameterDescriptor> resolveValueParameters(ParameterExtensibleScope parameterScope, List<JetParameter> valueParameters) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
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<TypeParameterDescriptor> resolveTypeParameters(ParameterExtensibleScope extensibleScope, List<JetTypeParameter> typeParameters) {
// TODO : When-clause
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>();
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<? extends Type> resolveTypes(TypeParameterExtensibleScope extensibleScope, List<JetDelegationSpecifier> delegationSpecifiers) {
private static Collection<? extends Type> resolveTypes(ParameterExtensibleScope extensibleScope, List<JetDelegationSpecifier> 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<String, TypeParameterDescriptor> typeParameterDescriptors = new HashMap<String, TypeParameterDescriptor>();
private TypeParameterExtensibleScope(JetScope scope) {
private final Map<String, PropertyDescriptor> propertyDescriptors = new HashMap<String, PropertyDescriptor>();
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);
}
}
......
......@@ -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<MethodDescriptor> 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);
}
......@@ -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<MethodDescriptor> 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);
}
}
......@@ -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<MethodDescriptor> 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;
}
}
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<Type> typeArguments, @NotNull Map<String, Type> valueArgumentTypes, @Nullable Type functionLiteralArgumentType) {
return null;
}
@Nullable
@Override
public Type getReturnTypeForPositionedArguments(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) {
return null;
}
};
@Nullable
Type getReturnTypeForNamedArguments(
@NotNull List<Type> typeArguments,
@NotNull Map<String, Type> valueArgumentTypes,
@Nullable Type functionLiteralArgumentType);
@Nullable
Type getReturnTypeForPositionedArguments(
@NotNull List<Type> typeArguments,
@NotNull List<Type> positionedValueArgumentTypes);
}
......@@ -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<MethodDescriptor> getMethods(String name) {
return receiverTypeScope.getMethods(name);
// TODO : Extension methods
// Collection<MethodDescriptor> 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
......
......@@ -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<MethodDescriptor> 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
}
}
......@@ -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,
......
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<FunctionDescriptor> 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<FunctionDescriptor> getFunctionDescriptors() {
if (functionDescriptors == null) {
functionDescriptors = new ArrayList<FunctionDescriptor>();
}
return functionDescriptors;
}
@NotNull
@Override
public Collection<FunctionDescriptor> getPossiblyApplicableFunctions(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) {
int typeArgCount = typeArguments.size();
int valueArgCount = positionedValueArgumentTypes.size();
Collection<FunctionDescriptor> result = new ArrayList<FunctionDescriptor>();
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<Type> typeArguments, FunctionDescriptor functionDescriptor) {
return new FunctionDescriptor(
// TODO : substitute
functionDescriptor.getAttributes(),
functionDescriptor.getName(),
Collections.<TypeParameterDescriptor>emptyList(), // TODO : questionable
functionDescriptor.getSubstitutedValueParameters(typeArguments),
functionDescriptor.getSubstitutedReturnType(typeArguments)
);
}
}
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<String, PropertyDescriptor> propertyDescriptors;
@Nullable
private Map<String, WritableFunctionGroup> functionGroups;
public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) {
@NotNull
private Map<String, PropertyDescriptor> getPropertyDescriptors() {
if (propertyDescriptors == null) {
propertyDescriptors = new HashMap<String, PropertyDescriptor>();
}
return propertyDescriptors;
}
public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) {
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
assert !propertyDescriptors.containsKey(propertyDescriptor.getName()) : "Property redeclared";
propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
}
@Override
public PropertyDescriptor getProperty(String name) {
@NotNull
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
return propertyDescriptors.get(name);
}
@NotNull
private Map<String, WritableFunctionGroup> getFunctionGroups() {
if (functionGroups == null) {
functionGroups = new HashMap<String, WritableFunctionGroup>();
}
return functionGroups;
}
public void addFunctionDescriptor(FunctionDescriptor functionDescriptor) {
String name = functionDescriptor.getName();
Map<String, WritableFunctionGroup> 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<MethodDescriptor> 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<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) {
Collection<FunctionDescriptor> possiblyApplicableFunctions = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes);
if (possiblyApplicableFunctions.isEmpty()) {
return null;
}
throw new UnsupportedOperationException();
}
@Override
public Type getReturnTypeForNamedArguments(@NotNull List<Type> typeArguments, @NotNull Map<String, Type> 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
}
......
......@@ -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<MethodDescriptor> 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() {}
......
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<TypeParameterDescriptor> typeParameters;
@NotNull
private final List<ValueParameterDescriptor> unsubstitutedValueParameters;
@NotNull
private final Type unsubstitutedReturnType;
public FunctionDescriptor(
@NotNull List<Attribute> attributes,
String name,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
@NotNull Type unsubstitutedReturnType) {
super(attributes, name);
this.typeParameters = typeParameters;
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
this.unsubstitutedReturnType = unsubstitutedReturnType;
}
@NotNull
public List<TypeParameterDescriptor> getTypeParameters() {
return typeParameters;
}
@NotNull
public List<ValueParameterDescriptor> 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<ValueParameterDescriptor> getSubstitutedValueParameters(@NotNull List<Type> typeArguments) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
Map<TypeConstructor,TypeProjection> 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<TypeConstructor, TypeProjection> createSubstitutionContext(List<Type> typeArguments) {
Map<TypeConstructor,TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
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<Type> typeArguments) {
return TypeSubstitutor.INSTANCE.substitute(createSubstitutionContext(typeArguments), unsubstitutedReturnType, Variance.OUT_VARIANCE);
}
}
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 "<empty>";
}
@NotNull
@Override
public Collection<FunctionDescriptor> getPossiblyApplicableFunctions(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) {
return Collections.emptySet();
}
};
@NotNull
@Override
String getName();
@NotNull
Collection<FunctionDescriptor> getPossiblyApplicableFunctions(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes);
}
......@@ -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.<Attribute>emptyList(), Arrays.asList(arguments));
}
public static Type getLabeledTupleType(List<Attribute> attributes, List<ParameterDescriptor> arguments) {
public static Type getLabeledTupleType(List<Attribute> attributes, List<ValueParameterDescriptor> arguments) {
// TODO
return getTupleType(attributes, toTypes(arguments));
}
public static Type getLabeledTupleType(List<ParameterDescriptor> arguments) {
public static Type getLabeledTupleType(List<ValueParameterDescriptor> arguments) {
// TODO
return getLabeledTupleType(Collections.<Attribute>emptyList(), arguments);
}
......@@ -340,9 +339,9 @@ public class JetStandardClasses {
return result;
}
private static List<Type> toTypes(List<ParameterDescriptor> labeledEntries) {
private static List<Type> toTypes(List<ValueParameterDescriptor> labeledEntries) {
List<Type> result = new ArrayList<Type>();
for (ParameterDescriptor entry : labeledEntries) {
for (ValueParameterDescriptor entry : labeledEntries) {
result.add(entry.getType());
}
return result;
......
......@@ -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<JetTypeProjection> typeArguments = expression.getTypeArguments();
List<JetArgument> valueArguments = expression.getValueArguments();
boolean someNamed = false;
for (JetArgument argument : valueArguments) {
if (argument.isNamed()) {
someNamed = true;
break;
}
}
List<JetExpression> 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<JetExpression> positionedValueArguments = new ArrayList<JetExpression>();
// 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) {
// <e> 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<TypeConstructor> commonSuperclasses = null;
List<TypeConstructor> order = null;
for (Iterator<Type> iterator = types.iterator(); iterator.hasNext();) {
Type type = iterator.next();
for (Type type : types) {
Set<TypeConstructor> visited = new HashSet<TypeConstructor>();
order = dfs(type, visited, new DfsNodeHandler<List<TypeConstructor>>() {
......@@ -477,7 +566,8 @@ public class JetTypeChecker {
if (commonSuperclasses == null) {
commonSuperclasses = visited;
} else {
}
else {
commonSuperclasses.retainAll(visited);
}
}
......
......@@ -12,7 +12,7 @@ public class NamespaceDescriptor implements NamespaceDomain {
throw new UnsupportedOperationException(); // TODO
}
public Collection<MethodDescriptor> getMethods(String name) {
public Collection<FunctionDescriptor> getMethods(String name) {
throw new UnsupportedOperationException(); // TODO
}
......
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<Attribute> attributes, Type type, String name) {
super(attributes);
this.type = type;
this.name = name;
}
public Type getType() {
return type;
}
public String getName() {
return name;
}
}
......@@ -13,10 +13,6 @@ public class PropertyDescriptorImpl extends MemberDescriptorImpl implements Prop
this.type = type;
}
public PropertyDescriptorImpl(List<Attribute> attributes, String name) {
this(attributes, name, null);
}
@Override
public Type getType() {
return type;
......
......@@ -3,5 +3,8 @@ package org.jetbrains.jet.lang.types;
/**
* @author abreslav
*/
public class MethodDescriptor {
public interface ValueParameterDescriptor extends PropertyDescriptor {
boolean hasDefaultValue();
boolean isRef();
boolean isVararg();
}
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<Attribute> 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
}
}
......@@ -317,6 +317,12 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
assertType("new Props<Properties>().p.p", "Int");
}
public void testOverloads() throws Exception {
assertType("new Functions<String>().f()", "Unit");
assertType("new Functions<String>().f(1)", "Int");
assertType("new Functions<String>().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<out T> : Base_outT<T>",
"class Properties { val p : Int }",
"class Props<T> { val p : T }",
"class Functions<T> { " +
"fun f() : Unit {} " +
"fun f(a : Int) : Int {} " +
"fun f(a : T) : Any {} " +
"}"
};
public static JetScope BASIC_SCOPE = new JetScopeAdapter(JetStandardClasses.STANDARD_CLASSES) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册