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: 2 additions & 9 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
<Project>
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<!-- Minimum Roslyn version required to compile this generator:
- ForAttributeWithMetadataName requires 4.3.1+
- ImmutableArray<T> collection expression support (CS9210) requires System.Collections.Immutable 9.0,
which ships with Roslyn 4.9.x (VS 2022 17.9 / .NET 9 SDK).
- IncrementalGeneratorPostInitializationContext.AddEmbeddedAttributeDefinition() requires Roslyn 4.14.0+,
which ships with VS 2022 17.14 / .NET 10 SDK.
Consumers on net48 or net8+ built with VS 2022 17.14+ or .NET 10+ SDK are fully supported. -->
<RoslynVersion>4.14.0</RoslynVersion>
<RoslynVersion>5.9.0</RoslynVersion>
<TUnitVersion>1.65.51</TUnitVersion>
<PurviewSGFVersion>1.0.0-prerelease.36</PurviewSGFVersion>
<PurviewSGFVersion>1.0.0-prerelease.37</PurviewSGFVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Purview.SourceGeneratorFramework" Version="$(PurviewSGFVersion)" />
Expand Down
19 changes: 16 additions & 3 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ build *args:
echo "Building {{ BLUE }}{{ solution_file }}{{ NORMAL }} with {{ YELLOW }}{{ build_configuration }}{{ NORMAL }}..."
dotnet build "{{ solution_file }}" --configuration "{{ build_configuration }}" {{ args }}

# Restore NuGet packages for the solution
[group('Build and Test')]
restore *args:
dotnet restore {{ solution_file }} {{ args }}

# Runs tests for the solution with the specified configuration (default: Release)
[group('Build and Test')]
test filter="/*/*/*/*/" *args:
Expand Down Expand Up @@ -163,25 +168,33 @@ update-version:

# Opens the solution in the default associated application

[group('System/ Shell')]
[group('Utilities')]
vs:
echo "Opening {{ BLUE }}{{ solution_file }}{{ NORMAL }}..."
open "{{ solution_file }}"

# Opens the root folder in Visual Studio Code

[group('System/ Shell')]
[group('Utilities')]
code:
echo "Opening {{ BLUE }}Visual Studio Code{{ NORMAL }}..."
code "{{ root_folder }}"

# Opens the sample solution in the default associated application

[group('System/ Shell')]
[group('Utilities')]
vs-s:
echo "Opening {{ BLUE }}{{ sample_solution_file }}{{ NORMAL }}..."
open "{{ sample_solution_file }}"

# Clean up the repository by removing build artifacts, bin/obj folders etc, and shutting down the build server
[group('Utilities')]
scrub:
find . -type d \( -name bin -o -name obj \) -exec rm -rf {} +
just clean
just restore --force-evaluate
dotnet build-server shutdown

