Constructors (all but Java) work, a draft version
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface ConstructorDescriptor extends FunctionDescriptor {
|
||||
/**
|
||||
* @throws UnsupportedOperationException -- no type parameters supported for constructors
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
List<TypeParameterDescriptor> getTypeParameters();
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException -- return type is not stored for constructors
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
JetType getUnsubstitutedReturnType();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
ClassDescriptor getContainingDeclaration();
|
||||
|
||||
/**
|
||||
* @return "<init>" -- name is not stored for constructors
|
||||
*/
|
||||
@Override
|
||||
String getName();
|
||||
|
||||
boolean isPrimary();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements ConstructorDescriptor {
|
||||
|
||||
private final boolean isPrimary;
|
||||
|
||||
public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull List<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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.SubstitutingScope;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -13,7 +14,7 @@ public class TypeSubstitutor {
|
||||
private TypeSubstitutor() {}
|
||||
|
||||
public JetType substitute(@NotNull JetType context, @NotNull JetType subject, @NotNull Variance howThisTypeIsUsed) {
|
||||
return substitute(getSubstitutionContext(context), subject, howThisTypeIsUsed);
|
||||
return substitute(buildSubstitutionContext(context), subject, howThisTypeIsUsed);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -28,14 +29,46 @@ 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();
|
||||
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));
|
||||
}
|
||||
|
||||
return buildSubstitutionContext(parameters, contextArguments);
|
||||
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 newArguments;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TypeProjection substituteInProjection(Map<TypeConstructor, TypeProjection> substitutionContext, TypeProjection subject) {
|
||||
JetType subjectType = subject.getType();
|
||||
TypeProjection value = substitutionContext.get(subjectType.getConstructor());
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
return new TypeProjection(subject.getProjectionKind(), specializeType(subjectType, substitutionContext));
|
||||
}
|
||||
|
||||
public Set<JetType> substituteInSet(Map<TypeConstructor, TypeProjection> substitutionContext, Set<JetType> types, Variance howTheseTypesWillBeUsed) {
|
||||
Set<JetType> result = new HashSet<JetType>();
|
||||
for (JetType type : types) {
|
||||
result.add(substitute(substitutionContext, type, howTheseTypesWillBeUsed));
|
||||
}
|
||||
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) {
|
||||
@@ -47,35 +80,4 @@ public class TypeSubstitutor {
|
||||
}
|
||||
return parameterValues;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TypeProjection substituteInProjection(Map<TypeConstructor, TypeProjection> parameterValues, TypeProjection subject) {
|
||||
@NotNull JetType subjectType = subject.getType();
|
||||
TypeProjection value = parameterValues.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());
|
||||
}
|
||||
|
||||
public Set<JetType> substituteInSet(Map<TypeConstructor, TypeProjection> substitutionContext, Set<JetType> types, Variance howTheseTypesWillBeUsed) {
|
||||
Set<JetType> result = new HashSet<JetType>();
|
||||
for (JetType type : types) {
|
||||
result.add(substitute(substitutionContext, type, howTheseTypesWillBeUsed));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -146,4 +145,25 @@ public class TypeUtils {
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetType makeUnsubstitutedType(ClassDescriptor classDescriptor) {
|
||||
List<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("<", "<");
|
||||
// text = text.replaceAll("<", "<");
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
~A~class A {
|
||||
~B~class B {
|
||||
|
||||
~B()~this() {}
|
||||
}
|
||||
|
||||
~foo~fun foo(~foo.a~a : `std::Char`Char) = `foo.a`a`:std::Char`
|
||||
~fooB~fun fooB() = `foo`foo('1')`:std::Char`
|
||||
~foo.1~fun foo() : Int = (1.`std::Int.plus(Int)`plus(1))`:std::Int`
|
||||
~foo1~fun foo1() : `B`B = new `B`B()`:B`
|
||||
~foo1~fun foo1() : `B`B = new `B()`B()`:B`
|
||||
~A.a~val a : `std::Int`Int
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user