public IHoconElement Clone(IHoconElement newParent)
        {
            var newField = new HoconField(Key, (HoconObject)newParent);

            foreach (var internalValue in _internalValues)
            {
                newField._internalValues.Add(internalValue);
            }
            return(newField);
        }
Exemple #2
0
        /// <summary>
        ///     Wraps this <see cref="HoconValue" /> into a new <see cref="HoconObject" /> at the specified key.
        /// </summary>
        /// <param name="key">The key designated to be the new root element.</param>
        /// <returns>A new HOCON root.</returns>
        /// <remarks>
        ///     Immutable. Performs a deep copy on this <see cref="HoconValue" /> first.
        /// </remarks>
        public HoconRoot AtKey(string key)
        {
            var value = new HoconValue(null);
            var obj   = new HoconObject(value);
            var field = new HoconField(key, obj);

            field.SetValue(Clone(field) as HoconValue);
            obj.Add(key, field);
            value.Add(obj);

            return(new HoconRoot(value));
        }
Exemple #3
0
        private HoconField ParseField(HoconObject owner)
        {
            // sanity check
            if (_tokens.Current.Type != TokenType.LiteralValue)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon field. Expected start of field {TokenType.LiteralValue}, " +
                                                  $"found {_tokens.Current.Type} instead.");
            }

            var pathDelta = ParseKey();

            if (_tokens.Current.IsNonSignificant())
            {
                ConsumeWhitelines();
            }

            // sanity check
            if (_tokens.Current.Type != TokenType.Assign &&
                _tokens.Current.Type != TokenType.StartOfObject &&
                _tokens.Current.Type != TokenType.PlusEqualAssign)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  $"Failed to parse Hocon field. Expected {TokenType.Assign}, {TokenType.StartOfObject} " +
                                                  $"or {TokenType.PlusEqualAssign}, found {{_tokens.Current.Type}} instead.");
            }

            // sanity check
            if (pathDelta == null || pathDelta.Count == 0)
            {
                throw HoconParserException.Create(_tokens.Current, Path,
                                                  "Failed to parse Hocon field. ParseField() was called with null or empty path");
            }

            List <HoconField> childInPath = owner.TraversePath(pathDelta);

            Path.AddRange(pathDelta);
            HoconField currentField = childInPath[childInPath.Count - 1];

            var parsedValue = ParseValue(currentField);

            foreach (var removedSub in currentField.SetValue(parsedValue))
            {
                _substitutions.Remove(removedSub);
            }

            Path.RemoveRange(Path.Count - pathDelta.Count, pathDelta.Count);
            return(childInPath[0]);
        }
Exemple #4
0
        private bool IsValueCyclic(HoconField field, HoconSubstitution sub)
        {
            var pendingValues = new Stack <HoconValue>();
            var visitedFields = new List <HoconField> {
                field
            };
            var pendingSubs = new Stack <HoconSubstitution>();

            pendingSubs.Push(sub);

            while (pendingSubs.Count > 0)
            {
                var currentSub = pendingSubs.Pop();
                if (!_root.GetObject().TryGetField(currentSub.Path, out var currentField))
                {
                    continue;
                }

                if (visitedFields.Contains(currentField))
                {
                    return(true);
                }

                visitedFields.Add(currentField);
                pendingValues.Push(currentField.Value);
                while (pendingValues.Count > 0)
                {
                    var currentValue = pendingValues.Pop();

                    foreach (var value in currentValue)
                    {
                        switch (value)
                        {
                        case HoconLiteral _:
                            break;

                        case HoconObject o:
                            foreach (var f in o.Values)
                            {
                                if (visitedFields.Contains(f))
                                {
                                    return(true);
                                }

                                visitedFields.Add(f);
                                pendingValues.Push(f.Value);
                            }

                            break;

                        case HoconArray a:
                            foreach (var item in a.GetArray())
                            {
                                pendingValues.Push(item);
                            }
                            break;

                        case HoconSubstitution s:
                            pendingSubs.Push(s);
                            break;
                        }
                    }
                }
            }

            return(false);
        }
Exemple #5
0
 internal override void SetField(string key, HoconField value)
 {
     Objects.Last().SetField(key, value);
     base.SetField(key, value);
 }