public bool TryGetNode(AccessPath path, [NotNullWhen(true)] out NullabilityNode?flowNode) { flowNode = null; int index; PathNode node; switch (path.Root) { case AccessPathRoot.This: index = 0; node = thisPath; break; case AccessPathRoot.Local: if (!locals.TryGetValue(path.Symbols[0], out node)) { return(false); } index = 1; break; default: throw new NotSupportedException(); } for (; index < path.Symbols.Length; index++) { if (!node.Members.TryGetValue(path.Symbols[index], out node)) { return(false); } } flowNode = node.Nullability; return(true); }
public void SetNode(AccessPath path, NullabilityNode newNode, bool clearMembers) { switch (path.Root) { case AccessPathRoot.This: thisPath = Visit(thisPath, 0); break; case AccessPathRoot.Local: if (!locals.TryGetValue(path.Symbols[0], out var localPathNode)) { localPathNode = new PathNode(typeSystem.NonNullNode, emptyMembers); } localPathNode = Visit(localPathNode, 1); locals[path.Symbols[0]] = localPathNode; break; default: throw new NotSupportedException(); } PathNode Visit(PathNode input, int index) { if (index == path.Symbols.Length) { if (clearMembers) { return(new PathNode(newNode, emptyMembers)); } else { return(new PathNode(newNode, input.Members)); } } var member = path.Symbols[index]; if (!input.Members.TryGetValue(member, out var childNode)) { childNode = new PathNode(typeSystem.NonNullNode, emptyMembers); } childNode = Visit(childNode, index + 1); return(new PathNode(typeSystem.NonNullNode, input.Members.SetItem(member, childNode))); } }