001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.resolve.calls.tasks;
018
019 import com.google.common.collect.Sets;
020 import com.intellij.lang.ASTNode;
021 import com.intellij.psi.PsiElement;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.kotlin.descriptors.*;
024 import org.jetbrains.kotlin.diagnostics.DiagnosticUtilsKt;
025 import org.jetbrains.kotlin.lexer.KtToken;
026 import org.jetbrains.kotlin.lexer.KtTokens;
027 import org.jetbrains.kotlin.name.FqName;
028 import org.jetbrains.kotlin.name.Name;
029 import org.jetbrains.kotlin.psi.*;
030 import org.jetbrains.kotlin.resolve.BindingTrace;
031 import org.jetbrains.kotlin.resolve.DescriptorUtils;
032 import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
033 import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
034 import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
035 import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemStatus;
036 import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
037 import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
038 import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
039 import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
040 import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
041 import org.jetbrains.kotlin.types.KotlinType;
042 import org.jetbrains.kotlin.types.Variance;
043 import org.jetbrains.kotlin.types.expressions.OperatorConventions;
044
045 import java.util.Collection;
046
047 import static org.jetbrains.kotlin.diagnostics.Errors.*;
048 import static org.jetbrains.kotlin.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
049 import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqNameFromTopLevelClass;
050 import static org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemUtilsKt.filterConstraintsOut;
051 import static org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION;
052 import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
053
054 public abstract class AbstractTracingStrategy implements TracingStrategy {
055 protected final KtExpression reference;
056 protected final Call call;
057
058 protected AbstractTracingStrategy(@NotNull KtExpression reference, @NotNull Call call) {
059 this.reference = reference;
060 this.call = call;
061 }
062
063 @Override
064 public <D extends CallableDescriptor> void recordAmbiguity(@NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> candidates) {
065 Collection<D> descriptors = Sets.newHashSet();
066 for (ResolvedCall<D> candidate : candidates) {
067 descriptors.add(candidate.getCandidateDescriptor());
068 }
069 trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, descriptors);
070 }
071
072 @Override
073 public void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter) {
074 KtElement reportOn = CallUtilKt.getValueArgumentListOrElement(call);
075 trace.report(NO_VALUE_FOR_PARAMETER.on(reportOn, valueParameter));
076 }
077
078 @Override
079 public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverParameterDescriptor expectedReceiver) {
080 trace.report(MISSING_RECEIVER.on(reference, expectedReceiver.getType()));
081 }
082
083 @Override
084 public void wrongReceiverType(
085 @NotNull BindingTrace trace,
086 @NotNull ReceiverParameterDescriptor receiverParameter,
087 @NotNull ReceiverValue receiverArgument,
088 @NotNull ResolutionContext<?> c
089 ) {
090 KtExpression reportOn = receiverArgument instanceof ExpressionReceiver
091 ? ((ExpressionReceiver) receiverArgument).getExpression()
092 : reference;
093
094 if (!DiagnosticUtilsKt.reportTypeMismatchDueToTypeProjection(
095 c, reportOn, receiverParameter.getType(), receiverArgument.getType())) {
096 trace.report(TYPE_MISMATCH.on(reportOn, receiverParameter.getType(), receiverArgument.getType()));
097 }
098 }
099
100 @Override
101 public void noReceiverAllowed(@NotNull BindingTrace trace) {
102 trace.report(NO_RECEIVER_ALLOWED.on(reference));
103 }
104
105 @Override
106 public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {
107 KtTypeArgumentList typeArgumentList = call.getTypeArgumentList();
108 if (typeArgumentList != null) {
109 trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeArgumentList, expectedTypeArgumentCount));
110 }
111 else {
112 trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(reference, expectedTypeArgumentCount));
113 }
114 }
115
116 @Override
117 public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> descriptors) {
118 trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(reference, descriptors));
119 }
120
121 @Override
122 public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> descriptors) {
123 trace.report(NONE_APPLICABLE.on(reference, descriptors));
124 }
125
126 @Override
127 public <D extends CallableDescriptor> void cannotCompleteResolve(
128 @NotNull BindingTrace trace,
129 @NotNull Collection<? extends ResolvedCall<D>> descriptors
130 ) {
131 trace.report(CANNOT_COMPLETE_RESOLVE.on(reference, descriptors));
132 }
133
134 @Override
135 public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {
136 trace.report(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS.on(call.getCallElement()));
137 }
138
139 @Override
140 public void abstractSuperCall(@NotNull BindingTrace trace) {
141 trace.report(ABSTRACT_SUPER_CALL.on(reference));
142 }
143
144 @Override
145 public void nestedClassAccessViaInstanceReference(
146 @NotNull BindingTrace trace,
147 @NotNull ClassDescriptor classDescriptor,
148 @NotNull ExplicitReceiverKind explicitReceiverKind
149 ) {
150 if (explicitReceiverKind == ExplicitReceiverKind.NO_EXPLICIT_RECEIVER) {
151 DeclarationDescriptor importableDescriptor = DescriptorUtilsKt.getImportableDescriptor(classDescriptor);
152 if (DescriptorUtils.getFqName(importableDescriptor).isSafe()) {
153 FqName fqName = getFqNameFromTopLevelClass(importableDescriptor);
154 String qualifiedName;
155 if (reference.getParent() instanceof KtCallableReferenceExpression) {
156 qualifiedName = fqName.parent() + "::" + classDescriptor.getName();
157 }
158 else {
159 qualifiedName = fqName.asString();
160 }
161 trace.report(NESTED_CLASS_SHOULD_BE_QUALIFIED.on(reference, classDescriptor, qualifiedName));
162 return;
163 }
164 }
165 trace.report(NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE.on(reference, classDescriptor));
166 }
167
168 @Override
169 public void unsafeCall(@NotNull BindingTrace trace, @NotNull KotlinType type, boolean isCallForImplicitInvoke) {
170 ASTNode callOperationNode = call.getCallOperationNode();
171 if (callOperationNode != null && !isCallForImplicitInvoke) {
172 trace.report(UNSAFE_CALL.on(callOperationNode.getPsi(), type));
173 }
174 else {
175 PsiElement callElement = call.getCallElement();
176 if (callElement instanceof KtBinaryExpression) {
177 KtBinaryExpression binaryExpression = (KtBinaryExpression)callElement;
178 KtSimpleNameExpression operationReference = binaryExpression.getOperationReference();
179
180 Name operationString = operationReference.getReferencedNameElementType() == KtTokens.IDENTIFIER ?
181 Name.identifier(operationReference.getText()) :
182 OperatorConventions.getNameForOperationSymbol((KtToken) operationReference.getReferencedNameElementType());
183
184 KtExpression left = binaryExpression.getLeft();
185 KtExpression right = binaryExpression.getRight();
186 if (left != null && right != null) {
187 trace.report(UNSAFE_INFIX_CALL.on(reference, left.getText(), operationString.asString(), right.getText()));
188 }
189 }
190 else if (isCallForImplicitInvoke) {
191 trace.report(UNSAFE_IMPLICIT_INVOKE_CALL.on(reference, type));
192 }
193 else {
194 trace.report(UNSAFE_CALL.on(reference, type));
195 }
196 }
197 }
198
199 @Override
200 public void invisibleMember(@NotNull BindingTrace trace, @NotNull DeclarationDescriptorWithVisibility descriptor) {
201 trace.report(INVISIBLE_MEMBER.on(call.getCallElement(), descriptor, descriptor.getVisibility(), descriptor));
202 }
203
204 @Override
205 public void typeInferenceFailed(@NotNull ResolutionContext<?> context, @NotNull InferenceErrorData data) {
206 ConstraintSystem constraintSystem = data.constraintSystem;
207 ConstraintSystemStatus status = constraintSystem.getStatus();
208 assert !status.isSuccessful() : "Report error only for not successful constraint system";
209
210 if (status.hasErrorInConstrainingTypes()) {
211 // Do not report type inference errors if there is one in the arguments
212 // (it's useful, when the arguments, e.g. lambdas or calls are incomplete)
213 return;
214 }
215 BindingTrace trace = context.trace;
216 if (status.hasOnlyErrorsDerivedFrom(EXPECTED_TYPE_POSITION)) {
217 KotlinType declaredReturnType = data.descriptor.getReturnType();
218 if (declaredReturnType == null) return;
219
220 ConstraintSystem systemWithoutExpectedTypeConstraint = filterConstraintsOut(constraintSystem, EXPECTED_TYPE_POSITION);
221 KotlinType substitutedReturnType = systemWithoutExpectedTypeConstraint.getResultingSubstitutor().substitute(
222 declaredReturnType, Variance.OUT_VARIANCE);
223 assert substitutedReturnType != null; //todo
224
225 assert !noExpectedType(data.expectedType) : "Expected type doesn't exist, but there is an expected type mismatch error";
226 if (!DiagnosticUtilsKt.reportTypeMismatchDueToTypeProjection(
227 context, call.getCallElement(), data.expectedType, substitutedReturnType)) {
228 trace.report(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH.on(call.getCallElement(), data.expectedType, substitutedReturnType));
229 }
230 }
231 else if (status.hasCannotCaptureTypesError()) {
232 trace.report(TYPE_INFERENCE_CANNOT_CAPTURE_TYPES.on(reference, data));
233 }
234 else if (status.hasViolatedUpperBound()) {
235 trace.report(TYPE_INFERENCE_UPPER_BOUND_VIOLATED.on(reference, data));
236 }
237 else if (status.hasParameterConstraintError()) {
238 trace.report(TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR.on(reference, data));
239 }
240 else if (status.hasConflictingConstraints()) {
241 trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(reference, data));
242 }
243 else if (status.hasTypeInferenceIncorporationError()) {
244 trace.report(TYPE_INFERENCE_INCORPORATION_ERROR.on(reference));
245 }
246 else if (status.hasTypeParameterWithUnsatisfiedOnlyInputTypesError()) {
247 //todo
248 trace.report(TYPE_INFERENCE_ONLY_INPUT_TYPES.on(reference, data.descriptor.getTypeParameters().get(0)));
249 }
250 else {
251 assert status.hasUnknownParameters();
252 trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(reference, data));
253 }
254 }
255
256 @Override
257 public void nonExtensionFunctionCalledAsExtension(@NotNull BindingTrace trace) {
258 trace.report(INVOKE_EXTENSION_ON_NOT_EXTENSION_FUNCTION.on(reference, reference));
259 }
260 }