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