示例#1
0
 public void GenerateCode(JsonRoot root, TextWriter writer)
 {
     CodeCompileUnit result = new CodeCompileUnit();
     result.Namespaces.Add(new CodeNamespace());
     GenerateType(result.Namespaces[0], root, new List<string>());
     CodeDomProvider provider = CodeDomProvider.CreateProvider(this.language);
     CodeGeneratorOptions options = new CodeGeneratorOptions();
     options.BracingStyle = "C";
     provider.GenerateCodeFromCompileUnit(result, writer, options);
 }
示例#2
0
        private bool CanMergeIntoUserDefinedType(JsonRoot other, out JsonRoot mergedType)
        {
            bool sameAsThis = true;
            mergedType = null;
            Dictionary<string, JsonRoot> members = new Dictionary<string, JsonRoot>();
            foreach (var memberName in this.Members.Keys.Union(other.Members.Keys))
            {
                if (this.Members.ContainsKey(memberName) && other.Members.ContainsKey(memberName))
                {
                    JsonRoot member1 = this.Members[memberName];
                    JsonRoot member2 = other.Members[memberName];
                    JsonRoot merged;
                    if (!member1.CanMerge(member2, out merged))
                    {
                        return false;
                    }
                    else
                    {
                        if (merged != member1)
                        {
                            sameAsThis = false;
                        }

                        members.Add(memberName, merged);
                    }
                }
                else if (this.Members.ContainsKey(memberName))
                {
                    members.Add(memberName, this.Members[memberName]);
                }
                else
                {
                    sameAsThis = false;
                    members.Add(memberName, other.Members[memberName]);
                }
            }

            if (sameAsThis)
            {
                mergedType = this;
            }
            else
            {
                mergedType = new JsonRoot(this.UserDefinedTypeName, this.ArrayRank, members);
            }

            return true;
        }
示例#3
0
        private bool CanMergeIntoPrimitiveType(JsonRoot other, out JsonRoot mergedType)
        {
            if (this.ElementType == other.ElementType)
            {
                mergedType = this;
                return true;
            }

            bool isThisNullable = this.IsNullableType();
            bool isOtherNullable = other.IsNullableType();

            Type thisElementType = this.ElementType != null && this.ElementType.IsGenericType && this.ElementType.GetGenericTypeDefinition() == typeof(Nullable<>) ?
                this.ElementType.GetGenericArguments()[0] : this.ElementType;

            Type otherElementType = other.ElementType != null && other.ElementType.IsGenericType && other.ElementType.GetGenericTypeDefinition() == typeof(Nullable<>) ?
                other.ElementType.GetGenericArguments()[0] : other.ElementType;

            if (thisElementType == otherElementType)
            {
                // one nullable, the other not
                if (isThisNullable)
                {
                    mergedType = this;
                }
                else
                {
                    mergedType = other;
                }

                return true;
            }

            if (thisElementType == null)
            {
                if (isOtherNullable || otherElementType == typeof(string))
                {
                    mergedType = other;
                    return true;
                }

                mergedType = new JsonRoot(typeof(Nullable<>).MakeGenericType(otherElementType), this.ArrayRank);
                return true;
            }

            if (otherElementType == null)
            {
                if (isThisNullable || thisElementType == typeof(string))
                {
                    mergedType = this;
                    return true;
                }

                mergedType = new JsonRoot(typeof(Nullable<>).MakeGenericType(thisElementType), this.ArrayRank);
                return true;
            }

            // Number coercions
            if (this.ElementType == typeof(int))
            {
                if (other.ElementType == typeof(long) || other.ElementType == typeof(double))
                {
                    mergedType = other;
                    if (!mergedType.IsNullableType() && isThisNullable)
                    {
                        mergedType = new JsonRoot(typeof(Nullable<>).MakeGenericType(mergedType.ElementType), mergedType.ArrayRank);
                    }

                    return true;
                }
            }
            else if (this.ElementType == typeof(long))
            {
                if (other.ElementType == typeof(double))
                {
                    mergedType = other;
                    if (!mergedType.IsNullableType() && isThisNullable)
                    {
                        mergedType = new JsonRoot(typeof(Nullable<>).MakeGenericType(mergedType.ElementType), mergedType.ArrayRank);
                    }

                    return true;
                }
            }

            mergedType = null;
            return false;
        }
