Exemple #1
0
        private void Generate(GeneratorExecutionContext context)
        {
            var calls = new List <MemoizerCall>();

            if (context.SyntaxReceiver is not RecieveExtensionCalls receiver)
            {
                context.AddSource("Memoized_ServiceCollectionExtensions", AddMemoizedExtensionCall.Generate(calls));
                return;
            }

            var compilation = context.Compilation;

            var createMemoizedAttribute  = compilation.GetSymbol(nameof(CreateMemoizedImplementationAttribute));
            var partitionAttribute       = compilation.GetSymbol(nameof(PartitionCacheAttribute));
            var slidingCacheAttribute    = compilation.GetSymbol(nameof(SlidingCacheAttribute));
            var sizeOfResultAttribute    = compilation.GetSymbol(nameof(SizeOfResultAttribute));
            var memoizerFactoryInterface = compilation.GetSymbol(nameof(IMemoizerFactory));

            #pragma warning disable RS1024
            var createAttributes = new Dictionary <ITypeSymbol, CreateMemoizeInterfaceContext>();
            #pragma warning restore RS1024

            foreach (var interfaceWithAttribute in receiver.CandidateAttributes)
            {
                var interfaceModel = compilation.GetSemanticModel(interfaceWithAttribute.SyntaxTree);
                var interfaceType  = interfaceModel.GetDeclaredSymbol(interfaceWithAttribute);
                if (interfaceType == null)
                {
                    continue;
                }
                var interfaceAttributes         = interfaceType.GetAttributes();
                var createMemoizedAttributeData = interfaceAttributes.FirstOrDefault(x => SymbolEqualityComparer.Default.Equals(x.AttributeClass, createMemoizedAttribute));
                if (createMemoizedAttributeData == null)
                {
                    continue;
                }

                var create = CreateMemoizeInterfaceContext.CreateFromSyntax(interfaceWithAttribute, interfaceType, interfaceModel, createMemoizedAttributeData);
                createAttributes.Add(interfaceType, create);
            }

            var assemblyAttributes = context.Compilation.Assembly.GetAttributes();

            var globalSizeOfAttribute = assemblyAttributes.FirstOrDefault(x => SymbolEqualityComparer.Default.Equals(x.AttributeClass, sizeOfResultAttribute));

            var myContext = new GeneratorContext(context, partitionAttribute, slidingCacheAttribute, memoizerFactoryInterface, createMemoizedAttribute, sizeOfResultAttribute, createAttributes, globalSizeOfAttribute);

            foreach (var call in receiver.Candidate)
            {
                var(addMemoizedScopeCall, singleton) = call;

                var model = compilation.GetSemanticModel(addMemoizedScopeCall.SyntaxTree);

                var name = addMemoizedScopeCall.Name as GenericNameSyntax;
                if (name != null && name.TypeArgumentList.Arguments.Count == 2)
                {
                    var interfaceArg = model.GetSymbolInfo(name.TypeArgumentList.Arguments[0]).Symbol as ITypeSymbol;
                    var implArg      = model.GetSymbolInfo(name.TypeArgumentList.Arguments[1]).Symbol as ITypeSymbol;

                    if (interfaceArg == null || implArg == null)
                    {
                        myContext.CreateError("Wrong Type", "Generic Arguments not found", name.GetLocation());
                        continue;
                    }

                    var mode = singleton? "Singleton" : "Scoped";

                    if (!MemoizerCall.TryCreate(myContext, addMemoizedScopeCall, interfaceArg, implArg, mode, out var scopedCall))
                    {
                        continue;
                    }

                    // Same Proj with multiple AddMemoizer() calls for same types
                    if (calls.Any(x => x.IsSameType(scopedCall)))
                    {
                        continue;
                    }

                    calls.Add(scopedCall);

                    var source = MemoizedClass.Generate(scopedCall);

                    context.AddSource(scopedCall.ClassName, source);
                }
            }

            context.AddSource("Memoized_ServiceCollectionExtensions", AddMemoizedExtensionCall.Generate(calls));
        }
Exemple #2
0
 public bool TryGetInterfaceContext(ITypeSymbol interfaceType, out CreateMemoizeInterfaceContext o)
 {
     return(_createMemoizeAttributeContexts.TryGetValue(interfaceType, out o));
 }