/// <summary> /// Search for ReplaceableParsers with the given name and attempt to transform the contents /// using the given transformation. The contents of the ReplaceableParser will be replaced /// with the transformed result if it is new and valid. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="root"></param> /// <param name="predicate"></param> /// <param name="transform"></param> /// <returns></returns> public static MultiReplaceResult ReplaceMulti <TInput, TOutput>(IParser root, Func <IReplaceableParserUntyped, bool> predicate, Func <IMultiParser <TInput, TOutput>, IMultiParser <TInput, TOutput> > transform) { if (root == null || predicate == null || transform == null) { return(MultiReplaceResult.Failure()); } var visitor = new FindParserVisitor(); var state = new State(p => p is IReplaceableParserUntyped replaceable && predicate(replaceable), true); visitor.Visit(root, state); var results = new List <SingleReplaceResult>(); foreach (var found in state.Found.Cast <IReplaceableParserUntyped>()) { if (found.ReplaceableChild is not IMultiParser <TInput, TOutput> parser) { continue; } var replacement = transform(parser); if (replacement == null || ReferenceEquals(replacement, parser)) { continue; } var result = found.SetParser(replacement); results.Add(result); } return(new MultiReplaceResult(results)); }
/// <summary> /// Search for ReplaceableParsers matching a predicate and attempt to replace their contents with the /// replacement parser if it is found. The replacement parser must be non-null and of the correct /// type. Replaces all matching instances. /// </summary> /// <param name="root"></param> /// <param name="predicate"></param> /// <param name="replacement"></param> /// <returns></returns> public static MultiReplaceResult Replace(IParser root, Func <IReplaceableParserUntyped, bool> predicate, IParser replacement) { if (root == null || predicate == null || replacement == null) { return(MultiReplaceResult.Failure()); } var visitor = new FindParserVisitor(); var state = new State(p => p is IReplaceableParserUntyped replaceable && predicate(replaceable), true); visitor.Visit(root, state); var results = new List <SingleReplaceResult>(); foreach (var found in state.Found.Cast <IReplaceableParserUntyped>()) { var result = found.SetParser(replacement); results.Add(result); } return(new MultiReplaceResult(results)); }