public IHoconElement Clone(IHoconElement newParent) { var newField = new HoconField(Key, (HoconObject)newParent); foreach (var internalValue in _internalValues) { newField._internalValues.Add(internalValue); } return(newField); }
/// <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)); }
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]); }
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); }
internal override void SetField(string key, HoconField value) { Objects.Last().SetField(key, value); base.SetField(key, value); }