Beispiel #1
0
        public static string GenerateStandAloneThriftSpec(Type type, List <string> dependentSpecFiles)
        {
            var builder = new CodeBuilder();

            builder.AppendLine();
            builder.AppendLine("namespace csharp " + type.Namespace);
            builder.AppendLine();

            var trackedTypes = new HashSet <Type>();
            var tobetracked  = new Queue <Type>();

            foreach (var m in GetServiceCalls(type))
            {
                var return_value_type = m.ReturnType.GetGenericArguments()[0];
                var parameter_type    = m.GetParameters()[0].ParameterType.GetGenericArguments()[0];

                if (!IsDependentOfPrimitiveTypes(return_value_type) && !trackedTypes.Contains(return_value_type))
                {
                    tobetracked.Enqueue(return_value_type);
                    trackedTypes.Add(return_value_type);
                }

                if (IsDependentOfPrimitiveTypes(parameter_type) || trackedTypes.Contains(parameter_type))
                {
                    continue;
                }
                tobetracked.Enqueue(parameter_type);
                trackedTypes.Add(parameter_type);
            }

            while (tobetracked.Count > 0)
            {
                var t = tobetracked.Dequeue();
                foreach (var fld in t.GetFields().Where(fld => !IsDependentOfPrimitiveTypes(fld.FieldType) && !trackedTypes.Contains(fld.FieldType)))
                {
                    if (fld.FieldType.IsGenericType)
                    {
                        foreach (var p in fld.FieldType.GetGenericArguments().Where(p => !IsDependentOfPrimitiveTypes(p) && !trackedTypes.Contains(p)))
                        {
                            tobetracked.Enqueue(p);
                            trackedTypes.Add(p);
                        }
                    }
                    else
                    {
                        tobetracked.Enqueue(fld.FieldType);
                        trackedTypes.Add(fld.FieldType);
                    }
                }
            }

            // dump types with dependency order
            var g = new TypeGraph();

            foreach (var t in trackedTypes)
            {
                var v = g.CreateVertex(typeof(TypeVertex), (ulong)t.GetHashCode());
                v.Owner = t;
            }

            foreach (var t in trackedTypes)
            {
                var fv = g.Vertices.First(v => v.Value.Owner == t);

                foreach (var fld in t.GetFields().Where(fld => !IsDependentOfPrimitiveTypes(fld.FieldType)))
                {
                    if (fld.FieldType.IsGenericType)
                    {
                        foreach (var tv in from p in fld.FieldType.GetGenericArguments() where !IsDependentOfPrimitiveTypes(p) select g.Vertices.First(v => v.Value.Owner == p))
                        {
                            tv.Value.ConnectTo <TypeEdge>(fv.Value);
                        }
                    }
                    else
                    {
                        var tv = g.Vertices.First(v => v.Value.Owner == fld.FieldType);

                        tv.Value.ConnectTo <TypeEdge>(fv.Value);
                    }
                }
            }

            var traversal = new DAGTraverserSatisfied <TypeVertex, TypeEdge, TypeGraph>(true);

            traversal.Traverse(g, v => {
                builder.AppendLine("struct " + GetThriftTypeName(v.Owner));

                builder.BeginBlock();
                var idx = 0;
                foreach (var fld in v.Owner.GetFields())
                {
                    if (fld.GetCustomAttributes().Any(a => a is FieldAttribute))
                    {
                        idx = ((FieldAttribute)fld.GetCustomAttributes().First(a => a is FieldAttribute)).index;
                    }
                    else
                    {
                        idx++;
                    }
                    builder.AppendLine(idx + ":" + GetThriftTypeName(fld.FieldType) + " " + fld.Name + ";");
                }
                builder.EndBlock();

                builder.AppendLine();
                return(true);
            }, false, false);

            builder.AppendLine("service " + type.Name);
            builder.BeginBlock();

            foreach (var m in GetServiceCalls(type))
            {
                var return_value_type = m.ReturnType.GetGenericArguments()[0];
                var parameter_type    = m.GetParameters()[0].ParameterType.GetGenericArguments()[0];
                var return_value_name = GetThriftTypeName(return_value_type);
                var parameter_name    = GetThriftTypeName(parameter_type);
                builder.AppendLine(return_value_name + " " + m.Name + "(1: " + parameter_name + " req);");
            }

            builder.EndBlock();
            builder.AppendLine();

            return(builder.ToString());
        }