示例#4
0
 private bool CanMergeInto(JsonRoot other, out JsonRoot mergedType)
 {
     if (this.IsUserDefinedType)
     {
         return this.CanMergeIntoUserDefinedType(other, out mergedType);
     }
     else
     {
         return this.CanMergeIntoPrimitiveType(other, out mergedType);
     }
 }
示例#5
0
        private bool CanMerge(JsonRoot other, out JsonRoot mergedType)
        {
            mergedType = null;

            if (this.ArrayRank != other.ArrayRank)
            {
                return false;
            }

            if (this.IsUserDefinedType != other.IsUserDefinedType)
            {
                return false;
            }

            if (this.CanMergeInto(other, out mergedType))
            {
                return true;
            }

            if (other.CanMergeInto(this, out mergedType))
            {
                return true;
            }

            return false;
        }
示例#6
0
        private static JsonRoot ParseJObjectIntoDataContract(JObject root, string rootTypeName)
        {
            Dictionary<string, JsonRoot> fields = new Dictionary<string, JsonRoot>();
            foreach (JProperty property in root.Properties())
            {
                JsonRoot fieldType = ParseJsonIntoDataContract(property.Value, property.Name);
                fields.Add(property.Name, fieldType);
            }

            JsonRoot result = new JsonRoot(rootTypeName, 0, fields);

            foreach (var field in fields.Values)
            {
                field.Parent = result;
            }

            return result;
        }
示例#7
0
        private string GenerateType(CodeNamespace ns, JsonRoot root, List<string> existingTypes)
        {
            if (!root.IsUserDefinedType) return null;

            CodeTypeDeclaration rootType = new CodeTypeDeclaration(GetUniqueDataContractName(root.UserDefinedTypeName, existingTypes));
            existingTypes.Add(rootType.Name);
            rootType.Attributes = MemberAttributes.Public;
            rootType.IsPartial = true;
            rootType.IsClass = true;
            ns.Types.Add(rootType);
            rootType.Comments.Add(
                new CodeCommentStatement(
                    string.Format(
                        "Type created for JSON at {0}",
                        string.Join(" --> ", root.GetAncestors()))));

            AddAttributeDeclaration(rootType, rootType.Name, root.UserDefinedTypeName);
            AddMembers(ns, rootType, root, existingTypes);
            return rootType.Name;
        }
示例#8
0
        private void AddMembers(CodeNamespace ns, CodeTypeDeclaration typeDecl, JsonRoot jsonRoot, List<string> existingTypes)
        {
            foreach (var memberName in jsonRoot.Members.Keys)
            {
                string fieldName = EscapeFieldName(memberName);
                var member = jsonRoot.Members[memberName];
                CodeTypeReference fieldType;
                if (member.IsUserDefinedType)
                {
                    string fieldTypeName = this.GenerateType(ns, member, existingTypes);
                    fieldType = new CodeTypeReference(fieldTypeName);
                }
                else
                {
                    fieldType = new CodeTypeReference(member.ElementType ?? typeof(object));
                }

                for (int i = 0; i < member.ArrayRank; i++)
                {
                    fieldType = new CodeTypeReference(fieldType, 1);
                }

                // TODO: implement members as properties instead of fields
                CodeMemberField field = new CodeMemberField(fieldType, fieldName);
                field.Attributes = MemberAttributes.Public;
                typeDecl.Members.Add(field);

                this.AddMemberAttributeDeclaration(field, memberName);
            }
        }