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;")); } }
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"); }