From 651c836d8e36cb6b4b4df8cd85551a917ba43e9b Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Mon, 2 Mar 2020 20:37:47 -0800 Subject: [PATCH 01/17] first draft for some handles for a package containing target specific information --- .../CommandLineTool/Commands/Build.cs | 22 +++---- .../CommandLineTool/Commands/Diagnose.cs | 15 ++--- src/QsCompiler/CommandLineTool/Options.cs | 59 ++++++++++++++++--- .../CompilationManager/AssemblyLoader.cs | 59 +++++++++++++++---- .../CompilationManager/ProjectManager.cs | 10 ++-- src/QsCompiler/Compiler/CompilationLoader.cs | 44 +++++++++++++- src/QsCompiler/DataStructures/Diagnostics.fs | 12 +++- 7 files changed, 170 insertions(+), 51 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index ba1a7965fd..b1f7d0bc9b 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -16,7 +16,7 @@ namespace Microsoft.Quantum.QsCompiler.CommandLineCompiler public static class BuildCompilation { [Verb("build", HelpText = "Builds a compilation unit to run on the Q# quantum simulation framework.")] - public class BuildOptions : Options + public class BuildOptions : CompilationOptions { [Usage(ApplicationAlias = "qsCompiler")] public static IEnumerable UsageExamples @@ -50,14 +50,6 @@ public static IEnumerable UsageExamples HelpText = "Name of the project (needs to be usable as file name).")] public string ProjectName { get; set; } - [Option("load", Required = false, SetName = CODE_MODE, - HelpText = "[Experimental feature] Path to the .NET Core dll(s) defining additional transformations to include in the compilation process.")] - public IEnumerable Plugins { get; set; } - - [Option("trim", Required = false, Default = 1, - HelpText = "[Experimental feature] Integer indicating how much to simplify the syntax tree by eliminating selective abstractions.")] - public int TrimLevel { get; set; } - [Option("emit-dll", Required = false, Default = false, SetName = CODE_MODE, HelpText = "Specifies whether the compiler should emit a .NET Core dll containing the compiled Q# code.")] public bool EmitDll { get; set; } @@ -121,14 +113,18 @@ public static int Run(BuildOptions options, ConsoleLogger logger) if (options == null) throw new ArgumentNullException(nameof(options)); if (logger == null) throw new ArgumentNullException(nameof(logger)); - if (options?.ResponseFiles != null && options.ResponseFiles.Any()) - { options = FromResponseFiles(options.ResponseFiles); } - if (options == null) return ReturnCode.INVALID_ARGUMENTS; + if (options.ResponseFiles != null && options.ResponseFiles.Any()) + { + var fromResponseFiles = FromResponseFiles(options.ResponseFiles); + options = fromResponseFiles; // FIXME: PROPERLY MERGE OPTIONS INSTEAD + if (options == null) return ReturnCode.INVALID_ARGUMENTS; + } var usesPlugins = options.Plugins != null && options.Plugins.Any(); var loadOptions = new CompilationLoader.Configuration { ProjectName = options.ProjectName, + TargetPackageAssembly = options.GetTargetPackageAssemblyPath(logger), GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = options.TrimLevel == 0, ConvertClassicalControl = options.TrimLevel >= 2, @@ -154,7 +150,7 @@ public static int Run(BuildOptions options, ConsoleLogger logger) } catch (Exception ex) { - logger.Log(ErrorCode.PublishingPerfResultsFailed, new string[]{options.PerfFolder}); + logger.Log(ErrorCode.PublishingPerfResultsFailed, new string[]{ options.PerfFolder }); logger.Log(ex); } } diff --git a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs index 8692affa79..20d58eede8 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs @@ -23,7 +23,7 @@ namespace Microsoft.Quantum.QsCompiler.CommandLineCompiler public static class DiagnoseCompilation { [Verb("diagnose", HelpText = "Generates intermediate representations of the code to help diagnose issues.")] - public class DiagnoseOptions : Options + public class DiagnoseOptions : CompilationOptions { [Usage(ApplicationAlias = "qsCompiler")] public static IEnumerable UsageExamples @@ -56,14 +56,6 @@ public static IEnumerable UsageExamples [Option("code", Required = false, Default = false, HelpText = "Specifies whether to print the Q# code generated based on the built syntax tree.")] public bool PrintCompiledCode { get; set; } - - [Option("trim", Required = false, Default = 1, - HelpText = "[Experimental feature] Integer indicating how much to simplify the syntax tree by eliminating selective abstractions.")] - public int TrimLevel { get; set; } - - [Option("load", Required = false, SetName = CODE_MODE, - HelpText = "[Experimental feature] Path to the .NET Core dll(s) defining additional transformations to include in the compilation process.")] - public IEnumerable Plugins { get; set; } } /// @@ -136,7 +128,7 @@ private static void PrintContentTokenization(Compilation compilation, ILogger lo private static void PrintSyntaxTree(IEnumerable evaluatedTree, Compilation compilation, ILogger logger) { if (compilation == null) throw new ArgumentNullException(nameof(compilation)); - evaluatedTree = evaluatedTree ?? compilation.SyntaxTree.Values; + evaluatedTree ??= compilation.SyntaxTree.Values; foreach (var file in compilation.SourceFiles) { @@ -166,7 +158,7 @@ void PrintTree(string serialization) => logger.Log( private static void PrintGeneratedQs(IEnumerable evaluatedTree, Compilation compilation, ILogger logger) { if (compilation == null) throw new ArgumentNullException(nameof(compilation)); - evaluatedTree = evaluatedTree ?? compilation.SyntaxTree.Values; + evaluatedTree ??= compilation.SyntaxTree.Values; foreach (var file in compilation.SourceFiles) { @@ -219,6 +211,7 @@ public static int Run(DiagnoseOptions options, ConsoleLogger logger) var loadOptions = new CompilationLoader.Configuration { + TargetPackageAssembly = options.GetTargetPackageAssemblyPath(logger), GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = options.TrimLevel == 0, ConvertClassicalControl = options.TrimLevel >= 2, diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index ddc0afe413..55a6a9124c 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -17,6 +17,49 @@ namespace Microsoft.Quantum.QsCompiler.CommandLineCompiler { + public class CompilationOptions : Options + { + [Option("trim", Required = false, Default = 1, + HelpText = "[Experimental feature] Integer indicating how much to simplify the syntax tree by eliminating selective abstractions.")] + public int TrimLevel { get; set; } + + [Option("load", Required = false, SetName = CODE_MODE, + HelpText = "[Experimental feature] Path to the .NET Core dll(s) defining additional transformations to include in the compilation process.")] + public IEnumerable Plugins { get; set; } + + [Option("target-package", Required = false, + HelpText = "Path to the NuGet package containing target specific information and implementations.")] + public string TargetPackage { get; set; } + + /// + /// Returns null if TargetPackage is not null or empty, and + /// returns the path to the assembly containing target specific implementations otherwise. + /// If a logger is specified, logs suitable diagnostics if a TargetPackages is not null or empty, + /// but no path to the target package assembly could be determined. + /// This may be the case if no directory at the TargetPackage location exists, or if its files can't be accessed, + /// or more than one dll matches the pattern by which the target package assembly is identified. + /// + public string GetTargetPackageAssemblyPath(ILogger logger = null) + { + if (String.IsNullOrEmpty(this.TargetPackage)) return null; + try + { + // Disclaimer: we may revise that in the future. + var targetPackageAssembly = Directory.GetFiles(this.TargetPackage, "*Intrinsics.dll", SearchOption.AllDirectories).SingleOrDefault(); + if (targetPackageAssembly != null) return targetPackageAssembly; + } + catch (Exception ex) + { + if (Directory.Exists(this.TargetPackage)) logger?.Log(ex); + else logger?.Log(ErrorCode.CouldNotFineTargetPackage, new[] { this.TargetPackage }); + } + + logger?.Log(ErrorCode.CouldNotFindTargetPackageAssembly, new[] { this.TargetPackage }); + return null; + } + } + + public class Options { public enum LogFormat @@ -59,7 +102,7 @@ public enum LogFormat public LogFormat OutputFormat { get; set; } [Option("package-load-fallback-folders", Required = false, SetName = CODE_MODE, - HelpText = "Specifies the directories the compiler will search when a rewrite step dependency could not be found.")] + HelpText = "Specifies the directories the compiler will search when a compiler dependency could not be found.")] public IEnumerable PackageLoadFallbackFolders { get; set; } @@ -87,15 +130,13 @@ string value(PropertyInfo p) /// /// Given a LogFormat, returns a suitable routing for formatting diagnostics. /// - internal static Func LoggingFormat(LogFormat format) - { - switch (format) + internal static Func LoggingFormat(LogFormat format) => + format switch { - case LogFormat.MsBuild: return Formatting.MsBuildFormat; - case LogFormat.Default: return Formatting.HumanReadableFormat; - default: throw new NotImplementedException("unknown output format for logger"); - } - } + LogFormat.MsBuild => Formatting.MsBuildFormat, + LogFormat.Default => Formatting.HumanReadableFormat, + _ => throw new NotImplementedException("unknown output format for logger"), + }; /// /// Creates a suitable logger for the given command line options, diff --git a/src/QsCompiler/CompilationManager/AssemblyLoader.cs b/src/QsCompiler/CompilationManager/AssemblyLoader.cs index d3b41243a2..7c4937112d 100644 --- a/src/QsCompiler/CompilationManager/AssemblyLoader.cs +++ b/src/QsCompiler/CompilationManager/AssemblyLoader.cs @@ -30,44 +30,82 @@ public static class AssemblyLoader /// and returns the loaded content as out parameter. /// Returns false if some of the content could not be loaded successfully, /// possibly because the referenced assembly has been compiled with an older compiler version. + /// If onDeserializationException is specified, invokes the given action on any exception thrown during deserialization. /// Throws an ArgumentNullException if the given uri is null. /// Throws a FileNotFoundException if no file with the given name exists. /// Throws the corresponding exceptions if the information cannot be extracted. /// - public static bool LoadReferencedAssembly(Uri asm, out References.Headers headers, bool ignoreDllResources = false) + public static bool LoadReferencedAssembly(Uri asm, out References.Headers headers, bool ignoreDllResources = false, Action onDeserializationException = null) { if (asm == null) throw new ArgumentNullException(nameof(asm)); if (!CompilationUnitManager.TryGetFileId(asm, out var id) || !File.Exists(asm.LocalPath)) - { throw new FileNotFoundException($"the uri '{asm}' given to the assembly loader is invalid or the file does not exist"); } + { throw new FileNotFoundException($"The uri '{asm}' given to the assembly loader is invalid or the file does not exist."); } using var stream = File.OpenRead(asm.LocalPath); using var assemblyFile = new PEReader(stream); - if (ignoreDllResources || !FromResource(assemblyFile, out var syntaxTree)) + if (ignoreDllResources || !FromResource(assemblyFile, out var compilation, onDeserializationException)) { var attributes = LoadHeaderAttributes(assemblyFile); headers = new References.Headers(id, attributes); return ignoreDllResources || !attributes.Any(); // just means we have no references } - headers = new References.Headers(id, syntaxTree?.Namespaces ?? ImmutableArray.Empty); + headers = new References.Headers(id, compilation?.Namespaces ?? ImmutableArray.Empty); return true; } + /// + /// Loads the Q# data structures in a referenced assembly given the Uri to that assembly, + /// and returns the loaded content as out parameter. + /// Returns false if some of the content could not be loaded successfully, + /// possibly because the referenced assembly has been compiled with an older compiler version. + /// Catches any exception throw upon loading the compilation, and invokes onException with it if such an action has been specified. + /// Sets the out parameter to null if an exception occurred during loading. + /// Throws an ArgumentNullException if the given uri is null. + /// Throws a FileNotFoundException if no file with the given name exists. + /// + public static bool LoadReferencedAssembly(string asmPath, out QsCompilation compilation, Action onException = null) + { + if (asmPath == null) throw new ArgumentNullException(nameof(asmPath)); + if (!File.Exists(asmPath)) throw new FileNotFoundException($"The file '{asmPath}' does not exist."); + + using var stream = File.OpenRead(asmPath); + using var assemblyFile = new PEReader(stream); + try + { + return FromResource(assemblyFile, out compilation, onException); + } + catch (Exception ex) + { + onException?.Invoke(ex); + compilation = null; + return false; + } + } + // tools for loading the compiled syntax tree from the dll resource (later setup for shipping Q# libraries) /// /// 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. + /// If onDeserializationException is specified, invokes the given action on any exception thrown during deserialization. /// Throws an ArgumentNullException if the given stream is null, but ignores exceptions thrown during deserialization. /// - public static bool LoadSyntaxTree(Stream stream, out QsCompilation compilation) + public static bool LoadSyntaxTree(Stream stream, out QsCompilation compilation, Action onDeserializationException = null) { if (stream == null) throw new ArgumentNullException(nameof(stream)); using var reader = new BsonDataReader(stream); (compilation, reader.ReadRootValueAsArray) = (null, false); - try { compilation = Json.Serializer.Deserialize(reader); } - catch { return false; } - return compilation != null && !compilation.Namespaces.IsDefault && !compilation.EntryPoints.IsDefault; + try + { + compilation = Json.Serializer.Deserialize(reader); + return compilation != null && !compilation.Namespaces.IsDefault && !compilation.EntryPoints.IsDefault; + } + catch (Exception ex) + { + onDeserializationException?.Invoke(ex); + return false; + } } /// @@ -85,10 +123,11 @@ private static ImmutableDictionary Resources(this Meta /// /// 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. + /// If onDeserializationException is specified, invokes the given action on any exception thrown during deserialization. /// 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. /// - private static bool FromResource(PEReader assemblyFile, out QsCompilation compilation) + private static bool FromResource(PEReader assemblyFile, out QsCompilation compilation, Action onDeserializationException = null) { if (assemblyFile == null) throw new ArgumentNullException(nameof(assemblyFile)); var metadataReader = assemblyFile.GetMetadataReader(); @@ -112,7 +151,7 @@ private static bool FromResource(PEReader assemblyFile, out QsCompilation compil // 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); + return LoadSyntaxTree(new MemoryStream(resourceData), out compilation, onDeserializationException); } diff --git a/src/QsCompiler/CompilationManager/ProjectManager.cs b/src/QsCompiler/CompilationManager/ProjectManager.cs index 339c48ed51..f73fed31d1 100644 --- a/src/QsCompiler/CompilationManager/ProjectManager.cs +++ b/src/QsCompiler/CompilationManager/ProjectManager.cs @@ -470,7 +470,7 @@ public Task ReloadProjectReferenceAsync(IDictionary projectOutputPaths public Task ReloadSourceFileAsync(Uri sourceFile, Func openInEditor = null) { if (sourceFile == null) throw new ArgumentNullException(nameof(sourceFile)); - openInEditor = openInEditor ?? (_ => null); + openInEditor ??= (_ => null); return this.Processing.QueueForExecutionAsync(() => { @@ -589,7 +589,7 @@ private Func, Uri, IEnumerable> Migrat if (openInEditor == null) throw new ArgumentNullException(nameof(openInEditor)); return (filesAddedToProject, projFile) => { - filesAddedToProject = filesAddedToProject ?? ImmutableHashSet.Empty; + filesAddedToProject ??= ImmutableHashSet.Empty; var openFiles = filesAddedToProject.Select(openInEditor).Where(m => m != null).ToImmutableArray(); var removals = openFiles.Select(file => { @@ -618,7 +618,7 @@ private Action, Task> MigrateToDefaultManager(Func { if (removal.IsCanceled) return; - filesRemovedFromProject = filesRemovedFromProject ?? ImmutableHashSet.Empty; + filesRemovedFromProject ??= ImmutableHashSet.Empty; Task.WaitAll(removal); // we *need* to wait here in order to make sure that change notifications are processed in order!! var openFiles = filesRemovedFromProject.Select(openInEditor).Where(m => m != null).ToImmutableHashSet(); foreach (var file in openFiles) @@ -642,7 +642,7 @@ public Task LoadProjectsAsync(IEnumerable projectFiles, ProjectInformation. { if (projectFiles == null || projectFiles.Contains(null)) throw new ArgumentNullException(nameof(projectFiles)); if (projectLoader == null) throw new ArgumentNullException(nameof(projectLoader)); - openInEditor = openInEditor ?? (_ => null); + openInEditor ??= (_ => null); return this.Load.QueueForExecutionAsync(() => { @@ -672,7 +672,7 @@ public Task ProjectChangedOnDiskAsync(Uri projectFile, ProjectInformation.Loader { if (projectFile == null) throw new ArgumentNullException(nameof(projectFile)); if (projectLoader == null) throw new ArgumentNullException(nameof(projectLoader)); - openInEditor = openInEditor ?? (_ => null); + openInEditor ??= (_ => null); // TODO: allow to cancel this task via cancellation token? return this.Load.QueueForExecutionAsync(() => diff --git a/src/QsCompiler/Compiler/CompilationLoader.cs b/src/QsCompiler/Compiler/CompilationLoader.cs index 5bd3c0e3fa..0584750f03 100644 --- a/src/QsCompiler/Compiler/CompilationLoader.cs +++ b/src/QsCompiler/Compiler/CompilationLoader.cs @@ -151,7 +151,13 @@ public struct Configuration /// However, the compiler may overwrite the assembly constants defined for the Q# compilation unit in the dictionary of the loaded step. /// The given dictionary in this configuration is left unchanged in any case. /// - public IReadOnlyDictionary AssemblyConstants; + public IReadOnlyDictionary AssemblyConstants; + /// + /// Path to the assembly that contains a syntax tree with target specific implementations for certain functions and operations. + /// The functions and operations defined in that assembly replace the ones declarated within the compilation unit. + /// If no path is specified here or the specified path is null then this compilation step is omitted. + /// + public string TargetPackageAssembly; /// /// Indicates whether a serialization of the syntax tree needs to be generated. @@ -190,6 +196,7 @@ private class ExecutionStatus internal Status ReferenceLoading = Status.NotRun; internal Status PluginLoading = Status.NotRun; internal Status Validation = Status.NotRun; + internal Status TargetSpecificReplacements = Status.NotRun; internal Status FunctorSupport = Status.NotRun; internal Status PreEvaluation = Status.NotRun; internal Status TreeTrimming = Status.NotRun; @@ -212,6 +219,7 @@ internal bool Success(Configuration options, bool isExe) => this.ReferenceLoading <= 0 && WasSuccessful(true, this.Validation) && WasSuccessful(true, this.PluginLoading) && + WasSuccessful(!String.IsNullOrWhiteSpace(options.TargetPackageAssembly), this.TargetSpecificReplacements) && WasSuccessful(options.GenerateFunctorSupport, this.FunctorSupport) && WasSuccessful(options.AttemptFullPreEvaluation, this.PreEvaluation) && WasSuccessful(!options.SkipSyntaxTreeTrimming, this.TreeTrimming) && @@ -247,6 +255,12 @@ internal bool Success(Configuration options, bool isExe) => /// public Status Validation => this.CompilationStatus.Validation; /// + /// Indicates whether target specific implementations for functions and operations + /// have been used to replace the ones declarated within the compilation unit. + /// This step is only executed if the specified configuration contains the path to the target package. + /// + public Status TargetSpecificReplacements => this.CompilationStatus.TargetSpecificReplacements; + /// /// Indicates whether all specializations were generated successfully. /// This rewrite step is only executed if the corresponding configuration is specified. /// @@ -420,6 +434,34 @@ QsCompilation ExecuteAsAtomicTransformation(RewriteSteps.LoadedStep rewriteStep, return status == Status.Succeeded ? transformed : this.CompilationOutput; } + if (!String.IsNullOrWhiteSpace(this.Config.TargetPackageAssembly)) + { + try + { + var targetDll = Path.GetFullPath(this.Config.TargetPackageAssembly); + var loaded = AssemblyLoader.LoadReferencedAssembly( + targetDll, + out var targetIntrinsics, + ex => this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ex)); + + if (loaded) + { + var rewriteStep = new RewriteSteps.LoadedStep(new IntrinsicResolution(targetIntrinsics), typeof(IRewriteStep), thisDllUri); + this.CompilationOutput = ExecuteAsAtomicTransformation(rewriteStep, ref this.CompilationStatus.TargetSpecificReplacements); + } + else + { + this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ErrorCode.FailedToLoadTargetPackageAssembly, new[] { targetDll }); + targetIntrinsics = null; + } + } + catch (Exception ex) + { + this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ErrorCode.InvalidTargetPackageAssemblyPath, new[] { this.Config.TargetPackageAssembly }); + this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ex); + } + } + if (this.Config.ConvertClassicalControl) { var rewriteStep = new RewriteSteps.LoadedStep(new ClassicallyControlled(), typeof(IRewriteStep), thisDllUri); diff --git a/src/QsCompiler/DataStructures/Diagnostics.fs b/src/QsCompiler/DataStructures/Diagnostics.fs index e960a53ee0..a09653b630 100644 --- a/src/QsCompiler/DataStructures/Diagnostics.fs +++ b/src/QsCompiler/DataStructures/Diagnostics.fs @@ -267,7 +267,11 @@ type ErrorCode = | UnknownCompilerPlugin = 7015 | CouldNotLoadCompilerPlugin = 7016 | CouldNotInstantiateRewriteStep = 7017 - | UnexpectedCompilerException = 7018 + | CouldNotFineTargetPackage = 7018 + | CouldNotFindTargetPackageAssembly = 7019 + | InvalidTargetPackageAssemblyPath = 7020 + | FailedToLoadTargetPackageAssembly = 7021 + | UnexpectedCompilerException = 7022 | FunctorGenerationFailed = 7101 | TreeTrimmingFailed = 7102 @@ -619,7 +623,11 @@ type DiagnosticItem = | ErrorCode.SourceFilesMissing -> "No source files have been specified." | ErrorCode.UnknownCompilerPlugin -> "Could not find the .NET Core library \"{0}\" specifying transformations to perform as part of the compilation process." | ErrorCode.CouldNotLoadCompilerPlugin -> "Unable to load the file \"{0}\" specifying transformations to perform as part of the compilation process. The file needs to be a suitable .NET Core library." - | ErrorCode.CouldNotInstantiateRewriteStep -> "Could not instantiate the type {0} in \"{1}\" specifying a rewrite step. The type may not have a parameterless constructor. " + | ErrorCode.CouldNotInstantiateRewriteStep -> "Could not instantiate the type {0} in \"{1}\" specifying a rewrite step. The type may not have a parameterless constructor." + | ErrorCode.CouldNotFineTargetPackage -> "Could not find the directory \"{0}\" containing target specific information." + | ErrorCode.CouldNotFindTargetPackageAssembly -> "Could not find the assembly specifying target specific implementations within the target package \"{0}\"." + | ErrorCode.InvalidTargetPackageAssemblyPath -> "Could not find the file \"{0}\" that specifies target specific implementations." + | ErrorCode.FailedToLoadTargetPackageAssembly -> "Unable to load target specific implementations from \"{0}\"." | ErrorCode.UnexpectedCompilerException -> "The compiler threw an exception." | ErrorCode.FunctorGenerationFailed -> "Auto-generation of functor specialization(s) failed." From 390908cffcb79d242be04b2c4ea0d72d107dc684 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Tue, 3 Mar 2020 13:16:50 -0800 Subject: [PATCH 02/17] That should properly merge options --- .../CommandLineTool/Commands/Build.cs | 25 ++++++++++++++++--- src/QsCompiler/CommandLineTool/Options.cs | 17 ++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index b1f7d0bc9b..c2dd49c0c2 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -35,7 +35,7 @@ public static IEnumerable UsageExamples } [Option("response-files", Required = true, SetName = RESPONSE_FILES, - HelpText = "Response file(s) providing the command arguments. Required only if no other arguments are specified. This option replaces all other arguments.")] + HelpText = "Response file(s) providing command arguments. Required only if no other arguments are specified. Non-default values for options specified via command line take precedence.")] public IEnumerable ResponseFiles { get; set; } [Option('o', "output", Required = false, SetName = CODE_MODE, @@ -113,11 +113,28 @@ public static int Run(BuildOptions options, ConsoleLogger logger) if (options == null) throw new ArgumentNullException(nameof(options)); if (logger == null) throw new ArgumentNullException(nameof(logger)); - if (options.ResponseFiles != null && options.ResponseFiles.Any()) + while (options.ResponseFiles != null && options.ResponseFiles.Any()) { var fromResponseFiles = FromResponseFiles(options.ResponseFiles); - options = fromResponseFiles; // FIXME: PROPERLY MERGE OPTIONS INSTEAD - if (options == null) return ReturnCode.INVALID_ARGUMENTS; + if (fromResponseFiles == null) return ReturnCode.INVALID_ARGUMENTS; + + options.CodeSnippet ??= fromResponseFiles.CodeSnippet; + options.DocFolder ??= fromResponseFiles.DocFolder; + options.EmitDll = options.EmitDll || fromResponseFiles.EmitDll; + options.Input = (options.Input ?? new string[0]).Concat(fromResponseFiles.Input ?? new string[0]); + options.NoWarn = (options.NoWarn ?? new int[0]).Concat(fromResponseFiles.NoWarn ?? new int[0]); + options.OutputFolder ??= fromResponseFiles.OutputFolder; + options.OutputFormat = options.OutputFormat != DefaultOptions.OutputFormat ? options.OutputFormat : fromResponseFiles.OutputFormat; + options.PackageLoadFallbackFolders = (options.PackageLoadFallbackFolders ?? new string[0]).Concat(fromResponseFiles.PackageLoadFallbackFolders ?? new string[0]); + options.PerfFolder ??= fromResponseFiles.PerfFolder; + options.Plugins = (options.Plugins ?? new string[0]).Concat(fromResponseFiles.Plugins ?? new string[0]); + options.ProjectName ??= fromResponseFiles.ProjectName; + options.References = (options.References ?? new string[0]).Concat(options.References ?? new string[0]); + options.ResponseFiles = fromResponseFiles.ResponseFiles; + options.TargetPackage ??= fromResponseFiles.TargetPackage; + options.TrimLevel = options.TrimLevel != DefaultOptions.TrimLevel ? options.TrimLevel : fromResponseFiles.TrimLevel; + options.Verbosity = options.Verbosity != DefaultOptions.Verbosity ? options.Verbosity : fromResponseFiles.Verbosity; + options.WithinFunction = options.WithinFunction || fromResponseFiles.WithinFunction; } var usesPlugins = options.Plugins != null && options.Plugins.Any(); diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index 55a6a9124c..82b4ed88e6 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -17,9 +17,20 @@ namespace Microsoft.Quantum.QsCompiler.CommandLineCompiler { + /// + /// Default values for command line options if nothing is specified. + /// + internal static class DefaultOptions + { + public const string Verbosity = "normal"; + public const Options.LogFormat OutputFormat = Options.LogFormat.Default; + public const int TrimLevel = 1; + } + + public class CompilationOptions : Options { - [Option("trim", Required = false, Default = 1, + [Option("trim", Required = false, Default = DefaultOptions.TrimLevel, HelpText = "[Experimental feature] Integer indicating how much to simplify the syntax tree by eliminating selective abstractions.")] public int TrimLevel { get; set; } @@ -73,7 +84,7 @@ public enum LogFormat protected const string SNIPPET_MODE = "snippetMode"; protected const string RESPONSE_FILES = "responseFiles"; - [Option('v', "verbosity", Required = false, Default = "normal", + [Option('v', "verbosity", Required = false, Default = DefaultOptions.Verbosity, HelpText = "Specifies the verbosity of the logged output. Valid values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].")] public string Verbosity { get; set; } @@ -97,7 +108,7 @@ public enum LogFormat HelpText = "Warnings with the given code(s) will be ignored.")] public IEnumerable NoWarn { get; set; } - [Option("format", Required = false, Default = LogFormat.Default, + [Option("format", Required = false, Default = DefaultOptions.OutputFormat, HelpText = "Specifies the output format of the command line compiler.")] public LogFormat OutputFormat { get; set; } From 2cf5a3578843b5c4486336f196ef359f79923499 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Tue, 10 Mar 2020 20:37:28 -0700 Subject: [PATCH 03/17] test --- .../Tests.Compiler/CommandLineTests.fs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs index a880acafb0..cbd52665f5 100644 --- a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs +++ b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs @@ -155,6 +155,29 @@ let ``diagnose outputs`` () = Assert.Equal(ReturnCode.INVALID_ARGUMENTS, result) +[] +let ``options from response files`` () = + let configFile = ("TestCases", "qsc-config.txt") |> Path.Combine + let configArgs = + [| + "-i" + ("TestCases","General.qs") |> Path.Combine + "--trim 0" + |] + File.WriteAllText(configFile, String.Join (" ", configArgs)) + let commandLineArgs = + [| + "-i" + ("TestCases","FunctorGeneration.qs") |> Path.Combine + "--trim 2" + "--response-files" + configFile + |] + + let result = Program.Main commandLineArgs + Assert.Equal(ReturnCode.SUCCESS, result) + + [] let ``generate docs`` () = let docsFolder = ("TestCases", "docs.Out") |> Path.Combine From 28d6d787b31a32fd47501514beb5ec48e4e29960 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Tue, 10 Mar 2020 20:58:35 -0700 Subject: [PATCH 04/17] fixing typo --- src/QsCompiler/CommandLineTool/Commands/Build.cs | 2 +- src/QsCompiler/CommandLineTool/Options.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index c2dd49c0c2..9450a86433 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -129,7 +129,7 @@ public static int Run(BuildOptions options, ConsoleLogger logger) options.PerfFolder ??= fromResponseFiles.PerfFolder; options.Plugins = (options.Plugins ?? new string[0]).Concat(fromResponseFiles.Plugins ?? new string[0]); options.ProjectName ??= fromResponseFiles.ProjectName; - options.References = (options.References ?? new string[0]).Concat(options.References ?? new string[0]); + options.References = (options.References ?? new string[0]).Concat(fromResponseFiles.References ?? new string[0]); options.ResponseFiles = fromResponseFiles.ResponseFiles; options.TargetPackage ??= fromResponseFiles.TargetPackage; options.TrimLevel = options.TrimLevel != DefaultOptions.TrimLevel ? options.TrimLevel : fromResponseFiles.TrimLevel; diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index 82b4ed88e6..5b3b5ea8ed 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -38,7 +38,7 @@ public class CompilationOptions : Options HelpText = "[Experimental feature] Path to the .NET Core dll(s) defining additional transformations to include in the compilation process.")] public IEnumerable Plugins { get; set; } - [Option("target-package", Required = false, + [Option("target-package", Required = false, SetName = CODE_MODE, HelpText = "Path to the NuGet package containing target specific information and implementations.")] public string TargetPackage { get; set; } From 5a26e212a549c3cc471d6dfff84e4b69b7c58255 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Tue, 10 Mar 2020 21:22:23 -0700 Subject: [PATCH 05/17] going with this test --- src/QsCompiler/CommandLineTool/Commands/Build.cs | 2 +- src/QsCompiler/CommandLineTool/Options.cs | 1 - src/QsCompiler/Tests.Compiler/CommandLineTests.fs | 11 +++++++---- .../Tests.Compiler/LocalVerificationTests.fs | 6 +++++- .../Tests.Compiler/TestCases/LinkingTests/Core.qs | 6 ------ .../TestCases/LinkingTests/Diagnostics.qs | 9 +++++++++ src/QsCompiler/Tests.Compiler/Tests.Compiler.fsproj | 3 +++ 7 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index 9450a86433..1ec8d2c9e6 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -34,7 +34,7 @@ public static IEnumerable UsageExamples } } - [Option("response-files", Required = true, SetName = RESPONSE_FILES, + [Option("response-files", Required = false, HelpText = "Response file(s) providing command arguments. Required only if no other arguments are specified. Non-default values for options specified via command line take precedence.")] public IEnumerable ResponseFiles { get; set; } diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index 5b3b5ea8ed..60acbbeef3 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -82,7 +82,6 @@ public enum LogFormat // Note: items in one set are mutually exclusive with items from other sets protected const string CODE_MODE = "codeMode"; protected const string SNIPPET_MODE = "snippetMode"; - protected const string RESPONSE_FILES = "responseFiles"; [Option('v', "verbosity", Required = false, Default = DefaultOptions.Verbosity, HelpText = "Specifies the verbosity of the logged output. Valid values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].")] diff --git a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs index cbd52665f5..5dbc692479 100644 --- a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs +++ b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs @@ -161,15 +161,18 @@ let ``options from response files`` () = let configArgs = [| "-i" - ("TestCases","General.qs") |> Path.Combine - "--trim 0" + ("TestCases","LinkingTests","Core.qs") |> Path.Combine + "--trim" + "0" |] File.WriteAllText(configFile, String.Join (" ", configArgs)) let commandLineArgs = [| + "build" "-i" - ("TestCases","FunctorGeneration.qs") |> Path.Combine - "--trim 2" + ("TestCases","LinkingTests","Diagnostics.qs") |> Path.Combine + "--trim" + "2" "--response-files" configFile |] diff --git a/src/QsCompiler/Tests.Compiler/LocalVerificationTests.fs b/src/QsCompiler/Tests.Compiler/LocalVerificationTests.fs index 2570fd7295..6cc5e4fc59 100644 --- a/src/QsCompiler/Tests.Compiler/LocalVerificationTests.fs +++ b/src/QsCompiler/Tests.Compiler/LocalVerificationTests.fs @@ -14,7 +14,11 @@ open Xunit.Abstractions type LocalVerificationTests (output:ITestOutputHelper) = - inherit CompilerTests(CompilerTests.Compile "TestCases" ["General.qs"; "LocalVerification.qs"; "Types.qs"; Path.Combine ("LinkingTests", "Core.qs")], output) + inherit CompilerTests( + CompilerTests.Compile "TestCases" [ + "General.qs"; "LocalVerification.qs"; "Types.qs"; + Path.Combine ("LinkingTests", "Core.qs"); Path.Combine ("LinkingTests", "Diagnostics.qs") + ], output) member private this.Expect name (diag : IEnumerable) = let ns = "Microsoft.Quantum.Testing.LocalVerification" |> NonNullable<_>.New diff --git a/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Core.qs b/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Core.qs index 66fe60a6f3..64005ce6d0 100644 --- a/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Core.qs +++ b/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Core.qs @@ -19,9 +19,3 @@ namespace Microsoft.Quantum.Core { } } -namespace Microsoft.Quantum.Diagnostics { - - // needs to be available for testing - @ Attribute() - newtype Test = String; -} \ No newline at end of file diff --git a/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs b/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs new file mode 100644 index 0000000000..ad5b6e9b25 --- /dev/null +++ b/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Diagnostics { + + // needs to be available for testing + @ Attribute() + newtype Test = String; +} \ No newline at end of file diff --git a/src/QsCompiler/Tests.Compiler/Tests.Compiler.fsproj b/src/QsCompiler/Tests.Compiler/Tests.Compiler.fsproj index b7f2118e59..a3e4648e0d 100644 --- a/src/QsCompiler/Tests.Compiler/Tests.Compiler.fsproj +++ b/src/QsCompiler/Tests.Compiler/Tests.Compiler.fsproj @@ -23,6 +23,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From d4b629342e3d75c490bf1f47381ec7c738fcb56b Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Tue, 10 Mar 2020 22:14:21 -0700 Subject: [PATCH 06/17] file structure --- src/QsCompiler/Compiler/CompilationLoader.cs | 227 ++++++++++-------- .../TestCases/LinkingTests/Diagnostics.qs | 3 +- 2 files changed, 127 insertions(+), 103 deletions(-) diff --git a/src/QsCompiler/Compiler/CompilationLoader.cs b/src/QsCompiler/Compiler/CompilationLoader.cs index 0584750f03..425844ffff 100644 --- a/src/QsCompiler/Compiler/CompilationLoader.cs +++ b/src/QsCompiler/Compiler/CompilationLoader.cs @@ -428,38 +428,9 @@ public CompilationLoader(SourceLoader loadSources, ReferenceLoader loadReference if (!Uri.TryCreate(Assembly.GetExecutingAssembly().CodeBase, UriKind.Absolute, out Uri thisDllUri)) { thisDllUri = new Uri(Path.GetFullPath(".", "CompilationLoader.cs")); } - QsCompilation ExecuteAsAtomicTransformation(RewriteSteps.LoadedStep rewriteStep, ref Status status) - { - status = this.ExecuteRewriteStep(rewriteStep, this.CompilationOutput, out var transformed); - return status == Status.Succeeded ? transformed : this.CompilationOutput; - } - if (!String.IsNullOrWhiteSpace(this.Config.TargetPackageAssembly)) { - try - { - var targetDll = Path.GetFullPath(this.Config.TargetPackageAssembly); - var loaded = AssemblyLoader.LoadReferencedAssembly( - targetDll, - out var targetIntrinsics, - ex => this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ex)); - - if (loaded) - { - var rewriteStep = new RewriteSteps.LoadedStep(new IntrinsicResolution(targetIntrinsics), typeof(IRewriteStep), thisDllUri); - this.CompilationOutput = ExecuteAsAtomicTransformation(rewriteStep, ref this.CompilationStatus.TargetSpecificReplacements); - } - else - { - this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ErrorCode.FailedToLoadTargetPackageAssembly, new[] { targetDll }); - targetIntrinsics = null; - } - } - catch (Exception ex) - { - this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ErrorCode.InvalidTargetPackageAssemblyPath, new[] { this.Config.TargetPackageAssembly }); - this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ex); - } + this.ReplaceTargetSpecificImplementations(thisDllUri, out this.CompilationOutput); } if (this.Config.ConvertClassicalControl) @@ -550,66 +521,6 @@ QsCompilation ExecuteAsAtomicTransformation(RewriteSteps.LoadedStep rewriteStep, RaiseCompilationTaskEnd(null, "OverallCompilation"); } - /// - /// Executes the given rewrite step on the given compilation, returning a transformed compilation as an out parameter. - /// Catches and logs any thrown exception. Returns the status of the rewrite step. - /// Throws an ArgumentNullException if the rewrite step to execute or the given compilation is null. - /// - private Status ExecuteRewriteStep(RewriteSteps.LoadedStep rewriteStep, QsCompilation compilation, out QsCompilation transformed) - { - if (rewriteStep == null) throw new ArgumentNullException(nameof(rewriteStep)); - if (compilation == null) throw new ArgumentNullException(nameof(compilation)); - - string GetDiagnosticsCode(DiagnosticSeverity severity) => - rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Error ? Errors.Code(ErrorCode.CsharpGenerationGeneratedError) : - rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Warning ? Warnings.Code(WarningCode.CsharpGenerationGeneratedWarning) : - rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Information ? Informations.Code(InformationCode.CsharpGenerationGeneratedInfo) : - null; - - Status LogDiagnostics(Status status = Status.Succeeded) - { - try - { - foreach (var diagnostic in rewriteStep.GeneratedDiagnostics ?? ImmutableArray.Empty) - { this.LogAndUpdate(ref status, RewriteSteps.LoadedStep.ConvertDiagnostic(diagnostic, GetDiagnosticsCode)); } - } - catch { this.LogAndUpdate(ref status, Warning(WarningCode.RewriteStepDiagnosticsGenerationFailed, new[] { rewriteStep.Name })); } - return status; - } - - var status = Status.Succeeded; - var messageSource = ProjectManager.MessageSource(rewriteStep.Origin); - Diagnostic Warning(WarningCode code, params string[] args) => Warnings.LoadWarning(code, args, messageSource); - try - { - transformed = compilation; - var preconditionFailed = rewriteStep.ImplementsPreconditionVerification && !rewriteStep.PreconditionVerification(compilation); - if (preconditionFailed) - { - LogDiagnostics(); - this.LogAndUpdate(ref status, Warning(WarningCode.PreconditionVerificationFailed, new[] { rewriteStep.Name, messageSource })); - return status; - } - - var transformationFailed = rewriteStep.ImplementsTransformation && !rewriteStep.Transformation(compilation, out transformed); - var postconditionFailed = this.Config.EnableAdditionalChecks && rewriteStep.ImplementsPostconditionVerification && !rewriteStep.PostconditionVerification(transformed); - LogDiagnostics(); - - if (transformationFailed) this.LogAndUpdate(ref status, ErrorCode.RewriteStepExecutionFailed, new[] { rewriteStep.Name, messageSource }); - if (postconditionFailed) this.LogAndUpdate(ref status, ErrorCode.PostconditionVerificationFailed, new[] { rewriteStep.Name, messageSource }); - return status; - } - catch (Exception ex) - { - this.LogAndUpdate(ref status, ex); - var isLoadException = ex is FileLoadException || ex.InnerException is FileLoadException; - if (isLoadException) this.LogAndUpdate(ref status, ErrorCode.FileNotFoundDuringPluginExecution, new[] { rewriteStep.Name, messageSource }); - else this.LogAndUpdate(ref status, ErrorCode.PluginExecutionFailed, new[] { rewriteStep.Name, messageSource }); - transformed = null; - } - return status; - } - /// /// Builds the compilation of the specified source files and references, /// executing the compilation steps specified by the given options. @@ -727,6 +638,130 @@ private void PrintLoadedRewriteSteps(IEnumerable rewrit } + // private helper methods used during construction + + /// + /// Raises a compilation task start event. + /// + private void RaiseCompilationTaskStart(string parentTaskName, string taskName) => + CompilationTaskEvent?.Invoke(this, new CompilationTaskEventArgs(CompilationTaskEventType.Start, parentTaskName, taskName)); + + /// + /// Raises a compilation task end event. + /// + private void RaiseCompilationTaskEnd(string parentTaskName, string taskName) => + CompilationTaskEvent?.Invoke(this, new CompilationTaskEventArgs(CompilationTaskEventType.End, parentTaskName, taskName)); + + /// + /// Executes the given rewrite step on the current CompilationOutput, and updates the given status accordingly. + /// Sets the CompilationOutput to the transformed compilation if the status indicates success. + /// + private QsCompilation ExecuteAsAtomicTransformation(RewriteSteps.LoadedStep rewriteStep, ref Status status) + { + status = this.ExecuteRewriteStep(rewriteStep, this.CompilationOutput, out var transformed); + return status == Status.Succeeded ? transformed : this.CompilationOutput; + } + + /// + /// Attempts to load the target package assembly specified in the configuration, + /// logging diagnostics when the loading fails or the corresponding configuration is not specified. + /// Updates the compilation status accordingly. + /// Executes the transformation to replace target specific implementations as atomic rewrite step, + /// returning the transformed compilation as out parameter. + /// Sets the out parameter to the unmodified CompilationOutput if the replacement fails. + /// Returns a boolean value indicating whether the returned compilation has been modified. + /// + private bool ReplaceTargetSpecificImplementations(Uri rewriteStepOrigin, out QsCompilation transformed) + { + try + { + var targetDll = Path.GetFullPath(this.Config.TargetPackageAssembly); + var loaded = AssemblyLoader.LoadReferencedAssembly( + targetDll, + out var targetIntrinsics, + ex => this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ex)); + + if (loaded) + { + var rewriteStep = new RewriteSteps.LoadedStep(new IntrinsicResolution(targetIntrinsics), typeof(IRewriteStep), rewriteStepOrigin); + transformed = ExecuteAsAtomicTransformation(rewriteStep, ref this.CompilationStatus.TargetSpecificReplacements); + return true; + } + else + { + this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ErrorCode.FailedToLoadTargetPackageAssembly, new[] { targetDll }); + } + } + catch (Exception ex) + { + this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ErrorCode.InvalidTargetPackageAssemblyPath, new[] { this.Config.TargetPackageAssembly }); + this.LogAndUpdate(ref this.CompilationStatus.TargetSpecificReplacements, ex); + } + transformed = this.CompilationOutput; + return false; + } + + /// + /// Executes the given rewrite step on the given compilation, returning a transformed compilation as an out parameter. + /// Catches and logs any thrown exception. Returns the status of the rewrite step. + /// Throws an ArgumentNullException if the rewrite step to execute or the given compilation is null. + /// + private Status ExecuteRewriteStep(RewriteSteps.LoadedStep rewriteStep, QsCompilation compilation, out QsCompilation transformed) + { + if (rewriteStep == null) throw new ArgumentNullException(nameof(rewriteStep)); + if (compilation == null) throw new ArgumentNullException(nameof(compilation)); + + string GetDiagnosticsCode(DiagnosticSeverity severity) => + rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Error ? Errors.Code(ErrorCode.CsharpGenerationGeneratedError) : + rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Warning ? Warnings.Code(WarningCode.CsharpGenerationGeneratedWarning) : + rewriteStep.Name == "CsharpGeneration" && severity == DiagnosticSeverity.Information ? Informations.Code(InformationCode.CsharpGenerationGeneratedInfo) : + null; + + Status LogDiagnostics(Status status = Status.Succeeded) + { + try + { + foreach (var diagnostic in rewriteStep.GeneratedDiagnostics ?? ImmutableArray.Empty) + { this.LogAndUpdate(ref status, RewriteSteps.LoadedStep.ConvertDiagnostic(diagnostic, GetDiagnosticsCode)); } + } + catch { this.LogAndUpdate(ref status, Warning(WarningCode.RewriteStepDiagnosticsGenerationFailed, new[] { rewriteStep.Name })); } + return status; + } + + var status = Status.Succeeded; + var messageSource = ProjectManager.MessageSource(rewriteStep.Origin); + Diagnostic Warning(WarningCode code, params string[] args) => Warnings.LoadWarning(code, args, messageSource); + try + { + transformed = compilation; + var preconditionFailed = rewriteStep.ImplementsPreconditionVerification && !rewriteStep.PreconditionVerification(compilation); + if (preconditionFailed) + { + LogDiagnostics(); + this.LogAndUpdate(ref status, Warning(WarningCode.PreconditionVerificationFailed, new[] { rewriteStep.Name, messageSource })); + return status; + } + + var transformationFailed = rewriteStep.ImplementsTransformation && !rewriteStep.Transformation(compilation, out transformed); + var postconditionFailed = this.Config.EnableAdditionalChecks && rewriteStep.ImplementsPostconditionVerification && !rewriteStep.PostconditionVerification(transformed); + LogDiagnostics(); + + if (transformationFailed) this.LogAndUpdate(ref status, ErrorCode.RewriteStepExecutionFailed, new[] { rewriteStep.Name, messageSource }); + if (postconditionFailed) this.LogAndUpdate(ref status, ErrorCode.PostconditionVerificationFailed, new[] { rewriteStep.Name, messageSource }); + return status; + } + catch (Exception ex) + { + this.LogAndUpdate(ref status, ex); + var isLoadException = ex is FileLoadException || ex.InnerException is FileLoadException; + if (isLoadException) this.LogAndUpdate(ref status, ErrorCode.FileNotFoundDuringPluginExecution, new[] { rewriteStep.Name, messageSource }); + else this.LogAndUpdate(ref status, ErrorCode.PluginExecutionFailed, new[] { rewriteStep.Name, messageSource }); + transformed = null; + } + return status; + } + + // routines for loading from and dumping to files /// @@ -951,17 +986,5 @@ string FullDirectoryName(string dir) => File.WriteAllText(targetFile, content); return targetFile; } - - /// - /// Raises a compilation task start event. - /// - private void RaiseCompilationTaskStart (string parentTaskName, string taskName) => - CompilationTaskEvent?.Invoke(this, new CompilationTaskEventArgs(CompilationTaskEventType.Start, parentTaskName, taskName)); - - /// - /// Raises a compilation task end event. - /// - private void RaiseCompilationTaskEnd(string parentTaskName, string taskName) => - CompilationTaskEvent?.Invoke(this, new CompilationTaskEventArgs(CompilationTaskEventType.End, parentTaskName, taskName)); } } diff --git a/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs b/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs index ad5b6e9b25..6a691e0946 100644 --- a/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs +++ b/src/QsCompiler/Tests.Compiler/TestCases/LinkingTests/Diagnostics.qs @@ -6,4 +6,5 @@ namespace Microsoft.Quantum.Diagnostics { // needs to be available for testing @ Attribute() newtype Test = String; -} \ No newline at end of file +} + From e973d379a439161ba272ad87bced4d524bf4c881 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Tue, 10 Mar 2020 23:32:36 -0700 Subject: [PATCH 07/17] let's stick with that --- src/QsCompiler/CommandLineTool/Commands/Build.cs | 2 +- src/QsCompiler/CommandLineTool/Options.cs | 1 + src/QsCompiler/Tests.Compiler/CommandLineTests.fs | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index 1ec8d2c9e6..9450a86433 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -34,7 +34,7 @@ public static IEnumerable UsageExamples } } - [Option("response-files", Required = false, + [Option("response-files", Required = true, SetName = RESPONSE_FILES, HelpText = "Response file(s) providing command arguments. Required only if no other arguments are specified. Non-default values for options specified via command line take precedence.")] public IEnumerable ResponseFiles { get; set; } diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index 60acbbeef3..5b3b5ea8ed 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -82,6 +82,7 @@ public enum LogFormat // Note: items in one set are mutually exclusive with items from other sets protected const string CODE_MODE = "codeMode"; protected const string SNIPPET_MODE = "snippetMode"; + protected const string RESPONSE_FILES = "responseFiles"; [Option('v', "verbosity", Required = false, Default = DefaultOptions.Verbosity, HelpText = "Specifies the verbosity of the logged output. Valid values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].")] diff --git a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs index 5dbc692479..9e013ca437 100644 --- a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs +++ b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs @@ -162,6 +162,7 @@ let ``options from response files`` () = [| "-i" ("TestCases","LinkingTests","Core.qs") |> Path.Combine + ("TestCases","LinkingTests","Diagnostics.qs") |> Path.Combine "--trim" "0" |] @@ -169,8 +170,6 @@ let ``options from response files`` () = let commandLineArgs = [| "build" - "-i" - ("TestCases","LinkingTests","Diagnostics.qs") |> Path.Combine "--trim" "2" "--response-files" From ade77a813e2c79fb8c7cb5a6e66130a6ca84767b Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Sat, 14 Mar 2020 19:57:58 -0700 Subject: [PATCH 08/17] basic outline for sdk - now we need to distinguish the partner package --- src/ProjectTemplates/Quantum.App1/Driver.cs | 11 ++----- .../DocumentationParser/DocComment.cs | 14 ++++---- .../DefaultItems/DefaultItems.targets | 33 ++++++++++++++----- src/QuantumSdk/Sdk/Sdk.props | 6 ++-- src/QuantumSdk/Sdk/Sdk.targets | 2 +- 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/ProjectTemplates/Quantum.App1/Driver.cs b/src/ProjectTemplates/Quantum.App1/Driver.cs index 5ab9441939..20a7ecae50 100644 --- a/src/ProjectTemplates/Quantum.App1/Driver.cs +++ b/src/ProjectTemplates/Quantum.App1/Driver.cs @@ -1,7 +1,4 @@ -using System; -using System.Threading.Tasks; - -using Microsoft.Quantum.Simulation.Core; +using System.Threading.Tasks; using Microsoft.Quantum.Simulation.Simulators; namespace Quantum.App1 @@ -10,10 +7,8 @@ class Driver { static async Task Main(string[] args) { - using (var qsim = new QuantumSimulator()) - { - await HelloQ.Run(qsim); - } + using var qsim = new QuantumSimulator(); + await HelloQ.Run(qsim); } } } \ No newline at end of file diff --git a/src/QsCompiler/DocumentationParser/DocComment.cs b/src/QsCompiler/DocumentationParser/DocComment.cs index 0c501cb27b..527ee9a4df 100644 --- a/src/QsCompiler/DocumentationParser/DocComment.cs +++ b/src/QsCompiler/DocumentationParser/DocComment.cs @@ -101,7 +101,7 @@ public class DocComment /// The name of the replacement element for deprecated elements, if given public DocComment(IEnumerable docComments, string name, bool deprecated, string replacement) { - string GetHeadingText(HeadingBlock heading) + static string GetHeadingText(HeadingBlock heading) { var sb = new StringBuilder(); foreach (var item in heading.Inline) @@ -111,7 +111,7 @@ string GetHeadingText(HeadingBlock heading) return sb.ToString(); } - string GetParagraphText(LeafBlock leaf) + static string GetParagraphText(LeafBlock leaf) { var sb = new StringBuilder(); foreach (var item in leaf.Inline) @@ -121,7 +121,7 @@ string GetParagraphText(LeafBlock leaf) return sb.ToString(); } - string ToMarkdown(IEnumerable blocks) + static string ToMarkdown(IEnumerable blocks) { var writer = new StringWriter(); var renderer = new NormalizeRenderer(writer); @@ -136,7 +136,7 @@ string ToMarkdown(IEnumerable blocks) return writer.ToString().TrimEnd().Replace('\n', '\r'); } - List>> BreakIntoSections(IEnumerable blocks, int level) + static List>> BreakIntoSections(IEnumerable blocks, int level) { var key = ""; var accum = new List(); @@ -174,7 +174,7 @@ List>> BreakIntoSections(IEnumerable block return result; } - void ParseListSection(IEnumerable blocks, List accum, bool lowerCase) + static void ParseListSection(IEnumerable blocks, List accum, bool lowerCase) { foreach (var block in blocks) { @@ -202,7 +202,7 @@ void ParseListSection(IEnumerable blocks, List accum, bool lowerC } } - void ParseMapSection(IEnumerable blocks, Dictionary accum) + static void ParseMapSection(IEnumerable blocks, Dictionary accum) { var subsections = BreakIntoSections(blocks, 2); foreach ((var key, var subs) in subsections) @@ -214,7 +214,7 @@ void ParseMapSection(IEnumerable blocks, Dictionary accum } // First element is not matching, second is matching - (List, List) PartitionNestedSection(IEnumerable blocks, int level, string name) + static (List, List) PartitionNestedSection(IEnumerable blocks, int level, string name) { var inMatch = false; var result = (new List(), new List()); diff --git a/src/QuantumSdk/DefaultItems/DefaultItems.targets b/src/QuantumSdk/DefaultItems/DefaultItems.targets index 764107d873..5950afd17d 100644 --- a/src/QuantumSdk/DefaultItems/DefaultItems.targets +++ b/src/QuantumSdk/DefaultItems/DefaultItems.targets @@ -17,7 +17,7 @@ - + QsharpLibrary QsharpExe @@ -25,15 +25,32 @@ Possible values are 'Exe', or 'Library'. - + - QuantumProcessorBackend - SimulatorBackend + HoneywellProcessor + IonQProcessor + QCIProcessor Unspecified - - Possible values are 'QuantumSimulator', 'ToffoliSimulator', 'ResourcesEstimator', or 'QuantumProcessor'. - The execution target for a Q# library needs to be 'Any'. - true + + Possible values are 'Honeywell', 'IonQ', 'QCI', or 'Any'. + The execution target for a Q# library needs to be 'Any'. + + + + + OpenQASM + ExtendedQASM + OpenQASM + + + + + + + QPGen1 + QPGen0 + QPGen1 + diff --git a/src/QuantumSdk/Sdk/Sdk.props b/src/QuantumSdk/Sdk/Sdk.props index ba31d6536e..f7853654a8 100644 --- a/src/QuantumSdk/Sdk/Sdk.props +++ b/src/QuantumSdk/Sdk/Sdk.props @@ -31,11 +31,13 @@ - + + - + + --input "@(QsharpCompile,'" "')" <_QscCommandReferencesFlag Condition="@(ResolvedQsharpReferences->Count()) > 0">--references "@(ResolvedQsharpReferences,'" "')" <_QscCommandLoadFlag Condition="@(_PrioritizedResolvedQscReferences->Count()) > 0">--load "@(_PrioritizedResolvedQscReferences,'" "')" - <_QscCommandTrimFlag Condition="'$(ResolvedQsharpExecutionTarget)' == 'QuantumProcessorBackend'">--trim 2 + <_QscCommandTrimFlag Condition="'$(ResolvedQuantumProcessor)' == 'QPGen1'">--trim 2 <_QscPackageLoadFallbackFoldersFlag Condition="@(ResolvedPackageLoadFallbackFolders->Count()) > 0">--package-load-fallback-folders "@(ResolvedPackageLoadFallbackFolders,'" "')" <_QscCommandArgs>--proj "$(PathCompatibleAssemblyName)" $(_QscCommandDocsFlag) $(_QscCommandInputFlag) $(_QscCommandOutputFlag) $(_QscCommandReferencesFlag) $(_QscCommandLoadFlag) $(_QscCommandTrimFlag) $(_QscPackageLoadFallbackFoldersFlag) $(AdditionalQscArguments) <_QscCommandArgsFile>$(QscBuildConfigOutputPath)qsc.rsp From 6341cb3aff9001052a6a27f6511f5b91e093c05c Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Sat, 14 Mar 2020 20:11:37 -0700 Subject: [PATCH 09/17] splitting out options merging --- .../CommandLineTool/Commands/Build.cs | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index 9450a86433..fd671a64b8 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -57,6 +57,40 @@ public static IEnumerable UsageExamples [Option('p', "perf", Required = false, SetName = CODE_MODE, HelpText = "Destination folder where the output of the performance assessment will be generated.")] public string PerfFolder { get; set; } + + + /// + /// Reads the content of all specified response files and processes it using FromResponseFiles. + /// Updates the options accordingly, prioritizing already specified non-default values over the values from response-files. + /// Returns false if the content of the specified response-files could not be processed. + /// + internal bool IncorporateResponseFiles() + { + while (this.ResponseFiles != null && this.ResponseFiles.Any()) + { + var fromResponseFiles = FromResponseFiles(this.ResponseFiles); + if (fromResponseFiles == null) return false; + + this.CodeSnippet ??= fromResponseFiles.CodeSnippet; + this.DocFolder ??= fromResponseFiles.DocFolder; + this.EmitDll = this.EmitDll || fromResponseFiles.EmitDll; + this.Input = (this.Input ?? new string[0]).Concat(fromResponseFiles.Input ?? new string[0]); + this.NoWarn = (this.NoWarn ?? new int[0]).Concat(fromResponseFiles.NoWarn ?? new int[0]); + this.OutputFolder ??= fromResponseFiles.OutputFolder; + this.OutputFormat = this.OutputFormat != DefaultOptions.OutputFormat ? this.OutputFormat : fromResponseFiles.OutputFormat; + this.PackageLoadFallbackFolders = (this.PackageLoadFallbackFolders ?? new string[0]).Concat(fromResponseFiles.PackageLoadFallbackFolders ?? new string[0]); + this.PerfFolder ??= fromResponseFiles.PerfFolder; + this.Plugins = (this.Plugins ?? new string[0]).Concat(fromResponseFiles.Plugins ?? new string[0]); + this.ProjectName ??= fromResponseFiles.ProjectName; + this.References = (this.References ?? new string[0]).Concat(fromResponseFiles.References ?? new string[0]); + this.ResponseFiles = fromResponseFiles.ResponseFiles; + this.TargetPackage ??= fromResponseFiles.TargetPackage; + this.TrimLevel = this.TrimLevel != DefaultOptions.TrimLevel ? this.TrimLevel : fromResponseFiles.TrimLevel; + this.Verbosity = this.Verbosity != DefaultOptions.Verbosity ? this.Verbosity : fromResponseFiles.Verbosity; + this.WithinFunction = this.WithinFunction || fromResponseFiles.WithinFunction; + } + return true; + } } /// @@ -112,30 +146,7 @@ public static int Run(BuildOptions options, ConsoleLogger logger) { if (options == null) throw new ArgumentNullException(nameof(options)); if (logger == null) throw new ArgumentNullException(nameof(logger)); - - while (options.ResponseFiles != null && options.ResponseFiles.Any()) - { - var fromResponseFiles = FromResponseFiles(options.ResponseFiles); - if (fromResponseFiles == null) return ReturnCode.INVALID_ARGUMENTS; - - options.CodeSnippet ??= fromResponseFiles.CodeSnippet; - options.DocFolder ??= fromResponseFiles.DocFolder; - options.EmitDll = options.EmitDll || fromResponseFiles.EmitDll; - options.Input = (options.Input ?? new string[0]).Concat(fromResponseFiles.Input ?? new string[0]); - options.NoWarn = (options.NoWarn ?? new int[0]).Concat(fromResponseFiles.NoWarn ?? new int[0]); - options.OutputFolder ??= fromResponseFiles.OutputFolder; - options.OutputFormat = options.OutputFormat != DefaultOptions.OutputFormat ? options.OutputFormat : fromResponseFiles.OutputFormat; - options.PackageLoadFallbackFolders = (options.PackageLoadFallbackFolders ?? new string[0]).Concat(fromResponseFiles.PackageLoadFallbackFolders ?? new string[0]); - options.PerfFolder ??= fromResponseFiles.PerfFolder; - options.Plugins = (options.Plugins ?? new string[0]).Concat(fromResponseFiles.Plugins ?? new string[0]); - options.ProjectName ??= fromResponseFiles.ProjectName; - options.References = (options.References ?? new string[0]).Concat(fromResponseFiles.References ?? new string[0]); - options.ResponseFiles = fromResponseFiles.ResponseFiles; - options.TargetPackage ??= fromResponseFiles.TargetPackage; - options.TrimLevel = options.TrimLevel != DefaultOptions.TrimLevel ? options.TrimLevel : fromResponseFiles.TrimLevel; - options.Verbosity = options.Verbosity != DefaultOptions.Verbosity ? options.Verbosity : fromResponseFiles.Verbosity; - options.WithinFunction = options.WithinFunction || fromResponseFiles.WithinFunction; - } + if (!options.IncorporateResponseFiles()) return ReturnCode.INVALID_ARGUMENTS; var usesPlugins = options.Plugins != null && options.Plugins.Any(); var loadOptions = new CompilationLoader.Configuration From 0292bd7157dabf63bb2350d94839bce988d589ec Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Sat, 14 Mar 2020 20:11:52 -0700 Subject: [PATCH 10/17] whitespace --- src/QsCompiler/CommandLineTool/Commands/Build.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index fd671a64b8..cb1718542a 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -93,6 +93,7 @@ internal bool IncorporateResponseFiles() } } + /// /// Given a string representing the command line arguments, splits them into a suitable string array. /// From ad5efe1879ef4f919bd8c9a73d54516a3ad87e2b Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Sat, 14 Mar 2020 20:42:35 -0700 Subject: [PATCH 11/17] take exclusive sets into account when merging options --- .../CommandLineTool/Commands/Build.cs | 19 +-------------- src/QsCompiler/CommandLineTool/Options.cs | 24 +++++++++++++++---- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index cb1718542a..a269d13506 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -70,24 +70,7 @@ internal bool IncorporateResponseFiles() { var fromResponseFiles = FromResponseFiles(this.ResponseFiles); if (fromResponseFiles == null) return false; - - this.CodeSnippet ??= fromResponseFiles.CodeSnippet; - this.DocFolder ??= fromResponseFiles.DocFolder; - this.EmitDll = this.EmitDll || fromResponseFiles.EmitDll; - this.Input = (this.Input ?? new string[0]).Concat(fromResponseFiles.Input ?? new string[0]); - this.NoWarn = (this.NoWarn ?? new int[0]).Concat(fromResponseFiles.NoWarn ?? new int[0]); - this.OutputFolder ??= fromResponseFiles.OutputFolder; - this.OutputFormat = this.OutputFormat != DefaultOptions.OutputFormat ? this.OutputFormat : fromResponseFiles.OutputFormat; - this.PackageLoadFallbackFolders = (this.PackageLoadFallbackFolders ?? new string[0]).Concat(fromResponseFiles.PackageLoadFallbackFolders ?? new string[0]); - this.PerfFolder ??= fromResponseFiles.PerfFolder; - this.Plugins = (this.Plugins ?? new string[0]).Concat(fromResponseFiles.Plugins ?? new string[0]); - this.ProjectName ??= fromResponseFiles.ProjectName; - this.References = (this.References ?? new string[0]).Concat(fromResponseFiles.References ?? new string[0]); - this.ResponseFiles = fromResponseFiles.ResponseFiles; - this.TargetPackage ??= fromResponseFiles.TargetPackage; - this.TrimLevel = this.TrimLevel != DefaultOptions.TrimLevel ? this.TrimLevel : fromResponseFiles.TrimLevel; - this.Verbosity = this.Verbosity != DefaultOptions.Verbosity ? this.Verbosity : fromResponseFiles.Verbosity; - this.WithinFunction = this.WithinFunction || fromResponseFiles.WithinFunction; + this.UpdateSetIndependentSettings(fromResponseFiles); } return true; } diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index 5b3b5ea8ed..5efa1dbc99 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -30,7 +30,7 @@ internal static class DefaultOptions public class CompilationOptions : Options { - [Option("trim", Required = false, Default = DefaultOptions.TrimLevel, + [Option("trim", Required = false, Default = DefaultOptions.TrimLevel, SetName = CODE_MODE, HelpText = "[Experimental feature] Integer indicating how much to simplify the syntax tree by eliminating selective abstractions.")] public int TrimLevel { get; set; } @@ -88,6 +88,10 @@ public enum LogFormat HelpText = "Specifies the verbosity of the logged output. Valid values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].")] public string Verbosity { get; set; } + [Option("format", Required = false, Default = DefaultOptions.OutputFormat, + HelpText = "Specifies the output format of the command line compiler.")] + public LogFormat OutputFormat { get; set; } + [Option('i', "input", Required = true, SetName = CODE_MODE, HelpText = "Q# code or name of the Q# file to compile.")] public IEnumerable Input { get; set; } @@ -108,15 +112,25 @@ public enum LogFormat HelpText = "Warnings with the given code(s) will be ignored.")] public IEnumerable NoWarn { get; set; } - [Option("format", Required = false, Default = DefaultOptions.OutputFormat, - HelpText = "Specifies the output format of the command line compiler.")] - public LogFormat OutputFormat { get; set; } - [Option("package-load-fallback-folders", Required = false, SetName = CODE_MODE, HelpText = "Specifies the directories the compiler will search when a compiler dependency could not be found.")] public IEnumerable PackageLoadFallbackFolders { get; set; } + /// + /// Updates the settings that can be used independent on the other arguments according to the setting in the given options. + /// Already specified non-default values are prioritized over the values in the given options, + /// unless overwriteNonDefaultValues is set to true. Sequences are merged. + /// + internal void UpdateSetIndependentSettings(Options updates, bool overwriteNonDefaultValues = false) + { + this.Verbosity = overwriteNonDefaultValues || this.Verbosity == DefaultOptions.Verbosity ? updates.Verbosity : this.Verbosity; + this.OutputFormat = overwriteNonDefaultValues || this.OutputFormat == DefaultOptions.OutputFormat ? updates.OutputFormat : this.OutputFormat; + this.NoWarn = (this.NoWarn ?? new int[0]).Concat(updates.NoWarn ?? new int[0]); + this.References = (this.References ?? new string[0]).Concat(updates.References ?? new string[0]); + } + + // routines related to logging /// From 3ccda80e921d44a13ef5f6d20e95a29de89ee0e6 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Sun, 15 Mar 2020 11:27:58 -0700 Subject: [PATCH 12/17] propagating target package info --- .../CommandLineTool/Commands/Build.cs | 16 ++++++---- .../DefaultItems/DefaultItems.targets | 30 +++++++++++++++---- src/QuantumSdk/Sdk/Sdk.props | 4 +-- src/QuantumSdk/Sdk/Sdk.targets | 7 +++-- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index a269d13506..7ec60f8ca0 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -61,17 +61,21 @@ public static IEnumerable UsageExamples /// /// Reads the content of all specified response files and processes it using FromResponseFiles. - /// Updates the options accordingly, prioritizing already specified non-default values over the values from response-files. + /// Updates the settings accordingly, prioritizing already specified non-default values over the values from response-files. + /// Returns true and a new BuildOptions object as out parameter with all the settings from response files incorporated. /// Returns false if the content of the specified response-files could not be processed. /// - internal bool IncorporateResponseFiles() + internal static bool IncorporateResponseFiles(BuildOptions options, out BuildOptions incorporated) { - while (this.ResponseFiles != null && this.ResponseFiles.Any()) + incorporated = null; + while (options.ResponseFiles != null && options.ResponseFiles.Any()) { - var fromResponseFiles = FromResponseFiles(this.ResponseFiles); + var fromResponseFiles = FromResponseFiles(options.ResponseFiles); if (fromResponseFiles == null) return false; - this.UpdateSetIndependentSettings(fromResponseFiles); + fromResponseFiles.UpdateSetIndependentSettings(options); + options = fromResponseFiles; } + incorporated = options; return true; } } @@ -130,7 +134,7 @@ public static int Run(BuildOptions options, ConsoleLogger logger) { if (options == null) throw new ArgumentNullException(nameof(options)); if (logger == null) throw new ArgumentNullException(nameof(logger)); - if (!options.IncorporateResponseFiles()) return ReturnCode.INVALID_ARGUMENTS; + if (!BuildOptions.IncorporateResponseFiles(options, out options)) return ReturnCode.INVALID_ARGUMENTS; var usesPlugins = options.Plugins != null && options.Plugins.Any(); var loadOptions = new CompilationLoader.Configuration diff --git a/src/QuantumSdk/DefaultItems/DefaultItems.targets b/src/QuantumSdk/DefaultItems/DefaultItems.targets index 5950afd17d..caf136ac33 100644 --- a/src/QuantumSdk/DefaultItems/DefaultItems.targets +++ b/src/QuantumSdk/DefaultItems/DefaultItems.targets @@ -9,8 +9,8 @@ - - + + @@ -44,7 +44,6 @@ - QPGen1 @@ -53,7 +52,7 @@ - + $([System.String]::Copy('$(AssemblyName)').Replace(' ','')) @@ -72,7 +71,28 @@ - + + + + <_TargetPackageReference Include="@(PackageReference)" Condition="@(PackageReference->Count()) > 0 And %(PackageReference.IsTargetPackage)" /> + <_TargetPackageReferencePathProperty Include="@(_TargetPackageReference->'Pkg$([System.String]::Copy('%(_TargetPackageReference.Identity)').Replace('.','_'))')" /> + <_ResolvedTargetPackageReferences Include="$(%(_TargetPackageReferencePathProperty.Identity))" /> + + + + + %(_ResolvedTargetPackageReferences.Identity) + + + + + diff --git a/src/QuantumSdk/Sdk/Sdk.props b/src/QuantumSdk/Sdk/Sdk.props index f7853654a8..f44ea733eb 100644 --- a/src/QuantumSdk/Sdk/Sdk.props +++ b/src/QuantumSdk/Sdk/Sdk.props @@ -31,8 +31,8 @@ - - + + diff --git a/src/QuantumSdk/Sdk/Sdk.targets b/src/QuantumSdk/Sdk/Sdk.targets index 8edc625354..b7bdbb32eb 100644 --- a/src/QuantumSdk/Sdk/Sdk.targets +++ b/src/QuantumSdk/Sdk/Sdk.targets @@ -43,7 +43,7 @@ @@ -64,7 +64,7 @@ - + @@ -74,8 +74,9 @@ <_QscCommandReferencesFlag Condition="@(ResolvedQsharpReferences->Count()) > 0">--references "@(ResolvedQsharpReferences,'" "')" <_QscCommandLoadFlag Condition="@(_PrioritizedResolvedQscReferences->Count()) > 0">--load "@(_PrioritizedResolvedQscReferences,'" "')" <_QscCommandTrimFlag Condition="'$(ResolvedQuantumProcessor)' == 'QPGen1'">--trim 2 + <_QscCommandTargetPackageFlag Condition="'$(ResolvedTargetPackage)' != ''">--target-package "$(ResolvedTargetPackage)" <_QscPackageLoadFallbackFoldersFlag Condition="@(ResolvedPackageLoadFallbackFolders->Count()) > 0">--package-load-fallback-folders "@(ResolvedPackageLoadFallbackFolders,'" "')" - <_QscCommandArgs>--proj "$(PathCompatibleAssemblyName)" $(_QscCommandDocsFlag) $(_QscCommandInputFlag) $(_QscCommandOutputFlag) $(_QscCommandReferencesFlag) $(_QscCommandLoadFlag) $(_QscCommandTrimFlag) $(_QscPackageLoadFallbackFoldersFlag) $(AdditionalQscArguments) + <_QscCommandArgs>--proj "$(PathCompatibleAssemblyName)" $(_QscCommandDocsFlag) $(_QscCommandInputFlag) $(_QscCommandOutputFlag) $(_QscCommandReferencesFlag) $(_QscCommandLoadFlag) $(_QscCommandTrimFlag) $(_QscCommandTargetPackageFlag) $(_QscPackageLoadFallbackFoldersFlag) $(AdditionalQscArguments) <_QscCommandArgsFile>$(QscBuildConfigOutputPath)qsc.rsp $(QscExe) build --format MsBuild $(_VerbosityFlag) --response-files $(_QscCommandArgsFile) From d87d398b9c31ac99c5056729b8081a72cdb82fc0 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Sun, 15 Mar 2020 11:43:58 -0700 Subject: [PATCH 13/17] forgot to adapt a test --- src/QsCompiler/Tests.Compiler/CommandLineTests.fs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs index 9e013ca437..38ffd7ec19 100644 --- a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs +++ b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs @@ -163,15 +163,11 @@ let ``options from response files`` () = "-i" ("TestCases","LinkingTests","Core.qs") |> Path.Combine ("TestCases","LinkingTests","Diagnostics.qs") |> Path.Combine - "--trim" - "0" |] File.WriteAllText(configFile, String.Join (" ", configArgs)) let commandLineArgs = [| "build" - "--trim" - "2" "--response-files" configFile |] From fc617043b172488e6bd68afc0c2f24c7c208e1eb Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Sun, 15 Mar 2020 11:51:50 -0700 Subject: [PATCH 14/17] minor thing --- src/QsCompiler/Tests.Compiler/CommandLineTests.fs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs index 38ffd7ec19..4a13ca8592 100644 --- a/src/QsCompiler/Tests.Compiler/CommandLineTests.fs +++ b/src/QsCompiler/Tests.Compiler/CommandLineTests.fs @@ -168,6 +168,10 @@ let ``options from response files`` () = let commandLineArgs = [| "build" + "-v" + "Detailed" + "--format" + "MsBuild" "--response-files" configFile |] From 62da3c1a573a4079402822069c378eef59e14dcc Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Mon, 16 Mar 2020 16:25:25 -0700 Subject: [PATCH 15/17] defining an assembly property with the resolved execution target --- .../CommandLineTool/Commands/Build.cs | 6 ++++++ .../CommandLineTool/Commands/Diagnose.cs | 6 ++++++ src/QsCompiler/CommandLineTool/Options.cs | 21 +++++++++++++++++++ .../Compiler/ExternalRewriteSteps.cs | 7 ++++--- src/QsCompiler/DataStructures/Diagnostics.fs | 7 ++++--- src/QuantumSdk/Sdk/Sdk.targets | 3 ++- 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Commands/Build.cs b/src/QsCompiler/CommandLineTool/Commands/Build.cs index 7ec60f8ca0..b9a7ac8356 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Build.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Build.cs @@ -137,9 +137,15 @@ public static int Run(BuildOptions options, ConsoleLogger logger) if (!BuildOptions.IncorporateResponseFiles(options, out options)) return ReturnCode.INVALID_ARGUMENTS; var usesPlugins = options.Plugins != null && options.Plugins.Any(); + if (!options.ParseAssemblyProperties(out var assemblyConstants)) + { + logger.Log(WarningCode.InvalidAssemblyProperties, new string[0]); + } + var loadOptions = new CompilationLoader.Configuration { ProjectName = options.ProjectName, + AssemblyConstants = assemblyConstants, TargetPackageAssembly = options.GetTargetPackageAssemblyPath(logger), GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = options.TrimLevel == 0, diff --git a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs index 20d58eede8..d11755ff9a 100644 --- a/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs +++ b/src/QsCompiler/CommandLineTool/Commands/Diagnose.cs @@ -209,8 +209,14 @@ public static int Run(DiagnoseOptions options, ConsoleLogger logger) if (options == null) throw new ArgumentNullException(nameof(options)); if (logger == null) throw new ArgumentNullException(nameof(logger)); + if (!options.ParseAssemblyProperties(out var assemblyConstants)) + { + logger.Log(WarningCode.InvalidAssemblyProperties, new string[0]); + } + var loadOptions = new CompilationLoader.Configuration { + AssemblyConstants = assemblyConstants, TargetPackageAssembly = options.GetTargetPackageAssemblyPath(logger), GenerateFunctorSupport = true, SkipSyntaxTreeTrimming = options.TrimLevel == 0, diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index 5efa1dbc99..5aa942d4f6 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -42,6 +42,27 @@ public class CompilationOptions : Options HelpText = "Path to the NuGet package containing target specific information and implementations.")] public string TargetPackage { get; set; } + [Option('p', "assembly-properties", Required = false, SetName = CODE_MODE, + HelpText = "Additional properties to populate the AssemblyConstants dictionary with. Each item is expected to be of the form \"key=value\".")] + public IEnumerable AdditionalAssemblyProperties { get; set; } + + /// + /// Returns a dictionary with the specified assembly properties as out parameter. + /// Returns a boolean indicating whether all specified properties were successfully added. + /// + internal bool ParseAssemblyProperties(out Dictionary parsed) + { + var success = true; + parsed = new Dictionary(); + foreach (var keyValue in this.AdditionalAssemblyProperties ?? new string[0]) + { + var pieces = keyValue?.Split("="); + var valid = pieces != null && pieces.Length == 2; + success = valid && parsed.TryAdd(pieces[0].Trim().Trim('"'), pieces[1].Trim().Trim('"')) && success; + } + return success; + } + /// /// Returns null if TargetPackage is not null or empty, and /// returns the path to the assembly containing target specific implementations otherwise. diff --git a/src/QsCompiler/Compiler/ExternalRewriteSteps.cs b/src/QsCompiler/Compiler/ExternalRewriteSteps.cs index 07531a5aef..fbbd3925a9 100644 --- a/src/QsCompiler/Compiler/ExternalRewriteSteps.cs +++ b/src/QsCompiler/Compiler/ExternalRewriteSteps.cs @@ -285,9 +285,10 @@ Uri WithFullPath(string file) foreach (var kvPair in config.AssemblyConstants ?? Enumerable.Empty>()) { assemblyConstants[kvPair.Key] = kvPair.Value; } - var defaultOutput = assemblyConstants.TryGetValue(AssemblyConstants.OutputPath, out var path) ? path : null; - assemblyConstants[AssemblyConstants.OutputPath] = outputFolder ?? defaultOutput ?? config.BuildOutputFolder; - assemblyConstants[AssemblyConstants.AssemblyName] = config.ProjectNameWithoutExtension; + // We don't overwrite assembly properties specified by configuration. + var defaultOutput = assemblyConstants.TryGetValue(AssemblyConstants.OutputPath, out var path) ? path : null; + assemblyConstants.TryAdd(AssemblyConstants.OutputPath, outputFolder ?? defaultOutput ?? config.BuildOutputFolder); + assemblyConstants.TryAdd(AssemblyConstants.AssemblyName, config.ProjectNameWithoutExtension); } loadedSteps.Sort((fst, snd) => snd.Priority - fst.Priority); diff --git a/src/QsCompiler/DataStructures/Diagnostics.fs b/src/QsCompiler/DataStructures/Diagnostics.fs index a09653b630..e92a4a0a2a 100644 --- a/src/QsCompiler/DataStructures/Diagnostics.fs +++ b/src/QsCompiler/DataStructures/Diagnostics.fs @@ -287,8 +287,7 @@ type ErrorCode = | PostconditionVerificationFailed = 7113 | CsharpGenerationGeneratedError = 8001 - - | PublishingPerfResultsFailed = 9001 + | PublishingPerfResultsFailed = 8101 type WarningCode = @@ -332,6 +331,7 @@ type WarningCode = | FailedToLoadRewriteStepViaReflection = 7204 | CsharpGenerationGeneratedWarning = 8001 + | InvalidAssemblyProperties = 8101 type InformationCode = @@ -644,8 +644,8 @@ type DiagnosticItem = | ErrorCode.PostconditionVerificationFailed -> "The postcondition for the compilation step \"{0}\" loaded from \"{1}\" was not satisfied. The transformation has produced incorrect output and should be excluded from the compilation process." | ErrorCode.CsharpGenerationGeneratedError -> "" - | ErrorCode.PublishingPerfResultsFailed -> "Performance results failed to be published at \"{0}\"." + | _ -> "" code |> ApplyArguments @@ -691,6 +691,7 @@ type DiagnosticItem = | WarningCode.FailedToLoadRewriteStepViaReflection -> "A possible rewrite step has been detected in \"{0}\". The step could not be loaded and will be ignored." | WarningCode.CsharpGenerationGeneratedWarning -> "" + | WarningCode.InvalidAssemblyProperties -> "Some of the specified assembly properties could not be processed. Either they did not match the expected format, or they duplicate existing ones." | _ -> "" code |> ApplyArguments diff --git a/src/QuantumSdk/Sdk/Sdk.targets b/src/QuantumSdk/Sdk/Sdk.targets index b7bdbb32eb..4be4d49d0c 100644 --- a/src/QuantumSdk/Sdk/Sdk.targets +++ b/src/QuantumSdk/Sdk/Sdk.targets @@ -75,8 +75,9 @@ <_QscCommandLoadFlag Condition="@(_PrioritizedResolvedQscReferences->Count()) > 0">--load "@(_PrioritizedResolvedQscReferences,'" "')" <_QscCommandTrimFlag Condition="'$(ResolvedQuantumProcessor)' == 'QPGen1'">--trim 2 <_QscCommandTargetPackageFlag Condition="'$(ResolvedTargetPackage)' != ''">--target-package "$(ResolvedTargetPackage)" + <_QscCommandAssemblyPropertiesFlag>-p ResolvedExecutionTarget=$(ResolvedQsharpExecutionTarget) $(QscCommandAssemblyProperties) <_QscPackageLoadFallbackFoldersFlag Condition="@(ResolvedPackageLoadFallbackFolders->Count()) > 0">--package-load-fallback-folders "@(ResolvedPackageLoadFallbackFolders,'" "')" - <_QscCommandArgs>--proj "$(PathCompatibleAssemblyName)" $(_QscCommandDocsFlag) $(_QscCommandInputFlag) $(_QscCommandOutputFlag) $(_QscCommandReferencesFlag) $(_QscCommandLoadFlag) $(_QscCommandTrimFlag) $(_QscCommandTargetPackageFlag) $(_QscPackageLoadFallbackFoldersFlag) $(AdditionalQscArguments) + <_QscCommandArgs>--proj "$(PathCompatibleAssemblyName)" $(_QscCommandDocsFlag) $(_QscCommandInputFlag) $(_QscCommandOutputFlag) $(_QscCommandReferencesFlag) $(_QscCommandLoadFlag) $(_QscCommandTrimFlag) $(_QscCommandTargetPackageFlag) $(_QscPackageLoadFallbackFoldersFlag) $(_QscCommandAssemblyPropertiesFlag) $(AdditionalQscArguments) <_QscCommandArgsFile>$(QscBuildConfigOutputPath)qsc.rsp $(QscExe) build --format MsBuild $(_VerbosityFlag) --response-files $(_QscCommandArgsFile) From b6e52de37ab004b556587249f261b5b04e2f2ba4 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Wed, 18 Mar 2020 15:02:18 -0700 Subject: [PATCH 16/17] fixing typos --- src/QsCompiler/CommandLineTool/Options.cs | 4 ++-- src/QsCompiler/DataStructures/Diagnostics.fs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/QsCompiler/CommandLineTool/Options.cs b/src/QsCompiler/CommandLineTool/Options.cs index 5aa942d4f6..124893dadd 100644 --- a/src/QsCompiler/CommandLineTool/Options.cs +++ b/src/QsCompiler/CommandLineTool/Options.cs @@ -64,7 +64,7 @@ internal bool ParseAssemblyProperties(out Dictionary parsed) } /// - /// Returns null if TargetPackage is not null or empty, and + /// Returns null if TargetPackage is null or empty, and /// returns the path to the assembly containing target specific implementations otherwise. /// If a logger is specified, logs suitable diagnostics if a TargetPackages is not null or empty, /// but no path to the target package assembly could be determined. @@ -83,7 +83,7 @@ public string GetTargetPackageAssemblyPath(ILogger logger = null) catch (Exception ex) { if (Directory.Exists(this.TargetPackage)) logger?.Log(ex); - else logger?.Log(ErrorCode.CouldNotFineTargetPackage, new[] { this.TargetPackage }); + else logger?.Log(ErrorCode.CouldNotFindTargetPackage, new[] { this.TargetPackage }); } logger?.Log(ErrorCode.CouldNotFindTargetPackageAssembly, new[] { this.TargetPackage }); diff --git a/src/QsCompiler/DataStructures/Diagnostics.fs b/src/QsCompiler/DataStructures/Diagnostics.fs index 528941abd6..95802c8c8f 100644 --- a/src/QsCompiler/DataStructures/Diagnostics.fs +++ b/src/QsCompiler/DataStructures/Diagnostics.fs @@ -273,7 +273,7 @@ type ErrorCode = | UnknownCompilerPlugin = 7015 | CouldNotLoadCompilerPlugin = 7016 | CouldNotInstantiateRewriteStep = 7017 - | CouldNotFineTargetPackage = 7018 + | CouldNotFindTargetPackage = 7018 | CouldNotFindTargetPackageAssembly = 7019 | InvalidTargetPackageAssemblyPath = 7020 | FailedToLoadTargetPackageAssembly = 7021 @@ -636,7 +636,7 @@ type DiagnosticItem = | ErrorCode.UnknownCompilerPlugin -> "Could not find the .NET Core library \"{0}\" specifying transformations to perform as part of the compilation process." | ErrorCode.CouldNotLoadCompilerPlugin -> "Unable to load the file \"{0}\" specifying transformations to perform as part of the compilation process. The file needs to be a suitable .NET Core library." | ErrorCode.CouldNotInstantiateRewriteStep -> "Could not instantiate the type {0} in \"{1}\" specifying a rewrite step. The type may not have a parameterless constructor." - | ErrorCode.CouldNotFineTargetPackage -> "Could not find the directory \"{0}\" containing target specific information." + | ErrorCode.CouldNotFindTargetPackage -> "Could not find the directory \"{0}\" containing target specific information." | ErrorCode.CouldNotFindTargetPackageAssembly -> "Could not find the assembly specifying target specific implementations within the target package \"{0}\"." | ErrorCode.InvalidTargetPackageAssemblyPath -> "Could not find the file \"{0}\" that specifies target specific implementations." | ErrorCode.FailedToLoadTargetPackageAssembly -> "Unable to load target specific implementations from \"{0}\"." From 30035cf89f98d3b51e1222b2b57bf31aeed82944 Mon Sep 17 00:00:00 2001 From: Bettina Heim Date: Wed, 18 Mar 2020 15:23:14 -0700 Subject: [PATCH 17/17] commenting out including partner packages --- src/QuantumSdk/DefaultItems/DefaultItems.targets | 6 +++--- src/QuantumSdk/Sdk/Sdk.props | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/QuantumSdk/DefaultItems/DefaultItems.targets b/src/QuantumSdk/DefaultItems/DefaultItems.targets index caf136ac33..4ba548dd5d 100644 --- a/src/QuantumSdk/DefaultItems/DefaultItems.targets +++ b/src/QuantumSdk/DefaultItems/DefaultItems.targets @@ -41,15 +41,15 @@ OpenQASM ExtendedQASM OpenQASM - + Default - + QPGen1 QPGen0 QPGen1 - + Unknown diff --git a/src/QuantumSdk/Sdk/Sdk.props b/src/QuantumSdk/Sdk/Sdk.props index f44ea733eb..7f9bd490b9 100644 --- a/src/QuantumSdk/Sdk/Sdk.props +++ b/src/QuantumSdk/Sdk/Sdk.props @@ -31,8 +31,9 @@ - - + +