Ejemplo n.º 1
0
        /// <summary>
        /// Generates source code to optimize serialization and deserialization with JsonSerializer.
        /// </summary>
        /// <param name="executionContext"></param>
        public void Execute(GeneratorExecutionContext executionContext)
        {
#if LAUNCH_DEBUGGER
            if (!Diagnostics.Debugger.IsAttached)
            {
                Diagnostics.Debugger.Launch();
            }
#endif
            SyntaxReceiver receiver = (SyntaxReceiver)executionContext.SyntaxReceiver;
            List <ClassDeclarationSyntax>?contextClasses = receiver.ClassDeclarationSyntaxList;
            if (contextClasses == null)
            {
                return;
            }

            Parser parser             = new(executionContext);
            SourceGenerationSpec?spec = parser.GetGenerationSpec(receiver.ClassDeclarationSyntaxList);
            if (spec != null)
            {
                _rootTypes = spec.ContextGenerationSpecList[0].RootSerializableTypes;

                Emitter emitter = new(executionContext, spec);
                emitter.Emit();
            }
        }
Ejemplo n.º 2
0
        // Finds all the classes annotated with the BitStruct attribute.
        private List <INamedTypeSymbol> FindAllBitStructClasses(SourceGeneratorContext context, INamedTypeSymbol bitStructAttributeSymbol)
        {
            // retreive the populated receiver
            SyntaxReceiver receiver = context.SyntaxReceiver as SyntaxReceiver;

            if (receiver == null)
            {
                return(null);
            }

            List <INamedTypeSymbol> result = new List <INamedTypeSymbol>();

            foreach (TypeDeclarationSyntax classDeclarationSyntax in receiver.CandidateClasses)
            {
                SemanticModel    model       = context.Compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);
                INamedTypeSymbol classSymbol = model.GetDeclaredSymbol(classDeclarationSyntax);

                if (SourceGenUtils.HasAttribute(classSymbol, bitStructAttributeSymbol))
                {
                    result.Add(classSymbol);
                }
            }

            return(result);
        }
Ejemplo n.º 3
0
        public void Execute(SourceGeneratorContext context)
        {
            SyntaxReceiver receiver = context.SyntaxReceiver as SyntaxReceiver;

            foreach (string name in receiver.Namespaces)
            {
                string code = GetCodeForNamespace(name);
                context.AddSource($"{name}.Console.Generated", SourceText.From(code, Encoding.UTF8));
            }
        }
