public static boolean shouldBeInlined(@NotNull CallableDescriptor descriptor) { if (descriptor instanceof SimpleFunctionDescriptor) { return InlineUtil.isInline(descriptor); } if (descriptor instanceof ValueParameterDescriptor) { return InlineUtil.isInline(descriptor.getContainingDeclaration()) && InlineUtil.isInlineLambdaParameter((ParameterDescriptor) descriptor); } return false; }
public InlineCodegen( @NotNull ExpressionCodegen codegen, @NotNull GenerationState state, @NotNull SimpleFunctionDescriptor functionDescriptor, @NotNull JetElement callElement, @Nullable ReifiedTypeParameterMappings typeParameterMappings) { assert InlineUtil.isInline(functionDescriptor) : "InlineCodegen could inline only inline function: " + functionDescriptor; this.state = state; this.typeMapper = state.getTypeMapper(); this.codegen = codegen; this.callElement = callElement; this.functionDescriptor = functionDescriptor.getOriginal(); reifiedTypeInliner = new ReifiedTypeInliner(typeParameterMappings); initialFrameSize = codegen.getFrameMap().getCurrentSize(); context = (MethodContext) getContext(functionDescriptor, state); jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind()); // TODO: implement AS_FUNCTION inline strategy InlineStrategy inlineStrategy = InlineUtil.getInlineStrategy(functionDescriptor); this.asFunctionInline = false; isSameModule = JvmCodegenUtil.isCallInsideSameModuleAsDeclared( functionDescriptor, codegen.getContext(), state.getOutDirectory()); sourceMapper = codegen.getParentCodegen().getOrCreateSourceMapper(); reportIncrementalInfo( functionDescriptor, codegen.getContext().getFunctionDescriptor().getOriginal()); }
private void checkValueParameter( @NotNull CallCheckerContext context, @NotNull CallableDescriptor targetDescriptor, @NotNull ValueArgument targetArgument, @NotNull ValueParameterDescriptor targetParameterDescriptor) { KtExpression argumentExpression = targetArgument.getArgumentExpression(); if (argumentExpression == null) { return; } CallableDescriptor argumentCallee = getCalleeDescriptor(context, argumentExpression, false); if (argumentCallee != null && inlinableParameters.contains(argumentCallee)) { if (InlineUtil.isInline(targetDescriptor) && isInlinableParameter(targetParameterDescriptor)) { if (allowsNonLocalReturns(argumentCallee) && !allowsNonLocalReturns(targetParameterDescriptor)) { context .getTrace() .report(NON_LOCAL_RETURN_NOT_ALLOWED.on(argumentExpression, argumentExpression)); } else { checkNonLocalReturn(context, argumentCallee, argumentExpression); } } else { context .getTrace() .report(USAGE_IS_NOT_INLINABLE.on(argumentExpression, argumentExpression, descriptor)); } } }
public InlineChecker(@NotNull FunctionDescriptor descriptor) { assert InlineUtil.isInline(descriptor) : "This extension should be created only for inline functions: " + descriptor; this.descriptor = descriptor; this.isEffectivelyPublicApiFunction = DescriptorUtilsKt.isEffectivelyPublicApi(descriptor); this.isEffectivelyPrivateApiFunction = DescriptorUtilsKt.isEffectivelyPrivateApi(descriptor); for (ValueParameterDescriptor param : descriptor.getValueParameters()) { if (isInlinableParameter(param)) { inlinableParameters.add(param); } } }
private static boolean isInvokeOrInlineExtension(@NotNull CallableDescriptor descriptor) { if (!(descriptor instanceof SimpleFunctionDescriptor)) { return false; } DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); boolean isInvoke = descriptor.getName().equals(OperatorNameConventions.INVOKE) && containingDeclaration instanceof ClassDescriptor && FunctionTypesKt.isFunctionType( ((ClassDescriptor) containingDeclaration).getDefaultType()); return isInvoke || InlineUtil.isInline(descriptor); }
/*descriptor is null for captured vars*/ public boolean shouldPutValue( @NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor descriptor) { if (stackValue == null) { // default or vararg return true; } // remap only inline functions (and maybe non primitives) // TODO - clean asserion and remapping logic if (isPrimitive(type) != isPrimitive(stackValue.type)) { // don't remap boxing/unboxing primitives - lost identity and perfomance return true; } if (stackValue instanceof StackValue.Local) { return false; } StackValue field = stackValue; if (stackValue instanceof StackValue.FieldForSharedVar) { field = ((StackValue.FieldForSharedVar) stackValue).receiver; } // check that value corresponds to captured inlining parameter if (field instanceof StackValue.Field) { DeclarationDescriptor varDescriptor = ((StackValue.Field) field).descriptor; // check that variable is inline function parameter return !(varDescriptor instanceof ParameterDescriptor && InlineUtil.isInlineLambdaParameter((ParameterDescriptor) varDescriptor) && InlineUtil.isInline(varDescriptor.getContainingDeclaration())); } return true; }