public FunctionCallGraphDiscoverer(Compilation compilation, TypeAndMethodName rootMethod) { Compilation = compilation; _rootNode = new CallGraphNode() { Name = rootMethod }; bool foundDecl = GetDeclaration(rootMethod, out _rootNode.Declaration); Debug.Assert(foundDecl); _nodesByName.Add(rootMethod, _rootNode); }
private CallGraphNode GetNode(TypeAndMethodName name) { if (!_nodesByName.TryGetValue(name, out CallGraphNode node)) { node = new CallGraphNode() { Name = name }; GetDeclaration(name, out node.Declaration); _nodesByName.Add(name, node); } return(node); }
private void TraverseNode(HashSet <TypeAndMethodName> result, CallGraphNode node) { foreach (TypeAndMethodName existing in result) { if (node.Parents.Any(cgn => cgn.Name.Equals(existing))) { throw new ShaderGenerationException("There was a cyclical call graph involving " + existing + " and " + node.Name); } } foreach (CallGraphNode child in node.Children) { TraverseNode(result, child); } result.Add(node.Name); }
private void ExploreCallNode(CallGraphNode node) { Debug.Assert(node.Declaration != null); MethodWalker walker = new MethodWalker(this); walker.Visit(node.Declaration); TypeAndMethodName[] childrenNames = walker.GetChildren(); foreach (TypeAndMethodName childName in childrenNames) { CallGraphNode childNode = GetNode(childName); if (childNode.Declaration != null) { childNode.Parents.Add(node); node.Children.Add(childNode); ExploreCallNode(childNode); } } }
private void TraverseNode(HashSet <ShaderFunctionAndBlockSyntax> result, CallGraphNode node) { foreach (ShaderFunctionAndBlockSyntax existing in result) { if (node.Parents.Any(cgn => cgn.Name.Equals(existing))) { throw new ShaderGenerationException("There was a cyclical call graph involving " + existing + " and " + node.Name); } } foreach (CallGraphNode child in node.Children) { TraverseNode(result, child); } ShaderFunctionAndBlockSyntax sfab = Utilities.GetShaderFunction(node.Declaration, Compilation, false); result.Add(sfab); }
private void ExploreCallNode(CallGraphNode node) { Debug.Assert(node.Declaration != null); MethodWalker walker = new MethodWalker(this); walker.Visit(node.Declaration); TypeAndMethodName[] childrenNames = walker.GetChildren(); foreach (TypeAndMethodName childName in childrenNames) { if (childName.Equals(node.Name)) { throw new ShaderGenerationException( $"A function invoked transitively by {_rootNode.Name} calls {childName}, which calls itself. Recursive functions are not supported."); } CallGraphNode childNode = GetNode(childName); if (childNode.Declaration != null) { childNode.Parents.Add(node); node.Children.Add(childNode); ExploreCallNode(childNode); } } }