Ejemplo n.º 4
0
        public void Execute(GeneratorExecutionContext context)
        {
            SyntaxReceiver rx = (SyntaxReceiver)context.SyntaxContextReceiver !;

            foreach ((string name, string template, string hash) in rx.TemplateInfo)
            {
                string source = SourceFileFromMustachePath(name, template, hash);
                context.AddSource($"Mustache{name}", source);
            }
        }
        public void OnVisitSyntaxNode_SyntaxWithFullyQualifiedIDisposableBase_AddsSingleCandidate()
        {
            // Arrange
            var tree           = CSharpSyntaxTree.ParseText(@"
                public class TestClass : System.IDisposable
                {

                }
                ");
            var classNode      = tree.GetRoot().DescendantNodes().OfType <ClassDeclarationSyntax>().First();
            var syntaxReceiver = new SyntaxReceiver();

            // Act
            syntaxReceiver.OnVisitSyntaxNode(classNode);

            // Assert
            Assert.Single(syntaxReceiver.CandidateClasses);
        }
        public void OnVisitSyntaxNode_SyntaxWithUninterestingBase_FindsNoCandidates()
        {
            // Arrange
            var tree           = CSharpSyntaxTree.ParseText(@"
                public class TestClass : IEnumerable
                {

                }
                ");
            var classNode      = tree.GetRoot().DescendantNodes().OfType <ClassDeclarationSyntax>().First();
            var syntaxReceiver = new SyntaxReceiver();

            // Act
            syntaxReceiver.OnVisitSyntaxNode(classNode);

            // Assert
            Assert.False(syntaxReceiver.CandidateClasses.Any());
        }
        public void Execute(GeneratorExecutionContext context)
        {
            SyntaxReceiver rx = (SyntaxReceiver)context.SyntaxContextReceiver !;

            HashSet <string> generatedInterfaces = new HashSet <string>();

            foreach (string interfaceFullTypeName in rx.InterfacesToGenerate)
            {
                INamedTypeSymbol?interfaceSymbol = context.Compilation.GetTypeByMetadataName(interfaceFullTypeName);
                if (interfaceSymbol == null)
                {
                    continue;
                }

                if (generatedInterfaces.Contains(interfaceFullTypeName))
                {
                    continue;
                }

                ImportedControlGenerator.GenerateSourceFile(context, interfaceFullTypeName);
                generatedInterfaces.Add(interfaceFullTypeName);

                // Generate any ancestor types
                INamedTypeSymbol?ancestorType = GetBaseInterface(interfaceSymbol);
                while (ancestorType != null)
                {
                    var symbolDisplayFormat = new SymbolDisplayFormat(
                        typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);
                    string ancestorFullTypeName = ancestorType.ToDisplayString(symbolDisplayFormat);

                    if (ancestorFullTypeName == "Microsoft.StandardUI.Controls.IStandardControl" || generatedInterfaces.Contains(ancestorFullTypeName))
                    {
                        break;
                    }

                    ImportedControlGenerator.GenerateSourceFile(context, ancestorFullTypeName);
                    generatedInterfaces.Add(ancestorFullTypeName);

                    ancestorType = GetBaseInterface(ancestorType);
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Generates source code to optimize serialization and deserialization with JsonSerializer.
        /// </summary>
        /// <param name="executionContext"></param>
        public void Execute(GeneratorExecutionContext executionContext)
        {
            SyntaxReceiver receiver = (SyntaxReceiver)executionContext.SyntaxReceiver;
            List <CompilationUnitSyntax> compilationUnits = receiver.CompilationUnits;

            if (compilationUnits == null)
            {
                return;
            }

            Parser parser = new(executionContext.Compilation);

            _rootTypes = parser.GetRootSerializableTypes(receiver.CompilationUnits);

            if (_rootTypes != null)
            {
                Emitter emitter = new(executionContext, _rootTypes);
                emitter.Emit();
            }
        }
        public void OnVisitSyntaxNode_MultipleVisitsWithInterestingClass_YieldsMultipleCandidates()
        {
            // Arrange
            var tree           = CSharpSyntaxTree.ParseText(@"
                public class TestClass : System.IDisposable
                {

                }
                ");
            var classNode      = tree.GetRoot().DescendantNodes().OfType <ClassDeclarationSyntax>().First();
            var syntaxReceiver = new SyntaxReceiver();

            // Act
            syntaxReceiver.OnVisitSyntaxNode(classNode);
            syntaxReceiver.OnVisitSyntaxNode(classNode);
            syntaxReceiver.OnVisitSyntaxNode(classNode);

            // Assert
            Assert.Equal(3, syntaxReceiver.CandidateClasses.Count);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Generates source code to optimize serialization and deserialization with JsonSerializer.
        /// </summary>
        /// <param name="executionContext"></param>
        public void Execute(GeneratorExecutionContext executionContext)
        {
            SyntaxReceiver receiver = (SyntaxReceiver)executionContext.SyntaxReceiver;
            List <ClassDeclarationSyntax>?contextClasses = receiver.ClassDeclarationSyntaxList;

            if (contextClasses == null)
            {
                return;
            }

            Parser parser             = new(executionContext);
            SourceGenerationSpec?spec = parser.GetGenerationSpec(receiver.ClassDeclarationSyntaxList);

            if (spec != null)
            {
                _rootTypes = spec.ContextGenerationSpecList[0].RootSerializableTypes;

                Emitter emitter = new(executionContext, spec);
                emitter.Emit();
            }
        }
Ejemplo n.º 11
0
        public void Execute(GeneratorExecutionContext context)
        {
#if DEBUG
            if (!Debugger.IsAttached)
            {
                //Debugger.Launch();
            }
#endif
            SyntaxReceiver rx = (SyntaxReceiver)context.SyntaxContextReceiver !;
            foreach (TypeInfo targetType in rx.GeneratedTypes)
            {
                if (targetType.Type?.IsAbstract == true)
                {
                    continue;
                }

                StringBuilder sb                 = new();
                const string  suffix             = "GeneratedExtensions";
                string        targetTypeFullName = $"{targetType.Type}";
                string        targetTypeName     = targetType.Type !.Name;
                var           extensionClass     = context.Compilation.GetTypeByMetadataName($"XamlTest.{targetTypeName}{suffix}");
                if (extensionClass is null)
                {
                    continue;
                }

                string variableTargetTypeName =
                    char.ToLowerInvariant(targetType.Type.Name[0])
                    + targetType.Type.Name.Substring(1);

                string className = $"{targetType.Type.Name}{suffix}Tests";

                sb.AppendLine($@"
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Threading.Tasks;
using System;

namespace XamlTest.Tests.Generated
{{
    [TestClass]
    public partial class {className}
    {{
        [NotNull]
        private static IApp? App {{ get; set; }}

        [NotNull]
        private static IWindow? Window {{ get; set; }}

        private static Func<string, string> GetWindowContent {{ get; set; }} = x => x;

        private static Func<string, Task<IVisualElement<{targetTypeFullName}>>> GetElement {{ get; set; }}
            = async x => await Window.GetElement<{targetTypeFullName}>(x);

        static partial void OnClassInitialize();

        [ClassInitialize]
        public static async Task ClassInitialize(TestContext context)
        {{
            OnClassInitialize();
            App = XamlTest.App.StartRemote(logMessage: msg => context.WriteLine(msg));

            await App.InitializeWithDefaults(Assembly.GetExecutingAssembly().Location);

            string content = @$""<{targetTypeName} x:Name=""""Test{targetTypeName}""""/>"";

            content = GetWindowContent(content);

            Window = await App.CreateWindowWithContent(content);
        }}

        [ClassCleanup]
        public static void TestCleanup()
        {{
            App.Dispose();
        }}

");

                foreach (IMethodSymbol getMethod in GetTestMethods(extensionClass))
                {
                    string methodReturnType = ((INamedTypeSymbol)getMethod.ReturnType).TypeArguments[0].ToString();

                    sb.AppendLine($@"
        [TestMethod]
        public async Task CanInvoke_{getMethod.Name}_ReturnsValue()
        {{
            // Arrange
            await using TestRecorder recorder = new(App);

            //Act
            IVisualElement<{targetTypeFullName}> {variableTargetTypeName} = await GetElement(""Test{targetTypeName}"");
            var actual = await {variableTargetTypeName}.{getMethod.Name}();

            //Assert
            //{GetAssertion(getMethod.Name.Substring(3), methodReturnType)}

            recorder.Success();
        }}
");
                }


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

                //System.IO.File.WriteAllText($@"D:\Dev\XAMLTest\XAMLTest.UnitTestGenerator\obj\{className}.cs", sb.ToString());

                context.AddSource($"{className}.cs", sb.ToString());
            }
Ejemplo n.º 12
0
    private static Dictionary <INamedTypeSymbol, IList <AttributeData> > GetClassAttributePairs(GeneratorExecutionContext context,
                                                                                                SyntaxReceiver receiver)
    {
        var compilation  = context.Compilation;
        var classSymbols = new Dictionary <INamedTypeSymbol, IList <AttributeData> >();

        foreach (var clazz in receiver.CandidateClasses)
        {
            var model       = compilation.GetSemanticModel(clazz.SyntaxTree);
            var classSymbol = model.GetDeclaredSymbol(clazz);
            var attributes  = classSymbol.GetAttributes();
            if (attributes.Any(ad => ad.AttributeClass.Name == nameof(GenerateAutoFilterAttribute)))
            {
                classSymbols.Add((INamedTypeSymbol)classSymbol, attributes.ToList());
            }
        }

        return(classSymbols);
    }
Ejemplo n.º 13
0
 private static void WriteMembers(SyntaxReceiver syntaxReceiver, CSharpCompilation compilation, in GeneratorExecutionContext context)
        private void ProcessRoute(GeneratorExecutionContext context, SyntaxReceiver receiver, CSharpParseOptions options)
        {
            Compilation routeAttributeCompilation = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(routeAttributeText, Encoding.UTF8), options));

            INamedTypeSymbol routeAttributeSymbol = routeAttributeCompilation.GetTypeByMetadataName("PlatformExtensions.RouteAttribute");

            // loop over the candidate fields, and keep the ones that are actually annotated
            List<(IMethodSymbol symbol, MethodDeclarationSyntax method)> routeAttributeSymbols = new ();
            bool isAsync = false;
            foreach (MethodDeclarationSyntax method in receiver.CandidateMethods)
            {
                SemanticModel routeModel = routeAttributeCompilation.GetSemanticModel(method.SyntaxTree);

                // Get the symbol being decleared by the field, and keep it if its annotated
                IMethodSymbol methodSymbol = routeModel.GetDeclaredSymbol(method);
                if (methodSymbol.GetAttributes().Any(ad => ad.AttributeClass.Equals(routeAttributeSymbol, SymbolEqualityComparer.Default)))
                {
                    routeAttributeSymbols.Add((methodSymbol, method));
                    if (!isAsync && method.ReturnType is GenericNameSyntax rt)
                    {
                        isAsync = rt.Identifier.ValueText == "Task";
                    }
                }
            }

            IEnumerable<IGrouping<INamedTypeSymbol, (IMethodSymbol symbol, MethodDeclarationSyntax method)>> classes = routeAttributeSymbols.GroupBy(f => f.symbol.ContainingType);
            if (classes.Count() != 1)
            {
                throw new Exception("One and only one application class should be defined");
            }

            var item = classes.FirstOrDefault();
            INamedTypeSymbol classSymbol = item.Key;
            string namespaceName = classSymbol.ContainingNamespace.ToDisplayString();

            var assembly = Assembly.GetExecutingAssembly();

            var fileName = "Ben.AspNetCore.PlatformExtensions.Application.cs";
            var stream = assembly.GetManifestResourceStream(fileName);
            if (stream == null) throw new FileNotFoundException("Cannot find mappings file.", fileName);

            // begin building the generated source
            StringBuilder source = new StringBuilder($@"
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using PlatformExtensions;

namespace {namespaceName}
{{
    public partial class {classSymbol.Name} : IHttpConnection
    {{
");
            using (var reader = new StreamReader(stream, Encoding.UTF8))
            {
                source.Append(reader.ReadToEnd());
            }

            var snippetFileName = $"Ben.AspNetCore.PlatformExtensions.Application.{(isAsync? "Async" : "Sync")}.cs";
            stream = assembly.GetManifestResourceStream(snippetFileName);
            if (stream == null) throw new FileNotFoundException("Cannot find mappings file.", snippetFileName);

            using (var reader = new StreamReader(stream, Encoding.UTF8))
            {
                source.Append(reader.ReadToEnd());
            }

            if (!isAsync)
            {
                source.Append(@"
        private void ProcessRequest(ref BufferWriter<WriterAdapter> writer)
        {
            var requestType = _requestType;
");
                foreach (var group in classes)
                {
                    var isFirst = true;
                    foreach (var methodData in group)
                    {
                        source.Append(@$"
            {(!isFirst ? "else " : "")}if (requestType == RequestType.{methodData.symbol.Name})
            {{
                {methodData.symbol.Name}_Routed(ref writer{(methodData.symbol.ReturnType.SpecialType == SpecialType.System_String ? "" : ", Writer")}{(methodData.method.ParameterList.Parameters.Count > 0 ? ", _queries" : "")});
 public static CompilationDatum Generate(SyntaxReceiver syntaxReceiver, CSharpCompilation compilation, in GeneratorExecutionContext context)