this() calls supported
properties integrated
This commit is contained in:
@@ -216,7 +216,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetFunction) {
|
if (declaration instanceof JetFunction) {
|
||||||
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, (JetNamedFunction) declaration).getOverriddenFunctions());
|
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, (JetNamedFunction) declaration).getOverriddenDescriptors());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface CallableDescriptor extends DeclarationDescriptor {
|
||||||
|
@Nullable
|
||||||
|
JetType getReceiverType();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<TypeParameterDescriptor> getTypeParameters();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
JetType getReturnType();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
CallableDescriptor getOriginal();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
CallableDescriptor substitute(TypeSubstitutor substitutor);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<ValueParameterDescriptor> getValueParameters();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
Set<? extends CallableDescriptor> getOverriddenDescriptors();
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,26 @@
|
|||||||
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.TypeSubstitutor;
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public interface FunctionDescriptor extends DeclarationDescriptor {
|
public interface FunctionDescriptor extends CallableDescriptor {
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
DeclarationDescriptor getContainingDeclaration();
|
DeclarationDescriptor getContainingDeclaration();
|
||||||
|
|
||||||
@Nullable
|
|
||||||
JetType getReceiverType();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
List<TypeParameterDescriptor> getTypeParameters();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
List<ValueParameterDescriptor> getValueParameters();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
JetType getReturnType();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@Override
|
||||||
FunctionDescriptor getOriginal();
|
FunctionDescriptor getOriginal();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FunctionDescriptor substitute(TypeSubstitutor substitutor);
|
FunctionDescriptor substitute(TypeSubstitutor substitutor);
|
||||||
|
|
||||||
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
Set<? extends FunctionDescriptor> getOverriddenFunctions();
|
Set<? extends FunctionDescriptor> getOverriddenDescriptors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||||
return overriddenFunctions;
|
return overriddenFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class FunctionDescriptorUtil {
|
|||||||
return unsubstitutedValueParameters.size();
|
return unsubstitutedValueParameters.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<TypeConstructor, TypeProjection> createSubstitutionContext(@NotNull FunctionDescriptor functionDescriptor, List<JetType> typeArguments) {
|
public static Map<TypeConstructor, TypeProjection> createSubstitutionContext(@NotNull FunctionDescriptor functionDescriptor, List<JetType> typeArguments) {
|
||||||
if (functionDescriptor.getTypeParameters().isEmpty()) return Collections.emptyMap();
|
if (functionDescriptor.getTypeParameters().isEmpty()) return Collections.emptyMap();
|
||||||
|
|
||||||
Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
|
Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
|
||||||
@@ -112,59 +112,6 @@ public class FunctionDescriptorUtil {
|
|||||||
return parameterScope;
|
return parameterScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static FunctionDescriptor substituteBounds(@NotNull FunctionDescriptor functionDescriptor) {
|
|
||||||
final List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
|
||||||
if (typeParameters.isEmpty()) return functionDescriptor;
|
|
||||||
final Map<TypeConstructor, TypeParameterDescriptor> typeConstructors = Maps.newHashMap();
|
|
||||||
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
|
||||||
typeConstructors.put(typeParameter.getTypeConstructor(), typeParameter);
|
|
||||||
}
|
|
||||||
return functionDescriptor.substitute(new TypeSubstitutor(TypeSubstitution.EMPTY) {
|
|
||||||
@Override
|
|
||||||
public boolean inRange(@NotNull TypeConstructor typeConstructor) {
|
|
||||||
return typeConstructors.containsKey(typeConstructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return typeParameters.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public TypeSubstitution getSubstitution() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public JetType safeSubstitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
|
|
||||||
JetType substituted = substitute(type, howThisTypeIsUsed);
|
|
||||||
if (substituted == null) {
|
|
||||||
return ErrorUtils.createErrorType("Substitution failed");
|
|
||||||
}
|
|
||||||
return substituted;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetType substitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
|
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeConstructors.get(type.getConstructor());
|
|
||||||
if (typeParameterDescriptor != null) {
|
|
||||||
switch (howThisTypeIsUsed) {
|
|
||||||
case INVARIANT:
|
|
||||||
return type;
|
|
||||||
case IN_VARIANCE:
|
|
||||||
throw new UnsupportedOperationException(); // TODO : lower bounds
|
|
||||||
case OUT_VARIANCE:
|
|
||||||
return typeParameterDescriptor.getDefaultType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.substitute(type, howThisTypeIsUsed);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class OverrideCompatibilityInfo {
|
public static class OverrideCompatibilityInfo {
|
||||||
|
|
||||||
private static final OverrideCompatibilityInfo SUCCESS = new OverrideCompatibilityInfo(false, "SUCCESS");
|
private static final OverrideCompatibilityInfo SUCCESS = new OverrideCompatibilityInfo(false, "SUCCESS");
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<TypeParameterDescriptor> getTypeParemeters() {
|
@Override
|
||||||
|
public List<TypeParameterDescriptor> getTypeParameters() {
|
||||||
return typeParemeters;
|
return typeParemeters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +88,12 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
|||||||
return receiverType;
|
return receiverType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetType getReturnType() {
|
||||||
|
return getOutType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isVar() {
|
public boolean isVar() {
|
||||||
return isVar;
|
return isVar;
|
||||||
@@ -110,7 +117,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public VariableDescriptor substitute(TypeSubstitutor substitutor) {
|
public PropertyDescriptor substitute(TypeSubstitutor substitutor) {
|
||||||
JetType originalInType = getInType();
|
JetType originalInType = getInType();
|
||||||
JetType inType = originalInType == null ? null : substitutor.substitute(originalInType, Variance.IN_VARIANCE);
|
JetType inType = originalInType == null ? null : substitutor.substitute(originalInType, Variance.IN_VARIANCE);
|
||||||
JetType originalOutType = getOutType();
|
JetType originalOutType = getOutType();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||||
return overriddenGetters;
|
return overriddenGetters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||||
return overriddenSetters;
|
return overriddenSetters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public interface VariableDescriptor extends DeclarationDescriptor {
|
public interface VariableDescriptor extends CallableDescriptor {
|
||||||
/**
|
/**
|
||||||
* @return <code>null</code> for write-only variables (i.e. properties), variable value type otherwise
|
* @return <code>null</code> for write-only variables (i.e. properties), variable value type otherwise
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -44,4 +46,39 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
|
|||||||
protected void setOutType(JetType outType) {
|
protected void setOutType(JetType outType) {
|
||||||
this.outType = outType;
|
this.outType = outType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public VariableDescriptor getOriginal() {
|
||||||
|
return (VariableDescriptor) super.getOriginal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<ValueParameterDescriptor> getValueParameters() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Set<? extends CallableDescriptor> getOverriddenDescriptors() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<TypeParameterDescriptor> getTypeParameters() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetType getReceiverType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetType getReturnType() {
|
||||||
|
return getOutType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -30,4 +35,58 @@ public class DescriptorUtils {
|
|||||||
}
|
}
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static <Descriptor extends CallableDescriptor> Descriptor substituteBounds(@NotNull Descriptor functionDescriptor) {
|
||||||
|
final List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||||
|
if (typeParameters.isEmpty()) return functionDescriptor;
|
||||||
|
final Map<TypeConstructor, TypeParameterDescriptor> typeConstructors = Maps.newHashMap();
|
||||||
|
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
||||||
|
typeConstructors.put(typeParameter.getTypeConstructor(), typeParameter);
|
||||||
|
}
|
||||||
|
//noinspection unchecked
|
||||||
|
return (Descriptor) functionDescriptor.substitute(new TypeSubstitutor(TypeSubstitutor.TypeSubstitution.EMPTY) {
|
||||||
|
@Override
|
||||||
|
public boolean inRange(@NotNull TypeConstructor typeConstructor) {
|
||||||
|
return typeConstructors.containsKey(typeConstructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return typeParameters.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public TypeSubstitution getSubstitution() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetType safeSubstitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
|
||||||
|
JetType substituted = substitute(type, howThisTypeIsUsed);
|
||||||
|
if (substituted == null) {
|
||||||
|
return ErrorUtils.createErrorType("Substitution failed");
|
||||||
|
}
|
||||||
|
return substituted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetType substitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = typeConstructors.get(type.getConstructor());
|
||||||
|
if (typeParameterDescriptor != null) {
|
||||||
|
switch (howThisTypeIsUsed) {
|
||||||
|
case INVARIANT:
|
||||||
|
return type;
|
||||||
|
case IN_VARIANCE:
|
||||||
|
throw new UnsupportedOperationException(); // TODO : lower bounds
|
||||||
|
case OUT_VARIANCE:
|
||||||
|
return typeParameterDescriptor.getDefaultType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.substitute(type, howThisTypeIsUsed);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ public class TopDownAnalyzer {
|
|||||||
JetTypeReference typeReference = call.getTypeReference();
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||||
typeInferrer.getCallResolver().resolveCall(scopeForConstructor, null, call, NO_EXPECTED_TYPE);
|
typeInferrer.getCallResolver().resolveCall(trace, scopeForConstructor, null, call, NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||||
@@ -685,7 +685,7 @@ public class TopDownAnalyzer {
|
|||||||
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
||||||
JetTypeReference typeReference = call.getTypeReference();
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
typeInferrerForInitializers.getCallResolver().resolveCall(functionInnerScope, null, call, NO_EXPECTED_TYPE);
|
typeInferrerForInitializers.getCallResolver().resolveCall(trace, functionInnerScope, null, call, NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,14 +693,16 @@ public class TopDownAnalyzer {
|
|||||||
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
||||||
// TODO : check that there's no recursion in this() calls
|
// TODO : check that there's no recursion in this() calls
|
||||||
// TODO : check: if a this() call is present, no other initializers are allowed
|
// TODO : check: if a this() call is present, no other initializers are allowed
|
||||||
// ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||||
// typeInferrerForInitializers.checkClassConstructorCall(
|
|
||||||
// functionInnerScope,
|
typeInferrerForInitializers.getCallResolver().resolveCall(trace,
|
||||||
|
functionInnerScope,
|
||||||
|
null, call, NO_EXPECTED_TYPE);
|
||||||
// call.getThisReference(),
|
// call.getThisReference(),
|
||||||
// classDescriptor,
|
// classDescriptor,
|
||||||
// classDescriptor.getDefaultType(),
|
// classDescriptor.getDefaultType(),
|
||||||
// call);
|
// call);
|
||||||
trace.getErrorHandler().genericError(call.getNode(), "this-calls are not supported");
|
// trace.getErrorHandler().genericError(call.getNode(), "this-calls are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -805,7 +807,7 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) {
|
private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||||
WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, trace.getErrorHandler()).setDebugName("Property declaration inner scope");
|
WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, trace.getErrorHandler()).setDebugName("Property declaration inner scope");
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParemeters()) {
|
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
|
||||||
result.addTypeParameterDescriptor(typeParameterDescriptor);
|
result.addTypeParameterDescriptor(typeParameterDescriptor);
|
||||||
}
|
}
|
||||||
JetType receiverType = propertyDescriptor.getReceiverType();
|
JetType receiverType = propertyDescriptor.getReceiverType();
|
||||||
|
|||||||
+378
-410
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,122 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||||
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
/*package*/ class OverloadingConflictResolver {
|
||||||
|
|
||||||
|
private final JetSemanticServices semanticServices;
|
||||||
|
|
||||||
|
public OverloadingConflictResolver(@NotNull JetSemanticServices semanticServices) {
|
||||||
|
this.semanticServices = semanticServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public <Descriptor extends CallableDescriptor> Descriptor findMaximallySpecific(Map<Descriptor, Descriptor> candidates, Map<Descriptor, TemporaryBindingTrace> traces, boolean discriminateGenericDescriptors) {
|
||||||
|
Map<Descriptor, TemporaryBindingTrace> maximallySpecific = Maps.newHashMap();
|
||||||
|
meLoop:
|
||||||
|
for (Map.Entry<Descriptor, Descriptor> myEntry : candidates.entrySet()) {
|
||||||
|
Descriptor me = myEntry.getValue();
|
||||||
|
TemporaryBindingTrace myTrace = traces.get(myEntry.getKey());
|
||||||
|
for (Descriptor other : candidates.values()) {
|
||||||
|
if (other == me) continue;
|
||||||
|
if (!moreSpecific(me, other, discriminateGenericDescriptors) || moreSpecific(other, me, discriminateGenericDescriptors)) continue meLoop;
|
||||||
|
}
|
||||||
|
maximallySpecific.put(me, myTrace);
|
||||||
|
}
|
||||||
|
if (maximallySpecific.size() == 1) {
|
||||||
|
Map.Entry<Descriptor, TemporaryBindingTrace> result = maximallySpecific.entrySet().iterator().next();
|
||||||
|
result.getValue().commit();
|
||||||
|
return result.getKey();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Let < mean "more specific"
|
||||||
|
* Subtype < supertype
|
||||||
|
* Double < Float
|
||||||
|
* Int < Long
|
||||||
|
* Int < Short < Byte
|
||||||
|
*/
|
||||||
|
private <Descriptor extends CallableDescriptor> boolean moreSpecific(Descriptor f, Descriptor g, boolean discriminateGenericDescriptors) {
|
||||||
|
if (overrides(f, g)) return true;
|
||||||
|
if (overrides(g, f)) return false;
|
||||||
|
|
||||||
|
List<ValueParameterDescriptor> fParams = f.getValueParameters();
|
||||||
|
List<ValueParameterDescriptor> gParams = g.getValueParameters();
|
||||||
|
|
||||||
|
int fSize = fParams.size();
|
||||||
|
if (fSize != gParams.size()) return false;
|
||||||
|
for (int i = 0; i < fSize; i++) {
|
||||||
|
JetType fParamType = fParams.get(i).getOutType();
|
||||||
|
JetType gParamType = gParams.get(i).getOutType();
|
||||||
|
|
||||||
|
if (!semanticServices.getTypeChecker().isSubtypeOf(fParamType, gParamType)
|
||||||
|
&& !numericTypeMoreSpecific(fParamType, gParamType)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discriminateGenericDescriptors && isGeneric(f)) {
|
||||||
|
if (!isGeneric(g)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// g is generic, too
|
||||||
|
|
||||||
|
return moreSpecific(DescriptorUtils.substituteBounds(f), DescriptorUtils.substituteBounds(g), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isGeneric(CallableDescriptor f) {
|
||||||
|
return !f.getOriginal().getTypeParameters().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean numericTypeMoreSpecific(@NotNull JetType specific, @NotNull JetType general) {
|
||||||
|
JetStandardLibrary standardLibrary = semanticServices.getStandardLibrary();
|
||||||
|
JetType _double = standardLibrary.getDoubleType();
|
||||||
|
JetType _float = standardLibrary.getFloatType();
|
||||||
|
JetType _long = standardLibrary.getLongType();
|
||||||
|
JetType _int = standardLibrary.getIntType();
|
||||||
|
JetType _byte = standardLibrary.getByteType();
|
||||||
|
JetType _short = standardLibrary.getShortType();
|
||||||
|
|
||||||
|
if (semanticServices.getTypeChecker().equalTypes(specific, _double) && semanticServices.getTypeChecker().equalTypes(general, _float)) return true;
|
||||||
|
if (semanticServices.getTypeChecker().equalTypes(specific, _int)) {
|
||||||
|
if (semanticServices.getTypeChecker().equalTypes(general, _long)) return true;
|
||||||
|
if (semanticServices.getTypeChecker().equalTypes(general, _byte)) return true;
|
||||||
|
if (semanticServices.getTypeChecker().equalTypes(general, _short)) return true;
|
||||||
|
}
|
||||||
|
if (semanticServices.getTypeChecker().equalTypes(specific, _short) && semanticServices.getTypeChecker().equalTypes(general, _byte)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <Descriptor extends CallableDescriptor> boolean overrides(@NotNull Descriptor f, @NotNull Descriptor g) {
|
||||||
|
Set<? extends CallableDescriptor> overriddenDescriptors = f.getOriginal().getOverriddenDescriptors();
|
||||||
|
CallableDescriptor originalG = g.getOriginal();
|
||||||
|
for (CallableDescriptor overriddenFunction : overriddenDescriptors) {
|
||||||
|
if (originalG.equals(overriddenFunction.getOriginal())) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.Call;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeProjection;
|
||||||
|
import org.jetbrains.jet.lang.psi.ValueArgument;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
/*package*/ class ResolutionTask<Descriptor extends CallableDescriptor> {
|
||||||
|
private final Collection<Descriptor> candidates;
|
||||||
|
private final JetType receiverType;
|
||||||
|
private final List<JetTypeProjection> typeArguments;
|
||||||
|
private final List<? extends ValueArgument> valueArguments;
|
||||||
|
private final List<JetExpression> functionLiteralArguments;
|
||||||
|
|
||||||
|
public ResolutionTask(
|
||||||
|
@NotNull Collection<Descriptor> candidates,
|
||||||
|
@Nullable JetType receiverType,
|
||||||
|
@NotNull List<JetTypeProjection> typeArguments,
|
||||||
|
@NotNull List<? extends ValueArgument> valueArguments,
|
||||||
|
@NotNull List<JetExpression> functionLiteralArguments) {
|
||||||
|
this.candidates = candidates;
|
||||||
|
this.receiverType = receiverType;
|
||||||
|
this.typeArguments = typeArguments;
|
||||||
|
this.valueArguments = valueArguments;
|
||||||
|
this.functionLiteralArguments = functionLiteralArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResolutionTask(
|
||||||
|
@NotNull Collection<Descriptor> candidates,
|
||||||
|
@Nullable JetType receiverType,
|
||||||
|
@NotNull Call call
|
||||||
|
) {
|
||||||
|
this(candidates, receiverType, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Collection<Descriptor> getCandidates() {
|
||||||
|
return candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JetType getReceiverType() {
|
||||||
|
return receiverType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<JetTypeProjection> getTypeArguments() {
|
||||||
|
return typeArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<? extends ValueArgument> getValueArguments() {
|
||||||
|
return valueArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<JetExpression> getFunctionLiteralArguments() {
|
||||||
|
return functionLiteralArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.Call;
|
||||||
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
/*package*/ abstract class TaskPrioritizer<Descriptor extends CallableDescriptor> {
|
||||||
|
|
||||||
|
public static <T extends DeclarationDescriptor> void splitLexicallyLocalDescriptors(
|
||||||
|
Collection<? extends T> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, List<? super T> local, List<? super T> nonlocal) {
|
||||||
|
|
||||||
|
for (T descriptor : allDescriptors) {
|
||||||
|
if (isLocal(containerOfTheCurrentLocality, descriptor)) {
|
||||||
|
local.add(descriptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nonlocal.add(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The primary case for local extensions is the following:
|
||||||
|
*
|
||||||
|
* I had a locally declared extension function or a local variable of function type called foo
|
||||||
|
* And I called it on my x
|
||||||
|
* Now, someone added function foo() to the class of x
|
||||||
|
* My code should not change
|
||||||
|
*
|
||||||
|
* thus
|
||||||
|
*
|
||||||
|
* local extension prevail over members (and members prevail over all non-local extensions)
|
||||||
|
*/
|
||||||
|
public static boolean isLocal(DeclarationDescriptor containerOfTheCurrentLocality, DeclarationDescriptor candidate) {
|
||||||
|
DeclarationDescriptor parent = candidate.getContainingDeclaration();
|
||||||
|
if (!(parent instanceof FunctionDescriptor)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FunctionDescriptor functionDescriptor = (FunctionDescriptor) parent;
|
||||||
|
DeclarationDescriptor current = containerOfTheCurrentLocality;
|
||||||
|
while (current != null) {
|
||||||
|
if (current == functionDescriptor) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
current = current.getContainingDeclaration();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ResolutionTask<Descriptor>> computePrioritizedTasks(JetScope scope, JetType receiverType, Call call, String name) {
|
||||||
|
List<ResolutionTask<Descriptor>> result = Lists.newArrayList();
|
||||||
|
if (receiverType != null) {
|
||||||
|
Collection<Descriptor> extensionFunctions = getExtensionsByName(scope, name);
|
||||||
|
|
||||||
|
List<Descriptor> nonlocals = Lists.newArrayList();
|
||||||
|
List<Descriptor> locals = Lists.newArrayList();
|
||||||
|
splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||||
|
|
||||||
|
Collection<Descriptor> members = getMembersByName(receiverType, name);
|
||||||
|
|
||||||
|
addTask(result, receiverType, call, locals);
|
||||||
|
addTask(result, null, call, members);
|
||||||
|
addTask(result, receiverType, call, nonlocals);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Collection<Descriptor> functions = getNonExtensionsByName(scope, name);
|
||||||
|
|
||||||
|
List<Descriptor> nonlocals = Lists.newArrayList();
|
||||||
|
List<Descriptor> locals = Lists.newArrayList();
|
||||||
|
splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||||
|
|
||||||
|
addTask(result, receiverType, call, locals);
|
||||||
|
|
||||||
|
addTask(result, receiverType, call, nonlocals);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract Collection<Descriptor> getNonExtensionsByName(JetScope scope, String name);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract Collection<Descriptor> getMembersByName(@NotNull JetType receiverType, String name);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract Collection<Descriptor> getExtensionsByName(JetScope scope, String name);
|
||||||
|
|
||||||
|
private void addTask(@NotNull List<ResolutionTask<Descriptor>> result, @Nullable JetType receiverType, @NotNull Call call, @NotNull Collection<Descriptor> candidates) {
|
||||||
|
if (candidates.isEmpty()) return;
|
||||||
|
result.add(createTask(receiverType, call, candidates));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract ResolutionTask<Descriptor> createTask(JetType receiverType, Call call, Collection<Descriptor> candidates);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
/*package*/ interface TracingStrategy {
|
||||||
|
void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor);
|
||||||
|
|
||||||
|
void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message);
|
||||||
|
|
||||||
|
void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message);
|
||||||
|
|
||||||
|
void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message);
|
||||||
|
|
||||||
|
void reportUnresolvedReference(@NotNull BindingTrace trace);
|
||||||
|
|
||||||
|
void reportErrorOnReference(BindingTrace trace, String message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetLabelQualifiedExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.ValueArgument;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
|
import org.jetbrains.jet.lang.types.CallMaker;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
/*package*/ class ValueArgumentsToParametersMapper {
|
||||||
|
public static <Descriptor extends CallableDescriptor> boolean mapValueArgumentsToParameters(
|
||||||
|
@NotNull ResolutionTask<Descriptor> task,
|
||||||
|
@NotNull TracingStrategy tracing,
|
||||||
|
@NotNull Descriptor candidate,
|
||||||
|
@NotNull BindingTrace temporaryTrace,
|
||||||
|
@NotNull Map<ValueArgument, ValueParameterDescriptor> argumentsToParameters
|
||||||
|
) {
|
||||||
|
Set<ValueParameterDescriptor> usedParameters = Sets.newHashSet();
|
||||||
|
|
||||||
|
List<ValueParameterDescriptor> valueParameters = candidate.getValueParameters();
|
||||||
|
|
||||||
|
Map<String, ValueParameterDescriptor> parameterByName = Maps.newHashMap();
|
||||||
|
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
||||||
|
parameterByName.put(valueParameter.getName(), valueParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<? extends ValueArgument> valueArguments = task.getValueArguments();
|
||||||
|
|
||||||
|
boolean error = false;
|
||||||
|
boolean someNamed = false;
|
||||||
|
boolean somePositioned = false;
|
||||||
|
for (int i = 0; i < valueArguments.size(); i++) {
|
||||||
|
ValueArgument valueArgument = valueArguments.get(i);
|
||||||
|
if (valueArgument.isNamed()) {
|
||||||
|
someNamed = true;
|
||||||
|
ASTNode nameNode = valueArgument.getArgumentName().getNode();
|
||||||
|
if (somePositioned) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName());
|
||||||
|
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(nameNode, "An argument is already passed for this parameter");
|
||||||
|
}
|
||||||
|
if (valueParameterDescriptor == null) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(nameNode, "Cannot find a parameter with this name");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temporaryTrace.record(REFERENCE_TARGET, valueArgument.getArgumentName().getReferenceExpression(), valueParameterDescriptor);
|
||||||
|
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
somePositioned = true;
|
||||||
|
if (someNamed) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int parameterCount = valueParameters.size();
|
||||||
|
if (i < parameterCount) {
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(i);
|
||||||
|
usedParameters.add(valueParameterDescriptor);
|
||||||
|
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
else if (!valueParameters.isEmpty()) {
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||||
|
if (valueParameterDescriptor.isVararg()) {
|
||||||
|
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||||
|
usedParameters.add(valueParameterDescriptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Too many arguments");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Too many arguments");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<JetExpression> functionLiteralArguments = task.getFunctionLiteralArguments();
|
||||||
|
if (!functionLiteralArguments.isEmpty()) {
|
||||||
|
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
|
||||||
|
|
||||||
|
if (valueParameters.isEmpty()) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Too many arguments");
|
||||||
|
error = true;
|
||||||
|
} else {
|
||||||
|
JetFunctionLiteralExpression functionLiteral;
|
||||||
|
if (possiblyLabeledFunctionLiteral instanceof JetLabelQualifiedExpression) {
|
||||||
|
JetLabelQualifiedExpression labeledFunctionLiteral = (JetLabelQualifiedExpression) possiblyLabeledFunctionLiteral;
|
||||||
|
functionLiteral = (JetFunctionLiteralExpression) labeledFunctionLiteral.getLabeledExpression();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
functionLiteral = (JetFunctionLiteralExpression) possiblyLabeledFunctionLiteral;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueParameterDescriptor parameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||||
|
if (parameterDescriptor.isVararg()) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!usedParameters.add(parameterDescriptor)) {
|
||||||
|
temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Too many arguments");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
argumentsToParameters.put(CallMaker.makeValueArgument(functionLiteral), parameterDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < functionLiteralArguments.size(); i++) {
|
||||||
|
JetExpression argument = functionLiteralArguments.get(i);
|
||||||
|
temporaryTrace.getErrorHandler().genericError(argument.getNode(), "Only one function literal is allowed outside a parenthesized argument list");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
||||||
|
if (!usedParameters.contains(valueParameter)) {
|
||||||
|
if (!valueParameter.hasDefaultValue()) {
|
||||||
|
tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,8 +17,8 @@ public class CallMaker {
|
|||||||
private static class ExpressionValueArgument implements ValueArgument {
|
private static class ExpressionValueArgument implements ValueArgument {
|
||||||
|
|
||||||
private final JetExpression expression;
|
private final JetExpression expression;
|
||||||
private final PsiElement reportErrorsOn;
|
|
||||||
|
|
||||||
|
private final PsiElement reportErrorsOn;
|
||||||
private ExpressionValueArgument(@NotNull JetExpression expression) {
|
private ExpressionValueArgument(@NotNull JetExpression expression) {
|
||||||
this(expression, expression);
|
this(expression, expression);
|
||||||
}
|
}
|
||||||
@@ -58,14 +58,14 @@ public class CallMaker {
|
|||||||
public PsiElement asElement() {
|
public PsiElement asElement() {
|
||||||
return reportErrorsOn;
|
return reportErrorsOn;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
private static abstract class CallStub implements Call {
|
private static abstract class CallStub implements Call {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetValueArgumentList getValueArgumentList() {
|
public JetValueArgumentList getValueArgumentList() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<JetExpression> getFunctionLiteralArguments() {
|
public List<JetExpression> getFunctionLiteralArguments() {
|
||||||
@@ -82,8 +82,8 @@ public class CallMaker {
|
|||||||
public JetTypeArgumentList getTypeArgumentList() {
|
public JetTypeArgumentList getTypeArgumentList() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
public static Call makeCallWithArguments(final JetExpression calleeExpression, final List<? extends ValueArgument> valueArguments) {
|
public static Call makeCallWithArguments(final JetExpression calleeExpression, final List<? extends ValueArgument> valueArguments) {
|
||||||
return new CallStub() {
|
return new CallStub() {
|
||||||
@Override
|
@Override
|
||||||
@@ -128,4 +128,8 @@ public class CallMaker {
|
|||||||
public static ValueArgument makeValueArgument(@Nullable JetExpression expression, @NotNull PsiElement reportErrorsOn) {
|
public static ValueArgument makeValueArgument(@Nullable JetExpression expression, @NotNull PsiElement reportErrorsOn) {
|
||||||
return new ExpressionValueArgument(expression, reportErrorsOn);
|
return new ExpressionValueArgument(expression, reportErrorsOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Call makePropertyCall(@NotNull JetSimpleNameExpression nameExpression) {
|
||||||
|
return makeCall(nameExpression, Collections.<JetExpression>emptyList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public class ErrorUtils {
|
|||||||
isError(type.getConstructor()));
|
isError(type.getConstructor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isError(@NotNull FunctionDescriptor candidate) {
|
public static boolean isError(@NotNull DeclarationDescriptor candidate) {
|
||||||
return candidate.getContainingDeclaration() == getErrorClass();
|
return candidate.getContainingDeclaration() == getErrorClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -334,6 +334,10 @@ public class JetTypeChecker {
|
|||||||
return new TypeCheckingProcedure().run(subtype, supertype);
|
return new TypeCheckingProcedure().run(subtype, supertype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean equalTypes(@NotNull JetType a, @NotNull JetType b) {
|
||||||
|
return isSubtypeOf(a, b) && isSubtypeOf(b, a);
|
||||||
|
}
|
||||||
|
|
||||||
private static class OldProcedure {
|
private static class OldProcedure {
|
||||||
public static boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
public static boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||||
if (ErrorUtils.isErrorType(subtype) || ErrorUtils.isErrorType(supertype)) {
|
if (ErrorUtils.isErrorType(subtype) || ErrorUtils.isErrorType(supertype)) {
|
||||||
@@ -593,7 +597,5 @@ public class JetTypeChecker {
|
|||||||
protected Boolean result() {
|
protected Boolean result() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
|
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
|
||||||
@@ -662,7 +663,7 @@ public class JetTypeInferrer {
|
|||||||
try {
|
try {
|
||||||
result = expression.visit(this, context);
|
result = expression.visit(this, context);
|
||||||
// Some recursive definitions (object expressions) must put their types in the cache manually:
|
// Some recursive definitions (object expressions) must put their types in the cache manually:
|
||||||
if ((boolean) context.trace.get(BindingContext.PROCESSED, expression)) {
|
if (context.trace.get(BindingContext.PROCESSED, expression)) {
|
||||||
return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,41 +731,70 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType();
|
return getSelectorReturnType(null, expression, context); // TODO : Extensions to this
|
||||||
if (referencedName != null) {
|
// assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType();
|
||||||
VariableDescriptor variable = context.scope.getVariable(referencedName);
|
// if (referencedName != null) {
|
||||||
if (variable != null) {
|
// VariableDescriptor variable = context.scope.getVariable(referencedName);
|
||||||
context.trace.record(REFERENCE_TARGET, expression, variable);
|
// if (variable != null) {
|
||||||
JetType result = variable.getOutType();
|
// context.trace.record(REFERENCE_TARGET, expression, variable);
|
||||||
if (result == null) {
|
// JetType result = variable.getOutType();
|
||||||
context.trace.getErrorHandler().genericError(expression.getNode(), "This variable is not readable in this context");
|
// if (result == null) {
|
||||||
}
|
// context.trace.getErrorHandler().genericError(expression.getNode(), "This variable is not readable in this context");
|
||||||
return context.services.checkEnrichedType(result, expression, context);
|
// }
|
||||||
}
|
// return context.services.checkEnrichedType(result, expression, context);
|
||||||
else {
|
// }
|
||||||
ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
|
// else {
|
||||||
if (classifier != null) {
|
// return lookupNamespaceOrClassObject(expression, referencedName, context);
|
||||||
JetType classObjectType = classifier.getClassObjectType();
|
// ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
|
||||||
JetType result = null;
|
// if (classifier != null) {
|
||||||
if (classObjectType != null && (isNamespacePosition() || classifier.isClassObjectAValue())) {
|
// JetType classObjectType = classifier.getClassObjectType();
|
||||||
result = classObjectType;
|
// JetType result = null;
|
||||||
}
|
// if (classObjectType != null && (isNamespacePosition() || classifier.isClassObjectAValue())) {
|
||||||
else {
|
// result = classObjectType;
|
||||||
context.trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object");
|
// }
|
||||||
}
|
// else {
|
||||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
// context.trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object");
|
||||||
return context.services.checkEnrichedType(result, expression, context);
|
// }
|
||||||
}
|
// context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||||
else {
|
// return context.services.checkEnrichedType(result, expression, context);
|
||||||
JetType[] result = new JetType[1];
|
// }
|
||||||
if (furtherNameLookup(expression, referencedName, result, context)) {
|
// else {
|
||||||
return context.services.checkEnrichedType(result[0], expression, context);
|
// JetType[] result = new JetType[1];
|
||||||
}
|
// if (furtherNameLookup(expression, referencedName, result, context)) {
|
||||||
|
// return context.services.checkEnrichedType(result[0], expression, context);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// context.trace.getErrorHandler().unresolvedReference(expression);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
private JetType lookupNamespaceOrClassObject(JetSimpleNameExpression expression, String referencedName, TypeInferenceContext context) {
|
||||||
}
|
ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
|
||||||
context.trace.getErrorHandler().unresolvedReference(expression);
|
if (classifier != null) {
|
||||||
|
JetType classObjectType = classifier.getClassObjectType();
|
||||||
|
JetType result = null;
|
||||||
|
if (classObjectType != null && (isNamespacePosition() || classifier.isClassObjectAValue())) {
|
||||||
|
result = classObjectType;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
context.trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object");
|
||||||
|
}
|
||||||
|
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||||
|
if (result == null) {
|
||||||
|
return ErrorUtils.createErrorType("No class object in " + expression.getReferencedName());
|
||||||
|
}
|
||||||
|
return context.services.checkEnrichedType(result, expression, context);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JetType[] result = new JetType[1];
|
||||||
|
if (furtherNameLookup(expression, referencedName, result, context)) {
|
||||||
|
return context.services.checkEnrichedType(result[0], expression, context);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1945,11 +1975,25 @@ public class JetTypeInferrer {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private JetType getSelectorReturnType(@Nullable JetType receiverType, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
|
private JetType getSelectorReturnType(@Nullable JetType receiverType, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
|
||||||
if (selectorExpression instanceof JetCallExpression) {
|
if (selectorExpression instanceof JetCallExpression) {
|
||||||
return context.services.callResolver.resolveCall(context.scope, receiverType, (JetCallExpression) selectorExpression, context.expectedType);
|
return context.services.callResolver.resolveCall(context.trace, context.scope, receiverType, (JetCallExpression) selectorExpression, context.expectedType);
|
||||||
}
|
}
|
||||||
else if (selectorExpression instanceof JetSimpleNameExpression) {
|
else if (selectorExpression instanceof JetSimpleNameExpression) {
|
||||||
JetScope scope = receiverType != null ? receiverType.getMemberScope() : context.scope;
|
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression;
|
||||||
return getType(selectorExpression, context.replaceScope(scope));
|
|
||||||
|
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
|
||||||
|
VariableDescriptor variableDescriptor = context.services.callResolver.resolveSimpleProperty(temporaryTrace, context.scope, receiverType, nameExpression, context.expectedType);
|
||||||
|
if (variableDescriptor != null) {
|
||||||
|
temporaryTrace.commit();
|
||||||
|
return context.services.checkEnrichedType(variableDescriptor.getOutType(), nameExpression, context);
|
||||||
|
}
|
||||||
|
TypeInferenceContext newContext = receiverType == null ? context : context.replaceScope(receiverType.getMemberScope());
|
||||||
|
JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext);
|
||||||
|
if (jetType == null) {
|
||||||
|
context.trace.getErrorHandler().unresolvedReference(nameExpression);
|
||||||
|
}
|
||||||
|
return context.services.checkEnrichedType(jetType, nameExpression, context);
|
||||||
|
// JetScope scope = receiverType != null ? receiverType.getMemberScope() : context.scope;
|
||||||
|
// return getType(selectorExpression, context.replaceScope(scope));
|
||||||
}
|
}
|
||||||
else if (selectorExpression instanceof JetQualifiedExpression) {
|
else if (selectorExpression instanceof JetQualifiedExpression) {
|
||||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression;
|
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression;
|
||||||
@@ -1968,7 +2012,7 @@ public class JetTypeInferrer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetType visitCallExpression(JetCallExpression expression, TypeInferenceContext context) {
|
public JetType visitCallExpression(JetCallExpression expression, TypeInferenceContext context) {
|
||||||
JetType expressionType = context.services.callResolver.resolveCall(context.scope, null, expression, context.expectedType);
|
JetType expressionType = context.services.callResolver.resolveCall(context.trace, context.scope, null, expression, context.expectedType);
|
||||||
return context.services.checkType(expressionType, expression, context);
|
return context.services.checkType(expressionType, expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2005,6 +2049,7 @@ public class JetTypeInferrer {
|
|||||||
if (receiverType == null) return null;
|
if (receiverType == null) return null;
|
||||||
|
|
||||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||||
|
context.trace,
|
||||||
context.scope,
|
context.scope,
|
||||||
CallMaker.makeCall(expression),
|
CallMaker.makeCall(expression),
|
||||||
expression.getOperationSign(),
|
expression.getOperationSign(),
|
||||||
@@ -2159,6 +2204,7 @@ public class JetTypeInferrer {
|
|||||||
String name = "contains";
|
String name = "contains";
|
||||||
JetType receiverType = context.services.safeGetType(context.scope, right, NO_EXPECTED_TYPE);
|
JetType receiverType = context.services.safeGetType(context.scope, right, NO_EXPECTED_TYPE);
|
||||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||||
|
context.trace,
|
||||||
context.scope,
|
context.scope,
|
||||||
CallMaker.makeCall(operationSign, Collections.singletonList(left)),
|
CallMaker.makeCall(operationSign, Collections.singletonList(left)),
|
||||||
operationSign,
|
operationSign,
|
||||||
@@ -2226,6 +2272,7 @@ public class JetTypeInferrer {
|
|||||||
|
|
||||||
if (receiverType != null) {
|
if (receiverType != null) {
|
||||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||||
|
context.trace,
|
||||||
context.scope,
|
context.scope,
|
||||||
CallMaker.makeCall(expression, expression.getIndexExpressions()),
|
CallMaker.makeCall(expression, expression.getIndexExpressions()),
|
||||||
expression,
|
expression,
|
||||||
@@ -2243,6 +2290,7 @@ public class JetTypeInferrer {
|
|||||||
protected JetType getTypeForBinaryCall(JetScope scope, String name, TypeInferenceContext context, JetBinaryExpression binaryExpression) {
|
protected JetType getTypeForBinaryCall(JetScope scope, String name, TypeInferenceContext context, JetBinaryExpression binaryExpression) {
|
||||||
JetType leftType = getType(binaryExpression.getLeft(), context.replaceScope(scope));
|
JetType leftType = getType(binaryExpression.getLeft(), context.replaceScope(scope));
|
||||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||||
|
context.trace,
|
||||||
scope,
|
scope,
|
||||||
CallMaker.makeCall(binaryExpression),
|
CallMaker.makeCall(binaryExpression),
|
||||||
binaryExpression.getOperationReference(),
|
binaryExpression.getOperationReference(),
|
||||||
@@ -2479,10 +2527,11 @@ public class JetTypeInferrer {
|
|||||||
// arrayAccessExpression,
|
// arrayAccessExpression,
|
||||||
// "set", arrayAccessExpression.getArrayExpression(), NO_EXPECTED_TYPE);
|
// "set", arrayAccessExpression.getArrayExpression(), NO_EXPECTED_TYPE);
|
||||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||||
scope,
|
context.trace,
|
||||||
call,
|
scope,
|
||||||
arrayAccessExpression,
|
call,
|
||||||
"set", receiverType, NO_EXPECTED_TYPE);
|
arrayAccessExpression,
|
||||||
|
"set", receiverType, NO_EXPECTED_TYPE);
|
||||||
if (functionDescriptor == null) return null;
|
if (functionDescriptor == null) return null;
|
||||||
context.trace.record(REFERENCE_TARGET, operationSign, functionDescriptor);
|
context.trace.record(REFERENCE_TARGET, operationSign, functionDescriptor);
|
||||||
return context.services.checkType(functionDescriptor.getReturnType(), arrayAccessExpression, context);
|
return context.services.checkType(functionDescriptor.getReturnType(), arrayAccessExpression, context);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class JetLineMarkerProvider implements LineMarkerProvider {
|
|||||||
|
|
||||||
final FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, jetFunction);
|
final FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, jetFunction);
|
||||||
if (functionDescriptor == null) return null;
|
if (functionDescriptor == null) return null;
|
||||||
final Set<? extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenFunctions();
|
final Set<? extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenDescriptors();
|
||||||
Icon icon = isMember(functionDescriptor) ? (overriddenFunctions.isEmpty() ? PlatformIcons.METHOD_ICON : OVERRIDING_FUNCTION) : PlatformIcons.FUNCTION_ICON;
|
Icon icon = isMember(functionDescriptor) ? (overriddenFunctions.isEmpty() ? PlatformIcons.METHOD_ICON : OVERRIDING_FUNCTION) : PlatformIcons.FUNCTION_ICON;
|
||||||
return new LineMarkerInfo<JetNamedFunction>(
|
return new LineMarkerInfo<JetNamedFunction>(
|
||||||
jetFunction, jetFunction.getTextOffset(), icon, Pass.UPDATE_ALL,
|
jetFunction, jetFunction.getTextOffset(), icon, Pass.UPDATE_ALL,
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ public class DescriptorRenderer {
|
|||||||
@Override
|
@Override
|
||||||
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) {
|
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) {
|
||||||
String typeString = renderPropertyPrefixAndComputeTypeString(
|
String typeString = renderPropertyPrefixAndComputeTypeString(
|
||||||
builder, descriptor.getTypeParemeters(),
|
builder, descriptor.getTypeParameters(),
|
||||||
descriptor.getReceiverType(),
|
descriptor.getReceiverType(),
|
||||||
descriptor.getOutType(),
|
descriptor.getOutType(),
|
||||||
descriptor.getInType());
|
descriptor.getInType());
|
||||||
|
|||||||
Reference in New Issue
Block a user