private static void CreateObjectMethodGraphs(GenesisContext genesis, TypeInfo cls, ObjectGraph obj) { var events = new List <string>(); foreach (var m in cls.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (m.Name.StartsWith("get_") || m.Name.StartsWith("set_")) { continue; //already did property accessors } if (m.Name.StartsWith("add_") || m.Name.StartsWith("remove_")) { var name = m.Name.Split('_')[1]; //just get the event Name if (!events.Contains(name)) { events.Add(name); } } Debug.WriteLine($@"Method:{(_nullableRegex.IsMatch(m.Name) ? _nullableRegex.Match(m.Name).Value : m.Name)}"); var methodGraph = new MethodGraph { Name = _nullableRegex.IsMatch(m.Name) ? _nullableRegex.Match(m.Name).Value : m.Name, MethodVisibility = MethodVisibilities.Public, ReturnDataType = m.ReturnType, ReturnTypeFormattedName = m.ReturnType.GetFormattedName(), HasGenericParams = m.ContainsGenericParameters, IsGeneric = m.IsGenericMethod, FormattedGenericArguments = m.GetGenericArguments().ToFormattedNames(), }; foreach (var par in m.GetParameters().OrderBy(o => o.Position)) { var mp = new ParameterGraph { DataType = par.ParameterType, DataTypeFormattedName = par.ParameterType.GetFormattedName(), DisplayName = par.ParameterType.GetDisplayName(), Name = par.Name, IsOut = par.IsOut, IsIn = par.IsIn, IsOptional = par.IsOptional, Position = par.Position, IsGeneric = par.ParameterType.IsGenericType, IsGenericMethodParameter = par.ParameterType.IsGenericMethodParameter, GenericArgumentFormattedTypeNames = par.ParameterType.GetGenericArguments().ToFormattedNames(), }; methodGraph.Parameters.Add(mp); } obj.Methods.Add(methodGraph); Text.GrayLine( $"\tMethod: {m.Name}, Return: {methodGraph.ReturnTypeFormattedName}, Visibility: {(m.IsPublic ? "public" : m.IsPrivate ? "private" : "protected")}"); } genesis.Objects.Add(obj); }
private ClassInfo GetPublicAndProtectedMethods(TypeInfo type) { var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) .Where(o => o.IsFamily || o.IsPublic); var methodInfos = methods.ToArray(); return new ClassInfo {Class = type, Methods = methodInfos}; }
public void Define() { if (!typeInfo.IsInterface || !typeInfo.IsPublic) { throw new ArgumentException($"{typeInfo.FullName} must be a public interface"); } if (typeInfo.IsGenericType) { throw new NotSupportedException($"Generic interfaces are not supported: {typeInfo.FullName}"); } var className = typeInfo.FullName.Replace(".", string.Empty); var serviceName = typeInfo.GetCustomAttribute <FauxClientAttribute>().Name; var baseRoute = typeInfo.GetCustomAttribute <RouteAttribute>().BaseRoute; var classBuilder = new StringBuilder(); classBuilder.AppendLine($"namespace {RootNamespace}"); classBuilder.AppendLine("{"); classBuilder.AppendLine(" // Generated by DHaven.Faux"); classBuilder.AppendLine($" public class {className} : DHaven.Faux.Compiler.DiscoveryAwareBase, {typeInfo.FullName}"); classBuilder.AppendLine(" {"); classBuilder.AppendLine($" public {className}()"); classBuilder.AppendLine($" : base(\"{serviceName}\", \"{baseRoute}\") {{ }}"); foreach (var method in typeInfo.GetMethods()) { BuildMethod(classBuilder, method); } classBuilder.AppendLine(" }"); classBuilder.AppendLine("}"); var sourceCode = classBuilder.ToString(); if (OutputSourceFiles) { var fullPath = Path.Combine(SourceFilePath, className + ".cs"); try { File.WriteAllText(fullPath, sourceCode, Encoding.UTF8); } catch (Exception ex) { DiscoverySupport.Logger.LogWarning(ex, "Could not write the source code for {0}", fullPath); } } syntaxTrees.Add(SyntaxFactory.ParseSyntaxTree(sourceCode)); }
public static BenchmarkMethodMetadata GetCleanupMethod(TypeInfo classWithBenchmarks) { Contract.Requires(classWithBenchmarks != null); var cleanupMethods = classWithBenchmarks.GetMethods().Where( y => y.IsDefined(typeof(PerfCleanupAttribute), true)).ToList(); if (!cleanupMethods.Any() || IsTypeInvalidForBenchmarks(classWithBenchmarks)) return BenchmarkMethodMetadata.Empty; // Need to log and throw an error here for benchmarks that have multiple setups declared if (cleanupMethods.Count > 1) { var ex = new NBenchException( $"{classWithBenchmarks.Name} has a declared {cleanupMethods.Count} PerfCleanupAttributes. A maximum of 1 is allowed per class. Failing..."); _reflectionOutput.Error(ex.Message); throw ex; } var matchingMethod = cleanupMethods.Single(); var takesContext = MethodTakesBenchmarkContext(matchingMethod); return new BenchmarkMethodMetadata(matchingMethod, takesContext, false); }
public static IReadOnlyList<BenchmarkClassMetadata> CreateBenchmarksForClass(TypeInfo classWithBenchmarks) { Contract.Requires(classWithBenchmarks != null); if(IsTypeInvalidForBenchmarks(classWithBenchmarks)) return new List<BenchmarkClassMetadata>(); var setupMethod = GetSetupMethod(classWithBenchmarks); var cleanupMethod = GetCleanupMethod(classWithBenchmarks); var allPerfMethods = classWithBenchmarks.GetMethods().Where( MethodHasValidBenchmark).ToList(); var benchmarks = new List<BenchmarkClassMetadata>(allPerfMethods.Count); foreach (var perfMethod in allPerfMethods) { var takesContext = MethodTakesBenchmarkContext(perfMethod); benchmarks.Add(new BenchmarkClassMetadata(classWithBenchmarks.AsType(), setupMethod, new BenchmarkMethodMetadata(perfMethod, takesContext, false), cleanupMethod)); } return benchmarks; }
public IEnumerable <string> GenerateSource(TypeInfo typeInfo, out string fullClassName) { if (!typeInfo.IsInterface || !typeInfo.IsPublic) { throw new ArgumentException($"{typeInfo.FullName} must be a public interface"); } if (typeInfo.IsGenericType) { throw new NotSupportedException($"Generic interfaces are not supported: {typeInfo.FullName}"); } var className = typeInfo.FullName?.Replace(".", string.Empty); fullClassName = $"{Config.RootNamespace}.{className}"; using (logger.BeginScope("Generator {0}:", className)) { var serviceName = typeInfo.GetCustomAttribute <FauxClientAttribute>().Name; var baseRoute = typeInfo.GetCustomAttribute <FauxClientAttribute>().Route ?? string.Empty; var sealedString = Config.GenerateSealedClasses ? "sealed" : string.Empty; logger.LogTrace("Beginning to generate source"); using (var namespaceBuilder = new IndentBuilder()) { namespaceBuilder.AppendLine($"namespace {Config.RootNamespace}"); namespaceBuilder.AppendLine("{"); using (var classBuilder = namespaceBuilder.Indent()) { classBuilder.AppendLine("// Generated by DHaven.Faux"); classBuilder.AppendLine( $"public {sealedString} class {className} : DHaven.Faux.HttpSupport.DiscoveryAwareBase, {typeInfo.FullName}"); classBuilder.AppendLine("{"); using (var fieldBuilder = classBuilder.Indent()) { fieldBuilder.AppendLine("private readonly Microsoft.Extensions.Logging.ILogger 仮logger;"); } using (var constructorBuilder = classBuilder.Indent()) { constructorBuilder.AppendLine($"public {className}(DHaven.Faux.HttpSupport.IHttpClient client,"); constructorBuilder.AppendLine(" Microsoft.Extensions.Logging.ILogger logger)"); constructorBuilder.AppendLine($" : base(client, \"{serviceName}\", \"{baseRoute}\")"); constructorBuilder.AppendLine("{"); using (var insideCxrBuilder = constructorBuilder.Indent()) { insideCxrBuilder.AppendLine("仮logger = logger;"); } constructorBuilder.AppendLine("}"); } foreach (var method in typeInfo.GetMethods()) { using (var methodBuilder = classBuilder.Indent()) { BuildMethod(methodBuilder, method); } } classBuilder.AppendLine("}"); } namespaceBuilder.AppendLine("}"); var sourceCode = namespaceBuilder.ToString(); logger.LogTrace("Source generated"); if (Config.OutputSourceFiles) { var fullPath = Path.Combine(Config.SourceFilePath, $"{className}.cs"); try { logger.LogTrace("Writing source file: {0}", fullPath); File.WriteAllText(fullPath, sourceCode, Encoding.UTF8); } catch (Exception ex) { logger.LogWarning(ex, "Could not write the source code for {0}", fullPath); } } return(new[] { sourceCode }); } } }
public static string GenerateSource(TypeInfo typeInfo, out string fullClassName) { if (!typeInfo.IsInterface || !typeInfo.IsPublic) { throw new ArgumentException($"{typeInfo.FullName} must be a public interface"); } if (typeInfo.IsGenericType) { throw new NotSupportedException($"Generic interfaces are not supported: {typeInfo.FullName}"); } var className = typeInfo.FullName?.Replace(".", string.Empty); fullClassName = $"{RootNamespace}.{className}"; using (Logger.BeginScope("Generator {0}:", className)) { var serviceName = typeInfo.GetCustomAttribute <FauxClientAttribute>().Name; var baseRoute = typeInfo.GetCustomAttribute <RouteAttribute>()?.BaseRoute ?? string.Empty; var sealedString = GenerateSealedClasses ? "sealed" : string.Empty; Logger.LogTrace("Beginning to generate source"); var classBuilder = new StringBuilder(); classBuilder.AppendLine($"namespace {RootNamespace}"); classBuilder.AppendLine("{"); classBuilder.AppendLine(" // Generated by DHaven.Faux"); classBuilder.AppendLine( $" public {sealedString} class {className} : DHaven.Faux.HttpSupport.DiscoveryAwareBase, {typeInfo.FullName}"); classBuilder.AppendLine(" {"); classBuilder.AppendLine($" public {className}()"); classBuilder.AppendLine($" : base(\"{serviceName}\", \"{baseRoute}\") {{ }}"); foreach (var method in typeInfo.GetMethods()) { BuildMethod(classBuilder, method); } classBuilder.AppendLine(" }"); classBuilder.AppendLine("}"); var sourceCode = classBuilder.ToString(); Logger.LogTrace("Source generated"); if (!OutputSourceFiles) { return(sourceCode); } var fullPath = Path.Combine(SourceFilePath, $"{className}.cs"); try { Logger.LogTrace("Writing source file: {0}", fullPath); File.WriteAllText(fullPath, sourceCode, Encoding.UTF8); } catch (Exception ex) { Logger.LogWarning(ex, "Could not write the source code for {0}", fullPath); } return(sourceCode); } }
private static void addMethods(TypeInfo type, CodeTypeReference typeRef, CodeFieldReferenceExpression this_underlyingObject, CodeTypeDeclaration wrap) { var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance & ~BindingFlags.SetProperty & ~BindingFlags.GetProperty).Where(x => x.Name != "GetType" && x.Name != "Equals" && x.Name != "ToString" && !x.Name.StartsWith("add_") && !x.Name.StartsWith("remove_")); foreach (var m in methods) { var method = new CodeMemberMethod(); method.Attributes = MemberAttributes.Public ; if (!m.IsVirtual) method.Attributes |= MemberAttributes.Final; method.Name = m.Name; foreach (var p in m.GetParameters()) { var param = new CodeParameterDeclarationExpression(new CodeTypeReference(p.ParameterType), p.Name); method.Parameters.Add(param); } var parameters = method.Parameters.Cast<CodeParameterDeclarationExpression>().Select(x => new CodeVariableReferenceExpression(x.Name)).ToArray(); var call = new CodeMethodInvokeExpression(this_underlyingObject, m.Name, parameters); if (m.ReturnParameter.ParameterType != typeof(void)) { var ret = new CodeMethodReturnStatement(call); method.ReturnType = new CodeTypeReference(m.ReturnParameter.ParameterType); method.Statements.Add(ret); } else { method.Statements.Add(call); } wrap.Members.Add(method); } }
public IEnumerable<MethodInfo> GetHandlerActions(TypeInfo handlerType) { List<MethodInfo> actions = handlerType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(IsHandlerAction).ToList(); return actions; }