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>();
|
||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||
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
|
||||
@Override
|
||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
||||
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +1,26 @@
|
||||
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 FunctionDescriptor extends DeclarationDescriptor {
|
||||
public interface FunctionDescriptor extends CallableDescriptor {
|
||||
@Override
|
||||
@NotNull
|
||||
DeclarationDescriptor getContainingDeclaration();
|
||||
|
||||
@Nullable
|
||||
JetType getReceiverType();
|
||||
|
||||
@NotNull
|
||||
List<TypeParameterDescriptor> getTypeParameters();
|
||||
|
||||
@NotNull
|
||||
List<ValueParameterDescriptor> getValueParameters();
|
||||
|
||||
@NotNull
|
||||
JetType getReturnType();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
FunctionDescriptor getOriginal();
|
||||
|
||||
@Override
|
||||
FunctionDescriptor substitute(TypeSubstitutor substitutor);
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
Set<? extends FunctionDescriptor> getOverriddenFunctions();
|
||||
Set<? extends FunctionDescriptor> getOverriddenDescriptors();
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
||||
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||
return overriddenFunctions;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class FunctionDescriptorUtil {
|
||||
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();
|
||||
|
||||
Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
|
||||
@@ -112,59 +112,6 @@ public class FunctionDescriptorUtil {
|
||||
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 {
|
||||
|
||||
private static final OverrideCompatibilityInfo SUCCESS = new OverrideCompatibilityInfo(false, "SUCCESS");
|
||||
|
||||
@@ -78,7 +78,8 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<TypeParameterDescriptor> getTypeParemeters() {
|
||||
@Override
|
||||
public List<TypeParameterDescriptor> getTypeParameters() {
|
||||
return typeParemeters;
|
||||
}
|
||||
|
||||
@@ -87,6 +88,12 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
||||
return receiverType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReturnType() {
|
||||
return getOutType();
|
||||
}
|
||||
|
||||
|
||||
public boolean isVar() {
|
||||
return isVar;
|
||||
@@ -110,7 +117,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VariableDescriptor substitute(TypeSubstitutor substitutor) {
|
||||
public PropertyDescriptor substitute(TypeSubstitutor substitutor) {
|
||||
JetType originalInType = getInType();
|
||||
JetType inType = originalInType == null ? null : substitutor.substitute(originalInType, Variance.IN_VARIANCE);
|
||||
JetType originalOutType = getOutType();
|
||||
|
||||
@@ -24,7 +24,7 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
||||
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||
return overriddenGetters;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<? extends FunctionDescriptor> getOverriddenFunctions() {
|
||||
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||
return overriddenSetters;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -44,4 +46,39 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
|
||||
protected void setOutType(JetType 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;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -30,4 +35,58 @@ public class DescriptorUtils {
|
||||
}
|
||||
}, 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();
|
||||
if (typeReference != 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 {
|
||||
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||
@@ -685,7 +685,7 @@ public class TopDownAnalyzer {
|
||||
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
||||
JetTypeReference typeReference = call.getTypeReference();
|
||||
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) {
|
||||
// TODO : check that there's no recursion in this() calls
|
||||
// TODO : check: if a this() call is present, no other initializers are allowed
|
||||
// ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||
// typeInferrerForInitializers.checkClassConstructorCall(
|
||||
// functionInnerScope,
|
||||
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||
|
||||
typeInferrerForInitializers.getCallResolver().resolveCall(trace,
|
||||
functionInnerScope,
|
||||
null, call, NO_EXPECTED_TYPE);
|
||||
// call.getThisReference(),
|
||||
// classDescriptor,
|
||||
// classDescriptor.getDefaultType(),
|
||||
// call);
|
||||
trace.getErrorHandler().genericError(call.getNode(), "this-calls are not supported");
|
||||
// trace.getErrorHandler().genericError(call.getNode(), "this-calls are not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -805,7 +807,7 @@ public class TopDownAnalyzer {
|
||||
|
||||
private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||
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);
|
||||
}
|
||||
JetType receiverType = propertyDescriptor.getReceiverType();
|
||||
|
||||
+380
-412
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 final JetExpression expression;
|
||||
private final PsiElement reportErrorsOn;
|
||||
|
||||
private final PsiElement reportErrorsOn;
|
||||
private ExpressionValueArgument(@NotNull JetExpression expression) {
|
||||
this(expression, expression);
|
||||
}
|
||||
@@ -58,14 +58,14 @@ public class CallMaker {
|
||||
public PsiElement asElement() {
|
||||
return reportErrorsOn;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private static abstract class CallStub implements Call {
|
||||
|
||||
@Override
|
||||
public JetValueArgumentList getValueArgumentList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetExpression> getFunctionLiteralArguments() {
|
||||
@@ -82,8 +82,8 @@ public class CallMaker {
|
||||
public JetTypeArgumentList getTypeArgumentList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public static Call makeCallWithArguments(final JetExpression calleeExpression, final List<? extends ValueArgument> valueArguments) {
|
||||
return new CallStub() {
|
||||
@Override
|
||||
@@ -128,4 +128,8 @@ public class CallMaker {
|
||||
public static ValueArgument makeValueArgument(@Nullable JetExpression expression, @NotNull PsiElement 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()));
|
||||
}
|
||||
|
||||
public static boolean isError(@NotNull FunctionDescriptor candidate) {
|
||||
public static boolean isError(@NotNull DeclarationDescriptor candidate) {
|
||||
return candidate.getContainingDeclaration() == getErrorClass();
|
||||
}
|
||||
|
||||
|
||||
@@ -334,6 +334,10 @@ public class JetTypeChecker {
|
||||
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 {
|
||||
public static boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
if (ErrorUtils.isErrorType(subtype) || ErrorUtils.isErrorType(supertype)) {
|
||||
@@ -593,7 +597,5 @@ public class JetTypeChecker {
|
||||
protected Boolean 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.psi.*;
|
||||
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.CompileTimeConstantResolver;
|
||||
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
|
||||
@@ -662,7 +663,7 @@ public class JetTypeInferrer {
|
||||
try {
|
||||
result = expression.visit(this, context);
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -730,41 +731,70 @@ public class JetTypeInferrer {
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType();
|
||||
if (referencedName != null) {
|
||||
VariableDescriptor variable = context.scope.getVariable(referencedName);
|
||||
if (variable != null) {
|
||||
context.trace.record(REFERENCE_TARGET, expression, variable);
|
||||
JetType result = variable.getOutType();
|
||||
if (result == null) {
|
||||
context.trace.getErrorHandler().genericError(expression.getNode(), "This variable is not readable in this context");
|
||||
}
|
||||
return context.services.checkEnrichedType(result, expression, context);
|
||||
}
|
||||
else {
|
||||
ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
context.trace.getErrorHandler().unresolvedReference(expression);
|
||||
return getSelectorReturnType(null, expression, context); // TODO : Extensions to this
|
||||
// assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType();
|
||||
// if (referencedName != null) {
|
||||
// VariableDescriptor variable = context.scope.getVariable(referencedName);
|
||||
// if (variable != null) {
|
||||
// context.trace.record(REFERENCE_TARGET, expression, variable);
|
||||
// JetType result = variable.getOutType();
|
||||
// if (result == null) {
|
||||
// context.trace.getErrorHandler().genericError(expression.getNode(), "This variable is not readable in this context");
|
||||
// }
|
||||
// return context.services.checkEnrichedType(result, expression, context);
|
||||
// }
|
||||
// else {
|
||||
// return lookupNamespaceOrClassObject(expression, referencedName, context);
|
||||
// ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
|
||||
// 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);
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// context.trace.getErrorHandler().unresolvedReference(expression);
|
||||
// }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private JetType lookupNamespaceOrClassObject(JetSimpleNameExpression expression, String referencedName, TypeInferenceContext context) {
|
||||
ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
|
||||
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;
|
||||
}
|
||||
@@ -1945,11 +1975,25 @@ public class JetTypeInferrer {
|
||||
@Nullable
|
||||
private JetType getSelectorReturnType(@Nullable JetType receiverType, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
|
||||
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) {
|
||||
JetScope scope = receiverType != null ? receiverType.getMemberScope() : context.scope;
|
||||
return getType(selectorExpression, context.replaceScope(scope));
|
||||
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression;
|
||||
|
||||
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) {
|
||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression;
|
||||
@@ -1968,7 +2012,7 @@ public class JetTypeInferrer {
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -2005,6 +2049,7 @@ public class JetTypeInferrer {
|
||||
if (receiverType == null) return null;
|
||||
|
||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
context.scope,
|
||||
CallMaker.makeCall(expression),
|
||||
expression.getOperationSign(),
|
||||
@@ -2159,6 +2204,7 @@ public class JetTypeInferrer {
|
||||
String name = "contains";
|
||||
JetType receiverType = context.services.safeGetType(context.scope, right, NO_EXPECTED_TYPE);
|
||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
context.scope,
|
||||
CallMaker.makeCall(operationSign, Collections.singletonList(left)),
|
||||
operationSign,
|
||||
@@ -2226,6 +2272,7 @@ public class JetTypeInferrer {
|
||||
|
||||
if (receiverType != null) {
|
||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
context.scope,
|
||||
CallMaker.makeCall(expression, expression.getIndexExpressions()),
|
||||
expression,
|
||||
@@ -2243,6 +2290,7 @@ public class JetTypeInferrer {
|
||||
protected JetType getTypeForBinaryCall(JetScope scope, String name, TypeInferenceContext context, JetBinaryExpression binaryExpression) {
|
||||
JetType leftType = getType(binaryExpression.getLeft(), context.replaceScope(scope));
|
||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
scope,
|
||||
CallMaker.makeCall(binaryExpression),
|
||||
binaryExpression.getOperationReference(),
|
||||
@@ -2479,10 +2527,11 @@ public class JetTypeInferrer {
|
||||
// arrayAccessExpression,
|
||||
// "set", arrayAccessExpression.getArrayExpression(), NO_EXPECTED_TYPE);
|
||||
FunctionDescriptor functionDescriptor = context.services.callResolver.resolveCallWithGivenName(
|
||||
scope,
|
||||
call,
|
||||
arrayAccessExpression,
|
||||
"set", receiverType, NO_EXPECTED_TYPE);
|
||||
context.trace,
|
||||
scope,
|
||||
call,
|
||||
arrayAccessExpression,
|
||||
"set", receiverType, NO_EXPECTED_TYPE);
|
||||
if (functionDescriptor == null) return null;
|
||||
context.trace.record(REFERENCE_TARGET, operationSign, functionDescriptor);
|
||||
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);
|
||||
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;
|
||||
return new LineMarkerInfo<JetNamedFunction>(
|
||||
jetFunction, jetFunction.getTextOffset(), icon, Pass.UPDATE_ALL,
|
||||
|
||||
@@ -171,7 +171,7 @@ public class DescriptorRenderer {
|
||||
@Override
|
||||
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) {
|
||||
String typeString = renderPropertyPrefixAndComputeTypeString(
|
||||
builder, descriptor.getTypeParemeters(),
|
||||
builder, descriptor.getTypeParameters(),
|
||||
descriptor.getReceiverType(),
|
||||
descriptor.getOutType(),
|
||||
descriptor.getInType());
|
||||
|
||||
Reference in New Issue
Block a user