Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #4
0
        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);
                }
            }
        }
Beispiel #5
0
        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);
                }
            }
        }