# -----------------------------------------------------------------------------
# Benchmarking
# -----------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "purview-telemetry-sourcegenerator",
"version": "5.0.0-prerelease.5",
"version": "5.0.0-prerelease.6",
"description": "Generates [`ActivitySource`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.activitysource), [`ILogger`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger), and [`Metrics`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.metrics) based on interface methods.",
"readme": "README.md",
"repository": {
Expand Down
14 changes: 11 additions & 3 deletions src/src/SourceGenerator/Analyzers/TelemetryDiagnosticAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,19 @@ static void AnalyzeNamedType(SymbolAnalysisContext context)

var hasActivitySource = Utilities.ContainsAttribute(
interfaceSymbol,
TypeLibrary.Activities.ActivitySourceAttribute,
TypeLibrary.Purview.Telemetry.ActivitySourceAttribute,
token
);
var hasLogger = Utilities.ContainsAttribute(
interfaceSymbol,
TypeLibrary.Purview.Telemetry.LoggerAttribute,
token
);
var hasMeter = Utilities.ContainsAttribute(
interfaceSymbol,
TypeLibrary.Purview.Telemetry.MeterAttribute,
token
);
var hasLogger = Utilities.ContainsAttribute(interfaceSymbol, TypeLibrary.Logging.LoggerAttribute, token);
var hasMeter = Utilities.ContainsAttribute(interfaceSymbol, TypeLibrary.Metrics.MeterAttribute, token);

if (!hasActivitySource && !hasLogger && !hasMeter)
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ out var _
var activityVariableName = "activity" + methodTarget.MethodName;

writer.Assignment(
TypeLibrary.Activities.SystemDiagnostics.Activity.MakeNullable(writer),
TypeLibrary.System.Diagnostics.Activity.MakeNullable(writer),
activityVariableName,
writeValue: assignmentWriter =>
{
Expand All @@ -62,9 +62,7 @@ out var _
var createOnly = methodTarget.ActivityAttribute?.CreateOnly == true;
var useParentContext =
parentContextOrId != null
&& parentContextOrId.ParameterType.Identity.Equals(
TypeLibrary.Activities.SystemDiagnostics.ActivityContext
);
&& parentContextOrId.ParameterType.Identity.Equals(TypeLibrary.System.Diagnostics.ActivityContext);
var parentContextParameterName = useParentContext ? "parentContext" : "parentId";

if (createOnly && startTimeParam != null)
Expand Down Expand Up @@ -120,7 +118,7 @@ out var _

context.CancellationToken.ThrowIfCancellationRequested();

if (methodTarget.ReturnType.Similar(TypeLibrary.Activities.SystemDiagnostics.Activity))
if (methodTarget.ReturnType.Similar(TypeLibrary.System.Diagnostics.Activity))
{
writer.Return(returnWriter =>
returnWriter.Write(activityVariableName).Write(methodTarget.ReturnType.IsNullable ? null : "!")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.CodeAnalysis;
using Purview.Telemetry.SourceGenerator.Helpers;
using Purview.Telemetry.SourceGenerator.Records;

namespace Purview.Telemetry.SourceGenerator.Emitters;
Expand Down Expand Up @@ -34,7 +33,7 @@ out var _
}

var activityVariableName =
activityParam?.ParameterName ?? TypeLibrary.Activities.SystemDiagnostics.Activity.StaticMember("Current");
activityParam?.ParameterName ?? TypeLibrary.System.Diagnostics.Activity.StaticMember("Current");

if (tagsParam != null)
{
Expand Down Expand Up @@ -63,7 +62,7 @@ out var _

context.CancellationToken.ThrowIfCancellationRequested();

if (methodTarget.ReturnType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.Activity))
if (methodTarget.ReturnType.Identity.Equals(TypeLibrary.System.Diagnostics.Activity))
{
writer.NewLine().Write("return ").Write(activityVariableName).Write(";").NewLine();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ out var statusDescriptionParam
}

var activityVariableName =
activityParam?.ParameterName ?? (TypeLibrary.Activities.SystemDiagnostics.Activity + ".Current");
activityParam?.ParameterName ?? (TypeLibrary.System.Diagnostics.Activity + ".Current");
if (parentContextOrId != null)
{
output.Context.Diagnostic("Parent context/ Id not allowed on event method, only activities.");
Expand Down Expand Up @@ -77,12 +77,12 @@ out var statusDescriptionParam

writer
.NewLine()
.Write(TypeLibrary.Activities.SystemDiagnostics.ActivityEvent)
.Write(TypeLibrary.System.Diagnostics.ActivityEvent)
.Write(' ')
.Write(eventVariableName)
.Write(" = new ")
// Use explicit type for C# 7.3 compatibility (target-typed new() requires C# 9+)
.Write(TypeLibrary.Activities.SystemDiagnostics.ActivityEvent)
.Write(TypeLibrary.System.Diagnostics.ActivityEvent)
.Write("(name: ")
.Write(methodTarget.ActivityOrEventName.Wrap())
// timestamp:
Expand All @@ -108,7 +108,7 @@ out var statusDescriptionParam

context.CancellationToken.ThrowIfCancellationRequested();

if (methodTarget.ReturnType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.Activity))
if (methodTarget.ReturnType.Identity.Equals(TypeLibrary.System.Diagnostics.Activity))
{
writer.NewLine().Write("return ").Write(activityVariableName).Write(";").NewLine();
}
Expand All @@ -128,11 +128,11 @@ static string EmitEventTags(

var tagsListVariableName = "tagsCollection" + methodTarget.MethodName;
writer
.Write(TypeLibrary.Activities.SystemDiagnostics.ActivityTagsCollection)
.Write(TypeLibrary.System.Diagnostics.ActivityTagsCollection)
.Write(' ')
.Write(tagsListVariableName)
.Write(
" = new(" // : $" = new {TypeLibrary.Activities.SystemDiagnostics.ActivityTagsCollection}("
" = new(" // : $" = new {TypeLibrary.System.Diagnostics.ActivityTagsCollection}("
);

if (tagsParam != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,22 @@ static void EmitFields(ActivityOutputContext output, CodeWriter writer, SourcePr
activitySourceName = PropertyLibrary.Activities.DefaultActivitySourceName;
}

#pragma warning disable IDE0002 // Simplify Member Access
writer
.Field(
new FieldDeclarationOptions(
PropertyLibrary.Activities.ActivitySourceFieldName,
TypeLibrary.Activities.SystemDiagnostics.ActivitySource.AsTypeReference()
TypeLibrary.System.Diagnostics.ActivitySource.AsTypeReference()
)
{
IsStatic = true,
IsReadOnly = true,
Initializer =
$"new {(string)TypeLibrary.Activities.SystemDiagnostics.ActivitySource}({activitySourceName!.Wrap()})",
$"new {(string)TypeLibrary.System.Diagnostics.ActivitySource}({activitySourceName!.Wrap()})",
IncludeGeneratedAttributes = false,
}
)
.NewLine();
#pragma warning restore IDE0002 // Simplify Member Access
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ SourceProductionContext context
writer.MethodScope(
new MethodDeclarationOptions(
PropertyLibrary.Activities.RecordExceptionMethodName,
PurviewTypeLibrary.System.Void.AsTypeReference()
TypeLibrary.System.Void.AsTypeReference()
)
{
IsStatic = true,
Parameters =
[
new ParameterDeclarationOptions(
"activity",
TypeLibrary.Activities.SystemDiagnostics.Activity.MakeNullable(writer)
TypeLibrary.System.Diagnostics.Activity.MakeNullable(writer)
),
new ParameterDeclarationOptions("exception", TypeLibrary.System.Exception.MakeNullable(writer)),
new ParameterDeclarationOptions("escape", PurviewTypeLibrary.System.Boolean.AsTypeReference()),
new ParameterDeclarationOptions("escape", TypeLibrary.System.Boolean.AsTypeReference()),
],
IncludeGeneratedAttributes = false,
}
Expand All @@ -73,9 +73,9 @@ SourceProductionContext context

const string tagsListVariableName = "tagsCollection";
writer.Assignment(
TypeLibrary.Activities.SystemDiagnostics.ActivityTagsCollection,
TypeLibrary.System.Diagnostics.ActivityTagsCollection,
tagsListVariableName,
"new " + TypeLibrary.Activities.SystemDiagnostics.ActivityTagsCollection + "()"
"new " + TypeLibrary.System.Diagnostics.ActivityTagsCollection + "()"
);

EmitExceptionParam(writer, tagsListVariableName, "escape", "exception");
Expand All @@ -84,11 +84,11 @@ SourceProductionContext context

writer
.NewLine()
.Write(TypeLibrary.Activities.SystemDiagnostics.ActivityEvent)
.Write(TypeLibrary.System.Diagnostics.ActivityEvent)
.Write(' ')
.Write(eventVariableName)
.Write(" = new ")
.Write(TypeLibrary.Activities.SystemDiagnostics.ActivityEvent)
.Write(TypeLibrary.System.Diagnostics.ActivityEvent)
// name:
.Write("(name: ")
.Write(PropertyLibrary.Activities.Tag_ExceptionEventName.Wrap())
Expand Down Expand Up @@ -299,21 +299,19 @@ SourceProductionContext context
)
)
{
var returnsActivity = methodTarget.ReturnType.Identity.Equals(
TypeLibrary.Activities.SystemDiagnostics.Activity
);
var returnsActivity = methodTarget.ReturnType.Identity.Equals(TypeLibrary.System.Diagnostics.Activity);
var paramList = string.Join(", ", methodTarget.Parameters.Select(p => p.ParameterName));

// Create filtered parameter list for Logging/Metrics (excludes Activity-related types)
var loggingMetricsParamList = string.Join(
", ",
methodTarget
.Parameters.Where(p =>
!p.ParameterType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.Activity)
&& !p.ParameterType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.ActivityContext)
&& !p.ParameterType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.ActivityLink)
&& !p.ParameterType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.ActivityLinkArray)
&& !p.ParameterType.Identity.Equals(TypeLibrary.System.TagList)
!p.ParameterType.Identity.Equals(TypeLibrary.System.Diagnostics.Activity)
&& !p.ParameterType.Identity.Equals(TypeLibrary.System.Diagnostics.ActivityContext)
&& !p.ParameterType.Identity.Equals(TypeLibrary.System.Diagnostics.ActivityLink)
&& !p.ParameterType.Identity.Equals(TypeLibrary.System.Diagnostics.ActivityLinkArray)
&& !p.ParameterType.Identity.Equals(TypeLibrary.System.Diagnostics.TagList)
)
.Select(p => p.ParameterName)
);
Expand Down Expand Up @@ -423,7 +421,7 @@ static bool GuardMethod(ActivityBasedGenerationTarget methodTarget, ActivityOutp
var isValidReturnType = isEvent
? methodTarget.ReturnType.Identity.SpecialType == SpecialType.System_Void
: methodTarget.ReturnType.Identity.SpecialType == SpecialType.System_Void
|| methodTarget.ReturnType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.Activity);
|| methodTarget.ReturnType.Identity.Equals(TypeLibrary.System.Diagnostics.Activity);

if (!isValidReturnType)
{
Expand All @@ -439,7 +437,7 @@ static bool GuardMethod(ActivityBasedGenerationTarget methodTarget, ActivityOutp
// Here we're opting in to generate diagnostics for missing activity return/ params.
if (methodTarget.MethodType == ActivityMethodType.Activity)
{
if (!methodTarget.ReturnType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.Activity))
if (!methodTarget.ReturnType.Identity.Equals(TypeLibrary.System.Diagnostics.Activity))
{
output.Context.Diagnostic($"No Activity returned for {methodTarget.MethodName}.");
}
Expand All @@ -455,9 +453,7 @@ static bool GuardMethod(ActivityBasedGenerationTarget methodTarget, ActivityOutp
output.Context.Diagnostic($"No Activity parameter is defined on {methodTarget.MethodName}.");
}
else if (
!methodTarget
.Parameters[0]
.ParameterType.Identity.Equals(TypeLibrary.Activities.SystemDiagnostics.Activity)
!methodTarget.Parameters[0].ParameterType.Identity.Equals(TypeLibrary.System.Diagnostics.Activity)
)
{
output.Context.Diagnostic(
Expand Down
6 changes: 3 additions & 3 deletions src/src/SourceGenerator/Emitters/ConstructorEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ GenerationContext<TelemetryCapabilities> generationContext

if (generationType.HasFlag(GenerationType.Logging))
{
var loggerType = TypeLibrary.Logging.MicrosoftExtensions.ILogger.MakeGeneric(interfaceType);
builder.Add(new ParameterDeclarationOptions(LoggerParameterName, new TypeReference(loggerType)));
var loggerType = TypeLibrary.Microsoft.Extensions.Logging.ILogger.MakeGeneric(interfaceType);
builder.Add(new(LoggerParameterName, new TypeReference(loggerType)));
}

if (generationType.HasFlag(GenerationType.Metrics) && generationContext.Capabilities.SupportsIMeterFactory)
{
builder.Add(
new ParameterDeclarationOptions(
PropertyLibrary.Metrics.MeterFactoryParameterName,
TypeLibrary.Metrics.SystemDiagnostics.IMeterFactory
TypeLibrary.System.Diagnostics.Metrics.IMeterFactory
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,17 @@ CancellationToken token
writer.MethodScope(
new(
"Add" + methodName,
TypeLibrary.DependencyInjection.IServiceCollection,
TypeLibrary.Microsoft.Extensions.DependencyInjection.IServiceCollection,
TypeDeclarationAccessibility.Public
)
{
IsStatic = true,
Parameters =
[
new("services", TypeLibrary.DependencyInjection.IServiceCollection) { IsThis = true },
new("services", TypeLibrary.Microsoft.Extensions.DependencyInjection.IServiceCollection)
{
IsThis = true,
},
],
IncludeGeneratedAttributes = false,
}
Expand Down
Loading