Skip to content

Removing warnings from Amazon.Lambda.RuntimeSupport #2125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\..\..\buildtools\common.props" />

Expand All @@ -13,7 +13,9 @@
<PackageReadmeFile>README.md</PackageReadmeFile>
<GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>true</GenerateAssemblyFileVersionAttribute>
<LangVersion>9.0</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>NU5048;NU1903;NU1902</NoWarn>
<LangVersion>9.0</LangVersion>
</PropertyGroup>

<PropertyGroup Condition=" '$(ExecutableOutputType)'=='true' ">
Expand All @@ -22,7 +24,6 @@
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0' or '$(TargetFramework)' == 'net9.0' or '$(TargetFramework)' == 'net10.0'">
<WarningsAsErrors>IL2026,IL2067,IL2075</WarningsAsErrors>
<IsTrimmable>true</IsTrimmable>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
Expand Down Expand Up @@ -29,8 +29,11 @@ public class HandlerWrapper : IDisposable
private static readonly InvocationResponse EmptyInvocationResponse =
new InvocationResponse(new MemoryStream(0), false);

private MemoryStream OutputStream = new MemoryStream();
private readonly MemoryStream OutputStream = new MemoryStream();

/// <summary>
/// The handler that will be called for each event.
/// </summary>
public LambdaBootstrapHandler Handler { get; private set; }

