protected override void GenerateClassMethods(GeneratorExecutionContext context, CodeGenNamespace @namespace, CodeGenClass @class)
        {
            StaticMethodCallSyntaxReceiver syntaxReceiver = (StaticMethodCallSyntaxReceiver)context.SyntaxReceiver;

            var foundTypes = new HashSet <string>();

            // No calls? Generate stub for intellisence.
            if (!syntaxReceiver.Calls.Any())
            {
                @class.Methods.Add(new CodeGenMethod(
                                       MethodName,
                                       "object",
                                       Scope.Public,
                                       MethodType.Static,
                                       null,
                                       new[] { "object arg" },
                                       @"// Stub method for intellisence.
return arg;"));

                return;
            }

            foreach (StaticMethodCall call in syntaxReceiver.Calls)
            {
                if (call.Arguments.Length != 1)
                {
                    continue;
                }

                var           argExpression = call.Arguments[0];
                SemanticModel semanticModel = context.Compilation.GetSemanticModel(argExpression.SyntaxTree);
                string        argumentType  = semanticModel.GetTypeInfo(argExpression).Type.ToString();

                if (argumentType == null || foundTypes.Contains(argumentType))
                {
                    continue;
                }

                foundTypes.Add(argumentType);

                @class.Methods.Add(new CodeGenMethod(
                                       MethodName,
                                       argumentType.ToString(),
                                       Scope.Public,
                                       MethodType.Static,
                                       null,
                                       new[] { $"{argumentType} arg" },
                                       "return arg;"));
            }
        }
Ejemplo n.º 2
0
        protected override void GenerateClassMethods(GeneratorExecutionContext context, CodeGenNamespace @namespace, CodeGenClass @class)
        {
            StaticMethodCallSyntaxReceiver syntaxReceiver = (StaticMethodCallSyntaxReceiver)context.SyntaxReceiver;

            // singleton store
            @class.Variables.Add(new CodeGenVariable("_SingletonLock", "object", Scope.Private, VariableType.Static, true, "new object()"));
            @class.Variables.Add(new CodeGenVariable("_Singletons", "IDictionary<Type, object>", Scope.Private, VariableType.Static, true, "new Dictionary<Type, object>()"));

            // static methods
            AddRegistrationMethods(@class);
            AddGetTMethod(@class);

            // get registrations
            IDictionary <string, DIRegistration> registrations = ProcessCalls(context, syntaxReceiver.Calls);

            // Function dictionary used by get method
            AddGetFunctionsDictionary(@class, registrations);

            foreach (DIRegistration registration in registrations.Values)
            {
                // Build stack contining the initialization of this registered resource, including any dependencies.
                Stack <DIDependencyInitialization> initStack = BuildInitStack(registration, registrations);

                // Use init stack to generate body
                string body = BuildTypedGetMethodBody(initStack);

                var method = new CodeGenMethod(
                    registration.DirectGetMethodName,
                    registration.IdentifierType,
                    Scope.Private,
                    MethodType.Static,
                    null,
                    null,
                    body);

                @class.Methods.Add(method);
            }

            ModifyNamespace(@namespace);
        }
        protected override void GenerateClassMethods(GeneratorExecutionContext context, CodeGenNamespace @namespace, CodeGenClass @class)
        {
            StaticMethodCallSyntaxReceiver syntaxReceiver = (StaticMethodCallSyntaxReceiver)context.SyntaxReceiver;

            var generatedHandlers = new HashSet <string>();

            GenerateStub(@class);

            foreach (StaticMethodCall call in syntaxReceiver.Calls)
            {
                SemanticModel semanticModel = context.Compilation.GetSemanticModel(call.Invocation.SyntaxTree);

                Dictionary <string, string> genericTypes = call.GenericTypes
                                                           .Select(gt => semanticModel.GetTypeInfo(gt))
                                                           .ToDictionary(typeInfo => typeInfo.Type.ToString(), typeInfo => typeInfo.Type.Name);

                string   handlerName = $"{string.Join(string.Empty, genericTypes.Values)}Handler";
                string[] argList     = genericTypes.Keys.Select((type, i) => $"{type} arg{i}").ToArray();
                string[] argNameList = genericTypes.Select((type, i) => $"arg{i}").ToArray();

                if (generatedHandlers.Contains(handlerName))
                {
                    continue;
                }

                generatedHandlers.Add(handlerName);

                // delegate
                @namespace.Content.Add(new CodeGenDelegate(
                                           handlerName,
                                           null,
                                           Scope.Public,
                                           null,
                                           argList));

                // private delegate variable
                @class.Variables.Add(new CodeGenVariable(
                                         $"_{handlerName}",
                                         handlerName,
                                         Scope.Private,
                                         VariableType.Static));

                // register method
                @class.Methods.Add(new CodeGenMethod(
                                       MethodName,
                                       null,
                                       Scope.Public,
                                       MethodType.Static,
                                       genericTypes.Keys.Select((gt, i) => new CodeGenGeneric($"TPayload{i}", gt)),
                                       new[] { $"Action<{string.Join(", ", genericTypes.Keys)}> handler" },
                                       $"_{handlerName} += new {handlerName}(handler);"));

                // notify method
                @class.Methods.Add(new CodeGenMethod(
                                       "Notify",
                                       null,
                                       Scope.Public,
                                       MethodType.Static,
                                       null,
                                       argList,
                                       $"_{handlerName}?.Invoke({string.Join(", ", argNameList)});"));
            }

            @namespace.Usings.Add("System");
        }