This repository has been archived by the owner on Jan 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 169
/
Copy pathPluginInterface.cs
210 lines (184 loc) · 10.1 KB
/
PluginInterface.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;
using Microsoft.Quantum.QsCompiler.CompilationBuilder;
using Microsoft.Quantum.QsCompiler.DataTypes;
using Microsoft.Quantum.QsCompiler.SyntaxTree;
using VS = Microsoft.VisualStudio.LanguageServer.Protocol;
namespace Microsoft.Quantum.QsCompiler
{
/// <summary>
/// Lists the priorities for built-in rewrite steps. Steps with a larger priority number
/// have higher priority and will be executed first.
/// </summary>
public static class RewriteStepPriorities
{
/// <summary>
/// Priority of the built-in transformation that removes all
/// unused callables from the syntax tree.
/// </summary>
public const int SyntaxTreeTrimming = 1300;
/// <summary>
/// Priority of the built-in transformation that replaces
/// lambda expressions with the corresponding calls to generated callables if possible.
/// </summary>
public const int LambdaExpressionElimination = 1200;
/// <summary>
/// Priority of the built-in transformation that replaces
/// if-statements with the corresponding calls to built-in quantum operations if possible.
/// </summary>
public const int ControlFlowSubstitutions = 1100;
/// <summary>
/// Priority of the built-in transformation that replaces
/// all functor generation directives with the corresponding implementation.
/// </summary>
public const int GenerationOfFunctorSupport = 600;
/// <summary>
/// Priority of the built-in transformation that inlines all conjugations
/// and thus eliminates that construct from the syntax tree.
/// </summary>
public const int InliningOfConjugations = 500;
/// <summary>
/// Priority of the built-in transformation that
/// evaluates classical computations as much as possible.
/// </summary>
public const int EvaluationOfClassicalComputations = 100;
/// <summary>
/// Priority of the built-in transformation that replaces
/// all type parametrized callables with concrete instantiations and drops any unused callables.
/// </summary>
public const int TypeParameterElimination = 80;
/// <summary>
/// Priority of the built-in transformation that infers the minimum runtime capabilities
/// required by each callable.
/// </summary>
public const int CapabilityInference = 60;
}
public interface IRewriteStep
{
public enum Stage
{
Unknown = 0,
PreconditionVerification = 1,
Transformation = 2,
PostconditionVerification = 3,
}
public struct Diagnostic
{
/// <summary>
/// Indicates the severity of the diagnostic.
/// Generated diagnostics may be prioritized and filtered according to their severity.
/// </summary>
public DiagnosticSeverity Severity { get; set; }
/// <summary>
/// Diagnostic message to be displayed to the user.
/// </summary>
public string? Message { get; set; }
/// <summary>
/// Absolute path of the file where the code that caused the generation of the diagnostic is located.
/// The source is null if the diagnostic is not caused by a piece of source code.
/// </summary>
public string? Source { get; set; }
/// <summary>
/// The stage during which the diagnostic was generated.
/// The stage is set to Unknown if no stage is specified.
/// </summary>
public Stage Stage { get; set; }
/// <summary>
/// Zero-based range in the source file of the code that caused the generation of the diagnostic.
/// The range is null if the diagnostic is not caused by a piece of source code.
/// </summary>
public Range? Range { get; set; }
/// <summary>
/// Initializes a new diagnostic.
/// If a diagnostic generated by the Q# compiler is given as argument, the values are initialized accordingly.
/// </summary>
public static Diagnostic Create(VS.Diagnostic? d = null, Stage stage = Stage.Unknown) =>
d == null ? default : new Diagnostic
{
Severity = d.Severity switch
{
VS.DiagnosticSeverity.Error => DiagnosticSeverity.Error,
VS.DiagnosticSeverity.Warning => DiagnosticSeverity.Warning,
VS.DiagnosticSeverity.Information => DiagnosticSeverity.Info,
_ => DiagnosticSeverity.Hidden,
},
Message = d.Message,
Source = d.Source,
Stage = stage,
Range = d.Range?.ToQSharp(),
};
}
/// <summary>
/// User facing name identifying the rewrite step used for logging and in diagnostics.
/// </summary>
public string Name { get; }
/// <summary>
/// The priority of the transformation relative to other transformations within the same dll or package.
/// Steps with a larger priority number have higher priority and will be executed first.
/// </summary>
public int Priority { get; }
/// <summary>
/// Dictionary that will be populated by the Q# compiler when the rewrite step is loaded.
/// It contains the assembly constants for the Q# compilation unit on which the rewrite step is acting.
/// </summary>
public IDictionary<string, string?> AssemblyConstants { get; }
/// <summary>
/// Contains diagnostics generated by the rewrite step and intended for display to the user.
/// Depending on the specified build configuration, the generated diagnostics may be queried
/// after all implemented interface methods have been executed.
/// </summary>
public IEnumerable<Diagnostic> GeneratedDiagnostics { get; }
/// <summary>
/// If a precondition verification is implemented, that verification is executed prior to executing anything else.
/// If the verification fails, nothing further is executed and the rewrite step is terminated.
/// </summary>
public bool ImplementsPreconditionVerification { get; }
/// <summary>
/// Indicates whether or not the rewrite step intends to modify the compilation in any form.
/// If a transformation is implemented, then that transformation will be executed only if either
/// no precondition verification is implemented, or the implemented precondition verification succeeds.
/// </summary>
public bool ImplementsTransformation { get; }
/// <summary>
/// A postcondition verification provides the means for diagnostics generation and detailed checks after transformation.
/// The verification is executed only if the precondition verification passes and after applying the implemented transformation (if any).
/// </summary>
public bool ImplementsPostconditionVerification { get; }
/// <summary>
/// Verifies whether a given compilation satisfies the precondition for executing this rewrite step.
/// <see cref="ImplementsPreconditionVerification"/> indicates whether or not this method is implemented.
/// If the precondition verification succeeds, then the invocation of an implemented transformation (if any)
/// with the given compilation should complete without throwing an exception.
/// The precondition verification should never throw an exception,
/// but instead indicate if the precondition is satisfied via the returned value.
/// More detailed information can be provided via logging.
/// </summary>
/// <param name="compilation">Q# compilation for which to verify the precondition.</param>
/// <returns>Whether or not the given compilation satisfies the precondition.</returns>
public bool PreconditionVerification(QsCompilation compilation);
/// <summary>
/// Implements a rewrite step transforming a Q# compilation.
/// <see cref="ImplementsTransformation"/> indicates whether or not this method is implemented.
/// The transformation should complete without throwing an exception
/// if no precondition verification is implemented or the implemented verification passes.
/// </summary>
/// <param name="compilation">Q# compilation that satisfies the implemented precondition, if any.</param>
/// <param name="transformed">Q# compilation after transformation. This value should not be null if the transformation succeeded.</param>
/// <returns>Whether or not the transformation succeeded.</returns>
public bool Transformation(QsCompilation compilation, [NotNullWhen(true)] out QsCompilation? transformed);
/// <summary>
/// Verifies whether a given compilation satisfies the postcondition after executing the implemented transformation (if any).
/// <see cref="ImplementsPostconditionVerification"/> indicates whether or not this method is implemented.
/// The verification may be omitted for performance reasons depending on the build configuration.
/// The postcondition verification should never throw an exception,
/// but instead indicate if the postcondition is satisfied via the returned value.
/// More detailed information can be displayed to the user by generating suitable diagnostics.
/// </summary>
/// <param name="compilation">Q# compilation after performing the implemented transformation.</param>
/// <returns>Whether or not the given compilation satisfies the postcondition of the transformation.</returns>
public bool PostconditionVerification(QsCompilation compilation);
}
}