private static void AddReferences(CodeToAssemblyGenerator generator, List <Type> allTypes, TypeToTypeWrapperOptions options, Type originalType) { generator.ReferenceAssemblyContainingType <Action>(); generator.ReferenceAssemblyContainingType <DelegateCache>(); generator.ReferenceAssemblyContainingType <DelegateToTypeWrapper>(); foreach (var allType in allTypes) { generator.ReferenceAssembly(allType.Assembly); } if (options?.AdditionalReferences?.Any() == true) { foreach (var additionalReference in options.AdditionalReferences) { generator.ReferenceAssembly(additionalReference); } } if (options?.TypeAttributesGenerator != null) { var attrs = options.TypeAttributesGenerator(options, originalType); foreach (var attribute in attrs) { generator.ReferenceAssembly(attribute.GetType().Assembly); } } if (options?.Inherits != null) { generator.ReferenceAssembly(options.Inherits.Assembly); } }
public void CanReferenceOutputOfFirstGeneration() { var firstCode = @"public class MyClass { public void RunThings() { var y = 0; var a = 1; a = y + 10; } }"; var firstGenerator = new CodeToAssemblyGenerator(); var firstAssembly = firstGenerator.GenerateAssembly(firstCode); var secondCode = @"public class AnotherClass { public void RunThings() { var y = new MyClass(); y.RunThings(); } }"; var secondGenerator = new CodeToAssemblyGenerator(); secondGenerator.ReferenceAssembly(firstAssembly); var secondAssembly = secondGenerator.GenerateAssembly(secondCode); var type = secondAssembly.GetExportedTypes().Single(); Assert.Equal("AnotherClass", type.Name); }
private static void AddReferences(CodeToAssemblyGenerator generator, List <Type> allTypes) { generator.ReferenceAssemblyContainingType <Action>(); generator.ReferenceAssemblyContainingType <DelegateCache>(); generator.ReferenceAssemblyContainingType <DelegateToTypeWrapper>(); foreach (var allType in allTypes) { generator.ReferenceAssembly(allType.Assembly); } }
public Task <Assembly> CreateAssembly() { try { var generator = new CodeToAssemblyGenerator(); generator.ReferenceAssemblyContainingType <Action>(); if (_options.AdditionalReferences?.Any() == true) { foreach (var assembly in _options.AdditionalReferences) { generator.ReferenceAssembly(assembly); } } var code = new StringBuilder(); code.AppendLine("using System;"); code.AppendLine("using System.Diagnostics;"); code.AppendLine("using System.Threading.Tasks;"); code.AppendLine("using System.Text;"); code.AppendLine("using System.Collections;"); code.AppendLine("using System.Collections.Generic;"); if (_options.AdditionalNamespaces?.Any() == true) { foreach (var ns in _options.AdditionalNamespaces) { code.AppendLine($"using {ns};"); } } code.AppendLine(_code); var assemblySourceCode = code.ToString(); var result = generator.Generate(assemblySourceCode); return(Task.FromResult(result)); } catch (Exception e) { throw new InvalidCodeException("Failed to create assembly from regular code. Code: " + _code, e); } }
public Assembly CreateAssembly(MulticastDelegate multicastDelegate, DelegatePluginCatalogOptions options) { var id = DelegateCache.Add(multicastDelegate); var generator = new CodeToAssemblyGenerator(); generator.ReferenceAssemblyContainingType <Action>(); generator.ReferenceAssemblyContainingType <DelegateCache>(); generator.ReferenceAssemblyContainingType <DelegateToAssemblyConverter>(); var methodInfo = multicastDelegate.GetMethodInfo(); if (methodInfo == null) { throw new Exception("Couldn't get method info from delegate"); } var parameters = methodInfo.GetParameters(); var returnType = methodInfo.ReturnType; var allTypes = new List <Type>(); allTypes.AddRange(parameters.Select(x => x.ParameterType)); allTypes.Add(returnType); var genTypes = new List <Type>(); foreach (var type in allTypes) { genTypes = GetGenericTypes(type, genTypes); } foreach (var genType in genTypes) { allTypes.Add(genType); } foreach (var allType in allTypes) { generator.ReferenceAssembly(allType.Assembly); } var code = new StringBuilder(); code.AppendLine("using System;"); code.AppendLine("using System.Diagnostics;"); code.AppendLine("using System.Threading.Tasks;"); code.AppendLine("using System.Text;"); code.AppendLine("using System.Collections;"); code.AppendLine("using System.Collections.Generic;"); foreach (var t in allTypes) { code.AppendLine($"using {t.Namespace};"); } var constructorParameterNames = new List <string>(); var methodParameterNamesWithTypes = new List <string>(); var constructorParameterNamesWithTypes = new List <string>(); var constructorFielsNamesWithTypes = new List <string>(); var propertyNamesWithTypes = new List <string>(); // var propertyNames = new List<string>(); var delegateMethodParameters = new List <string>(); var conversionRules = options?.ConversionRules; if (conversionRules == null) { conversionRules = new List <DelegateConversionRule>(); } for (var index = 0; index < parameters.Length; index++) { var parameterInfo = parameters[index]; var parameterType = parameterInfo.ParameterType; var parameterName = parameterInfo.Name ?? $"param{Guid.NewGuid().ToString().ToLowerInvariant().Replace("-", "")}"; var handled = false; foreach (var conversionRule in conversionRules) { var canHandle = conversionRule.CanHandle(parameterInfo); if (canHandle) { var conversionResult = conversionRule.Handle(parameterInfo); if (!string.IsNullOrWhiteSpace(conversionResult.Name)) { parameterName = conversionResult.Name; } if (conversionResult.ToConstructor) { constructorParameterNames.Add(parameterName); constructorParameterNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {parameterName}"); var fieldName = $"_{parameterName}"; constructorFielsNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {fieldName}"); delegateMethodParameters.Add(fieldName); handled = true; break; } if (conversionResult.ToPublicProperty) { var propertyName = $"{CultureInfo.InvariantCulture.TextInfo.ToTitleCase(parameterName)}"; if (string.Equals(parameterName, propertyName)) { propertyName = $"{propertyName}Prop"; } propertyNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {propertyName}"); delegateMethodParameters.Add(propertyName); handled = true; break; } methodParameterNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {parameterName}"); delegateMethodParameters.Add(parameterName); handled = true; break; } } if (handled) { continue; } methodParameterNamesWithTypes.Add($"{GetFriendlyName(parameterType)} {parameterName}"); delegateMethodParameters.Add(parameterName); } code.AppendLine(); code.AppendLine($"namespace {GetNamespace(options)}"); code.AppendLine("{"); code.AppendLine($"public class {GetTypeName(options)}"); code.AppendLine("{"); if (constructorParameterNames?.Any() == true) { foreach (var fieldNameWithType in constructorFielsNamesWithTypes) { code.AppendLine($"private {fieldNameWithType};"); } code.AppendLine($"public {GetTypeName(options)}({string.Join(", ", constructorParameterNamesWithTypes)})"); code.AppendLine("{"); foreach (var constructorParameterName in constructorParameterNames) { code.AppendLine($"_{constructorParameterName} = {constructorParameterName};"); } code.AppendLine("}"); // Close constructor } if (propertyNamesWithTypes?.Any() == true) { code.AppendLine(); foreach (var fieldNameWithType in propertyNamesWithTypes) { code.AppendLine($"public {fieldNameWithType} {{get; set;}}"); } code.AppendLine(); } if (typeof(void) != returnType) { code.AppendLine( $"public {GetFriendlyName(returnType)} {GetMethodName(options)} ({string.Join(", ", methodParameterNamesWithTypes)})"); } else { code.AppendLine( $"public void Run ({string.Join(", ", methodParameterNamesWithTypes)})"); } code.AppendLine("{"); code.AppendLine($"var deleg = Weikio.PluginFramework.Catalogs.Delegates.DelegateCache.Get(System.Guid.Parse(\"{id.ToString()}\"));"); if (typeof(void) != returnType) { code.AppendLine( $"return ({GetFriendlyName(returnType)}) deleg.DynamicInvoke({string.Join(", ", delegateMethodParameters)});"); } else { code.AppendLine( $"deleg.DynamicInvoke({string.Join(", ", delegateMethodParameters)});"); } code.AppendLine("}"); // Close method code.AppendLine("}"); // Close class code.AppendLine("}"); // Close namespace var s = code.ToString(); var result = generator.Generate(s); return(result); }