@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { JetCallExpression call = (JetCallExpression) element; ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); Type type = state .getInjector() .getJetTypeMapper() .mapType( resultingDescriptor.getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE); JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(type); if (primitiveType != null) { v.getstatic( primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;"); } else { v.aconst(type); } return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE); }
@NotNull @Override public StackValue outerValue( @NotNull EnclosedValueDescriptor d, @NotNull ExpressionCodegen codegen) { CallableDescriptor descriptor = (CallableDescriptor) d.getDescriptor(); return StackValue.local(descriptor.getExpectedThisObject() != null ? 1 : 0, d.getType()); }
public static boolean isOptimizableRangeTo(CallableDescriptor rangeTo) { if ("rangeTo".equals(rangeTo.getName().getName())) { if (isPrimitiveNumberClassDescriptor(rangeTo.getContainingDeclaration())) { return true; } } return false; }
private static boolean isDeclaredInJava( @NotNull CallableDescriptor callableDescriptor, @NotNull BindingContext context) { CallableDescriptor descriptor = callableDescriptor; while (true) { if (Boolean.TRUE.equals(context.get(BindingContext.IS_DECLARED_IN_JAVA, descriptor))) { return true; } CallableDescriptor original = descriptor.getOriginal(); if (descriptor == original) break; descriptor = original; } return false; }
@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(); }
private static void genNotNullAssertion( @NotNull InstructionAdapter v, @NotNull GenerationState state, @NotNull CallableDescriptor descriptor, @NotNull String assertMethodToCall) { if (!state.isGenerateNotNullAssertions()) return; if (!isDeclaredInJava(descriptor, state.getBindingContext())) return; JetType type = descriptor.getReturnType(); if (type == null || isNullableType(type)) return; Type asmType = state.getTypeMapper().mapReturnType(type); if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { v.dup(); v.visitLdcInsn(descriptor.getContainingDeclaration().getName().asString()); v.visitLdcInsn(descriptor.getName().asString()); v.invokestatic( "jet/runtime/Intrinsics", assertMethodToCall, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V"); } }
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); }
public static boolean isCompareTo(@NotNull CallableDescriptor descriptor) { return descriptor.getName().equals(OperatorConventions.COMPARE_TO); }