KT-377 Prohibit 'super' as a receiver argument to extension functions
+ SEVERITY_LEVELS added instead of hardcoding weak errors + commit() in temporary trace removed the data, so that double commit does not cause duplication of data
This commit is contained in:
@@ -70,6 +70,11 @@ public class DelegatingBindingTrace implements BindingTrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
diagnostics.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void report(@NotNull Diagnostic diagnostic) {
|
public void report(@NotNull Diagnostic diagnostic) {
|
||||||
diagnostics.add(diagnostic);
|
diagnostics.add(diagnostic);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
|
|||||||
|
|
||||||
private final BindingTrace trace;
|
private final BindingTrace trace;
|
||||||
|
|
||||||
|
|
||||||
private TemporaryBindingTrace(BindingTrace trace) {
|
private TemporaryBindingTrace(BindingTrace trace) {
|
||||||
super(trace.getBindingContext());
|
super(trace.getBindingContext());
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
@@ -18,5 +19,6 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
|
|||||||
|
|
||||||
public void commit() {
|
public void commit() {
|
||||||
addAllMyDataTo(trace);
|
addAllMyDataTo(trace);
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,8 +206,6 @@ public class CallResolver {
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
|
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
|
||||||
@NotNull final JetReferenceExpression reference) {
|
@NotNull final JetReferenceExpression reference) {
|
||||||
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
|
|
||||||
OverloadResolutionResults<D> resultsForFirstNonemptyCandidateSet = null;
|
|
||||||
TracingStrategy tracing = new TracingStrategy() {
|
TracingStrategy tracing = new TracingStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl<D> resolvedCall) {
|
public <D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl<D> resolvedCall) {
|
||||||
@@ -272,12 +270,12 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {
|
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {
|
||||||
trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(call.getCallNode(), descriptors));
|
trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(call.getCallNode(), descriptors));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {
|
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {
|
||||||
trace.report(NONE_APPLICABLE.on(reference, descriptors));
|
trace.report(NONE_APPLICABLE.on(reference, descriptors));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,6 +321,9 @@ public class CallResolver {
|
|||||||
trace.report(UNNECESSARY_SAFE_CALL.on((JetElement) callOperationNode.getTreeParent().getPsi(), callOperationNode, type));
|
trace.report(UNNECESSARY_SAFE_CALL.on((JetElement) callOperationNode.getTreeParent().getPsi(), callOperationNode, type));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
|
||||||
|
OverloadResolutionResults<D> resultsForFirstNonemptyCandidateSet = null;
|
||||||
for (ResolutionTask<D> task : prioritizedTasks) {
|
for (ResolutionTask<D> task : prioritizedTasks) {
|
||||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
||||||
OverloadResolutionResults<D> results = performResolution(temporaryTrace, scope, expectedType, task, tracing);
|
OverloadResolutionResults<D> results = performResolution(temporaryTrace, scope, expectedType, task, tracing);
|
||||||
@@ -479,6 +480,14 @@ public class CallResolver {
|
|||||||
|
|
||||||
task.performAdvancedChecks(candidate, temporaryTrace, tracing);
|
task.performAdvancedChecks(candidate, temporaryTrace, tracing);
|
||||||
|
|
||||||
|
// 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
|
||||||
|
// See TaskPrioritizer for more
|
||||||
|
JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
|
||||||
|
if (superExpression != null) {
|
||||||
|
temporaryTrace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
|
||||||
|
candidateCall.setStatus(OTHER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
||||||
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
||||||
}
|
}
|
||||||
@@ -540,21 +549,6 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private <D extends CallableDescriptor> Function<ValueParameterDescriptor, ValueParameterDescriptor> createMapFunction(D substitutedFunctionDescriptor) {
|
|
||||||
// assert substitutedFunctionDescriptor != null;
|
|
||||||
// final Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
|
||||||
// for (ValueParameterDescriptor valueParameterDescriptor : substitutedFunctionDescriptor.getValueParameters()) {
|
|
||||||
// parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return new Function<ValueParameterDescriptor, ValueParameterDescriptor>() {
|
|
||||||
// @Override
|
|
||||||
// public ValueParameterDescriptor apply(ValueParameterDescriptor input) {
|
|
||||||
// return parameterMap.get(input.getOriginal());
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
private <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
private <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
||||||
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
||||||
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
|
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
|
||||||
@@ -656,30 +650,47 @@ public class CallResolver {
|
|||||||
Set<ResolvedCallImpl<D>> successfulCandidates,
|
Set<ResolvedCallImpl<D>> successfulCandidates,
|
||||||
Set<ResolvedCallImpl<D>> failedCandidates) {
|
Set<ResolvedCallImpl<D>> failedCandidates) {
|
||||||
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
|
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
|
||||||
|
|
||||||
if (successfulCandidates.size() > 0) {
|
if (successfulCandidates.size() > 0) {
|
||||||
return chooseAndReportMaximallySpecific(trace, tracing, successfulCandidates);
|
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(successfulCandidates);
|
||||||
|
if (results.isAmbiguity()) {
|
||||||
|
// This check is needed for the following case:
|
||||||
|
// x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here
|
||||||
|
if (allClean(results.getResults())) {
|
||||||
|
tracing.ambiguity(trace, results.getResults());
|
||||||
|
}
|
||||||
|
tracing.recordAmbiguity(trace, results.getResults());
|
||||||
|
}
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
else if (!failedCandidates.isEmpty()) {
|
else if (!failedCandidates.isEmpty()) {
|
||||||
if (failedCandidates.size() != 1) {
|
if (failedCandidates.size() != 1) {
|
||||||
Set<ResolvedCallImpl<D>> weakErrors = Sets.newLinkedHashSet();
|
// This is needed when there are several overloads some of which are OK but for nullability of the receiver,
|
||||||
for (ResolvedCallImpl<D> candidate : failedCandidates) {
|
// and some are not OK at all. In this case we'd like to say "unsafe call" rather than "none applicable"
|
||||||
if (candidate.getStatus().isWeakError()) {
|
// Used to be: weak errors. Generalized for future extensions
|
||||||
weakErrors.add(candidate);
|
for (EnumSet<ResolutionStatus> severityLevel : SEVERITY_LEVELS) {
|
||||||
}
|
Set<ResolvedCallImpl<D>> thisLevel = Sets.newLinkedHashSet();
|
||||||
}
|
for (ResolvedCallImpl<D> candidate : failedCandidates) {
|
||||||
if (!weakErrors.isEmpty()) {
|
if (severityLevel.contains(candidate.getStatus())) {
|
||||||
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(trace, tracing, weakErrors);
|
thisLevel.add(candidate);
|
||||||
if (results.isSuccess()) {
|
}
|
||||||
return OverloadResolutionResults.singleFailedCandidate(results.getResult());
|
|
||||||
}
|
}
|
||||||
|
if (!thisLevel.isEmpty()) {
|
||||||
|
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(thisLevel);
|
||||||
|
if (results.isSuccess()) {
|
||||||
|
results.getResult().getTrace().commit();
|
||||||
|
return OverloadResolutionResults.singleFailedCandidate(results.getResult());
|
||||||
|
}
|
||||||
|
|
||||||
return OverloadResolutionResults.manyFailedCandidates(results.getResults());
|
tracing.noneApplicable(trace, results.getResults());
|
||||||
|
tracing.recordAmbiguity(trace, results.getResults());
|
||||||
|
return OverloadResolutionResults.manyFailedCandidates(results.getResults());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
assert false : "Should not be reachable, cause every status must belong to some level";
|
||||||
|
|
||||||
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
|
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
|
||||||
if (noOverrides.size() != 1) {
|
if (noOverrides.size() != 1) {
|
||||||
// tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: "
|
|
||||||
// + makeErrorMessageForMultipleDescriptors(noOverrides));
|
|
||||||
tracing.noneApplicable(trace, noOverrides);
|
tracing.noneApplicable(trace, noOverrides);
|
||||||
tracing.recordAmbiguity(trace, noOverrides);
|
tracing.recordAmbiguity(trace, noOverrides);
|
||||||
return OverloadResolutionResults.manyFailedCandidates(noOverrides);
|
return OverloadResolutionResults.manyFailedCandidates(noOverrides);
|
||||||
@@ -696,15 +707,20 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> chooseAndReportMaximallySpecific(BindingTrace trace, TracingStrategy tracing, Set<ResolvedCallImpl<D>> candidates) {
|
private <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallImpl<D>> results) {
|
||||||
|
for (ResolvedCallImpl<D> result : results) {
|
||||||
|
if (result.isDirty()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D extends CallableDescriptor> OverloadResolutionResults<D> chooseAndReportMaximallySpecific(Set<ResolvedCallImpl<D>> candidates) {
|
||||||
if (candidates.size() != 1) {
|
if (candidates.size() != 1) {
|
||||||
Set<ResolvedCallImpl<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
Set<ResolvedCallImpl<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
||||||
boolean allClean = true;
|
|
||||||
for (Iterator<ResolvedCallImpl<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
for (Iterator<ResolvedCallImpl<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
||||||
ResolvedCallImpl<D> candidate = iterator.next();
|
ResolvedCallImpl<D> candidate = iterator.next();
|
||||||
if (candidate.isDirty()) {
|
if (candidate.isDirty()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
allClean = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,13 +738,6 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
||||||
if (allClean) {
|
|
||||||
// tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: "
|
|
||||||
// + makeErrorMessageForMultipleDescriptors(noOverrides));
|
|
||||||
tracing.ambiguity(trace, noOverrides);
|
|
||||||
}
|
|
||||||
|
|
||||||
tracing.recordAmbiguity(trace, noOverrides);
|
|
||||||
|
|
||||||
return OverloadResolutionResults.ambiguity(noOverrides);
|
return OverloadResolutionResults.ambiguity(noOverrides);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.calls;
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
@@ -9,7 +11,14 @@ public enum ResolutionStatus {
|
|||||||
OTHER_ERROR,
|
OTHER_ERROR,
|
||||||
SUCCESS(true);
|
SUCCESS(true);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] {
|
||||||
|
EnumSet.of(UNSAFE_CALL_ERROR), // weakest
|
||||||
|
EnumSet.of(OTHER_ERROR), // most severe
|
||||||
|
};
|
||||||
|
|
||||||
private final boolean success;
|
private final boolean success;
|
||||||
|
private int severityIndex = -1;
|
||||||
|
|
||||||
private ResolutionStatus(boolean success) {
|
private ResolutionStatus(boolean success) {
|
||||||
this.success = success;
|
this.success = success;
|
||||||
@@ -25,11 +34,21 @@ public enum ResolutionStatus {
|
|||||||
|
|
||||||
public ResolutionStatus combine(ResolutionStatus other) {
|
public ResolutionStatus combine(ResolutionStatus other) {
|
||||||
if (this.isSuccess()) return other;
|
if (this.isSuccess()) return other;
|
||||||
if (this.isWeakError() && !other.isSuccess()) return other;
|
if (!other.isSuccess() && this.getSeverityIndex() < other.getSeverityIndex()) return other;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getSeverityIndex() {
|
||||||
|
if (severityIndex == -1) {
|
||||||
|
for (int i = 0; i < SEVERITY_LEVELS.length; i++) {
|
||||||
|
if (SEVERITY_LEVELS[i].contains(this)) {
|
||||||
|
severityIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert severityIndex >= 0;
|
||||||
|
|
||||||
public boolean isWeakError() {
|
return severityIndex;
|
||||||
return this == UNSAFE_CALL_ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,20 @@ package org.jetbrains.jet.lang.resolve.calls;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.Call;
|
import org.jetbrains.jet.lang.psi.Call;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSuperExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastService;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastService;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||||
@@ -72,6 +76,18 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
/*package*/ static JetSuperExpression getReceiverSuper(@NotNull ReceiverDescriptor receiver) {
|
||||||
|
if (receiver instanceof ExpressionReceiver) {
|
||||||
|
ExpressionReceiver expressionReceiver = (ExpressionReceiver) receiver;
|
||||||
|
JetExpression expression = expressionReceiver.getExpression();
|
||||||
|
if (expression instanceof JetSuperExpression) {
|
||||||
|
return (JetSuperExpression) expression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
||||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||||
|
|
||||||
@@ -108,8 +124,17 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members);
|
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members);
|
||||||
}
|
}
|
||||||
|
|
||||||
addTask(result, call, locals, dataFlowInfo);
|
if (getReceiverSuper(receiver) != null) {
|
||||||
addTask(result, call, members, dataFlowInfo);
|
// If the call is of the form super.foo(), it can actually be only a member
|
||||||
|
// But if there's no appropriate member, we would like to report that super cannot be a receiver for an extension
|
||||||
|
// Thus, put members first
|
||||||
|
addTask(result, call, members, dataFlowInfo);
|
||||||
|
addTask(result, call, locals, dataFlowInfo);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addTask(result, call, locals, dataFlowInfo);
|
||||||
|
addTask(result, call, members, dataFlowInfo);
|
||||||
|
}
|
||||||
|
|
||||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||||
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
|||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -40,10 +39,10 @@ import java.util.Set;
|
|||||||
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {}
|
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {}
|
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {}
|
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
|
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
|
||||||
@@ -74,9 +73,9 @@ import java.util.Set;
|
|||||||
|
|
||||||
void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount);
|
void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount);
|
||||||
|
|
||||||
<D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors);
|
<D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors);
|
||||||
|
|
||||||
<D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors);
|
<D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors);
|
||||||
|
|
||||||
void instantiationOfAbstractClass(@NotNull BindingTrace trace);
|
void instantiationOfAbstractClass(@NotNull BindingTrace trace);
|
||||||
|
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ public interface MutableSlicedMap extends SlicedMap {
|
|||||||
<K, V> void put(WritableSlice<K, V> slice, K key, V value);
|
<K, V> void put(WritableSlice<K, V> slice, K key, V value);
|
||||||
|
|
||||||
<K, V> V remove(RemovableSlice<K, V> slice, K key);
|
<K, V> V remove(RemovableSlice<K, V> slice, K key);
|
||||||
|
|
||||||
|
void clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ public class SlicedMapImpl implements MutableSlicedMap {
|
|||||||
slice.afterPut(this, key, value);
|
slice.afterPut(this, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
||||||
SlicedMapKey<K, V> slicedMapKey = slice.makeKey(key);
|
SlicedMapKey<K, V> slicedMapKey = slice.makeKey(key);
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
trait T {
|
||||||
|
fun foo() {}
|
||||||
|
fun buzz() {}
|
||||||
|
fun buzz1(i : Int) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun T.bar() {}
|
||||||
|
|
||||||
|
fun T.buzz() {}
|
||||||
|
fun T.buzz1() {}
|
||||||
|
|
||||||
|
class C : T {
|
||||||
|
fun test() {
|
||||||
|
fun T.buzz() {}
|
||||||
|
fun T.buzz1() {}
|
||||||
|
super.foo() // OK
|
||||||
|
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>.bar() // Error
|
||||||
|
super.buzz() // OK, resolved to a member
|
||||||
|
super.<!NO_VALUE_FOR_PARAMETER!>buzz1<!>() // Resolved to a member, but error: no parameter passed where required
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,17 @@
|
|||||||
namespace example;
|
namespace example;
|
||||||
|
|
||||||
|
fun any(a : Any) {}
|
||||||
|
|
||||||
|
fun notAnExpression() {
|
||||||
|
any(<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>) // not an expression
|
||||||
|
if (<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>) {} else {} // not an expression
|
||||||
|
val x = <!SUPER_IS_NOT_AN_EXPRESSION!>super<!> // not an expression
|
||||||
|
when (1) {
|
||||||
|
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> => 1 // not an expression
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
trait T {
|
trait T {
|
||||||
fun foo() {}
|
fun foo() {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user