Set reference target and report custom error instead unresolved reference for cases: interface, generic parameter, object + invoke, class without companion.

#KT-2787 Fixed.
This commit is contained in:
Stanislav Erokhin
2016-08-31 16:03:11 +03:00
parent eb6f444c19
commit bebc75c8ef
17 changed files with 338 additions and 12 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData;
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier;
import org.jetbrains.kotlin.types.KotlinType;
import java.lang.reflect.Field;
@@ -531,6 +532,9 @@ public interface Errors {
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_FORBIDDEN_SUBSTITUTION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_UNSAFE_SUBSTITUTION = DiagnosticFactory1.create(WARNING);
DiagnosticFactory3<KtReferenceExpression, ClassifierDescriptor, WrongResolutionToClassifier, String> RESOLUTION_TO_CLASSIFIER =
DiagnosticFactory3.create(ERROR);
// Type inference
DiagnosticFactory0<KtParameter> CANNOT_INFER_PARAMETER_TYPE = DiagnosticFactory0.create(ERROR);
@@ -303,6 +303,7 @@ public class DefaultErrorMessages {
MAP.put(DELEGATION_IN_INTERFACE, "Interfaces cannot use delegation");
MAP.put(DELEGATION_NOT_TO_INTERFACE, "Only interfaces can be delegated to");
MAP.put(NO_CONSTRUCTOR, "This class does not have a constructor");
MAP.put(RESOLUTION_TO_CLASSIFIER, "{2}", NAME, TO_STRING, STRING);
MAP.put(NOT_A_CLASS, "Not a class");
MAP.put(ILLEGAL_ESCAPE_SEQUENCE, "Illegal escape sequence");
@@ -17,12 +17,15 @@
package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.psi.KtReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
@@ -157,6 +160,13 @@ class NewResolutionOldInference(
}
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kind != ResolutionKind.CallableReference)
if (candidates.isEmpty()) {
if (reportAdditionalDiagnosticIfNoCandidates(context, name, kind, scopeTower, detailedReceiver)) {
return OverloadResolutionResultsImpl.nameNotFound()
}
}
return convertToOverloadResults(candidates, tracing, context)
}
@@ -242,6 +252,32 @@ class NewResolutionOldInference(
return resolutionResultsHandler.computeResultAndReportErrors(basicCallContext, tracing, resolvedCalls)
}
// true if we found something
private fun reportAdditionalDiagnosticIfNoCandidates(
context: BasicCallResolutionContext,
name: Name,
kind: ResolutionKind<*>,
scopeTower: ImplicitScopeTower,
detailedReceiver: DetailedReceiver?
): Boolean {
val reference = context.call.calleeExpression as? KtReferenceExpression ?: return false
val errorCadidates = when (kind) {
ResolutionKind.Function -> collectErrorCandidatesForFunction(scopeTower, name, detailedReceiver)
ResolutionKind.Variable -> collectErrorCandidatesForVariable(scopeTower, name, detailedReceiver)
else -> emptyList()
}
for (candidate in errorCadidates) {
if (candidate is ErrorCandidate.Classifier) {
context.trace.record(BindingContext.REFERENCE_TARGET, reference, candidate.descriptor)
context.trace.report(Errors.RESOLUTION_TO_CLASSIFIER.on(reference, candidate.descriptor, candidate.kind, candidate.errorMessage))
return true
}
}
return false
}
private class ImplicitScopeTowerImpl(
val resolutionContext: ResolutionContext<*>,
override val dynamicScope: MemberScope,