Example #1
0
        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);
        }
Example #2
0
        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;
 }