/// <summary> /// Merge two nodes. Both of them become equiualent. /// /// In complex situation, 'secondary' node becomes reference to 'main' node, if it is possible /// </summary> public static void MergeInplace(TicNode main, TicNode secondary) { if (main == secondary) { return; } if (main.State is StateRefTo) { var nonreferenceMain = main.GetNonReference(); var nonreferenceSecondary = secondary.GetNonReference(); MergeInplace(nonreferenceMain, nonreferenceSecondary); return; } if (secondary.GetNonReference() == main) { return; } var res = GetMergedStateOrNull(main.State, secondary.State); if (res == null) { throw TicErrors.CannotMerge(main, secondary); } main.State = res; if (res is ITypeState t && t.IsSolved) { secondary.State = res; return; } main.AddAncestors(secondary.Ancestors.Where(a => a != main)); secondary.ClearAncestors(); secondary.State = new StateRefTo(main); }
public static void BecomeReferenceFor(this TicNode referencedNode, TicNode original) { referencedNode = referencedNode.GetNonReference(); original = original.GetNonReference(); if (referencedNode.Type == TicNodeType.SyntaxNode) { MergeInplace(original, referencedNode); } else { MergeInplace(referencedNode, original); } }
public static bool Destruction(TicNode descendantNode, TicNode ancestorNode) { var nonRefAncestor = ancestorNode.GetNonReference(); var nonRefDescendant = descendantNode.GetNonReference(); if (nonRefDescendant == nonRefAncestor) { return(true); } return(nonRefAncestor.State.ApplyDescendant( DestructionFunctions.Singletone, nonRefAncestor, nonRefDescendant)); }