提交 0340e962 编写于 作者: A Andrey Breslav

Constructors (all but Java) work, a draft version

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