@NotNull private CallTranslator finish() { if (resolvedCall == null) { assert descriptor != null; resolvedCall = ResolvedCallImpl.create( ResolutionCandidate.create( descriptor, DescriptorUtils.safeGetValue(descriptor.getExpectedThisObject()), DescriptorUtils.safeGetValue(descriptor.getReceiverParameter()), ExplicitReceiverKind.THIS_OBJECT, false), TemporaryBindingTrace.create( new BindingTraceContext(), "trace to resolve call (in js)")); } if (descriptor == null) { descriptor = resolvedCall.getCandidateDescriptor().getOriginal(); } assert resolvedCall != null; return new CallTranslator(receiver, callee, args, resolvedCall, descriptor, callType, context); }
private static boolean checkReceiverResolution( @NotNull ReceiverDescriptor expectedReceiver, @NotNull JetType receiverType, @NotNull CallableDescriptor receiverArgument) { ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING); for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) { constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); } ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter(); if (expectedReceiver.exists() && receiverParameter.exists()) { constraintSystem.addSubtypingConstraint( ConstraintType.RECEIVER.assertSubtyping(receiverType, receiverParameter.getType())); } else if (expectedReceiver.exists() || receiverParameter.exists()) { // Only one of receivers exist return false; } ConstraintSystemSolution solution = constraintSystem.solve(); return solution.getStatus().isSuccessful(); }
static void recordClosure( BindingTrace bindingTrace, @Nullable JetElement element, ClassDescriptor classDescriptor, @Nullable ClassDescriptor enclosing, JvmClassName name, boolean functionLiteral) { JetDelegatorToSuperCall superCall = findSuperCall(bindingTrace.getBindingContext(), element); CallableDescriptor enclosingReceiver = null; if (classDescriptor.getContainingDeclaration() instanceof CallableDescriptor) { enclosingReceiver = (CallableDescriptor) classDescriptor.getContainingDeclaration(); enclosingReceiver = enclosingReceiver instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor) enclosingReceiver).getCorrespondingProperty() : enclosingReceiver; if (enclosingReceiver.getReceiverParameter() == null) { enclosingReceiver = null; } } MutableClosure closure = new MutableClosure(superCall, enclosing, enclosingReceiver); assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, classDescriptor, name); bindingTrace.record(FQN, classDescriptor, name); bindingTrace.record(CLOSURE, classDescriptor, closure); // TODO: this is temporary before we have proper inner classes if (canHaveOuter(bindingTrace.getBindingContext(), classDescriptor) && !functionLiteral) { closure.setCaptureThis(); } if (enclosing != null) { recordInnerClass(bindingTrace, enclosing, classDescriptor); } }
public static TabledDescriptorRenderer renderConflictingSubstitutionsInferenceError( ExtendedInferenceErrorData inferenceErrorData, TabledDescriptorRenderer result) { assert inferenceErrorData.constraintSystem.hasConflictingConstraints(); Collection<CallableDescriptor> substitutedDescriptors = Lists.newArrayList(); Collection<TypeSubstitutor> substitutors = ConstraintsUtil.getSubstitutorsForConflictingParameters( inferenceErrorData.constraintSystem); for (TypeSubstitutor substitutor : substitutors) { CallableDescriptor substitutedDescriptor = inferenceErrorData.descriptor.substitute(substitutor); substitutedDescriptors.add(substitutedDescriptor); } TypeParameterDescriptor firstConflictingParameter = ConstraintsUtil.getFirstConflictingParameter(inferenceErrorData.constraintSystem); assert firstConflictingParameter != null; result.text( newText() .normal("Cannot infer type parameter ") .strong(firstConflictingParameter.getName()) .normal(" in")); // String type = strong(firstConflictingParameter.getName()); TableRenderer table = newTable(); result.table(table); table.descriptor(inferenceErrorData.descriptor).text("None of the following substitutions"); for (CallableDescriptor substitutedDescriptor : substitutedDescriptors) { JetType receiverType = DescriptorUtils.getReceiverParameterType(substitutedDescriptor.getReceiverParameter()); final Collection<ConstraintPosition> errorPositions = Sets.newHashSet(); List<JetType> parameterTypes = Lists.newArrayList(); for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) { parameterTypes.add(valueParameterDescriptor.getType()); if (valueParameterDescriptor.getIndex() >= inferenceErrorData.valueArgumentsTypes.size()) continue; JetType actualType = inferenceErrorData.valueArgumentsTypes.get(valueParameterDescriptor.getIndex()); if (!JetTypeChecker.INSTANCE.isSubtypeOf(actualType, valueParameterDescriptor.getType())) { errorPositions.add( ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex())); } } if (receiverType != null && inferenceErrorData.receiverArgumentType != null && !JetTypeChecker.INSTANCE.isSubtypeOf( inferenceErrorData.receiverArgumentType, receiverType)) { errorPositions.add(ConstraintPosition.RECEIVER_POSITION); } Predicate<ConstraintPosition> isErrorPosition = new Predicate<ConstraintPosition>() { @Override public boolean apply(@Nullable ConstraintPosition constraintPosition) { return errorPositions.contains(constraintPosition); } }; table.functionArgumentTypeList(receiverType, parameterTypes, isErrorPosition); } table .text("can be applied to") .functionArgumentTypeList( inferenceErrorData.receiverArgumentType, inferenceErrorData.valueArgumentsTypes); return result; }
public static boolean isExtension(@NotNull CallableDescriptor functionDescriptor) { return (functionDescriptor.getReceiverParameter() != null); }