Skip to content
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
11 changes: 3 additions & 8 deletions TUnit.Core.SourceGenerator/CodeGenerationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public static string GenerateAttributeInstantiation(AttributeData attr, Immutabl
var arg = attr.ConstructorArguments[i];

// Check if this is a params array parameter
if (i == attr.ConstructorArguments.Length - 1 && IsParamsArrayArgument(attr, i))
if (i == attr.ConstructorArguments.Length - 1 && IsParamsArrayArgument(attr))
{
if (arg.Kind == TypedConstantKind.Array)
{
Expand Down Expand Up @@ -282,16 +282,11 @@ public static string GenerateAttributeInstantiation(AttributeData attr, Immutabl
/// <summary>
/// Determines if an argument is for a params array parameter.
/// </summary>
private static bool IsParamsArrayArgument(AttributeData attr, int argumentIndex)
private static bool IsParamsArrayArgument(AttributeData attr)
{
var typeName = attr.AttributeClass!.GloballyQualified();

if (typeName is "global::TUnit.Core.ArgumentsAttribute" or "global::TUnit.Core.InlineDataAttribute")
{
return true;
}

return false;
return typeName is "global::TUnit.Core.ArgumentsAttribute" or "global::TUnit.Core.InlineDataAttribute";
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static void GenerateInstanceFactory(CodeWriter writer, ITypeSymbol typeSy
var constructor = GetPrimaryConstructor(typeSymbol);
if (constructor != null)
{
GenerateTypedConstructorCall(writer, className, constructor, testMethod);
GenerateTypedConstructorCall(writer, className, constructor);
}
else
{
Expand Down Expand Up @@ -145,7 +145,7 @@ public static void GenerateInstanceFactory(CodeWriter writer, ITypeSymbol typeSy
return publicConstructors.Length == 1 ? publicConstructors[0] : publicConstructors.FirstOrDefault();
}

private static void GenerateTypedConstructorCall(CodeWriter writer, string className, IMethodSymbol constructor, TestMethodMetadata? testMethod)
private static void GenerateTypedConstructorCall(CodeWriter writer, string className, IMethodSymbol constructor)
{
writer.AppendLine("InstanceFactory = (typeArgs, args) =>");
writer.AppendLine("{");
Expand All @@ -164,17 +164,17 @@ private static void GenerateTypedConstructorCall(CodeWriter writer, string class

// Generate constructor arguments
var parameterTypes = constructor.Parameters.Select(p => p.Type).ToList();

for (var i = 0; i < parameterTypes.Count; i++)
{
if (i > 0)
{
writer.Append(", ");
}

var parameterType = parameterTypes[i];
var argAccess = $"args[{i}]";

// Use CastHelper which now has AOT converter registry support
writer.Append($"global::TUnit.Core.Helpers.CastHelper.Cast<{parameterType.GloballyQualified()}>({argAccess})");
}
Expand Down Expand Up @@ -214,11 +214,11 @@ private static void GenerateGenericInstanceFactory(CodeWriter writer, INamedType
// Get the open generic type
writer.AppendLine($"var openGenericType = typeof({genericType.OriginalDefinition.GloballyQualified()});");
writer.AppendLine();

// Create the closed generic type
writer.AppendLine("var closedGenericType = global::TUnit.Core.Helpers.GenericTypeHelper.MakeGenericTypeSafe(openGenericType, typeArgs);");
writer.AppendLine();

// Check for constructor parameters
var constructor = GetPrimaryConstructor(genericType);
if (constructor is { Parameters.Length: > 0 })
Expand All @@ -230,7 +230,7 @@ private static void GenerateGenericInstanceFactory(CodeWriter writer, INamedType
{
writer.AppendLine("// Create instance with parameterless constructor");
writer.AppendLine("var instance = global::System.Activator.CreateInstance(closedGenericType);");

// Check for required properties
var requiredProperties = RequiredPropertyHelper.GetAllRequiredProperties(genericType);
if (requiredProperties.Any())
Expand All @@ -243,7 +243,7 @@ private static void GenerateGenericInstanceFactory(CodeWriter writer, INamedType
writer.AppendLine($"closedGenericType.GetProperty(\"{property.Name}\")?.SetValue(instance, {defaultValue});");
}
}

writer.AppendLine("return instance!;");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private static void GenerateStaticPropertyInitialization(SourceProductionContext
// Use a dictionary to deduplicate static properties by their declaring type and name
// This prevents duplicate initialization when derived classes inherit static properties
var uniqueStaticProperties = new Dictionary<(INamedTypeSymbol DeclaringType, string Name), PropertyWithDataSource>(SymbolEqualityComparer.Default.ToTupleComparer());

foreach (var testClass in testClasses)
{
var properties = GetStaticPropertyDataSources(testClass);
Expand All @@ -87,7 +87,7 @@ private static void GenerateStaticPropertyInitialization(SourceProductionContext
}
}
}

var allStaticProperties = uniqueStaticProperties.Values.ToImmutableArray();

if (allStaticProperties.IsEmpty)
Expand All @@ -109,14 +109,14 @@ private static string GenerateInitializationCode(ImmutableArray<PropertyWithData
writer.AppendLine("namespace TUnit.Core.Generated");
writer.AppendLine("{");
writer.Indent();

writer.AppendLine("/// <summary>");
writer.AppendLine("/// Auto-generated static property initializer");
writer.AppendLine("/// </summary>");
writer.AppendLine("internal static class StaticPropertyInitializer");
writer.AppendLine("{");
writer.Indent();

writer.AppendLine("/// <summary>");
writer.AppendLine("/// Module initializer that registers static property metadata");
writer.AppendLine("/// </summary>");
Expand Down Expand Up @@ -179,7 +179,7 @@ private static void GenerateIndividualPropertyInitializer(CodeWriter writer, Pro
writer.AppendLine($"private static async global::System.Threading.Tasks.Task<object?> {methodName}()");
writer.AppendLine("{");
writer.Indent();

// Create PropertyMetadata with containing type information
writer.AppendLine($"// Create PropertyMetadata for {propertyName}");
writer.AppendLine("var containingTypeMetadata = new global::TUnit.Core.ClassMetadata");
Expand All @@ -196,7 +196,7 @@ private static void GenerateIndividualPropertyInitializer(CodeWriter writer, Pro
writer.Unindent();
writer.AppendLine("};");
writer.AppendLine();

writer.AppendLine("var propertyMetadata = new global::TUnit.Core.PropertyMetadata");
writer.AppendLine("{");
writer.Indent();
Expand All @@ -210,7 +210,7 @@ private static void GenerateIndividualPropertyInitializer(CodeWriter writer, Pro
writer.Unindent();
writer.AppendLine("};");
writer.AppendLine();

var attr = propertyData.DataSourceAttribute;
var attributeClassName = attr.AttributeClass?.Name;

Expand All @@ -230,7 +230,7 @@ private static void GenerateIndividualPropertyInitializer(CodeWriter writer, Pro
else if (attr.AttributeClass?.IsOrInherits("global::TUnit.Core.AsyncDataSourceGeneratorAttribute") == true ||
attr.AttributeClass?.IsOrInherits("global::TUnit.Core.AsyncUntypedDataSourceGeneratorAttribute") == true)
{
GenerateAsyncDataSourceGeneratorWithPropertyWithAssignment(writer, attr, propertyData.Property.ContainingType);
GenerateAsyncDataSourceGeneratorWithPropertyWithAssignment(writer, attr);
}
else
{
Expand Down Expand Up @@ -306,7 +306,7 @@ private static void GenerateMethodDataSourceWithAssignment(CodeWriter writer, At
}


private static void GenerateAsyncDataSourceGeneratorWithPropertyWithAssignment(CodeWriter writer, AttributeData attr, INamedTypeSymbol containingType)
private static void GenerateAsyncDataSourceGeneratorWithPropertyWithAssignment(CodeWriter writer, AttributeData attr)
{
var generatorCode = CodeGenerationHelpers.GenerateAttributeInstantiation(attr);
writer.AppendLine($"var generator = {generatorCode};");
Expand Down Expand Up @@ -375,4 +375,4 @@ private static ImmutableArray<PropertyWithDataSource> GetStaticPropertyDataSourc
return properties.ToImmutableArray();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class AttributeWriter(Compilation compilation, TUnit.Core.SourceGenerator
private readonly Dictionary<AttributeData, string> _attributeObjectInitializerCache = new();

public void WriteAttributes(ICodeWriter sourceCodeWriter,
ImmutableArray<AttributeData> attributeDatas)
IEnumerable<AttributeData> attributeDatas)
{
var attributesToWrite = new List<AttributeData>();

Expand Down
14 changes: 7 additions & 7 deletions TUnit.Core.SourceGenerator/Generators/HookMetadataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ private static void GenerateHookFile(SourceProductionContext context, (HookModel
var isOpenGeneric = typeSymbol.IsGenericType && typeSymbol.TypeArguments.Any(t => t.TypeKind == TypeKind.TypeParameter);

// Pre-generate method info expression
var methodInfoExpression = GenerateMethodInfoExpression(context.SemanticModel.Compilation, typeSymbol, methodSymbol);
var methodInfoExpression = GenerateMethodInfoExpression(typeSymbol, methodSymbol);

// Extract parameters using the existing static method
var parameters = ParameterModel.ExtractAll(methodSymbol);
Expand Down Expand Up @@ -200,7 +200,7 @@ private static void GenerateHookFile(SourceProductionContext context, (HookModel
};
}

private static string GenerateMethodInfoExpression(Compilation compilation, INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol)
private static string GenerateMethodInfoExpression(INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol)
{
// Generate the MethodMetadata expression as a string - no header since this is inline
using var writer = new CodeWriter(includeHeader: false);
Expand Down Expand Up @@ -632,19 +632,19 @@ private static void GenerateHookDelegate(CodeWriter writer, HookModel hook)
{
if (hook.ClassIsOpenGeneric)
{
GenerateReflectionBasedInvocation(writer, hook, true);
GenerateReflectionBasedInvocation(writer, hook);
}
else
{
GenerateDirectInvocation(writer, hook, true);
GenerateDirectInvocation(writer, hook);
}
}
}
else
{
using (writer.BeginBlock($"private static async ValueTask {delegateKey}_Body({contextType} context, CancellationToken cancellationToken)"))
{
if (hook.ClassIsOpenGeneric && hook.IsStatic)
if (hook is { ClassIsOpenGeneric: true, IsStatic: true })
{
GenerateOpenGenericStaticInvocation(writer, hook);
}
Expand All @@ -658,7 +658,7 @@ private static void GenerateHookDelegate(CodeWriter writer, HookModel hook)
writer.AppendLine();
}

private static void GenerateReflectionBasedInvocation(CodeWriter writer, HookModel hook, bool isInstance)
private static void GenerateReflectionBasedInvocation(CodeWriter writer, HookModel hook)
{
writer.AppendLine("var instanceType = instance.GetType();");
writer.AppendLine($"var method = instanceType.GetMethod(\"{hook.MethodName}\", global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance{(hook.IsStatic ? " | global::System.Reflection.BindingFlags.Static" : "")});");
Expand Down Expand Up @@ -700,7 +700,7 @@ private static void GenerateReflectionBasedInvocation(CodeWriter writer, HookMod
writer.AppendLine("}");
}

private static void GenerateDirectInvocation(CodeWriter writer, HookModel hook, bool isInstance)
private static void GenerateDirectInvocation(CodeWriter writer, HookModel hook)
{
var className = hook.FullyQualifiedTypeName;
writer.AppendLine($"var typedInstance = ({className})instance;");
Expand Down
Loading
Loading