/// <summary> /// Populates the given graph based on the given compilation. Only the compilation's entry points and /// those callables that the entry points depend on will be included in the graph. All Generated /// Implementations for specializations should be resolved before calling this, except Self-Inverse, /// which is handled by creating a dependency to the appropriate specialization of the same callable. /// This will throw an error if a Generated Implementation other than a Self-Inverse is encountered. /// </summary> public static void PopulateConcreteGraph(ConcreteGraphBuilder graph, QsCompilation compilation) { var walker = new BuildGraph(graph); var entryPointNodes = compilation.EntryPoints.Select(name => new ConcreteCallGraphNode(name, QsSpecializationKind.QsBody, TypeParameterResolutions.Empty)); foreach (var entryPoint in entryPointNodes) { // Make sure all the entry points are added to the graph walker.SharedState.Graph.AddNode(entryPoint); walker.SharedState.RequestStack.Push(entryPoint); } var globals = compilation.Namespaces.GlobalCallableResolutions(); while (walker.SharedState.RequestStack.TryPop(out var currentRequest)) { // If there is a call to an unknown callable, throw exception if (!globals.TryGetValue(currentRequest.CallableName, out QsCallable currentCallable)) { throw new ArgumentException($"Couldn't find definition for callable: {currentRequest.CallableName}"); } var spec = GetSpecializationFromRequest(currentRequest, currentCallable); // The current request must be added before it is processed to prevent // self-references from duplicating on the stack. walker.SharedState.ResolvedNodeSet.Add(currentRequest); walker.SharedState.CurrentNode = currentRequest; walker.SharedState.GetSpecializationKinds = (callableName) => GetSpecializationKinds(globals, callableName); walker.Namespaces.OnSpecializationImplementation(spec.Implementation); } }
public BuildGraph(ConcreteGraphBuilder graph) : base(new TransformationState(graph)) { this.Namespaces = new NamespaceWalker(this); this.Statements = new CallGraphWalkerBase <ConcreteGraphBuilder, ConcreteCallGraphNode, ConcreteCallGraphEdge> .StatementWalker <TransformationState>(this); this.StatementKinds = new StatementKindTransformation <TransformationState>(this, TransformationOptions.NoRebuild); this.Expressions = new CallGraphWalkerBase <ConcreteGraphBuilder, ConcreteCallGraphNode, ConcreteCallGraphEdge> .ExpressionWalker <TransformationState>(this); this.ExpressionKinds = new ExpressionKindWalker(this); this.Types = new TypeTransformation <TransformationState>(this, TransformationOptions.Disabled); }
/// <summary> /// Populates the given graph based on the given compilation. Only the compilation's entry points and /// those callables that the entry points depend on will be included in the graph. All Generated /// Implementations for specializations should be resolved before calling this. This will throw an /// error if a Generated Implementation is encountered. /// </summary> public static void PopulateConcreteGraph(ConcreteGraphBuilder graph, QsCompilation compilation) => ConcreteCallGraphWalker.PopulateConcreteGraph(graph, compilation);