コード例 #1
0
        private static void GenType(EventSourceClass ec, StringBuilder sb)
        {
            if (!string.IsNullOrWhiteSpace(ec.Namespace))
            {
                sb.AppendLine($@"
namespace {ec.Namespace}
{{");
            }

            sb.AppendLine($@"
    {s_generatedCodeAttribute}
    partial class {ec.ClassName}
    {{");
            GenerateConstructor(ec, sb);

            GenerateProviderMetadata(ec.SourceName, sb);

            sb.AppendLine($@"
    }}");

            if (!string.IsNullOrWhiteSpace(ec.Namespace))
            {
                sb.AppendLine($@"
}}");
            }
        }
コード例 #2
0
            private void GenType(EventSourceClass ec)
            {
                if (!string.IsNullOrWhiteSpace(ec.Namespace))
                {
                    _builder.AppendLine($@"
namespace {ec.Namespace}
{{");
                }

                _builder.AppendLine($@"
    partial class {ec.ClassName}
    {{");
                GenerateConstructor(ec);

                GenerateProviderMetadata(ec.SourceName);

                _builder.AppendLine($@"
    }}");

                if (!string.IsNullOrWhiteSpace(ec.Namespace))
                {
                    _builder.AppendLine($@"
}}");
                }
            }
コード例 #3
0
        private static void EmitSourceFile(SourceProductionContext context, EventSourceClass ec)
        {
            StringBuilder sb = new StringBuilder(1024);

            sb.AppendLine(@"// <auto-generated/>");
            sb.AppendLine();
            sb.AppendLine("using System;");
            GenType(ec, sb);

            context.AddSource($"{ec.ClassName}.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
        }
コード例 #4
0
            public EventSourceClass[] GetEventSourceClasses(List <ClassDeclarationSyntax> classDeclarations)
            {
                INamedTypeSymbol?autogenerateAttribute = _compilation.GetTypeByMetadataName("System.Diagnostics.Tracing.EventSourceAutoGenerateAttribute");

                if (autogenerateAttribute is null)
                {
                    // No EventSourceAutoGenerateAttribute
                    return(Array.Empty <EventSourceClass>());
                }

                INamedTypeSymbol?eventSourceAttribute = _compilation.GetTypeByMetadataName("System.Diagnostics.Tracing.EventSourceAttribute");

                if (eventSourceAttribute is null)
                {
                    // No EventSourceAttribute
                    return(Array.Empty <EventSourceClass>());
                }

                List <EventSourceClass>?results = null;

                // we enumerate by syntax tree, to minimize the need to instantiate semantic models (since they're expensive)
                foreach (IGrouping <SyntaxTree, ClassDeclarationSyntax>?group in classDeclarations.GroupBy(x => x.SyntaxTree))
                {
                    SemanticModel?   sm = null;
                    EventSourceClass?eventSourceClass = null;
                    foreach (ClassDeclarationSyntax?classDef in group)
                    {
                        if (_cancellationToken.IsCancellationRequested)
                        {
                            // be nice and stop if we're asked to
                            return(results?.ToArray() ?? Array.Empty <EventSourceClass>());
                        }

                        bool autoGenerate = false;
                        foreach (AttributeListSyntax?cal in classDef.AttributeLists)
                        {
                            foreach (AttributeSyntax?ca in cal.Attributes)
                            {
                                // need a semantic model for this tree
                                sm ??= _compilation.GetSemanticModel(classDef.SyntaxTree);

                                if (sm.GetSymbolInfo(ca, _cancellationToken).Symbol is not IMethodSymbol caSymbol)
                                {
                                    // badly formed attribute definition, or not the right attribute
                                    continue;
                                }

                                if (autogenerateAttribute.Equals(caSymbol.ContainingType, SymbolEqualityComparer.Default))
                                {
                                    autoGenerate = true;
                                    continue;
                                }
                                if (eventSourceAttribute.Equals(caSymbol.ContainingType, SymbolEqualityComparer.Default))
                                {
                                    string nspace = string.Empty;
                                    NamespaceDeclarationSyntax?ns = classDef.Parent as NamespaceDeclarationSyntax;
                                    if (ns is null)
                                    {
                                        if (classDef.Parent is not CompilationUnitSyntax)
                                        {
                                            // since this generator doesn't know how to generate a nested type...
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        nspace = ns.Name.ToString();
                                        while (true)
                                        {
                                            ns = ns.Parent as NamespaceDeclarationSyntax;
                                            if (ns == null)
                                            {
                                                break;
                                            }

                                            nspace = $"{ns.Name}.{nspace}";
                                        }
                                    }

                                    string className = classDef.Identifier.ToString();
                                    string name      = className;
                                    string guid      = "";

                                    SeparatedSyntaxList <AttributeArgumentSyntax>?args = ca.ArgumentList?.Arguments;
                                    if (args is not null)
                                    {
                                        foreach (AttributeArgumentSyntax?arg in args)
                                        {
                                            string?argName = arg.NameEquals !.Name.Identifier.ToString();
                                            string?value   = sm.GetConstantValue(arg.Expression, _cancellationToken).ToString();

                                            switch (argName)
                                            {
                                            case "Guid":
                                                guid = value;
                                                break;

                                            case "Name":
                                                name = value;
                                                break;
                                            }
                                        }
                                    }

                                    if (!Guid.TryParse(guid, out Guid result))
                                    {
                                        result = GenerateGuidFromName(name.ToUpperInvariant());
                                    }

                                    eventSourceClass = new EventSourceClass
                                    {
                                        Namespace  = nspace,
                                        ClassName  = className,
                                        SourceName = name,
                                        Guid       = result
                                    };
                                    continue;
                                }
                            }
                        }

                        if (!autoGenerate)
                        {
                            continue;
                        }

                        if (eventSourceClass is null)
                        {
                            continue;
                        }

                        results ??= new List <EventSourceClass>();
                        results.Add(eventSourceClass);
                    }
                }

                return(results?.ToArray() ?? Array.Empty <EventSourceClass>());
            }
コード例 #5
0
 private static void GenerateConstructor(EventSourceClass ec, StringBuilder sb)
 {
     sb.AppendLine($@"
 private {ec.ClassName}() : base(new Guid({ec.Guid.ToString("x").Replace("{", "").Replace("}", "")}), ""{ec.SourceName}"") {{ }}");
 }
コード例 #6
0
        private static EventSourceClass?GetSemanticTargetForGeneration(GeneratorAttributeSyntaxContext context, CancellationToken cancellationToken)
        {
            const string EventSourceAttribute = "System.Diagnostics.Tracing.EventSourceAttribute";

            var classDef = (ClassDeclarationSyntax)context.TargetNode;
            NamespaceDeclarationSyntax?ns = classDef.Parent as NamespaceDeclarationSyntax;

            if (ns is null)
            {
                if (classDef.Parent is not CompilationUnitSyntax)
                {
                    // since this generator doesn't know how to generate a nested type...
                    return(null);
                }
            }

            EventSourceClass?eventSourceClass = null;
            string?          nspace           = null;

            foreach (AttributeData attribute in context.TargetSymbol.GetAttributes())
            {
                if (attribute.AttributeClass?.Name != "EventSourceAttribute" ||
                    attribute.AttributeClass.ToDisplayString() != EventSourceAttribute)
                {
                    continue;
                }

                nspace ??= ConstructNamespace(ns);

                string className = classDef.Identifier.ValueText;
                string name      = className;
                string guid      = "";

                ImmutableArray <KeyValuePair <string, TypedConstant> > args = attribute.NamedArguments;
                foreach (KeyValuePair <string, TypedConstant> arg in args)
                {
                    string argName = arg.Key;
                    string value   = arg.Value.Value?.ToString();

                    switch (argName)
                    {
                    case "Guid":
                        guid = value;
                        break;

                    case "Name":
                        name = value;
                        break;
                    }
                }

                if (!Guid.TryParse(guid, out Guid result))
                {
                    result = GenerateGuidFromName(name.ToUpperInvariant());
                }

                eventSourceClass = new EventSourceClass(nspace, className, name, result);
                continue;
            }

            return(eventSourceClass);
        }