Resolve invisible references and mark them 'invisible' instead of mark them 'unresolved'
This commit is contained in:
@@ -53,7 +53,10 @@ public interface Errors {
|
||||
});
|
||||
|
||||
UnresolvedReferenceDiagnosticFactory UNRESOLVED_REFERENCE = UnresolvedReferenceDiagnosticFactory.create("Unresolved reference");
|
||||
DiagnosticFactory2<JetSimpleNameExpression, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER = DiagnosticFactory2.create(ERROR, "''{0}'' has private access in ''{1}''", NAME, NAME);
|
||||
|
||||
//Elements with "INVISIBLE_REFERENCE" error are marked as unresolved, unlike elements with "INVISIBLE_MEMBER" error
|
||||
DiagnosticFactory2<JetSimpleNameExpression, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_REFERENCE = DiagnosticFactory2.create(ERROR, "Cannot access ''{0}'' in ''{1}''", NAME, NAME);
|
||||
DiagnosticFactory2<PsiElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER = DiagnosticFactory2.create(ERROR, "Cannot access ''{0}'' in ''{1}''", NAME, NAME);
|
||||
|
||||
RedeclarationDiagnosticFactory REDECLARATION = RedeclarationDiagnosticFactory.REDECLARATION;
|
||||
RedeclarationDiagnosticFactory NAME_SHADOWING = RedeclarationDiagnosticFactory.NAME_SHADOWING;
|
||||
|
||||
@@ -20,10 +20,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
@@ -91,13 +88,13 @@ public class ImportsResolver {
|
||||
Collection<JetImportDirective> defaultImportDirectives = Lists.newArrayList();
|
||||
configuration.addDefaultImports(defaultImportDirectives);
|
||||
for (JetImportDirective defaultImportDirective : defaultImportDirectives) {
|
||||
qualifiedExpressionResolver.processImportReference(defaultImportDirective, rootScope, delayedImporter, temporaryTrace, onlyClasses);
|
||||
qualifiedExpressionResolver.processImportReference(defaultImportDirective, rootScope, namespaceScope, delayedImporter, temporaryTrace, onlyClasses);
|
||||
}
|
||||
|
||||
List<JetImportDirective> importDirectives = file.getImportDirectives();
|
||||
for (JetImportDirective importDirective : importDirectives) {
|
||||
Collection<? extends DeclarationDescriptor> descriptors =
|
||||
qualifiedExpressionResolver.processImportReference(importDirective, rootScope, delayedImporter, trace, onlyClasses);
|
||||
qualifiedExpressionResolver.processImportReference(importDirective, rootScope, namespaceScope, delayedImporter, trace, onlyClasses);
|
||||
if (descriptors.size() == 1) {
|
||||
resolvedDirectives.put(importDirective, descriptors.iterator().next());
|
||||
}
|
||||
|
||||
+44
-23
@@ -42,12 +42,12 @@ public class QualifiedExpressionResolver {
|
||||
public Collection<? extends DeclarationDescriptor> analyseImportReference(@NotNull JetImportDirective importDirective,
|
||||
@NotNull JetScope scope, @NotNull BindingTrace trace) {
|
||||
|
||||
return processImportReference(importDirective, scope, Importer.DO_NOTHING, trace, false);
|
||||
return processImportReference(importDirective, scope, scope, Importer.DO_NOTHING, trace, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<? extends DeclarationDescriptor> processImportReference(@NotNull JetImportDirective importDirective,
|
||||
@NotNull JetScope scope, @NotNull Importer importer, @NotNull BindingTrace trace, boolean onlyClasses) {
|
||||
@NotNull JetScope scope, @NotNull JetScope scopeToCheckVisibility, @NotNull Importer importer, @NotNull BindingTrace trace, boolean onlyClasses) {
|
||||
|
||||
if (importDirective.isAbsoluteInRootNamespace()) {
|
||||
trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
|
||||
@@ -61,11 +61,11 @@ public class QualifiedExpressionResolver {
|
||||
Collection<? extends DeclarationDescriptor> descriptors;
|
||||
if (importedReference instanceof JetQualifiedExpression) {
|
||||
//store result only when we find all descriptors, not only classes on the second phase
|
||||
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression)importedReference, scope, trace, onlyClasses, !onlyClasses);
|
||||
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression)importedReference, scope, scopeToCheckVisibility, trace, onlyClasses, !onlyClasses);
|
||||
}
|
||||
else {
|
||||
assert importedReference instanceof JetSimpleNameExpression;
|
||||
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression)importedReference, scope, trace, onlyClasses, true, !onlyClasses);
|
||||
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression)importedReference, scope, scopeToCheckVisibility, trace, onlyClasses, true, !onlyClasses);
|
||||
}
|
||||
|
||||
JetSimpleNameExpression referenceExpression = JetPsiUtil.getLastReference(importedReference);
|
||||
@@ -140,24 +140,24 @@ public class QualifiedExpressionResolver {
|
||||
}
|
||||
JetUserType qualifier = userType.getQualifier();
|
||||
if (qualifier == null) {
|
||||
return lookupDescriptorsForSimpleNameReference(referenceExpression, outerScope, trace, true, false, true);
|
||||
return lookupDescriptorsForSimpleNameReference(referenceExpression, outerScope, outerScope, trace, true, false, true);
|
||||
}
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = lookupDescriptorsForUserType(qualifier, outerScope, trace);
|
||||
return lookupSelectorDescriptors(referenceExpression, declarationDescriptors, trace, true, true);
|
||||
return lookupSelectorDescriptors(referenceExpression, declarationDescriptors, trace, outerScope, true, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<? extends DeclarationDescriptor> lookupDescriptorsForQualifiedExpression(@NotNull JetQualifiedExpression importedReference,
|
||||
@NotNull JetScope outerScope, @NotNull BindingTrace trace, boolean onlyClasses, boolean storeResult) {
|
||||
@NotNull JetScope outerScope, @NotNull JetScope scopeToCheckVisibility, @NotNull BindingTrace trace, boolean onlyClasses, boolean storeResult) {
|
||||
|
||||
JetExpression receiverExpression = importedReference.getReceiverExpression();
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors;
|
||||
if (receiverExpression instanceof JetQualifiedExpression) {
|
||||
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression)receiverExpression, outerScope, trace, onlyClasses, storeResult);
|
||||
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression)receiverExpression, outerScope, scopeToCheckVisibility, trace, onlyClasses, storeResult);
|
||||
}
|
||||
else {
|
||||
assert receiverExpression instanceof JetSimpleNameExpression;
|
||||
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression)receiverExpression, outerScope, trace, onlyClasses, true, storeResult);
|
||||
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression)receiverExpression, outerScope, scopeToCheckVisibility, trace, onlyClasses, true, storeResult);
|
||||
}
|
||||
|
||||
JetExpression selectorExpression = importedReference.getSelectorExpression();
|
||||
@@ -171,12 +171,13 @@ public class QualifiedExpressionResolver {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return lookupSelectorDescriptors(selector, declarationDescriptors, trace, onlyClasses, storeResult);
|
||||
return lookupSelectorDescriptors(selector, declarationDescriptors, trace, scopeToCheckVisibility, onlyClasses, storeResult);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<? extends DeclarationDescriptor> lookupSelectorDescriptors(@NotNull JetSimpleNameExpression selector,
|
||||
@NotNull Collection<? extends DeclarationDescriptor> declarationDescriptors, @NotNull BindingTrace trace, boolean onlyClasses, boolean storeResult) {
|
||||
@NotNull Collection<? extends DeclarationDescriptor> declarationDescriptors, @NotNull BindingTrace trace,
|
||||
@NotNull JetScope scopeToCheckVisibility, boolean onlyClasses, boolean storeResult) {
|
||||
|
||||
Set<SuccessfulLookupResult> results = Sets.newHashSet();
|
||||
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
|
||||
@@ -191,7 +192,7 @@ public class QualifiedExpressionResolver {
|
||||
}
|
||||
}
|
||||
}
|
||||
return filterAndStoreResolutionResult(results, selector, trace, onlyClasses, storeResult);
|
||||
return filterAndStoreResolutionResult(results, selector, trace, scopeToCheckVisibility, onlyClasses, storeResult);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -207,11 +208,11 @@ public class QualifiedExpressionResolver {
|
||||
|
||||
@NotNull
|
||||
public Collection<? extends DeclarationDescriptor> lookupDescriptorsForSimpleNameReference(@NotNull JetSimpleNameExpression referenceExpression,
|
||||
@NotNull JetScope outerScope, @NotNull BindingTrace trace, boolean onlyClasses, boolean namespaceLevel, boolean storeResult) {
|
||||
@NotNull JetScope outerScope, @NotNull JetScope scopeToCheckVisibility, @NotNull BindingTrace trace, boolean onlyClasses, boolean namespaceLevel, boolean storeResult) {
|
||||
|
||||
LookupResult lookupResult = lookupSimpleNameReference(referenceExpression, outerScope, onlyClasses, namespaceLevel);
|
||||
if (lookupResult == LookupResult.EMPTY) return Collections.emptyList();
|
||||
return filterAndStoreResolutionResult(Collections.singletonList((SuccessfulLookupResult)lookupResult), referenceExpression, trace,
|
||||
return filterAndStoreResolutionResult(Collections.singletonList((SuccessfulLookupResult)lookupResult), referenceExpression, trace, scopeToCheckVisibility,
|
||||
onlyClasses, storeResult);
|
||||
}
|
||||
|
||||
@@ -256,7 +257,8 @@ public class QualifiedExpressionResolver {
|
||||
|
||||
@NotNull
|
||||
private Collection<? extends DeclarationDescriptor> filterAndStoreResolutionResult(@NotNull Collection<SuccessfulLookupResult> lookupResults,
|
||||
@NotNull JetSimpleNameExpression referenceExpression, @NotNull BindingTrace trace, boolean onlyClasses, boolean storeResult) {
|
||||
@NotNull JetSimpleNameExpression referenceExpression, @NotNull BindingTrace trace, @NotNull JetScope scopeToCheckVisibility,
|
||||
boolean onlyClasses, boolean storeResult) {
|
||||
|
||||
if (lookupResults.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
@@ -307,7 +309,7 @@ public class QualifiedExpressionResolver {
|
||||
}
|
||||
}
|
||||
if (storeResult) {
|
||||
storeResolutionResult(descriptors, filteredDescriptors, referenceExpression, possibleResolutionScopes, trace);
|
||||
storeResolutionResult(descriptors, filteredDescriptors, referenceExpression, possibleResolutionScopes, trace, scopeToCheckVisibility);
|
||||
}
|
||||
return filteredDescriptors;
|
||||
}
|
||||
@@ -316,7 +318,8 @@ public class QualifiedExpressionResolver {
|
||||
@NotNull Collection<? extends DeclarationDescriptor> canBeImportedDescriptors,
|
||||
@NotNull JetSimpleNameExpression referenceExpression,
|
||||
@NotNull Collection<JetScope> possibleResolutionScopes,
|
||||
@NotNull BindingTrace trace) {
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scopeToCheckVisibility) {
|
||||
|
||||
assert canBeImportedDescriptors.size() <= descriptors.size();
|
||||
assert !possibleResolutionScopes.isEmpty();
|
||||
@@ -324,7 +327,7 @@ public class QualifiedExpressionResolver {
|
||||
JetScope resolutionScope = possibleResolutionScopes.iterator().next();
|
||||
|
||||
// A special case - will fill all trace information
|
||||
if (resolveClassNamespaceAmbiguity(canBeImportedDescriptors, referenceExpression, resolutionScope, trace)) {
|
||||
if (resolveClassNamespaceAmbiguity(canBeImportedDescriptors, referenceExpression, resolutionScope, trace, scopeToCheckVisibility)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -336,22 +339,30 @@ public class QualifiedExpressionResolver {
|
||||
}
|
||||
|
||||
// Decide if expression has resolved reference
|
||||
DeclarationDescriptor descriptor = null;
|
||||
if (descriptors.size() == 1) {
|
||||
descriptor = descriptors.iterator().next();
|
||||
assert canBeImportedDescriptors.size() <= 1;
|
||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next());
|
||||
trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope);
|
||||
}
|
||||
else if (canBeImportedDescriptors.size() == 1) {
|
||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, canBeImportedDescriptors.iterator().next());
|
||||
descriptor = canBeImportedDescriptors.iterator().next();
|
||||
}
|
||||
if (descriptor != null) {
|
||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next());
|
||||
trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope);
|
||||
|
||||
if (descriptor instanceof DeclarationDescriptorWithVisibility) {
|
||||
checkVisibility((DeclarationDescriptorWithVisibility)descriptor, trace, referenceExpression, scopeToCheckVisibility);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for more information and additional errors
|
||||
if (canBeImportedDescriptors.isEmpty()) {
|
||||
assert descriptors.size() >= 1;
|
||||
trace.report(CANNOT_BE_IMPORTED.on(referenceExpression, descriptors.iterator().next()));
|
||||
return;
|
||||
}
|
||||
else if (canBeImportedDescriptors.size() > 1) {
|
||||
if (canBeImportedDescriptors.size() > 1) {
|
||||
trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors);
|
||||
}
|
||||
}
|
||||
@@ -363,7 +374,8 @@ public class QualifiedExpressionResolver {
|
||||
* @return <code>true</code> if method has successfully resolved ambiguity
|
||||
*/
|
||||
private boolean resolveClassNamespaceAmbiguity(@NotNull Collection<? extends DeclarationDescriptor> filteredDescriptors,
|
||||
@NotNull JetSimpleNameExpression referenceExpression, @NotNull JetScope resolutionScope, @NotNull BindingTrace trace) {
|
||||
@NotNull JetSimpleNameExpression referenceExpression, @NotNull JetScope resolutionScope, @NotNull BindingTrace trace,
|
||||
@NotNull JetScope scopeToCheckVisibility) {
|
||||
|
||||
if (filteredDescriptors.size() == 2) {
|
||||
NamespaceDescriptor namespaceDescriptor = null;
|
||||
@@ -382,6 +394,7 @@ public class QualifiedExpressionResolver {
|
||||
if (DescriptorUtils.getFQName(namespaceDescriptor).equals(DescriptorUtils.getFQName(classDescriptor))) {
|
||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classDescriptor);
|
||||
trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope);
|
||||
checkVisibility(classDescriptor, trace, referenceExpression, scopeToCheckVisibility);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -390,6 +403,14 @@ public class QualifiedExpressionResolver {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkVisibility(@NotNull DeclarationDescriptorWithVisibility descriptor, @NotNull BindingTrace trace,
|
||||
@NotNull JetSimpleNameExpression referenceExpression, @NotNull JetScope scopeToCheckVisibility) {
|
||||
|
||||
if (!Visibilities.isVisible(descriptor, scopeToCheckVisibility.getContainingDeclaration())) {
|
||||
trace.report(INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.getContainingDeclaration()));
|
||||
}
|
||||
}
|
||||
|
||||
private interface LookupResult {
|
||||
LookupResult EMPTY = new LookupResult() {
|
||||
};
|
||||
|
||||
@@ -270,15 +270,9 @@ public class TypeResolver {
|
||||
|
||||
@Nullable
|
||||
public ClassifierDescriptor resolveClass(JetScope scope, JetUserType userType, BindingTrace trace) {
|
||||
Collection<? extends DeclarationDescriptor> descriptors = qualifiedExpressionResolver
|
||||
.lookupDescriptorsForUserType(userType, scope, trace);
|
||||
Collection<? extends DeclarationDescriptor> descriptors = qualifiedExpressionResolver.lookupDescriptorsForUserType(userType, scope, trace);
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
if (descriptor instanceof ClassifierDescriptor) {
|
||||
if (descriptor instanceof ClassDescriptor && !Visibilities.isVisible((ClassDescriptor)descriptor, scope.getContainingDeclaration())) {
|
||||
JetSimpleNameExpression referenceExpression = userType.getReferenceExpression();
|
||||
assert referenceExpression != null;
|
||||
trace.report(INVISIBLE_MEMBER.on(referenceExpression, descriptor, ((ClassDescriptor)descriptor).getContainingDeclaration()));
|
||||
}
|
||||
return (ClassifierDescriptor) descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,6 +352,12 @@ public class CallResolver {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
context.tracing.invisibleMember(context.trace, candidate);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean errorInArgumentMapping = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, candidateCall);
|
||||
if (errorInArgumentMapping) {
|
||||
candidateCall.setStatus(OTHER_ERROR);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
@@ -224,5 +225,11 @@ public class ResolutionTask<D extends CallableDescriptor> extends ResolutionCont
|
||||
trace.report(DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED.on(functionLiteralArgument));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invisibleMember(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor descriptor) {
|
||||
JetExpression expression = call.getCalleeExpression();
|
||||
trace.report(INVISIBLE_MEMBER.on(expression != null ? expression : call.getCallElement(), descriptor, descriptor.getContainingDeclaration()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,18 +82,40 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||
|
||||
ReceiverDescriptor explicitReceiver = context.call.getExplicitReceiver();
|
||||
JetScope scope = context.scope;
|
||||
final JetScope scope;
|
||||
if (explicitReceiver.exists() && explicitReceiver.getType() instanceof NamespaceType) {
|
||||
// Receiver is a namespace
|
||||
scope = explicitReceiver.getType().getMemberScope();
|
||||
explicitReceiver = NO_RECEIVER;
|
||||
}
|
||||
doComputeTasks(scope, explicitReceiver, name, result, context, functionReference);
|
||||
else {
|
||||
scope = context.scope;
|
||||
}
|
||||
final Predicate<ResolvedCallImpl<D>> visibleStrategy = new Predicate<ResolvedCallImpl<D>>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable ResolvedCallImpl<D> call) {
|
||||
if (call == null) return false;
|
||||
D candidateDescriptor = call.getCandidateDescriptor();
|
||||
if (ErrorUtils.isError(candidateDescriptor)) return true;
|
||||
return Visibilities.isVisible(candidateDescriptor, scope.getContainingDeclaration());
|
||||
}
|
||||
};
|
||||
Predicate<ResolvedCallImpl<D>> invisibleStrategy = new Predicate<ResolvedCallImpl<D>>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable ResolvedCallImpl<D> call) {
|
||||
return !visibleStrategy.apply(call);
|
||||
}
|
||||
};
|
||||
doComputeTasks(scope, explicitReceiver, name, result, context, functionReference, visibleStrategy);
|
||||
doComputeTasks(scope, explicitReceiver, name, result, context, functionReference, invisibleStrategy);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void doComputeTasks(JetScope scope, ReceiverDescriptor receiver, String name, List<ResolutionTask<D>> result, @NotNull BasicResolutionContext context, @NotNull JetReferenceExpression functionReference) {
|
||||
private void doComputeTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver,
|
||||
@NotNull String name, @NotNull List<ResolutionTask<D>> result,
|
||||
@NotNull BasicResolutionContext context, @NotNull JetReferenceExpression functionReference,
|
||||
@NotNull Predicate<ResolvedCallImpl<D>> filterStrategy) {
|
||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext());
|
||||
DataFlowInfo dataFlowInfo = autoCastService.getDataFlowInfo();
|
||||
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
|
||||
@@ -117,21 +139,21 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
// 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, members, context, functionReference);
|
||||
addTask(result, locals, context, functionReference);
|
||||
addTask(result, members, context, functionReference, filterStrategy);
|
||||
addTask(result, locals, context, functionReference, filterStrategy);
|
||||
}
|
||||
else {
|
||||
addTask(result, locals, context, functionReference);
|
||||
addTask(result, members, context, functionReference);
|
||||
addTask(result, locals, context, functionReference, filterStrategy);
|
||||
addTask(result, members, context, functionReference, filterStrategy);
|
||||
}
|
||||
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
||||
List<ReceiverDescriptor> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
|
||||
addTask(result, convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver), context, functionReference);
|
||||
addTask(result, convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver), context, functionReference, filterStrategy);
|
||||
}
|
||||
|
||||
addTask(result, nonlocals, context, functionReference);
|
||||
addTask(result, nonlocals, context, functionReference, filterStrategy);
|
||||
}
|
||||
else {
|
||||
Collection<ResolvedCallImpl<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), getNonExtensionsByName(scope, name));
|
||||
@@ -141,13 +163,13 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
addTask(result, locals, context, functionReference);
|
||||
addTask(result, locals, context, functionReference, filterStrategy);
|
||||
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
doComputeTasks(scope, implicitReceiver, name, result, context, functionReference);
|
||||
doComputeTasks(scope, implicitReceiver, name, result, context, functionReference, filterStrategy);
|
||||
}
|
||||
|
||||
addTask(result, nonlocals, context, functionReference);
|
||||
addTask(result, nonlocals, context, functionReference, filterStrategy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,18 +237,14 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addTask(@NotNull List<ResolutionTask<D>> result, @NotNull Collection<ResolvedCallImpl<D>> candidates, @NotNull final BasicResolutionContext context, @NotNull JetReferenceExpression functionReference) {
|
||||
Collection<ResolvedCallImpl<D>> visibleCandidates = Collections2.filter(candidates, new Predicate<ResolvedCallImpl<D>>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable ResolvedCallImpl<D> call) {
|
||||
if (call == null) return false;
|
||||
D candidateDescriptor = call.getCandidateDescriptor();
|
||||
if (ErrorUtils.isError(candidateDescriptor)) return true;
|
||||
return Visibilities.isVisible(candidateDescriptor, context.scope.getContainingDeclaration());
|
||||
}
|
||||
});
|
||||
if (visibleCandidates.isEmpty()) return;
|
||||
result.add(new ResolutionTask<D>(visibleCandidates, functionReference, context));
|
||||
private void addTask(@NotNull List<ResolutionTask<D>> result,
|
||||
@NotNull Collection<ResolvedCallImpl<D>> candidates,
|
||||
@NotNull final BasicResolutionContext context,
|
||||
@NotNull JetReferenceExpression functionReference,
|
||||
@NotNull Predicate<ResolvedCallImpl<D>> filterStrategy) {
|
||||
Collection<ResolvedCallImpl<D>> filteredCandidates = Collections2.filter(candidates, filterStrategy);
|
||||
if (filteredCandidates.isEmpty()) return;
|
||||
result.add(new ResolutionTask<D>(filteredCandidates, functionReference, context));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
@@ -77,6 +78,9 @@ import java.util.List;
|
||||
|
||||
@Override
|
||||
public void danglingFunctionLiteralArgumentSuspected(@NotNull BindingTrace trace, @NotNull List<JetExpression> functionLiteralArguments) {}
|
||||
|
||||
@Override
|
||||
public void invisibleMember(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor descriptor) {}
|
||||
};
|
||||
|
||||
<D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl<D> resolvedCall);
|
||||
@@ -108,4 +112,6 @@ import java.util.List;
|
||||
void unnecessarySafeCall(@NotNull BindingTrace trace, @NotNull JetType type);
|
||||
|
||||
void danglingFunctionLiteralArgumentSuspected(@NotNull BindingTrace trace, @NotNull List<JetExpression> functionLiteralArguments);
|
||||
|
||||
void invisibleMember(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor descriptor);
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ val mc = MyJavaClass()
|
||||
//FILE: b.kt
|
||||
package b
|
||||
|
||||
import a.MyJavaClass
|
||||
import a.<!INVISIBLE_REFERENCE!>MyJavaClass<!>
|
||||
|
||||
val mc1 = <!UNRESOLVED_REFERENCE!>MyJavaClass<!>()
|
||||
val mc1 = <!INVISIBLE_MEMBER!>MyJavaClass<!>()
|
||||
|
||||
//FILE: c.kt
|
||||
package a.c
|
||||
|
||||
import a.MyJavaClass
|
||||
import a.<!INVISIBLE_REFERENCE!>MyJavaClass<!>
|
||||
|
||||
val mc1 = <!UNRESOLVED_REFERENCE!>MyJavaClass<!>()
|
||||
val mc1 = <!INVISIBLE_MEMBER!>MyJavaClass<!>()
|
||||
@@ -6,13 +6,13 @@ package example;
|
||||
fun test() {
|
||||
val p = test.Public()
|
||||
if (p.public is Int) <!AUTOCAST_IMPOSSIBLE!>p.public<!> + 1
|
||||
if (p.<!UNRESOLVED_REFERENCE!>protected<!> is Int) p.<!UNRESOLVED_REFERENCE!>protected<!> + 1
|
||||
if (p.<!UNRESOLVED_REFERENCE!>i_protected<!> is Int) p.<!UNRESOLVED_REFERENCE!>i_protected<!> + 1
|
||||
if (p.<!INVISIBLE_MEMBER!>protected<!> is Int) <!AUTOCAST_IMPOSSIBLE!>p.<!INVISIBLE_MEMBER!>protected<!><!> + 1
|
||||
if (p.<!INVISIBLE_MEMBER!>i_protected<!> is Int) p.<!INVISIBLE_MEMBER!>i_protected<!> + 1
|
||||
if (p.internal is Int) p.internal + 1
|
||||
val i = test.Public()
|
||||
if (i.public is Int) <!AUTOCAST_IMPOSSIBLE!>i.public<!> + 1
|
||||
if (i.<!UNRESOLVED_REFERENCE!>protected<!> is Int) i.<!UNRESOLVED_REFERENCE!>protected<!> + 1
|
||||
if (i.<!UNRESOLVED_REFERENCE!>i_protected<!> is Int) i.<!UNRESOLVED_REFERENCE!>i_protected<!> + 1
|
||||
if (i.<!INVISIBLE_MEMBER!>protected<!> is Int) <!AUTOCAST_IMPOSSIBLE!>i.<!INVISIBLE_MEMBER!>protected<!><!> + 1
|
||||
if (i.<!INVISIBLE_MEMBER!>i_protected<!> is Int) i.<!INVISIBLE_MEMBER!>i_protected<!> + 1
|
||||
if (i.internal is Int) i.internal + 1
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,6 @@ class C() {
|
||||
|
||||
fun box(): String {
|
||||
val c = C()
|
||||
if (c.<!UNRESOLVED_REFERENCE!>f<!> != 610) return "fail"
|
||||
if (c.<!INVISIBLE_MEMBER!>f<!> != 610) return "fail"
|
||||
return "OK"
|
||||
}
|
||||
@@ -35,8 +35,8 @@ class B {
|
||||
}
|
||||
|
||||
fun test3(a: A) {
|
||||
a.<!UNRESOLVED_REFERENCE!>v<!> //todo .bMethod()
|
||||
a.<!UNRESOLVED_REFERENCE!>f<!>(0, 1) //todo .bMethod()
|
||||
a.<!INVISIBLE_MEMBER!>v<!> //todo .bMethod()
|
||||
a.<!INVISIBLE_MEMBER!>f<!>(0, 1) //todo .bMethod()
|
||||
}
|
||||
|
||||
trait T
|
||||
@@ -49,7 +49,7 @@ open class C : T {
|
||||
}
|
||||
|
||||
fun test4(c: C) {
|
||||
c.<!UNRESOLVED_REFERENCE!>i<!>++
|
||||
c.<!INVISIBLE_MEMBER!>i<!>++
|
||||
}
|
||||
|
||||
class D : C() {
|
||||
@@ -73,7 +73,7 @@ class F : C() {
|
||||
|
||||
class G : T {
|
||||
fun test8(c: C) {
|
||||
doSmth(c.<!UNRESOLVED_REFERENCE!>i<!>)
|
||||
doSmth(c.<!INVISIBLE_MEMBER!>i<!>)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,5 +86,5 @@ import test_visibility.*
|
||||
|
||||
fun test() {
|
||||
internal_fun()
|
||||
<!UNRESOLVED_REFERENCE!>private_fun<!>()
|
||||
}
|
||||
<!INVISIBLE_MEMBER!>private_fun<!>()
|
||||
}
|
||||
@@ -15,20 +15,23 @@ private object PO {}
|
||||
//+JDK
|
||||
package b
|
||||
|
||||
import a.*
|
||||
import a.<!INVISIBLE_REFERENCE!>A<!>
|
||||
import a.<!INVISIBLE_REFERENCE!>foo<!>
|
||||
import a.makeA
|
||||
import a.<!INVISIBLE_REFERENCE!>PO<!>
|
||||
|
||||
fun test() {
|
||||
val y = makeA()
|
||||
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||
y.<!INVISIBLE_MEMBER!>bar<!>()
|
||||
<!INVISIBLE_MEMBER!>foo<!>()
|
||||
|
||||
val <!UNUSED_VARIABLE!>u<!> : <!INVISIBLE_MEMBER!>A<!> = <!UNRESOLVED_REFERENCE!>A<!>()
|
||||
val <!UNUSED_VARIABLE!>a<!> : java.util.Arrays.<!INVISIBLE_MEMBER!>ArrayList<!><Int>;
|
||||
val <!UNUSED_VARIABLE!>u<!> : <!INVISIBLE_REFERENCE!>A<!> = <!INVISIBLE_MEMBER!>A<!>()
|
||||
val <!UNUSED_VARIABLE!>a<!> : java.util.Arrays.<!INVISIBLE_REFERENCE!>ArrayList<!><Int>;
|
||||
|
||||
val <!UNUSED_VARIABLE!>po<!> = <!UNRESOLVED_REFERENCE!>PO<!>()
|
||||
val <!UNUSED_VARIABLE!>po<!> = <!INVISIBLE_MEMBER!>PO<!>
|
||||
}
|
||||
|
||||
class B : <!INVISIBLE_MEMBER!>A<!>() {}
|
||||
class B : <!INVISIBLE_REFERENCE, INVISIBLE_MEMBER!>A<!>() {}
|
||||
|
||||
class Q {
|
||||
class W {
|
||||
@@ -41,4 +44,4 @@ class Q {
|
||||
//check that 'toString' can be invoked without specifying return type
|
||||
class NewClass : java.util.ArrayList<Integer>() {
|
||||
public override fun toString() = "a"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user