Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit 8d9982d

Browse files
authored
Formatter Updates Deprecated Specialization Declaration Parameters (#1226)
1 parent 9c34c04 commit 8d9982d

File tree

11 files changed

+136
-20
lines changed

11 files changed

+136
-20
lines changed

src/QsFmt/Formatter.Tests/Examples.fs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,50 @@ let ``Removes For-Loop Parens`` =
245245
}
246246
}"""
247247

248+
[<Example(ExampleKind.Update)>]
249+
let ``Update Specialization Declaration`` =
250+
"""namespace Foo {
251+
operation Bar() : Unit is Ctl + Adj {
252+
body () {
253+
}
254+
adjoint () {
255+
}
256+
controlled (q) {
257+
}
258+
controlled adjoint (q) {
259+
}
260+
}
261+
}""",
262+
263+
"""namespace Foo {
264+
operation Bar() : Unit is Ctl + Adj {
265+
body (...) {
266+
}
267+
adjoint (...) {
268+
}
269+
controlled (q, ...) {
270+
}
271+
controlled adjoint (q, ...) {
272+
}
273+
}
274+
}"""
275+
276+
[<Example(ExampleKind.Update)>]
277+
let ``Update Specialization Declaration No Parens`` =
278+
"""namespace Foo {
279+
operation Bar() : Unit is Ctl + Adj {
280+
body {}
281+
adjoint {}
282+
}
283+
}""",
284+
285+
"""namespace Foo {
286+
operation Bar() : Unit is Ctl + Adj {
287+
body (...) {}
288+
adjoint (...) {}
289+
}
290+
}"""
291+
248292
[<Example(ExampleKind.Update)>]
249293
let ``Allows size as an Identifier`` =
250294
"""namespace Foo {

src/QsFmt/Formatter/Formatter.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ let versionToUpdateRules (version: Version option) =
8484
simpleRule qubitBindingUpdate
8585
simpleRule unitUpdate
8686
simpleRule forParensUpdate
87+
simpleRule specializationUpdate
8788
simpleRule arraySyntaxUpdate
8889
simpleRule booleanOperatorUpdate
8990
]

src/QsFmt/Formatter/ParseTree/Namespace.fs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,18 @@ type SpecializationGeneratorVisitor(tokens) =
3333
toBuiltIn context.intrinsic context.semicolon
3434

3535
override _.VisitProvidedGenerator context =
36+
let tospecializationParameters tokens (context: QSharpParser.SpecializationParameterTupleContext) =
37+
let parameters = context._parameters |> Seq.map (Node.toUnknown tokens)
38+
let commas = context._commas |> Seq.map (Node.toTerminal tokens)
39+
40+
{
41+
OpenParen = context.openParen |> Node.toTerminal tokens
42+
Items = Node.tupleItems parameters commas
43+
CloseParen = context.closeParen |> Node.toTerminal tokens
44+
}
45+
3646
Provided(
37-
parameters = (Option.ofObj context.provided.parameters |> Option.map (Node.toUnknown tokens)),
47+
parameters = (Option.ofObj context.provided.parameters |> Option.map (tospecializationParameters tokens)),
3848
statements =
3949
{
4050
OpenBrace = context.provided.block.openBrace |> Node.toTerminal tokens

src/QsFmt/Formatter/Rules.fs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,61 @@ let forParensUpdate =
160160
}
161161
}
162162

