Preliminary support for extension functions: they participate in overload resolution only if no such name is found in the receiver type itself.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -26,12 +27,13 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public FunctionDescriptor initialize(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @NotNull JetType unsubstitutedReturnType) {
|
public FunctionDescriptor initialize(@Nullable JetType receiverType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @NotNull JetType unsubstitutedReturnType) {
|
||||||
return super.initialize(typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType);
|
assert receiverType == null;
|
||||||
|
return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstructorDescriptor initialize(@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters) {
|
public ConstructorDescriptor initialize(@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters) {
|
||||||
super.initialize(Collections.<TypeParameterDescriptor>emptyList(), unsubstitutedValueParameters, getContainingDeclaration().getDefaultType());
|
super.initialize(null, Collections.<TypeParameterDescriptor>emptyList(), unsubstitutedValueParameters, getContainingDeclaration().getDefaultType());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ public interface FunctionDescriptor extends DeclarationDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
DeclarationDescriptor getContainingDeclaration();
|
DeclarationDescriptor getContainingDeclaration();
|
||||||
|
|
||||||
// @Nullable
|
@Nullable
|
||||||
// JetType getReceiverType();
|
JetType getReceiverType();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<TypeParameterDescriptor> getTypeParameters();
|
List<TypeParameterDescriptor> getTypeParameters();
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -18,9 +19,9 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
|||||||
private List<TypeParameterDescriptor> typeParameters;
|
private List<TypeParameterDescriptor> typeParameters;
|
||||||
private List<ValueParameterDescriptor> unsubstitutedValueParameters;
|
private List<ValueParameterDescriptor> unsubstitutedValueParameters;
|
||||||
private JetType unsubstitutedReturnType;
|
private JetType unsubstitutedReturnType;
|
||||||
|
private JetType receiverType;
|
||||||
|
|
||||||
private final Set<FunctionDescriptor> overriddenFunctions = Sets.newHashSet();
|
private final Set<FunctionDescriptor> overriddenFunctions = Sets.newHashSet();
|
||||||
|
|
||||||
private final FunctionDescriptor original;
|
private final FunctionDescriptor original;
|
||||||
|
|
||||||
public FunctionDescriptorImpl(
|
public FunctionDescriptorImpl(
|
||||||
@@ -40,15 +41,22 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FunctionDescriptor initialize(
|
public FunctionDescriptor initialize(
|
||||||
|
@Nullable JetType receiverType,
|
||||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||||
@Nullable JetType unsubstitutedReturnType) {
|
@Nullable JetType unsubstitutedReturnType) {
|
||||||
|
this.receiverType = receiverType;
|
||||||
this.typeParameters = typeParameters;
|
this.typeParameters = typeParameters;
|
||||||
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
|
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
|
||||||
this.unsubstitutedReturnType = unsubstitutedReturnType;
|
this.unsubstitutedReturnType = unsubstitutedReturnType;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetType getReceiverType() {
|
||||||
|
return receiverType;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
||||||
@@ -91,6 +99,15 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
|||||||
FunctionDescriptorImpl substitutedDescriptor;
|
FunctionDescriptorImpl substitutedDescriptor;
|
||||||
substitutedDescriptor = createSubstitutedCopy();
|
substitutedDescriptor = createSubstitutedCopy();
|
||||||
|
|
||||||
|
JetType receiverType = getReceiverType();
|
||||||
|
JetType substitutedReceiverType = null;
|
||||||
|
if (receiverType != null) {
|
||||||
|
substitutedReceiverType = substitutor.substitute(receiverType, Variance.IN_VARIANCE);
|
||||||
|
if (substitutedReceiverType == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
|
List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
|
||||||
if (substitutedValueParameters == null) {
|
if (substitutedValueParameters == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -102,6 +119,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
substitutedDescriptor.initialize(
|
substitutedDescriptor.initialize(
|
||||||
|
substitutedReceiverType,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(), // TODO : questionable
|
Collections.<TypeParameterDescriptor>emptyList(), // TODO : questionable
|
||||||
substitutedValueParameters,
|
substitutedValueParameters,
|
||||||
substitutedReturnType
|
substitutedReturnType
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.BiMap;
|
import com.google.common.collect.BiMap;
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
|
||||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
|
||||||
import org.jetbrains.jet.lang.resolve.WritableScopeImpl;
|
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -99,6 +98,10 @@ public class FunctionDescriptorUtil {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) {
|
public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) {
|
||||||
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, trace.getErrorHandler());
|
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, trace.getErrorHandler());
|
||||||
|
JetType receiverType = descriptor.getReceiverType();
|
||||||
|
if (receiverType != null) {
|
||||||
|
parameterScope.setThisType(receiverType);
|
||||||
|
}
|
||||||
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
|
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
|
||||||
parameterScope.addTypeParameterDescriptor(typeParameter);
|
parameterScope.addTypeParameterDescriptor(typeParameter);
|
||||||
}
|
}
|
||||||
@@ -229,4 +232,54 @@ public class FunctionDescriptorUtil {
|
|||||||
|
|
||||||
return OverrideCompatibilityInfo.success();
|
return OverrideCompatibilityInfo.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static FunctionGroup filteredFunctionGroup(@NotNull final FunctionGroup functionGroup, @NotNull final Function<FunctionDescriptor, Boolean> criterion) {
|
||||||
|
return new FunctionGroup() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return functionGroup.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public OverloadResolutionResult getPossiblyApplicableFunctions(@NotNull List<JetType> typeArguments, @NotNull List<JetType> positionedValueArgumentTypes) {
|
||||||
|
OverloadResolutionResult possiblyApplicableFunctions = functionGroup.getPossiblyApplicableFunctions(typeArguments, positionedValueArgumentTypes);
|
||||||
|
List<FunctionDescriptor> functionDescriptors = Lists.newArrayList(possiblyApplicableFunctions.getFunctionDescriptors());
|
||||||
|
for (Iterator<FunctionDescriptor> iterator = functionDescriptors.iterator(); iterator.hasNext(); ) {
|
||||||
|
FunctionDescriptor functionDescriptor = iterator.next();
|
||||||
|
if (!criterion.apply(functionDescriptor)) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (functionDescriptors.isEmpty()) {
|
||||||
|
return OverloadResolutionResult.nameNotFound();
|
||||||
|
}
|
||||||
|
if (possiblyApplicableFunctions.isSuccess() || possiblyApplicableFunctions.isAmbiguity()) {
|
||||||
|
if (functionDescriptors.size() == 1) {
|
||||||
|
return OverloadResolutionResult.success(functionDescriptors.get(0));
|
||||||
|
}
|
||||||
|
return OverloadResolutionResult.ambiguity(functionDescriptors);
|
||||||
|
}
|
||||||
|
if (functionDescriptors.size() == 1) {
|
||||||
|
return OverloadResolutionResult.singleFunctionArgumentMismatch(functionDescriptors.get(0));
|
||||||
|
}
|
||||||
|
return OverloadResolutionResult.ambiguity(functionDescriptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
// TODO: not implemented
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Set<FunctionDescriptor> getFunctionDescriptors() {
|
||||||
|
// TODO: not implemented
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
overriddenGetters.add(overriddenGetter);
|
overriddenGetters.add(overriddenGetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetType getReceiverType() {
|
||||||
|
return null; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
|
public List<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
overriddenSetters.add(overriddenSetter);
|
overriddenSetters.add(overriddenSetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetType getReceiverType() {
|
||||||
|
return null; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
|
public List<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
|
||||||
|
|||||||
@@ -24,6 +24,18 @@ public class JetFunction extends JetTypeParameterListOwner implements JetDeclara
|
|||||||
visitor.visitFunction(this);
|
visitor.visitFunction(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasTypeParameterListBeforeFunctionName() {
|
||||||
|
JetTypeParameterList typeParameterList = getTypeParameterList();
|
||||||
|
if (typeParameterList == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PsiElement nameIdentifier = getNameIdentifier();
|
||||||
|
if (nameIdentifier == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return nameIdentifier.getTextOffset() > typeParameterList.getTextOffset();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable @IfNotParsed
|
@Nullable @IfNotParsed
|
||||||
public JetParameterList getValueParameterList() {
|
public JetParameterList getValueParameterList() {
|
||||||
return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST);
|
return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST);
|
||||||
|
|||||||
@@ -174,8 +174,19 @@ public class ClassDescriptorResolver {
|
|||||||
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler());
|
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler());
|
||||||
innerScope.addLabeledDeclaration(functionDescriptor);
|
innerScope.addLabeledDeclaration(functionDescriptor);
|
||||||
|
|
||||||
// The two calls below have side-effects on parameterScope
|
|
||||||
List<TypeParameterDescriptor> typeParameterDescriptors = resolveTypeParameters(functionDescriptor, innerScope, function.getTypeParameters());
|
List<TypeParameterDescriptor> typeParameterDescriptors = resolveTypeParameters(functionDescriptor, innerScope, function.getTypeParameters());
|
||||||
|
|
||||||
|
JetType receiverType = null;
|
||||||
|
JetTypeReference receiverTypeRef = function.getReceiverTypeRef();
|
||||||
|
if (receiverTypeRef != null) {
|
||||||
|
JetScope scopeForReceiver =
|
||||||
|
function.hasTypeParameterListBeforeFunctionName()
|
||||||
|
? innerScope
|
||||||
|
: scope;
|
||||||
|
receiverType = typeResolver.resolveType(scopeForReceiver, receiverTypeRef);
|
||||||
|
}
|
||||||
|
|
||||||
List<ValueParameterDescriptor> valueParameterDescriptors = resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters());
|
List<ValueParameterDescriptor> valueParameterDescriptors = resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters());
|
||||||
|
|
||||||
JetTypeReference returnTypeRef = function.getReturnTypeRef();
|
JetTypeReference returnTypeRef = function.getReturnTypeRef();
|
||||||
@@ -201,6 +212,7 @@ public class ClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
functionDescriptor.initialize(
|
functionDescriptor.initialize(
|
||||||
|
receiverType,
|
||||||
typeParameterDescriptors,
|
typeParameterDescriptors,
|
||||||
valueParameterDescriptors,
|
valueParameterDescriptors,
|
||||||
returnType);
|
returnType);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class OverloadResolver {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public OverloadDomain getOverloadDomain(JetType receiverType, @NotNull JetScope outerScope, @NotNull String name) {
|
public OverloadDomain getOverloadDomain(JetType receiverType, @NotNull JetScope outerScope, @NotNull String name) {
|
||||||
// TODO : extension lookup
|
// TODO : extension lookup
|
||||||
JetScope scope = receiverType == null ? outerScope : receiverType.getMemberScope();
|
JetScope scope = receiverType == null ? outerScope : new ScopeWithReceiver(outerScope, receiverType, typeChecker);
|
||||||
|
|
||||||
final FunctionGroup functionGroup = scope.getFunctionGroup(name);
|
final FunctionGroup functionGroup = scope.getFunctionGroup(name);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -11,16 +14,33 @@ public class ScopeWithReceiver extends JetScopeImpl {
|
|||||||
|
|
||||||
private final JetScope receiverTypeScope;
|
private final JetScope receiverTypeScope;
|
||||||
private final JetScope outerScope;
|
private final JetScope outerScope;
|
||||||
|
private final JetTypeChecker typeChecker;
|
||||||
|
|
||||||
public ScopeWithReceiver(JetScope outerScope, JetType receiverType) {
|
public ScopeWithReceiver(JetScope outerScope, JetType receiverType, JetTypeChecker typeChecker) {
|
||||||
this.outerScope = outerScope;
|
this.outerScope = outerScope;
|
||||||
this.receiverTypeScope = receiverType.getMemberScope();
|
this.receiverTypeScope = receiverType.getMemberScope();
|
||||||
|
this.typeChecker = typeChecker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public FunctionGroup getFunctionGroup(@NotNull String name) {
|
public FunctionGroup getFunctionGroup(@NotNull String name) {
|
||||||
return receiverTypeScope.getFunctionGroup(name); // TODO
|
FunctionGroup functionGroup = receiverTypeScope.getFunctionGroup(name);
|
||||||
|
if (functionGroup.isEmpty()) {
|
||||||
|
return FunctionDescriptorUtil.filteredFunctionGroup(outerScope.getFunctionGroup(name),
|
||||||
|
new Function<FunctionDescriptor, Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean apply(@Nullable FunctionDescriptor functionDescriptor) {
|
||||||
|
if (functionDescriptor == null) return false;
|
||||||
|
JetType functionReceiverType = functionDescriptor.getReceiverType();
|
||||||
|
if (functionReceiverType == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return typeChecker.isSubtypeOf(receiverTypeScope.getThisType(), functionReceiverType);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return functionGroup; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ public class JavaDescriptorResolver {
|
|||||||
methodName
|
methodName
|
||||||
);
|
);
|
||||||
functionDescriptor.initialize(
|
functionDescriptor.initialize(
|
||||||
|
null,
|
||||||
resolveTypeParameters(method.getTypeParameters()),
|
resolveTypeParameters(method.getTypeParameters()),
|
||||||
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptor, parameters),
|
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptor, parameters),
|
||||||
semanticServices.getTypeTransformer().transformToType(method.getReturnType())
|
semanticServices.getTypeTransformer().transformToType(method.getReturnType())
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ public class ErrorUtils {
|
|||||||
private static FunctionDescriptor createErrorFunction(List<TypeParameterDescriptor> typeParameters, List<JetType> positionedValueArgumentTypes) {
|
private static FunctionDescriptor createErrorFunction(List<TypeParameterDescriptor> typeParameters, List<JetType> positionedValueArgumentTypes) {
|
||||||
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<Annotation>emptyList(), "<ERROR FUNCTION>");
|
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<Annotation>emptyList(), "<ERROR FUNCTION>");
|
||||||
return functionDescriptor.initialize(
|
return functionDescriptor.initialize(
|
||||||
|
null,
|
||||||
typeParameters,
|
typeParameters,
|
||||||
getValueParameters(functionDescriptor, positionedValueArgumentTypes),
|
getValueParameters(functionDescriptor, positionedValueArgumentTypes),
|
||||||
createErrorType("<ERROR FUNCTION RETURN>")
|
createErrorType("<ERROR FUNCTION RETURN>")
|
||||||
@@ -117,6 +118,7 @@ public class ErrorUtils {
|
|||||||
|
|
||||||
private static FunctionDescriptor createErrorFunction(int typeParameterCount, List<JetType> positionedValueParameterTypes) {
|
private static FunctionDescriptor createErrorFunction(int typeParameterCount, List<JetType> positionedValueParameterTypes) {
|
||||||
return new FunctionDescriptorImpl(ERROR_CLASS, Collections.<Annotation>emptyList(), "<ERROR FUNCTION>").initialize(
|
return new FunctionDescriptorImpl(ERROR_CLASS, Collections.<Annotation>emptyList(), "<ERROR FUNCTION>").initialize(
|
||||||
|
null,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(), // TODO
|
Collections.<TypeParameterDescriptor>emptyList(), // TODO
|
||||||
Collections.<ValueParameterDescriptor>emptyList(), // TODO
|
Collections.<ValueParameterDescriptor>emptyList(), // TODO
|
||||||
createErrorType("<ERROR FUNCTION RETURN TYPE>")
|
createErrorType("<ERROR FUNCTION RETURN TYPE>")
|
||||||
|
|||||||
@@ -1002,7 +1002,7 @@ public class JetTypeInferrer {
|
|||||||
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
||||||
checkNullSafety(finalSubjectType, condition.getOperationTokenNode());
|
checkNullSafety(finalSubjectType, condition.getOperationTokenNode());
|
||||||
JetExpression callSuffixExpression = condition.getCallSuffixExpression();
|
JetExpression callSuffixExpression = condition.getCallSuffixExpression();
|
||||||
JetScope compositeScope = new ScopeWithReceiver(scope, finalSubjectType);
|
JetScope compositeScope = new ScopeWithReceiver(scope, finalSubjectType, semanticServices.getTypeChecker());
|
||||||
if (callSuffixExpression != null) {
|
if (callSuffixExpression != null) {
|
||||||
JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false);
|
JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false);
|
||||||
ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression");
|
ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression");
|
||||||
@@ -1290,11 +1290,12 @@ public class JetTypeInferrer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitQualifiedExpression(JetQualifiedExpression expression) {
|
public void visitQualifiedExpression(JetQualifiedExpression expression) {
|
||||||
// TODO : functions
|
// TODO : functions as values
|
||||||
JetExpression selectorExpression = expression.getSelectorExpression();
|
JetExpression selectorExpression = expression.getSelectorExpression();
|
||||||
JetExpression receiverExpression = expression.getReceiverExpression();
|
JetExpression receiverExpression = expression.getReceiverExpression();
|
||||||
JetType receiverType = new TypeInferrerVisitorWithNamespaces(scope, false).getType(receiverExpression);
|
JetType receiverType = new TypeInferrerVisitorWithNamespaces(scope, false).getType(receiverExpression);
|
||||||
if (receiverType != null) {
|
if (receiverType != null) {
|
||||||
|
// TODO : extensions to 'Any?'
|
||||||
checkNullSafety(receiverType, expression.getOperationTokenNode());
|
checkNullSafety(receiverType, expression.getOperationTokenNode());
|
||||||
JetType selectorReturnType = getSelectorReturnType(receiverType, selectorExpression);
|
JetType selectorReturnType = getSelectorReturnType(receiverType, selectorExpression);
|
||||||
if (expression.getOperationSign() == JetTokens.QUEST) {
|
if (expression.getOperationSign() == JetTokens.QUEST) {
|
||||||
@@ -1314,7 +1315,7 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JetType getSelectorReturnType(JetType receiverType, JetExpression selectorExpression) {
|
private JetType getSelectorReturnType(JetType receiverType, JetExpression selectorExpression) {
|
||||||
JetScope compositeScope = new ScopeWithReceiver(scope, receiverType);
|
JetScope compositeScope = new ScopeWithReceiver(scope, receiverType, semanticServices.getTypeChecker());
|
||||||
if (selectorExpression instanceof JetCallExpression) {
|
if (selectorExpression instanceof JetCallExpression) {
|
||||||
JetCallExpression callExpression = (JetCallExpression) selectorExpression;
|
JetCallExpression callExpression = (JetCallExpression) selectorExpression;
|
||||||
OverloadDomain overloadDomain = getOverloadDomain(compositeScope, callExpression.getCalleeExpression(), callExpression.getValueArgumentList());
|
OverloadDomain overloadDomain = getOverloadDomain(compositeScope, callExpression.getCalleeExpression(), callExpression.getValueArgumentList());
|
||||||
|
|||||||
@@ -46,6 +46,17 @@ public class DescriptorRenderer {
|
|||||||
protected void renderName(DeclarationDescriptor descriptor, StringBuilder stringBuilder) {
|
protected void renderName(DeclarationDescriptor descriptor, StringBuilder stringBuilder) {
|
||||||
stringBuilder.append(descriptor.getName());
|
stringBuilder.append(descriptor.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, StringBuilder builder) {
|
||||||
|
renderTypeParameter(descriptor, builder);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitValueParameterDescriptor(ValueParameterDescriptor descriptor, StringBuilder builder) {
|
||||||
|
return super.visitVariableDescriptor(descriptor, builder);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private DescriptorRenderer() {}
|
private DescriptorRenderer() {}
|
||||||
@@ -106,9 +117,18 @@ public class DescriptorRenderer {
|
|||||||
@Override
|
@Override
|
||||||
public Void visitFunctionDescriptor(FunctionDescriptor descriptor, StringBuilder builder) {
|
public Void visitFunctionDescriptor(FunctionDescriptor descriptor, StringBuilder builder) {
|
||||||
builder.append(renderKeyword("fun")).append(" ");
|
builder.append(renderKeyword("fun")).append(" ");
|
||||||
renderName(descriptor, builder);
|
|
||||||
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeParameters();
|
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeParameters();
|
||||||
renderTypeParameters(typeParameters, builder);
|
renderTypeParameters(typeParameters, builder);
|
||||||
|
if (!typeParameters.isEmpty()) {
|
||||||
|
builder.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
JetType receiverType = descriptor.getReceiverType();
|
||||||
|
if (receiverType != null) {
|
||||||
|
builder.append(escape(receiverType.toString())).append(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
renderName(descriptor, builder);
|
||||||
builder.append("(");
|
builder.append("(");
|
||||||
for (Iterator<ValueParameterDescriptor> iterator = descriptor.getUnsubstitutedValueParameters().iterator(); iterator.hasNext(); ) {
|
for (Iterator<ValueParameterDescriptor> iterator = descriptor.getUnsubstitutedValueParameters().iterator(); iterator.hasNext(); ) {
|
||||||
ValueParameterDescriptor parameterDescriptor = iterator.next();
|
ValueParameterDescriptor parameterDescriptor = iterator.next();
|
||||||
@@ -178,7 +198,7 @@ public class DescriptorRenderer {
|
|||||||
stringBuilder.append(escape(descriptor.getName()));
|
stringBuilder.append(escape(descriptor.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder) {
|
protected void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder) {
|
||||||
renderName(descriptor, builder);
|
renderName(descriptor, builder);
|
||||||
if (!descriptor.getUpperBounds().isEmpty()) {
|
if (!descriptor.getUpperBounds().isEmpty()) {
|
||||||
JetType bound = descriptor.getUpperBounds().iterator().next();
|
JetType bound = descriptor.getUpperBounds().iterator().next();
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
fun <~T~T, ~E~E> `T`T.foo(x : `E`E, y : `A`A) : `T`T {
|
||||||
|
y.`+`plus(1)
|
||||||
|
y `+`plus 1
|
||||||
|
y `+1`+ 1.0
|
||||||
|
|
||||||
|
this?.`-`minus<T>(this)
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
~A~class A
|
||||||
|
|
||||||
|
~+1~fun `A`A.plus(a : Any) {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
~+~fun `A`A.plus(a : Int) {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
~-~fun <T> T.minus(t : T) : Int = 1
|
||||||
Reference in New Issue
Block a user