Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
            }
        }
Exemplo n.º 3
0
        private static JsonRoot ParseJArrayIntoDataContract(JArray root, string rootTypeName)
        {
            if (root.Count == 0)
            {
                return(new JsonRoot(null, 1));
            }

            JsonRoot first = ParseJsonIntoDataContract(root[0], rootTypeName);

            for (int i = 1; i < root.Count; i++)
            {
                JsonRoot next = ParseJsonIntoDataContract(root[i], rootTypeName);
                JsonRoot mergedType;
                if (first.CanMerge(next, out mergedType))
                {
                    first = mergedType;
                }
                else
                {
                    throw new ArgumentException(string.Format("Cannot merge array elements {0} ({1}) and {2} ({3})",
                                                              0, root[0], i, root[i]));
                }
            }

            if (first.IsUserDefinedType)
            {
                return(new JsonRoot(first.UserDefinedTypeName, first.ArrayRank + 1, first.Members));
            }
            else
            {
                return(new JsonRoot(first.ElementType, first.ArrayRank + 1));
            }
        }
Exemplo n.º 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));
     }
 }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
        public static JsonRoot ParseJsonIntoDataContract(JToken root, string rootTypeName)
        {
            JsonRoot results = null;

            if (root == null || root.Type == JTokenType.Null)
            {
                results = new JsonRoot(null, 0);
            }
            else
            {
                switch (root.Type)
                {
                case JTokenType.Boolean:
                    results = new JsonRoot(typeof(bool), 0);
                    break;

                case JTokenType.String:
                    results = new JsonRoot(typeof(string), 0);
                    break;

                case JTokenType.Float:
                    results = new JsonRoot(typeof(double), 0);
                    break;

                case JTokenType.Date:
                    results = new JsonRoot(typeof(DateTime), 0);
                    break;

                case JTokenType.TimeSpan:
                    results = new JsonRoot(typeof(TimeSpan), 0);
                    break;

                case JTokenType.Integer:
                    results = new JsonRoot(GetClrIntegerType(root.ToString()), 0);
                    break;

                case JTokenType.Object:
                    results = ParseJObjectIntoDataContract((JObject)root, rootTypeName);
                    break;

                case JTokenType.Array:
                    results = ParseJArrayIntoDataContract((JArray)root, rootTypeName);
                    break;

                default:
                    throw new ArgumentException("Cannot work with JSON token of type " + root.Type);
                }
            }

            return(results);
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
0
        public List <string> GetAncestors()
        {
            List <string> result = new List <string>();
            JsonRoot      temp   = this;

            while (temp != null)
            {
                if (temp.Parent != null)
                {
                    result.Insert(0, temp.UserDefinedTypeName);
                }

                temp = temp.Parent;
            }

            result.Insert(0, "<<root>>");
            return(result);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
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);
        }