private HandlerWrapper(LambdaBootstrapHandler handler)
Expand Down Expand Up @@ -163,7 +166,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, ILambdaConte
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltStream&gt Handler()
/// Example handler signature: Task&lt;Stream&gt; Handler()
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <returns>A HandlerWrapper</returns>
Expand All @@ -178,7 +181,7 @@ public static HandlerWrapper GetHandlerWrapper(Func<Task<Stream>> handler)
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltStream&gt Handler(Stream)
/// Example handler signature: Task&lt;Stream&gt; Handler(Stream)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <returns>A HandlerWrapper</returns>
Expand All @@ -193,7 +196,7 @@ public static HandlerWrapper GetHandlerWrapper(Func<Stream, Task<Stream>> handle
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltStream&gt Handler(PocoIn)
/// Example handler signature: Task&lt;Stream&gt; Handler(PocoIn)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand All @@ -210,7 +213,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, Task<Stream>
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltStream&gt Handler(ILambdaContext)
/// Example handler signature: Task&lt;Stream&gt; Handler(ILambdaContext)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <returns>A HandlerWrapper</returns>
Expand All @@ -225,7 +228,7 @@ public static HandlerWrapper GetHandlerWrapper(Func<ILambdaContext, Task<Stream>
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltStream&gt Handler(Stream, ILambdaContext)
/// Example handler signature: Task&lt;Stream&gt; Handler(Stream, ILambdaContext)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <returns>A HandlerWrapper</returns>
Expand All @@ -240,7 +243,7 @@ public static HandlerWrapper GetHandlerWrapper(Func<Stream, ILambdaContext, Task
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltStream&gt Handler(PocoIn, ILambdaContext)
/// Example handler signature: Task&lt;Stream&gt; Handler(PocoIn, ILambdaContext)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand All @@ -257,7 +260,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, ILambdaConte
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltPocoOut&gt Handler()
/// Example handler signature: Task&lt;PocoOut&gt; Handler()
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand All @@ -279,7 +282,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Task<TOutput>> hand
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltPocoOut&gt Handler(Stream)
/// Example handler signature: Task&lt;PocoOut&gt; Handler(Stream)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand All @@ -301,7 +304,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, Task<TOutpu
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltPocoOut&gt Handler(PocoIn)
/// Example handler signature: Task&lt;PocoOut&gt; Handler(PocoIn)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand All @@ -324,7 +327,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, Tas
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltPocoOut&gt Handler(ILambdaContext)
/// Example handler signature: Task&lt;PocoOut&gt; Handler(ILambdaContext)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand All @@ -346,7 +349,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<ILambdaContext, Tas
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltPocoOut&gt Handler(Stream, ILambdaContext)
/// Example handler signature: Task&lt;PocoOut&gt; Handler(Stream, ILambdaContext)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand All @@ -368,7 +371,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, ILambdaCont
/// <summary>
/// Get a HandlerWrapper that will call the given method on function invocation.
/// Note that you may have to cast your handler to its specific type to help the compiler.
/// Example handler signature: Task&ltPocoOut&gt Handler(PocoIn, ILambdaContext)
/// Example handler signature: Task&lt;PocoOut&gt; Handler(PocoIn, ILambdaContext)
/// </summary>
/// <param name="handler">Func called for each invocation of the Lambda function.</param>
/// <param name="serializer">ILambdaSerializer to use when calling the handler</param>
Expand Down Expand Up @@ -719,6 +722,9 @@ public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, ILa
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls

/// <summary>
/// Dispose the HandlerWrapper
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
Expand All @@ -732,6 +738,9 @@ protected virtual void Dispose(bool disposing)
}
}

/// <summary>
/// Dispose the HandlerWrapper
/// </summary>
public void Dispose()
{
Dispose(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public InvokeDelegateBuilder(InternalLogger logger, HandlerInfo handler, MethodI
/// <summary>
/// Constructs the invoke delegate using Expressions
///
/// Serialize & Deserialize calls are only made when a serializer is provided.
/// Serialize and Deserialize calls are only made when a serializer is provided.
/// Context is only passed when customer method has context parameter.
/// Lambda return type can be void.
///
Expand All @@ -62,7 +62,8 @@ public InvokeDelegateBuilder(InternalLogger logger, HandlerInfo handler, MethodI
///
/// </summary>
/// <param name="customerObject">Wrapped customer object.</param>
/// <param name="customerSerializerInstance">Instance of lambda input & output serializer.</param>
/// <param name="customerSerializerInstance">Instance of lambda input &amp; output serializer.</param>
/// <param name="isPreJit">If true forces more .NET code to get loaded during startup for jitting.</param>
/// <returns>Action delegate pointing to customer's handler.</returns>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("ConstructInvokeDelegate does not support trimming and is meant to be used in class library based Lambda functions.")]
Expand All @@ -73,54 +74,54 @@ public Action<Stream, ILambdaContext, Stream> ConstructInvokeDelegate(object cus
var outStreamParameter = Expression.Parameter(Types.StreamType, "outStream");
var contextParameter = Expression.Parameter(typeof(ILambdaContext), "context");

_logger.LogDebug($"UCL : Constructing input expression");
_logger.LogDebug("UCL : Constructing input expression");
var inputExpression = BuildInputExpressionOrNull(customerSerializerInstance, inStreamParameter, out var iLambdaContextType);
if (isPreJit)
{
_logger.LogInformation("PreJit: inputExpression");
UserCodeInit.InitDeserializationAssembly(inputExpression, inStreamParameter);
}

_logger.LogDebug($"UCL : Constructing context expression");
_logger.LogDebug("UCL : Constructing context expression");
var contextExpression = BuildContextExpressionOrNull(iLambdaContextType, contextParameter);

_logger.LogDebug($"UCL : Constructing handler expression");
_logger.LogDebug("UCL : Constructing handler expression");
var handlerExpression = CreateHandlerCallExpression(customerObject, inputExpression, contextExpression);

_logger.LogDebug($"UCL : Constructing output expression");
_logger.LogDebug("UCL : Constructing output expression");
var outputExpression = CreateOutputExpression(customerSerializerInstance, outStreamParameter, handlerExpression);
if (isPreJit)
{
_logger.LogInformation("PreJit: outputExpression");
UserCodeInit.InitSerializationAssembly(outputExpression, outStreamParameter, CustomerOutputType);
}

_logger.LogDebug($"UCL : Constructing final expression");
_logger.LogDebug("UCL : Constructing final expression");

var finalExpression = Expression.Lambda<Action<Stream, ILambdaContext, Stream>>(outputExpression, inStreamParameter, contextParameter, outStreamParameter);
#if DEBUG
var finalExpressionDebugView = typeof(Expression)
.GetTypeInfo()
.GetProperty("DebugView", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(finalExpression);
_logger.LogDebug($"UCL : Constructed final expression:\n'{finalExpressionDebugView}'");
_logger.LogDebug("UCL : Constructed final expression:\n'{finalExpressionDebugView}'");
#endif

_logger.LogDebug($"UCL : Compiling final expression");
_logger.LogDebug("UCL : Compiling final expression");
return finalExpression.Compile();
}

/// <summary>
/// Creates an expression to convert incoming Stream to the customer method inputs.
/// If customer method takes no inputs or only takes ILambdaContext, return null.
/// </summary>
/// <param name="customerSerializerInstance">Instance of lambda input & output serializer.</param>
/// <param name="customerSerializerInstance">Instance of lambda input and output serializer.</param>
/// <param name="inStreamParameter">Input stream parameter.</param>
/// <param name="iLambdaContextType">Type of context passed for the invocation.</param>
/// <returns>Expression that deserializes incoming stream to the customer method inputs or null if customer method takes no input.</returns>
/// <exception cref="LambdaValidationException">Thrown when customer method inputs don't meet lambda requirements.</exception>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("BuildInputExpressionOrNull does not support trimming and is meant to be used in class library based Lambda functions.")]
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("BuildInputExpressionOrNull does not support trimming and is meant to be used in class library based Lambda functions.")]
#endif
private Expression BuildInputExpressionOrNull(object customerSerializerInstance, Expression inStreamParameter, out Type iLambdaContextType)
{
Expand Down Expand Up @@ -171,7 +172,7 @@ private Expression BuildInputExpressionOrNull(object customerSerializerInstance,

if (iLambdaContextType != null)
{
_logger.LogDebug($"UCL : Validating iLambdaContextType");
_logger.LogDebug("UCL : Validating iLambdaContextType");
UserCodeValidator.ValidateILambdaContextType(iLambdaContextType);
}

Expand Down Expand Up @@ -257,7 +258,7 @@ private Expression CreateHandlerCallExpression(object customerObject, Expression
/// is just the handler call expression. Otherwise, the final expression is the
/// serialization expression operating on the handler call expression.
/// </summary>
/// <param name="customerSerializerInstance">Instance of lambda input & output serializer.</param>
/// <param name="customerSerializerInstance">Instance of lambda input and output serializer.</param>
/// <param name="outStreamParameter">Expression that defines customer output.</param>
/// <param name="handlerCallExpression">Expression that defines customer handler call.</param>
/// <returns>Expression that serializes customer method output to outgoing stream.</returns>
Expand Down Expand Up @@ -313,12 +314,12 @@ private static Type GetTaskTSubclassOrNull(Type type)
/// <summary>
/// Generates an expression to serialize customer method result into the output stream
/// </summary>
/// <param name="customerSerializerInstance">Instance of lambda input & output serializer.</param>
/// <param name="customerSerializerInstance">Instance of lambda input and output serializer.</param>
/// <param name="dataType">Customer input type.</param>
/// <param name="customerObject">Expression that define customer object.</param>
/// <param name="outStreamParameter">Expression that defines customer output.</param>
/// <returns>Expression that serializes returned object to output stream.</returns>
/// <exception cref="LambdaValidationException">Thrown when customer input is serializable & serializer instance is null.</exception>
/// <exception cref="LambdaValidationException">Thrown when customer input is serializable &amp; serializer instance is null.</exception>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("CreateSerializeExpression does not support trimming and is meant to be used in class library based Lambda functions.")]
#endif
Expand Down Expand Up @@ -371,7 +372,7 @@ private Expression CreateSerializeExpression(object customerSerializerInstance,
/// <summary>
/// Generates an expression to deserialize incoming data to customer method input
/// </summary>
/// <param name="customerSerializerInstance">Instance of lambda input & output serializer.</param>
/// <param name="customerSerializerInstance">Instance of lambda input and output serializer.</param>
/// <param name="dataType">Customer input type.</param>
/// <param name="inStream">Input expression that defines customer input.</param>
/// <returns>Expression that deserializes incoming data to customer method input.</returns>
Expand Down Expand Up @@ -411,4 +412,4 @@ private Expression CreateDeserializeExpression(object customerSerializerInstance
return deserializeCall;
}
}
}
}
Loading