Working on overloads. The corresponding test fails. That's allright: the work is not finished yet.
This commit is contained in:
@@ -105,7 +105,7 @@ public interface JetNodeTypes {
|
|||||||
JetNodeType DOT_QIALIFIED_EXPRESSION = new JetNodeType("DOT_QIALIFIED_EXPRESSION", JetDotQualifiedExpression.class);
|
JetNodeType DOT_QIALIFIED_EXPRESSION = new JetNodeType("DOT_QIALIFIED_EXPRESSION", JetDotQualifiedExpression.class);
|
||||||
JetNodeType HASH_QIALIFIED_EXPRESSION = new JetNodeType("HASH_QIALIFIED_EXPRESSION", JetHashQualifiedExpression.class);
|
JetNodeType HASH_QIALIFIED_EXPRESSION = new JetNodeType("HASH_QIALIFIED_EXPRESSION", JetHashQualifiedExpression.class);
|
||||||
JetNodeType SAFE_ACCESS_EXPRESSION = new JetNodeType("SAFE_ACCESS_EXPRESSION", JetSafeQualifiedExpression.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 DECOMPOSER_PATTERN = new JetNodeType("DECOMPOSER_PATTERN");
|
||||||
JetNodeType TUPLE_PATTERN = new JetNodeType("TUPLE_PATTERN");
|
JetNodeType TUPLE_PATTERN = new JetNodeType("TUPLE_PATTERN");
|
||||||
JetNodeType OBJECT_LITERAL = new JetNodeType("OBJECT_LITERAL", JetObjectLiteralExpression.class);
|
JetNodeType OBJECT_LITERAL = new JetNodeType("OBJECT_LITERAL", JetObjectLiteralExpression.class);
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ public class JetPsiChecker implements Annotator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFunction(JetFunction fun) {
|
public void visitFunction(JetFunction function) {
|
||||||
super.visitFunction(fun); //To change body of overridden methods use File | Settings | File Templates.
|
super.visitFunction(function); //To change body of overridden methods use File | Settings | File Templates.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class JetCallExpression extends JetExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public JetArgumentList getArgumentList() {
|
public JetArgumentList getValueArgumentList() {
|
||||||
return (JetArgumentList) findChildByType(JetNodeTypes.VALUE_ARGUMENT_LIST);
|
return (JetArgumentList) findChildByType(JetNodeTypes.VALUE_ARGUMENT_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,8 +39,13 @@ public class JetCallExpression extends JetExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetArgument> getArguments() {
|
public List<JetExpression> getFunctionLiteralArguments() {
|
||||||
JetArgumentList list = getArgumentList();
|
return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<JetArgument> getValueArguments() {
|
||||||
|
JetArgumentList list = getValueArgumentList();
|
||||||
return list != null ? list.getArguments() : Collections.<JetArgument>emptyList();
|
return list != null ? list.getArguments() : Collections.<JetArgument>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ public class JetFunction extends JetTypeParameterListOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable @IfNotParsed
|
@Nullable @IfNotParsed
|
||||||
public JetParameterList getParameterList() {
|
public JetParameterList getValueParameterList() {
|
||||||
return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST);
|
return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetParameter> getParameters() {
|
public List<JetParameter> getValueParameters() {
|
||||||
JetParameterList list = getParameterList();
|
JetParameterList list = getValueParameterList();
|
||||||
return list != null ? list.getParameters() : Collections.<JetParameter>emptyList();
|
return list != null ? list.getParameters() : Collections.<JetParameter>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,4 +73,8 @@ public class JetFunction extends JetTypeParameterListOwner {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasBlockBody() {
|
||||||
|
return findChildByType(JetTokens.EQ) != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -34,8 +34,8 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
visitNamedDeclaration(extension);
|
visitNamedDeclaration(extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitFunction(JetFunction fun) {
|
public void visitFunction(JetFunction function) {
|
||||||
visitNamedDeclaration(fun);
|
visitNamedDeclaration(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitProperty(JetProperty property) {
|
public void visitProperty(JetProperty property) {
|
||||||
@@ -238,6 +238,10 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
visitQualifiedExpression(expression);
|
visitQualifiedExpression(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitPredicateExpression(JetPredicateExpression expression) {
|
||||||
|
visitQualifiedExpression(expression);
|
||||||
|
}
|
||||||
|
|
||||||
public void visitSafeQualifiedExpression(JetSafeQualifiedExpression expression) {
|
public void visitSafeQualifiedExpression(JetSafeQualifiedExpression expression) {
|
||||||
visitQualifiedExpression(expression);
|
visitQualifiedExpression(expression);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,19 +18,19 @@ public class ClassDescriptorResolver {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public ClassDescriptor resolveClassDescriptor(@NotNull JetScope scope, @NotNull JetClass classElement) {
|
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
|
List<TypeParameterDescriptor> typeParameters
|
||||||
= resolveTypeParameters(typeParameterScope, classElement.getTypeParameters());
|
= resolveTypeParameters(parameterScope, classElement.getTypeParameters());
|
||||||
|
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers();
|
List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers();
|
||||||
// TODO : assuming that the hierarchy is acyclic
|
// TODO : assuming that the hierarchy is acyclic
|
||||||
Collection<? extends Type> superclasses = delegationSpecifiers.isEmpty()
|
Collection<? extends Type> superclasses = delegationSpecifiers.isEmpty()
|
||||||
? Collections.singleton(JetStandardClasses.getAnyType())
|
? Collections.singleton(JetStandardClasses.getAnyType())
|
||||||
: resolveTypes(typeParameterScope, delegationSpecifiers);
|
: resolveTypes(parameterScope, delegationSpecifiers);
|
||||||
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
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(
|
return new ClassDescriptor(
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()),
|
AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()),
|
||||||
@@ -46,31 +46,94 @@ public class ClassDescriptorResolver {
|
|||||||
final JetClass classElement,
|
final JetClass classElement,
|
||||||
List<TypeParameterDescriptor> typeParameters,
|
List<TypeParameterDescriptor> typeParameters,
|
||||||
final JetScope outerScope,
|
final JetScope outerScope,
|
||||||
final TypeParameterExtensibleScope typeParameterScope,
|
final JetScope typeParameterScope,
|
||||||
final Collection<? extends Type> supertypes) {
|
final Collection<? extends Type> supertypes) {
|
||||||
|
|
||||||
WritableScope memberDeclarations = new WritableScope();
|
final WritableScope memberDeclarations = new WritableScope();
|
||||||
|
|
||||||
List<JetDeclaration> declarations = classElement.getDeclarations();
|
List<JetDeclaration> declarations = classElement.getDeclarations();
|
||||||
for (JetDeclaration declaration : declarations) {
|
for (JetDeclaration declaration : declarations) {
|
||||||
if (declaration instanceof JetProperty) {
|
declaration.accept(new JetVisitor() {
|
||||||
JetProperty property = (JetProperty) declaration;
|
@Override
|
||||||
|
public void visitProperty(JetProperty property) {
|
||||||
if (property.getPropertyTypeRef() != null) {
|
if (property.getPropertyTypeRef() != null) {
|
||||||
memberDeclarations.addPropertyDescriptor(resolvePropertyDescriptor(typeParameterScope, property));
|
memberDeclarations.addPropertyDescriptor(resolvePropertyDescriptor(typeParameterScope, property));
|
||||||
} else {
|
} else {
|
||||||
// TODO : Caution: a cyclic dependency possible
|
// TODO : Caution: a cyclic dependency possible
|
||||||
throw new UnsupportedOperationException();
|
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;
|
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
|
// TODO : When-clause
|
||||||
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>();
|
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>();
|
||||||
for (JetTypeParameter typeParameter : typeParameters) {
|
for (JetTypeParameter typeParameter : typeParameters) {
|
||||||
@@ -79,7 +142,7 @@ public class ClassDescriptorResolver {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TypeParameterDescriptor resolveTypeParameter(TypeParameterExtensibleScope extensibleScope, JetTypeParameter typeParameter) {
|
private static TypeParameterDescriptor resolveTypeParameter(ParameterExtensibleScope extensibleScope, JetTypeParameter typeParameter) {
|
||||||
JetTypeReference extendsBound = typeParameter.getExtendsBound();
|
JetTypeReference extendsBound = typeParameter.getExtendsBound();
|
||||||
TypeParameterDescriptor typeParameterDescriptor = new TypeParameterDescriptor(
|
TypeParameterDescriptor typeParameterDescriptor = new TypeParameterDescriptor(
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(typeParameter.getModifierList()),
|
AttributeResolver.INSTANCE.resolveAttributes(typeParameter.getModifierList()),
|
||||||
@@ -93,7 +156,7 @@ public class ClassDescriptorResolver {
|
|||||||
return typeParameterDescriptor;
|
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()) {
|
if (delegationSpecifiers.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -137,10 +200,12 @@ public class ClassDescriptorResolver {
|
|||||||
type);
|
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 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);
|
super(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,12 +218,29 @@ public class ClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
public TypeParameterDescriptor getTypeParameter(String name) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptors.get(name);
|
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptors.get(name);
|
||||||
if (typeParameterDescriptor != null) {
|
if (typeParameterDescriptor != null) {
|
||||||
return typeParameterDescriptor;
|
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.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public interface JetScope {
|
public interface JetScope {
|
||||||
JetScope EMPTY = new JetScopeImpl() {};
|
JetScope EMPTY = new JetScopeImpl() {};
|
||||||
|
|
||||||
@NotNull
|
|
||||||
Collection<MethodDescriptor> getMethods(String name);
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
ClassDescriptor getClass(String name);
|
ClassDescriptor getClass(String name);
|
||||||
|
|
||||||
@@ -28,8 +23,11 @@ public interface JetScope {
|
|||||||
NamespaceDescriptor getNamespace(String name);
|
NamespaceDescriptor getNamespace(String name);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
TypeParameterDescriptor getTypeParameterDescriptor(String name);
|
TypeParameterDescriptor getTypeParameter(String name);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
Type getThisType();
|
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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
@@ -22,8 +20,8 @@ public class JetScopeAdapter implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
public TypeParameterDescriptor getTypeParameter(String name) {
|
||||||
return scope.getTypeParameterDescriptor(name);
|
return scope.getTypeParameter(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,11 +29,6 @@ public class JetScopeAdapter implements JetScope {
|
|||||||
return scope.getNamespace(name);
|
return scope.getNamespace(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
|
||||||
return scope.getMethods(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(String name) {
|
||||||
return scope.getClass(name);
|
return scope.getClass(name);
|
||||||
@@ -50,4 +43,10 @@ public class JetScopeAdapter implements JetScope {
|
|||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
return scope.getExtension(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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public abstract class JetScopeImpl implements JetScope {
|
public abstract class JetScopeImpl implements JetScope {
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(String name) {
|
||||||
return null;
|
return null;
|
||||||
@@ -37,7 +28,7 @@ public abstract class JetScopeImpl implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
public TypeParameterDescriptor getTypeParameter(String name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,4 +37,10 @@ public abstract class JetScopeImpl implements JetScope {
|
|||||||
public Type getThisType() {
|
public Type getThisType() {
|
||||||
return JetStandardClasses.getNothingType();
|
return JetStandardClasses.getNothingType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
||||||
|
return OverloadDomain.EMPTY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
@@ -18,17 +16,6 @@ public class ScopeWithReceiver extends JetScopeImpl {
|
|||||||
this.receiverTypeScope = receiverType.getMemberScope();
|
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
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(String name) {
|
||||||
return super.getClass(name); // TODO
|
return super.getClass(name); // TODO
|
||||||
@@ -51,8 +38,8 @@ public class ScopeWithReceiver extends JetScopeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
public TypeParameterDescriptor getTypeParameter(String name) {
|
||||||
return outerScope.getTypeParameterDescriptor(name);
|
return outerScope.getTypeParameter(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,12 +27,6 @@ public class SubstitutingScope implements JetScope {
|
|||||||
return new LazySubstitutedPropertyDescriptorImpl(property, substitutionContext);
|
return new LazySubstitutedPropertyDescriptorImpl(property, substitutionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
@@ -50,7 +43,7 @@ public class SubstitutingScope implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
public TypeParameterDescriptor getTypeParameter(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,4 +52,10 @@ public class SubstitutingScope implements JetScope {
|
|||||||
public Type getThisType() {
|
public Type getThisType() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
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()) {
|
else if (type.getTypeArguments().isEmpty()) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameterDescriptor(type.getReferencedName());
|
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameter(type.getReferencedName());
|
||||||
if (typeParameterDescriptor != null) {
|
if (typeParameterDescriptor != null) {
|
||||||
result[0] = new TypeImpl(
|
result[0] = new TypeImpl(
|
||||||
attributes,
|
attributes,
|
||||||
|
|||||||
@@ -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<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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,35 +1,98 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class WritableScope implements JetScope {
|
public class WritableScope implements JetScope {
|
||||||
|
@Nullable
|
||||||
private Map<String, PropertyDescriptor> propertyDescriptors;
|
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) {
|
if (propertyDescriptors == null) {
|
||||||
propertyDescriptors = new HashMap<String, PropertyDescriptor>();
|
propertyDescriptors = new HashMap<String, PropertyDescriptor>();
|
||||||
}
|
}
|
||||||
|
return propertyDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) {
|
||||||
|
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
|
||||||
assert !propertyDescriptors.containsKey(propertyDescriptor.getName()) : "Property redeclared";
|
assert !propertyDescriptors.containsKey(propertyDescriptor.getName()) : "Property redeclared";
|
||||||
propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
|
propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(String name) {
|
||||||
|
@NotNull
|
||||||
|
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
|
||||||
return propertyDescriptors.get(name);
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
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
|
@Override
|
||||||
@@ -48,7 +111,7 @@ public class WritableScope implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
public TypeParameterDescriptor getTypeParameter(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package org.jetbrains.jet.lang.types;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -12,12 +12,6 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ErrorType {
|
public class ErrorType {
|
||||||
private static final JetScope ERROR_SCOPE = new JetScope() {
|
private static final JetScope ERROR_SCOPE = new JetScope() {
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
@@ -39,7 +33,7 @@ public class ErrorType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
public TypeParameterDescriptor getTypeParameter(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +42,12 @@ public class ErrorType {
|
|||||||
public Type getThisType() {
|
public Type getThisType() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public OverloadDomain getOverloadDomain(Type receiverType, String referencedName) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private ErrorType() {}
|
private ErrorType() {}
|
||||||
|
|||||||
@@ -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<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 "<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.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScopeImpl;
|
import org.jetbrains.jet.lang.resolve.JetScopeImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -322,12 +321,12 @@ public class JetStandardClasses {
|
|||||||
return getTupleType(Collections.<Attribute>emptyList(), Arrays.asList(arguments));
|
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
|
// TODO
|
||||||
return getTupleType(attributes, toTypes(arguments));
|
return getTupleType(attributes, toTypes(arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type getLabeledTupleType(List<ParameterDescriptor> arguments) {
|
public static Type getLabeledTupleType(List<ValueParameterDescriptor> arguments) {
|
||||||
// TODO
|
// TODO
|
||||||
return getLabeledTupleType(Collections.<Attribute>emptyList(), arguments);
|
return getLabeledTupleType(Collections.<Attribute>emptyList(), arguments);
|
||||||
}
|
}
|
||||||
@@ -340,9 +339,9 @@ public class JetStandardClasses {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Type> toTypes(List<ParameterDescriptor> labeledEntries) {
|
private static List<Type> toTypes(List<ValueParameterDescriptor> labeledEntries) {
|
||||||
List<Type> result = new ArrayList<Type>();
|
List<Type> result = new ArrayList<Type>();
|
||||||
for (ParameterDescriptor entry : labeledEntries) {
|
for (ValueParameterDescriptor entry : labeledEntries) {
|
||||||
result.add(entry.getType());
|
result.add(entry.getType());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -265,6 +265,7 @@ public class JetTypeChecker {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDotQualifiedExpression(JetDotQualifiedExpression expression) {
|
public void visitDotQualifiedExpression(JetDotQualifiedExpression expression) {
|
||||||
|
// TODO : functions
|
||||||
JetExpression receiverExpression = expression.getReceiverExpression();
|
JetExpression receiverExpression = expression.getReceiverExpression();
|
||||||
JetExpression selectorExpression = expression.getSelectorExpression();
|
JetExpression selectorExpression = expression.getSelectorExpression();
|
||||||
Type receiverType = getType(scope, receiverExpression, false);
|
Type receiverType = getType(scope, receiverExpression, false);
|
||||||
@@ -272,6 +273,96 @@ public class JetTypeChecker {
|
|||||||
result[0] = getType(compositeScope, selectorExpression, false);
|
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
|
@Override
|
||||||
public void visitJetElement(JetElement elem) {
|
public void visitJetElement(JetElement elem) {
|
||||||
throw new IllegalArgumentException("Unsupported element: " + elem);
|
throw new IllegalArgumentException("Unsupported element: " + elem);
|
||||||
@@ -444,9 +535,7 @@ public class JetTypeChecker {
|
|||||||
Set<TypeConstructor> commonSuperclasses = null;
|
Set<TypeConstructor> commonSuperclasses = null;
|
||||||
|
|
||||||
List<TypeConstructor> order = null;
|
List<TypeConstructor> order = null;
|
||||||
for (Iterator<Type> iterator = types.iterator(); iterator.hasNext();) {
|
for (Type type : types) {
|
||||||
Type type = iterator.next();
|
|
||||||
|
|
||||||
Set<TypeConstructor> visited = new HashSet<TypeConstructor>();
|
Set<TypeConstructor> visited = new HashSet<TypeConstructor>();
|
||||||
|
|
||||||
order = dfs(type, visited, new DfsNodeHandler<List<TypeConstructor>>() {
|
order = dfs(type, visited, new DfsNodeHandler<List<TypeConstructor>>() {
|
||||||
@@ -477,7 +566,8 @@ public class JetTypeChecker {
|
|||||||
|
|
||||||
if (commonSuperclasses == null) {
|
if (commonSuperclasses == null) {
|
||||||
commonSuperclasses = visited;
|
commonSuperclasses = visited;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
commonSuperclasses.retainAll(visited);
|
commonSuperclasses.retainAll(visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class MethodDescriptor {
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,7 @@ public class NamespaceDescriptor implements NamespaceDomain {
|
|||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
public Collection<FunctionDescriptor> getMethods(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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<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;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyDescriptorImpl(List<Attribute> attributes, String name) {
|
|
||||||
this(attributes, name, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
return type;
|
return type;
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface ValueParameterDescriptor extends PropertyDescriptor {
|
||||||
|
boolean hasDefaultValue();
|
||||||
|
boolean isRef();
|
||||||
|
boolean isVararg();
|
||||||
|
}
|
||||||
@@ -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<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");
|
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 {
|
// public void testImplicitConversions() throws Exception {
|
||||||
// assertConvertibleTo("1", JetStandardClasses.getByteType());
|
// assertConvertibleTo("1", JetStandardClasses.getByteType());
|
||||||
// }
|
// }
|
||||||
@@ -421,6 +427,11 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
"open class Derived_outT<out T> : Base_outT<T>",
|
"open class Derived_outT<out T> : Base_outT<T>",
|
||||||
"class Properties { val p : Int }",
|
"class Properties { val p : Int }",
|
||||||
"class Props<T> { val p : T }",
|
"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) {
|
public static JetScope BASIC_SCOPE = new JetScopeAdapter(JetStandardClasses.STANDARD_CLASSES) {
|
||||||
|
|||||||
Reference in New Issue
Block a user