/// <summary> /// Returns a look-up with all Q# examples extracted from doc comments for each namespace. /// The key may be null if the extracted example is specified outside a namespace. /// </summary> public static ILookup <string, string> Extract(QsCompilation compilation) { var instance = new ExamplesInDocs(); instance.Apply(compilation); return(instance.SharedState.ToLookup(entry => entry.Item1, entry => entry.Item2)); }
public bool PreconditionVerification(QsCompilation compilation) { var controlNs = compilation.Namespaces .FirstOrDefault(ns => ns.Name.Equals(BuiltIn.ClassicallyControlledNamespace)); if (controlNs == null) { return(false); } var providedOperations = new QsNamespace[] { controlNs }.Callables().Select(c => c.FullName.Name); var requiredBuiltIns = new List <NonNullable <string> >() { BuiltIn.ApplyIfZero.Name, BuiltIn.ApplyIfZeroA.Name, BuiltIn.ApplyIfZeroC.Name, BuiltIn.ApplyIfZeroCA.Name, BuiltIn.ApplyIfOne.Name, BuiltIn.ApplyIfOneA.Name, BuiltIn.ApplyIfOneC.Name, BuiltIn.ApplyIfOneCA.Name, BuiltIn.ApplyIfElseR.Name, BuiltIn.ApplyIfElseRA.Name, BuiltIn.ApplyIfElseRC.Name, BuiltIn.ApplyIfElseRCA.Name }; return(requiredBuiltIns.All(builtIn => providedOperations.Any(provided => provided.Equals(builtIn)))); }
/// <inheritdoc/> public bool PreconditionVerification(QsCompilation compilation) { var attributes = compilation.Namespaces.Attributes().Select(att => att.FullName).ToImmutableHashSet(); return(attributes.Contains(BuiltIn.TargetInstruction.FullName) && attributes.Contains(BuiltIn.Inline.FullName)); }
public bool PreconditionVerification(QsCompilation compilation) { var classicallyControlledRequired = ImmutableHashSet.Create( BuiltIn.ApplyIfZero.FullName, BuiltIn.ApplyIfZeroA.FullName, BuiltIn.ApplyIfZeroC.FullName, BuiltIn.ApplyIfZeroCA.FullName, BuiltIn.ApplyIfOne.FullName, BuiltIn.ApplyIfOneA.FullName, BuiltIn.ApplyIfOneC.FullName, BuiltIn.ApplyIfOneCA.FullName, BuiltIn.ApplyIfElseR.FullName, BuiltIn.ApplyIfElseRA.FullName, BuiltIn.ApplyIfElseRC.FullName, BuiltIn.ApplyIfElseRCA.FullName); if (!this.CheckForRequired(compilation, BuiltIn.ClassicallyControlledNamespace, classicallyControlledRequired)) { return(false); } var cannonRequired = ImmutableHashSet.Create( BuiltIn.NoOp.FullName); if (!this.CheckForRequired(compilation, BuiltIn.CanonNamespace, cannonRequired)) { return(false); } return(true); }
/// <summary> /// Performs Monomorphization on the given compilation. If the keepAllIntrinsics parameter /// is set to true, then unused intrinsics will not be removed from the resulting compilation. /// </summary> public static QsCompilation Apply(QsCompilation compilation, bool keepAllIntrinsics = true) { var globals = compilation.Namespaces.GlobalCallableResolutions(); var concretizations = new List <QsCallable>(); var concreteNames = new Dictionary <ConcreteCallGraphNode, QsQualifiedName>(); var nodes = new ConcreteCallGraph(compilation).Nodes // Remove specialization information so that we only deal with the full callables. .Select(n => new ConcreteCallGraphNode(n.CallableName, QsSpecializationKind.QsBody, n.ParamResolutions)) .ToImmutableHashSet(); var getAccessModifiers = new GetAccessModifiers((typeName) => GetAccessModifier(compilation.Namespaces.GlobalTypeResolutions(), typeName)); // Loop through the nodes, getting a list of concrete callables foreach (var node in nodes) { // If there is a call to an unknown callable, throw exception if (!globals.TryGetValue(node.CallableName, out QsCallable originalGlobal)) { throw new ArgumentException($"Couldn't find definition for callable: {node.CallableName}"); } if (node.ParamResolutions.Any()) { // Get concrete name var concreteName = UniqueVariableNames.PrependGuid(node.CallableName); // Add to concrete name mapping concreteNames[node] = concreteName; // Generate the concrete version of the callable var concrete = ReplaceTypeParamImplementations.Apply(originalGlobal, node.ParamResolutions, getAccessModifiers); concretizations.Add( concrete.WithFullName(oldName => concreteName) .WithSpecializations(specs => specs.Select(spec => spec.WithParent(_ => concreteName)).ToImmutableArray())); } else { concretizations.Add(originalGlobal); } } GetConcreteIdentifierFunc getConcreteIdentifier = (globalCallable, types) => GetConcreteIdentifier(concreteNames, globalCallable, types); var intrinsicCallableSet = globals .Where(kvp => kvp.Value.Specializations.Any(spec => spec.Implementation.IsIntrinsic)) .Select(kvp => kvp.Key) .ToImmutableHashSet(); var final = new List <QsCallable>(); // Loop through concretizations, replacing all references to generics with their concrete counterparts foreach (var callable in concretizations) { final.Add(ReplaceTypeParamCalls.Apply(callable, getConcreteIdentifier, intrinsicCallableSet)); } return(ResolveGenerics.Apply(compilation, final, intrinsicCallableSet, keepAllIntrinsics)); }
public bool PreconditionVerification(QsCompilation compilation) { var controlNs = compilation.Namespaces .FirstOrDefault(ns => ns.Name.Equals(BuiltIn.ClassicallyControlledNamespace)); if (controlNs == null) { return(false); } var providedOperations = new QsNamespace[] { controlNs } .Callables() .Select(c => c.FullName) .ToHashSet(); var requiredBuiltIns = new HashSet <QsQualifiedName>() { BuiltIn.ApplyIfZero.FullName, BuiltIn.ApplyIfZeroA.FullName, BuiltIn.ApplyIfZeroC.FullName, BuiltIn.ApplyIfZeroCA.FullName, BuiltIn.ApplyIfOne.FullName, BuiltIn.ApplyIfOneA.FullName, BuiltIn.ApplyIfOneC.FullName, BuiltIn.ApplyIfOneCA.FullName, BuiltIn.ApplyIfElseR.FullName, BuiltIn.ApplyIfElseRA.FullName, BuiltIn.ApplyIfElseRC.FullName, BuiltIn.ApplyIfElseRCA.FullName }; return(requiredBuiltIns.IsSubsetOf(providedOperations)); }
public bool Transformation(QsCompilation compilation, out QsCompilation transformed) { var rewriter = new RewriteAccessModifiers(); transformed = rewriter.OnCompilation(compilation); return(true); }
/// <inheritdoc/> public bool Transformation(QsCompilation compilation, out QsCompilation transformed) { transformed = compilation; var generator = new Generator(transformed); generator.Apply(); // write generated QIR to disk var assemblyName = this.AssemblyConstants.TryGetValue(ReservedKeywords.AssemblyConstants.AssemblyName, out var asmName) ? asmName : null; var targetFile = Path.GetFullPath(string.IsNullOrWhiteSpace(assemblyName) ? "main.txt" : $"{Path.GetFileName(assemblyName)}.txt"); PerformanceTracking.TaskStart(PerformanceTracking.Task.BitcodeGeneration); var bcOutputFolder = this.AssemblyConstants.TryGetValue(ReservedKeywords.AssemblyConstants.OutputPath, out var path) && !string.IsNullOrWhiteSpace(path) ? path : "qir"; var bcFile = CompilationLoader.GeneratedFile(targetFile, Path.GetFullPath(bcOutputFolder), ".bc", ""); generator.Emit(bcFile, emitBitcode: true); PerformanceTracking.TaskEnd(PerformanceTracking.Task.BitcodeGeneration); // create the human readable version as well var sourceOutputFolder = this.AssemblyConstants.TryGetValue(ReservedKeywords.AssemblyConstants.QirOutputPath, out path) && !string.IsNullOrWhiteSpace(path) ? path : "qir"; var llvmSourceFile = CompilationLoader.GeneratedFile(targetFile, Path.GetFullPath(sourceOutputFolder), ".ll", ""); generator.Emit(llvmSourceFile, emitBitcode: false); return(true); }
/// <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); } }
/// <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. /// </summary> public static void PopulateTrimmedGraph(GraphBuilder graph, QsCompilation compilation) { var walker = new BuildGraph(graph); var entryPointNodes = compilation.EntryPoints.Select(name => new CallGraphNode(name)); walker.SharedState.WithTrimming = true; 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}"); } // 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.Namespaces.OnCallableDeclaration(currentCallable); } }
/// <summary> /// Given a reader for the byte stream of a dotnet dll, loads any Q# compilation included as a resource. /// Returns true as well as the loaded compilation if the given dll includes a suitable resource, and returns false otherwise. /// Throws an ArgumentNullException if any of the given readers is null. /// May throw an exception if the given binary file has been compiled with a different compiler version. /// </summary> private static bool FromResource(PEReader assemblyFile, out QsCompilation compilation) { if (assemblyFile == null) { throw new ArgumentNullException(nameof(assemblyFile)); } var metadataReader = assemblyFile.GetMetadataReader(); compilation = null; // The offset of resources is relative to the resources directory. // It is possible that there is no offset given because a valid dll allows for extenal resources. // In all Q# dlls there will be a resource with the specific name chosen by the compiler. var resourceDir = assemblyFile.PEHeaders.CorHeader.ResourcesDirectory; if (!assemblyFile.PEHeaders.TryGetDirectoryOffset(resourceDir, out var directoryOffset) || !metadataReader.Resources().TryGetValue(DotnetCoreDll.ResourceName, out var resource) || !resource.Implementation.IsNil) { return(false); } // This is going to be very slow, as it loads the entire assembly into a managed array, byte by byte. // Due to the finite size of the managed array, that imposes a memory limitation of around 4GB. // The other alternative would be to have an unsafe block, or to contribute a fix to PEMemoryBlock to expose a ReadOnlySpan. var image = assemblyFile.GetEntireImage(); // uses int to denote the length and access parameters var absResourceOffset = (int)resource.Offset + directoryOffset; // the first four bytes of the resource denote how long the resource is, and are followed by the actual resource data var resourceLength = BitConverter.ToInt32(image.GetContent(absResourceOffset, sizeof(Int32)).ToArray(), 0); var resourceData = image.GetContent(absResourceOffset + sizeof(Int32), resourceLength).ToArray(); return(LoadSyntaxTree(new MemoryStream(resourceData), out compilation)); }
public static QsCompilation Apply(QsCompilation compilation, bool keepAllIntrinsics) { var globals = compilation.Namespaces.GlobalCallableResolutions(); var augmentedEntryPoints = BuiltIn.AllBuiltIns .Where(bi => bi.Kind != BuiltInKind.Attribute && globals.ContainsKey(bi.FullName)) .Select(bi => bi.FullName) .Concat(compilation.EntryPoints) .Distinct() .ToImmutableArray(); var compilationWithBuiltIns = new QsCompilation(compilation.Namespaces, augmentedEntryPoints); var callablesToKeep = new CallGraph(compilationWithBuiltIns, true).Nodes.Select(node => node.CallableName).ToImmutableHashSet(); // ToDo: convert to using ternary operator, when target-type // conditional expressions are supported in C# Func <QsNamespaceElement, bool> filter = elem => Filter(elem, callablesToKeep); if (keepAllIntrinsics) { filter = elem => FilterWithIntrinsics(elem, callablesToKeep); } var transformed = new TrimTree(filter).OnCompilation(compilation); return(new QsCompilation(transformed.Namespaces.Where(ns => ns.Elements.Any()).ToImmutableArray(), transformed.EntryPoints)); }
private ConvertConditions(QsCompilation compilation) : base(new TransformationState(compilation)) { this.Namespaces = new NamespaceTransformation(this); this.Statements = new StatementTransformation(this); this.Expressions = new ExpressionTransformation <TransformationState>(this, TransformationOptions.Disabled); this.Types = new TypeTransformation <TransformationState>(this, TransformationOptions.Disabled); }
/// <summary> /// Adds a comment to each callable listing all identifiers used within the callable. /// </summary> public QsCompilation OnCompilation(QsCompilation compilation) { var namespaces = compilation.Namespaces .Select(this.Namespaces.OnNamespace) .ToImmutableArray(); return(new QsCompilation(namespaces, compilation.EntryPoints)); }
/// <summary> /// Eliminates all conjugations from the given compilation by replacing them with the corresponding implementations (i.e. inlining them). /// The generation of the adjoint for the outer block is subject to the same limitation as any adjoint auto-generation. /// In particular, it is only guaranteed to be valid if operation calls only occur within expression statements, and /// throws an InvalidOperationException if the outer block contains while-loops. /// Any thrown exception is logged using the given onException action and silently ignored if onException is not specified or null. /// Returns true if the transformation succeeded without throwing an exception, and false otherwise. /// </summary> public static bool InlineConjugations(this QsCompilation compilation, out QsCompilation inlined, Action <Exception>?onException = null) { var inline = new InlineConjugations(onException); var namespaces = compilation.Namespaces.Select(inline.Namespaces.OnNamespace).ToImmutableArray(); inlined = new QsCompilation(namespaces, compilation.EntryPoints); return(inline.SharedState.Success); }
public static QsCompilation Apply(QsCompilation compilation, List <Response> responses) { var filter = new ResolveGenerics(responses .GroupBy(res => res.concreteCallable.FullName.Namespace) .ToImmutableDictionary(group => group.Key, group => group.Select(res => res.concreteCallable))); return(new QsCompilation(compilation.Namespaces.Select(ns => filter.Namespaces.OnNamespace(ns)).ToImmutableArray(), compilation.EntryPoints)); }
public static void Apply(QsCompilation compilation) { var intrinsicCallableSet = compilation.Namespaces.GlobalCallableResolutions() .Where(kvp => kvp.Value.Specializations.Any(spec => spec.Implementation.IsIntrinsic)) .Select(kvp => kvp.Key) .ToImmutableHashSet(); new ValidateMonomorphization(intrinsicCallableSet).OnCompilation(compilation); }
public static void Apply(QsCompilation compilation) { var filter = new ValidateMonomorphization(); foreach (var ns in compilation.Namespaces) { filter.Namespaces.OnNamespace(ns); } }
public bool PreconditionVerification(QsCompilation compilation) { var targetingNamespace = compilation.Namespaces.FirstOrDefault(ns => ns.Name.Equals(BuiltIn.TargetingNamespace)); var hasCapabilityAttribute = targetingNamespace?.Elements.Any(element => element.GetFullName().Equals(BuiltIn.RequiresCapability.FullName)) ?? false; return(hasCapabilityAttribute && !this.AssemblyConstants.ContainsKey(ExecutionTarget)); }
/// <inheritdoc/> public bool Transformation(QsCompilation compilation, out QsCompilation transformed) { var generator = new Generator(compilation); generator.Apply(); generator.Emit(this.outputFile); transformed = compilation; return(true); }
public static void Apply(QsCompilation compilation) { var filter = new MonomorphizationValidationSyntax(); foreach (var ns in compilation.Namespaces) { filter.Transform(ns); } }
public static QsCompilation Apply(QsCompilation compilation) { if (compilation == null || compilation.Namespaces.Contains(null)) { throw new ArgumentNullException(nameof(compilation)); } var globals = compilation.Namespaces.GlobalCallableResolutions(); var intrinsicCallableSet = globals .Where(kvp => kvp.Value.Specializations.Any(spec => spec.Implementation.IsIntrinsic)) .Select(kvp => kvp.Key) .ToImmutableHashSet(); var entryPoints = compilation.EntryPoints .Select(call => new Request { OriginalName = call, TypeResolutions = ImmutableConcretion.Empty, ConcreteName = call }); var requests = new Stack <Request>(entryPoints); var responses = new List <Response>(); while (requests.Any()) { Request currentRequest = requests.Pop(); // If there is a call to an unknown callable, throw exception if (!globals.TryGetValue(currentRequest.OriginalName, out QsCallable originalGlobal)) { throw new ArgumentException($"Couldn't find definition for callable: {currentRequest.OriginalName}"); } var currentResponse = new Response { OriginalName = currentRequest.OriginalName, TypeResolutions = currentRequest.TypeResolutions, ConcreteCallable = originalGlobal.WithFullName(name => currentRequest.ConcreteName) }; GetConcreteIdentifierFunc getConcreteIdentifier = (globalCallable, types) => GetConcreteIdentifier(currentResponse, requests, responses, globalCallable, types); // Rewrite implementation currentResponse = ReplaceTypeParamImplementations.Apply(currentResponse); // Rewrite calls currentResponse = ReplaceTypeParamCalls.Apply(currentResponse, getConcreteIdentifier, intrinsicCallableSet); responses.Add(currentResponse); } return(ResolveGenerics.Apply(compilation, responses, intrinsicCallableSet)); }
private static IList <EntryPointOperation> GenerateEntryPointOperations(QsCompilation compilation) { var globals = compilation.Namespaces.GlobalCallableResolutions(); return(compilation.EntryPoints.Select(ep => new EntryPointOperation() { Name = NameGeneration.InteropFriendlyWrapperName(ep), Parameters = GetParams(globals[ep]), }).ToList()); }
/// <summary> /// Adds a TargetInstruction attribute to each intrinsic callable that doesn't have one, /// unless the automatically determined target instruction name conflicts with another target instruction name. /// The automatically determined name of the target instruction is the lower case version of the unqualified callable name. /// Type constructors and generic callables are left unchanged. /// </summary> /// <returns>Returns true if all missing attributes have been successfully added and false if some attributes could not be added.</returns> /// <exception cref="InvalidOperationException">All intrinsic callables need to have exactly one body specialization.</exception> public static bool TryAddMissingTargetInstructionAttributes(QsCompilation compilation, out QsCompilation transformed) { var success = true; List <string> instructionNames = new List <string>(); // populate the intruction names with all manually specified ones first foreach (var callable in compilation.Namespaces.Callables()) { var manuallySpecified = SymbolResolution.TryGetTargetInstructionName(callable.Attributes); if (manuallySpecified.IsValue) { instructionNames.Add(manuallySpecified.Item); } } QsCallable AddAttribute(QsCallable callable) { if (callable.Specializations.Length != 1) { throw new InvalidOperationException("intrinsic callable needs to have exactly one body specialization"); } var instructionName = callable.FullName.Name.ToLowerInvariant(); if (instructionNames.Contains(instructionName)) { success = false; return(callable); } return(callable.AddAttribute( AttributeUtils.BuildAttribute( BuiltIn.TargetInstruction.FullName, AttributeUtils.StringArgument(instructionName)))); } QsNamespace AddAttributes(QsNamespace ns) { var elements = ns.Elements.Select(element => element is QsNamespaceElement.QsCallable callable && callable.Item.IsIntrinsic && callable.Item.Signature.TypeParameters.Length == 0 && !NameDecorator.IsAutoGeneratedName(callable.Item.FullName) && !callable.Item.Kind.IsTypeConstructor && !callable.Item.Attributes.Any(BuiltIn.DefinesTargetInstruction) ? QsNamespaceElement.NewQsCallable(AddAttribute(callable.Item)) : element); return(new QsNamespace(ns.Name, elements.ToImmutableArray(), ns.Documentation)); } var namespaces = compilation.Namespaces.Select(AddAttributes).ToImmutableArray(); transformed = new QsCompilation(namespaces, compilation.EntryPoints); return(success); }
public static QsCompilation Apply(QsCompilation compilation) { if (compilation == null || compilation.Namespaces.Contains(null)) { throw new ArgumentNullException(nameof(compilation)); } var globals = compilation.Namespaces.GlobalCallableResolutions(); var entryPoints = compilation.EntryPoints .Select(call => new Request { originalName = call, typeResolutions = ImmutableConcretion.Empty, concreteName = call }); var requests = new Stack <Request>(entryPoints); var responses = new List <Response>(); while (requests.Any()) { Request currentRequest = requests.Pop(); // If there is a call to an unknown callable, throw exception if (!globals.TryGetValue(currentRequest.originalName, out QsCallable originalGlobal)) { throw new ArgumentException($"Couldn't find definition for callable: {currentRequest.originalName.Namespace.Value + "." + currentRequest.originalName.Name.Value}"); } var currentResponse = new Response { originalName = currentRequest.originalName, typeResolutions = currentRequest.typeResolutions, concreteCallable = originalGlobal.WithFullName(name => currentRequest.concreteName) }; GetConcreteIdentifierFunc getConcreteIdentifier = (globalCallable, types) => GetConcreteIdentifier(currentResponse, requests, responses, globalCallable, types); // Rewrite implementation currentResponse = ReplaceTypeParamImplementationsSyntax.Apply(currentResponse); // Rewrite calls currentResponse = ReplaceTypeParamCallsSyntax.Apply(currentResponse, getConcreteIdentifier); responses.Add(currentResponse); } var filter = new ResolveGenericsSyntax(responses .GroupBy(res => res.concreteCallable.FullName.Namespace) .ToImmutableDictionary(group => group.Key, group => group.Select(res => res.concreteCallable))); return(new QsCompilation(compilation.Namespaces.Select(ns => filter.Transform(ns)).ToImmutableArray(), compilation.EntryPoints)); }
public IntrinsicResolution(QsCompilation environment) { Name = "IntrinsicResolution"; Priority = 10; // Not used for built-in transformations like this AssemblyConstants = new Dictionary <string, string>(); ImplementsTransformation = true; ImplementsPreconditionVerification = false; ImplementsPostconditionVerification = false; Environment = environment; }
public static void Apply(QsCompilation compilation, bool allowTypeParametersForIntrinsics = true) { var intrinsicCallableSet = allowTypeParametersForIntrinsics ? compilation.Namespaces.GlobalCallableResolutions() .Where(kvp => kvp.Value.Specializations.Any(spec => spec.Implementation.IsIntrinsic)) .Select(kvp => kvp.Key) .ToImmutableHashSet() : ImmutableHashSet <QsQualifiedName> .Empty; new ValidateMonomorphization(intrinsicCallableSet).OnCompilation(compilation); }
// Constructors /// <summary> /// Constructs a call graph from a compilation. The optional trim argument may be /// used to specify the call graph to be trimmed to only include callables that /// entry points are dependent on. /// </summary> public CallGraph(QsCompilation compilation, bool trim = false) { if (trim) { BuildCallGraph.PopulateTrimmedGraph(this.graphBuilder, compilation); } else { BuildCallGraph.PopulateGraph(this.graphBuilder, compilation); } }
public static QsCompilation Apply(QsCompilation compilation, List <QsCallable> callables, ImmutableHashSet <QsQualifiedName> intrinsicCallableSet, bool keepAllIntrinsics) { var filter = new ResolveGenerics( callables .Where(call => !keepAllIntrinsics || !intrinsicCallableSet.Contains(call.FullName)) .ToLookup(res => res.FullName.Namespace), intrinsicCallableSet, keepAllIntrinsics); return(filter.OnCompilation(compilation)); }
// tools for loading the compiled syntax tree from the dll resource (later setup for shipping Q# libraries) /// <summary> /// Given a stream containing the binary representation of compiled Q# code, returns the corresponding Q# compilation. /// Returns true if the compilation could be deserialized without throwing an exception, and false otherwise. /// Throws an ArgumentNullException if the given stream is null, but ignores exceptions thrown during deserialization. /// </summary> public static bool LoadSyntaxTree(Stream stream, out QsCompilation compilation) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } using var reader = new BsonDataReader(stream); (compilation, reader.ReadRootValueAsArray) = (null, false); try { compilation = Json.Serializer.Deserialize <QsCompilation>(reader); } catch { return(false); } return(compilation != null && !compilation.Namespaces.IsDefault && !compilation.EntryPoints.IsDefault); }