Exemplo n.º 1
0
        /// <summary>
        /// Mixintos stuff.
        /// </summary>
        /// <param name="mixintoResource"></param>
        /// <param name="origin"></param>
        /// <param name="mixinto"></param>
        private static JToken mergeTokens(Resource targetResource, Resource mixintoResource, JToken origin, JToken mixinto)
        {
            // Compare types.
            Debug.Assert(origin != null);

            if (origin == null)
            {
                ErrorReporter.AddError(mixintoResource.Mod, mixintoResource, "Cannot mixinto {0} into {1}: Target has invalid JSON", mixintoResource.Location, targetResource.Location);
                return null;
            }

            if (mixinto == null)
            {
                ErrorReporter.AddError(targetResource.Mod, targetResource, "Cannot mixinto {0} into {1}: Mixinto has invalid JSON", mixintoResource.Location, targetResource.Location);
                return null;
            }

            JTokenType originType = origin.Type, mixintoType = mixinto.Type;

            if (originType == mixintoType)
            {
                switch (originType)
                {
                    case JTokenType.Object:
                        JObject originObj = (JObject)origin, mixintoObj = (JObject)mixinto;
                        foreach (var property in mixintoObj)
                        {
                            if (originObj[property.Key] == null)
                                originObj[property.Key] = property.Value;
                            else
                                originObj[property.Key] = mergeTokens(targetResource, mixintoResource, (JToken)originObj[property.Key], property.Value);
                        }

                        return originObj;
                    case JTokenType.Array:
                        JArray originArray = (JArray)origin, mixintoArray = (JArray)mixinto;
                        foreach (var item in mixinto.Reverse())
                            originArray.AddFirst(item);
                        return originArray;
                    case JTokenType.Integer:
                        return mixinto.Value<int>();
                    case JTokenType.String:
                        origin = mixinto.Value<string>();
                        return mixinto.Value<string>();
                    case JTokenType.Float:
                        return mixinto.Value<float>();
                    default:
                        ErrorReporter.AddError(mixintoResource.Mod, mixintoResource, "Invalid mixinto type {0} at {1}", mixinto.Type, mixinto.Path);
                        return null;
                }
            }
            else if (IncompatibleTypes(originType, mixintoType))
            {
                ErrorReporter.AddError(mixintoResource.Mod, mixintoResource, "Cannot mixinto {3}: Types for {2} differ (original: {0}; mixinto: {1})", originType, mixintoType, origin.Path, mixintoResource.Location);
                mixintoResource.Invalidate();
                return null;
            }

            return null;
        }