163+
/// <summary>
164+
/// Make sure that a <see cref="SequenceItem"/> contains a comma.
165+
/// </summary>
166+
let ensureComma (item: 'a SequenceItem) =
167+
match item.Comma with
168+
| None -> { Item = item.Item; Comma = { Prefix = []; Text = "," } |> Some }
169+
| Some _ -> item
170+
171+
/// <summary>
172+
/// Prepends the <paramref name="parameters"/> with an ellipsis <see cref="Terminal"/> item if it does not already contain one.
173+
/// </summary>
174+
let ensureEllipsis (parameters: Terminal Tuple) =
175+
let ellipsis nspace =
176+
{ Prefix = [ spaces nspace ]; Text = "..." }
177+
178+
let ellipsisItem nspace =
179+
{ Item = ellipsis nspace |> Some; Comma = None }
180+
181+
{ parameters with
182+
Items =
183+
match parameters.Items with
184+
// Replace, e.g., `body ()` with `body (...)`
185+
| [] -> [ ellipsisItem 0 ]
186+
// Replace, e.g., `controlled (q)` with `controlled (q, ...)`
187+
| [ x ] ->
188+
match Option.get(x.Item).Text with
189+
| "..." -> [ x ]
190+
| _ -> [ ensureComma x; ellipsisItem 1 ]
191+
| _ -> parameters.Items
192+
}
193+
194+
let specializationUpdate =
195+
{ new Rewriter<_>() with
196+
override _.SpecializationGenerator((), generator) =
197+
let emptyTuple =
198+
{
199+
OpenParen = { Prefix = [ spaces 1 ]; Text = "(" }
200+
Items = []
201+
CloseParen = { Prefix = []; Text = ")" }
202+
}
203+
204+
match generator with
205+
| Provided (parameters, statements) ->
206+
Provided(
207+
parameters =
208+
(match parameters with
209+
// Replace, e.g., `body` with `body (...)`
210+
| None -> ensureEllipsis emptyTuple |> Some
211+
// Replace, e.g., `body ()` with `body (...)`
212+
| Some par -> ensureEllipsis par |> Some),
213+
statements = statements
214+
)
215+
| _ -> generator
216+
}
217+
163218
let arraySyntaxUpdate =
164219

165220
let getBuiltInDefault builtIn =

src/QsFmt/Formatter/Rules.fsi

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ val unitUpdate : unit Rewriter
2929
/// Updates for-loops to remove deprecated parentheses.
3030
val forParensUpdate: unit Rewriter
3131

32+
/// Updates deprecated specialization declarations to add a `...` parameter.
33+
val specializationUpdate: unit Rewriter
34+
3235
/// Updates the `new <Type>[n]` array syntax to the new `[val, size = n]` array syntax.
3336
val arraySyntaxUpdate: unit Rewriter
3437

3538
/// Provides warnings for deprecated array syntax still in the syntax tree.
3639
val checkArraySyntax: string -> Document -> string list
3740

38-
/// Replaces `&&`, `||`, and `!` with `and`, `or`, and `not`, respectively.
41+
/// Replaces deprecated use of boolean operators `&&`, `||`, and `!` with their keyword
42+
/// equivalence `and`, `or`, and `not` respectively.
3943
val booleanOperatorUpdate : unit Rewriter

src/QsFmt/Formatter/SyntaxTree/Namespace.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type TypeParameterBinding =
1414

1515
type SpecializationGenerator =
1616
| BuiltIn of name: Terminal * semicolon: Terminal
17-
| Provided of parameters: Terminal option * statements: Statement Block
17+
| Provided of parameters: Terminal Tuple option * statements: Statement Block
1818

1919
type Specialization = { Names: Terminal list; Generator: SpecializationGenerator }
2020

src/QsFmt/Formatter/SyntaxTree/Namespace.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type internal SpecializationGenerator =
3232
| BuiltIn of name: Terminal * semicolon: Terminal
3333

3434
/// A provided specialization.
35-
| Provided of parameters: Terminal option * statements: Statement Block
35+
| Provided of parameters: Terminal Tuple option * statements: Statement Block
3636

3737
/// A specialization.
3838
type internal Specialization =

src/QsFmt/Formatter/SyntaxTree/Reducer.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ type internal 'result Reducer() as reducer =
152152
match generator with
153153
| BuiltIn (name, semicolon) -> [ reducer.Terminal name; reducer.Terminal semicolon ] |> reduce
154154
| Provided (parameters, statements) ->
155-
(parameters |> Option.map reducer.Terminal |> Option.toList)
155+
(parameters |> Option.map (curry reducer.Tuple reducer.Terminal) |> Option.toList)
156156
@ [ reducer.Block(reducer.Statement, statements) ]
157157
|> reduce
158158

src/QsFmt/Formatter/SyntaxTree/Rewriter.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ type 'context Rewriter() =
151151
BuiltIn(name = rewriter.Terminal(context, name), semicolon = rewriter.Terminal(context, semicolon))
152152
| Provided (parameters, statements) ->
153153
Provided(
154-
parameters = (parameters |> Option.map (curry rewriter.Terminal context)),
154+
parameters = (parameters |> Option.map (curry3 rewriter.Tuple context rewriter.Terminal)),
155155
statements = rewriter.Block(context, rewriter.Statement, statements)
156156
)
157157

src/QsFmt/Parser/QSharpParser.g4

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ specializationGenerator
109109

110110
providedSpecialization : parameters=specializationParameterTuple? block=scope;
111111

112-
specializationParameterTuple : '(' (specializationParameter (',' specializationParameter)*)? ')';
112+
specializationParameterTuple
113+
: openParen='(' (parameters+=specializationParameter (commas+=',' parameters+=specializationParameter)*)? closeParen=')';
113114

114115
specializationParameter
115116
: Identifier

0 commit comments

Comments
 (0)