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); }
public void CanGenerateAssemblyFromCode() { var code = @"public class MyClass { public void RunThings() { var y = 0; var a = 1; a = y + 10; } }"; var result = _generator.GenerateAssembly(code); var type = result.GetExportedTypes().Single(); Assert.Equal("MyClass", type.Name); }
public Task <Assembly> CreateAssembly(AssemblyLoadContext loadContext) { 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.GenerateAssembly(assemblySourceCode, loadContext); return(Task.FromResult(result)); } catch (Exception e) { throw new InvalidCodeException("Failed to create assembly from regular code. Code: " + _code, e); } }
public void CanWrapGeneratedType() { var code = @"namespace MyTest { public class MyClass { public void RunThings() { var y = 0; var a = 1; a = y + 10; } }}"; var generator = new CodeToAssemblyGenerator(); var assembly = generator.GenerateAssembly(code); var type = assembly.GetExportedTypes().Single(); var wrapper = new TypeToTypeWrapper(); var result = wrapper.CreateType(type, new TypeToTypeWrapperOptions() { IncludedProperties = new List <string>() { "*" }, TypeName = "WrappedType", AdditionalNamespaces = new List <string>() { type.Namespace }, AssemblyGenerator = generator }); dynamic inst = Activator.CreateInstance(result); inst.RunThings(); }
public async Task <Assembly> CreateAssembly(AssemblyLoadContext loadContext) { try { var returnType = await GetReturnType(); var parameters = await GetParameters(); var updatedScript = await RemoveProperties(_code); var generator = new CodeToAssemblyGenerator(); generator.ReferenceAssemblyContainingType <Action>(); 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;"); code.AppendLine("using System.Reflection;"); code.AppendLine("[assembly: AssemblyFileVersion(\"1.0.0.0\")]"); if (_options.AdditionalNamespaces?.Any() == true) { foreach (var ns in _options.AdditionalNamespaces) { code.AppendLine($"using {ns};"); } } code.AppendLine($"namespace {_options.NamespaceNameGenerator(_options)}"); code.AppendLine("{"); code.AppendLine($"public class {_options.TypeNameGenerator(_options)}"); code.AppendLine("{"); if (returnType == null) { if (_options.ReturnsTask) { code.AppendLine($"public async Task {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})"); } else { code.AppendLine($"public void {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})"); } } else { if (_options.ReturnsTask) { code.AppendLine($"public async Task<{returnType.FullName}> {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})"); } else { code.AppendLine($"public {returnType.FullName} {_options.MethodNameGenerator(_options)}({GetParametersString(parameters)})"); } } code.AppendLine("{"); // Start method code.AppendLine(updatedScript); code.AppendLine("}"); // End method code.AppendLine("}"); // End class code.AppendLine("}"); // End namespace var assemblySourceCode = code.ToString(); var result = generator.GenerateAssembly(assemblySourceCode, loadContext); return(result); } catch (Exception e) { throw new InvalidCodeException("Failed to create assembly from script. Code: " + _code, e); } }
public Type CreateType(MulticastDelegate multicastDelegate, DelegateToTypeWrapperOptions options = default) { 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 id = DelegateCache.Add(multicastDelegate); var allTypes = GetRequiredTypes(parameters, returnType); var generator = new CodeToAssemblyGenerator(); AddReferences(generator, allTypes); var code = new StringBuilder(); AddNamespaces(code, allTypes); 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 delegateMethodParameters = new List <string>(); var conversionRules = options?.ConversionRules; if (conversionRules == null) { conversionRules = new List <ParameterConversionRule>(); } DoConversions(parameters, conversionRules, constructorParameterNames, constructorParameterNamesWithTypes, constructorFielsNamesWithTypes, delegateMethodParameters, propertyNamesWithTypes, methodParameterNamesWithTypes); code.AppendLine(); code.AppendLine($"namespace {GetNamespace(options)}"); code.AppendLine("{"); code.AppendLine($"public class {GetTypeName(options)}"); code.AppendLine("{"); CreateConstructor(options, constructorParameterNames, constructorFielsNamesWithTypes, code, constructorParameterNamesWithTypes); CreateProperties(propertyNamesWithTypes, code); CreateDelegateWrapperMethod(options, returnType, code, methodParameterNamesWithTypes, id, delegateMethodParameters); code.AppendLine("}"); // Close class code.AppendLine("}"); // Close namespace var s = code.ToString(); var assembly = generator.GenerateAssembly(s); var result = assembly.GetExportedTypes().Single(); return(result); }
public Type CreateType(Type originalType, TypeToTypeWrapperOptions options = default) { if (originalType == null) { throw new ArgumentNullException(nameof(originalType)); } if (options == null) { options = new TypeToTypeWrapperOptions(); } var methods = GetMethodsToWrap(originalType, options); var allTypes = new List <Type> { originalType }; foreach (var methodInfo in methods) { var parameters = methodInfo.GetParameters(); var returnType = methodInfo.ReturnType; var requiredTypesForMethod = GetRequiredTypes(parameters, returnType); foreach (var type in requiredTypesForMethod) { if (allTypes.Contains(type)) { continue; } allTypes.Add(type); } } var id = TypeCache.Add(originalType, options); var generator = new CodeToAssemblyGenerator(); AddReferences(generator, allTypes, options, originalType); var code = new StringBuilder(); AddNamespaces(code, allTypes); var constructorParameterNames = new List <string>(); var constructorParameterNamesWithTypes = new List <string>(); var constructorFieldNamesWithTypes = new List <string>(); var propertyNamesWithTypes = new List <string>(); var conversionRules = options?.ConversionRules; if (conversionRules == null) { conversionRules = new List <ParameterConversionRule>(); } var d = new Dictionary <MethodInfo, (List <string>, List <string>)>(); foreach (var methodInfo in methods) { var parameters = methodInfo.GetParameters(); var methodParameterNamesWithTypes = new List <string>(); var delegateMethodParameters = new List <string>(); DoConversions(parameters, conversionRules, constructorParameterNames, constructorParameterNamesWithTypes, constructorFieldNamesWithTypes, propertyNamesWithTypes, delegateMethodParameters, methodParameterNamesWithTypes, options, originalType); d.Add(methodInfo, (delegateMethodParameters, methodParameterNamesWithTypes)); } if (options.AdditionalConstructorParameters?.Any() == true) { foreach (var additionalConstructorParameter in options.AdditionalConstructorParameters) { AddConstructorParameter(additionalConstructorParameter, constructorParameterNames, constructorParameterNamesWithTypes, constructorFieldNamesWithTypes, options, originalType); } } code.AppendLine(); code.AppendLine($"namespace {GetNamespace(options, originalType)}"); code.AppendLine("{"); var inheritedAndImplementedTypes = new List <Type>(); if (options.Inherits != null) { inheritedAndImplementedTypes.Add(options.Inherits); } if (options.Implements != null) { inheritedAndImplementedTypes.AddRange(options.Implements); } var inheritance = ""; if (inheritedAndImplementedTypes.Any()) { inheritance = $" : {string.Join(", ", inheritedAndImplementedTypes.Select(x => x.FullName))}"; } code.AppendLine($"public class {GetTypeName(options, originalType)} {inheritance}"); code.AppendLine("{"); CreateInstance(originalType, code, id); CreateConstructor(options, constructorParameterNames, constructorFieldNamesWithTypes, code, constructorParameterNamesWithTypes, originalType, id); CreateProperties(propertyNamesWithTypes, code); foreach (var methodInfo in methods) { var parameters = methodInfo.GetParameters(); var returnType = methodInfo.ReturnType; var p = d[methodInfo]; CreateWrapperMethod(options, returnType, code, p.Item2, id, p.Item1, methodInfo, originalType); } if (options.CustomCodeGenerator != null) { code.AppendLine("// Custom code begins"); code.AppendLine(options.CustomCodeGenerator(options, originalType)); code.AppendLine("// Custom code ends"); } if (options.IsSourceCodeIncluded) { code.AppendLine("##sourceplaceholder##"); } code.AppendLine("}"); // Close class code.AppendLine("}"); // Close namespace var fullCode = code.ToString(); if (options.IsSourceCodePrettified) { fullCode = CSharpSyntaxTree.ParseText(fullCode).GetRoot().NormalizeWhitespace().ToFullString(); } if (options.IsSourceCodeIncluded) { code.AppendLine("// Source code begins"); fullCode = fullCode.Replace("##sourceplaceholder##", $"private string _source = @\"{Environment.NewLine}{fullCode.Replace("\"", "\"\"").Replace("##sourceplaceholder##", "")}\";"); code.AppendLine("// Source code ends"); } var assembly = generator.GenerateAssembly(fullCode); var result = assembly.GetExportedTypes().Single(); return(result); }