Skip to content

Commit ee0fdd6

Browse files
CopilotT-Gro
andcommitted
Updated WriteCodeFragment to use _IsLiteral suffix
Co-authored-by: T-Gro <[email protected]>
1 parent b59a35d commit ee0fdd6

File tree

2 files changed

+94
-57
lines changed

2 files changed

+94
-57
lines changed

src/FSharp.Build/WriteCodeFragment.fs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -90,33 +90,43 @@ type WriteCodeFragment() as this =
9090
let combinedOrderedParameters = String.Join(", ", orderedParametersArray)
9191

9292
let combinedNamedParameters =
93+
// Define "_IsLiteral" suffix to match MSBuild behavior
94+
let isLiteralSuffix = "_IsLiteral"
95+
9396
// Process named parameters to handle IsLiteral suffix
94-
let processedNamedParameters =
97+
let processedNamedParameters =
98+
// First identify all parameters with _IsLiteral suffix
99+
let isLiteralParams =
100+
namedParameters
101+
|> List.filter (fun (key, _) -> key.EndsWith(isLiteralSuffix))
102+
|> List.map (fun (key, value) ->
103+
// Extract the base parameter name by removing the suffix
104+
let baseKey = key.Substring(0, key.Length - isLiteralSuffix.Length)
105+
(baseKey, value))
106+
|> List.filter (fun (_, value) -> value = "true" || value = "True")
107+
|> Set.ofList
108+
|> Set.map fst
109+
110+
// Process all parameters, handling literals appropriately
95111
namedParameters
96112
|> List.fold (fun (acc, processedKeys) (key, value) ->
97-
if key.EndsWith("IsLiteral") then
98-
// Skip IsLiteral metadata entries
113+
// Skip _IsLiteral metadata entries
114+
if key.EndsWith(isLiteralSuffix) then
99115
(acc, Set.add key processedKeys)
100116
else
101-
let baseKey = key
102-
let isLiteralKey = key + "IsLiteral"
103-
let isLiteral =
104-
namedParameters
105-
|> List.exists (fun (k, v) ->
106-
k = isLiteralKey &&
107-
(v = "true" || v = "True"))
117+
// Check if this parameter should be treated as a literal
118+
let isLiteral = Set.contains key isLiteralParams
108119

109120
// If this is a parameter with IsLiteral=true, use the value without escaping
110121
if isLiteral then
111-
// Use the value as-is without quotes
112-
let unquotedValue =
113-
if value.StartsWith("\"") && value.EndsWith("\"") && value.Length >= 2 then
114-
value.Substring(1, value.Length - 2)
115-
else
116-
value
117-
((baseKey, unquotedValue) :: acc, Set.add isLiteralKey processedKeys)
122+
let literalValue =
123+
// For literals, preserve the value as-is (without quotes)
124+
// If it's already quoted, use as is (will be handled by CodeDOM)
125+
value
126+
((key, literalValue) :: acc, processedKeys)
118127
else
119-
((baseKey, value) :: acc, processedKeys)
128+
// Regular parameter, keep as is (with quotes)
129+
((key, value) :: acc, processedKeys)
120130
) ([], Set.empty)
121131
|> fst
122132
|> List.rev

tests/FSharp.Build.UnitTests/WriteCodeFragmentTests.fs

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -37,29 +37,38 @@ type WriteCodeFragmentFSharpTests() =
3737
verifyAttribute "SomeAttribute" [("_Parameter1", "\"uno\"")] "SomeAttribute(\"\\\"uno\\\"\")"
3838

3939
[<Fact>]
40-
member _.``Named parameters with IsLiteral suffix``() =
41-
verifyAttribute "SomeAttribute" [("Bool", "true"); ("BoolIsLiteral", "true")] "SomeAttribute(Bool = true)"
40+
member _.``Named parameters with _IsLiteral suffix``() =
41+
verifyAttribute "SomeAttribute" [("Bool", "true"); ("Bool_IsLiteral", "true")] "SomeAttribute(Bool = true)"
4242

4343
[<Fact>]
44-
member _.``Multiple named parameters with IsLiteral suffix``() =
44+
member _.``Multiple named parameters with _IsLiteral suffix``() =
4545
verifyAttribute "SomeAttribute"
4646
[
4747
("Number", "42");
48-
("NumberIsLiteral", "true");
48+
("Number_IsLiteral", "true");
4949
("Bool", "false");
50-
("BoolIsLiteral", "true")
50+
("Bool_IsLiteral", "true")
5151
]
5252
"SomeAttribute(Number = 42, Bool = false)"
5353

5454
[<Fact>]
55-
member _.``Mixed named parameters with and without IsLiteral suffix``() =
55+
member _.``Mixed named parameters with and without _IsLiteral suffix``() =
5656
verifyAttribute "SomeAttribute"
5757
[
5858
("Number", "42");
59-
("NumberIsLiteral", "true");
59+
("Number_IsLiteral", "true");
6060
("Text", "hello")
6161
]
6262
"SomeAttribute(Number = 42, Text = \"hello\")"
63+
64+
[<Fact>]
65+
member _.``Enum _IsLiteral suffix``() =
66+
verifyAttribute "SomeAttribute"
67+
[
68+
("EnumValue", "System.StringComparison.OrdinalIgnoreCase");
69+
("EnumValue_IsLiteral", "true")
70+
]
71+
"SomeAttribute(EnumValue = System.StringComparison.OrdinalIgnoreCase)"
6372

6473
type WriteCodeFragmentCSharpTests() =
6574

@@ -70,31 +79,6 @@ type WriteCodeFragmentCSharpTests() =
7079
let fullExpectedAttributeText = "[assembly: " + expectedAttributeText + "]"
7180
Assert.Equal(fullExpectedAttributeText, actualAttributeText)
7281

73-
[<Fact>]
74-
member _.``Named parameters with IsLiteral suffix``() =
75-
verifyAttribute "SomeAttribute" [("Bool", "true"); ("BoolIsLiteral", "true")] "SomeAttribute(Bool = true)"
76-
77-
[<Fact>]
78-
member _.``Multiple named parameters with IsLiteral suffix``() =
79-
verifyAttribute "SomeAttribute"
80-
[
81-
("Number", "42");
82-
("NumberIsLiteral", "true");
83-
("Bool", "false");
84-
("BoolIsLiteral", "true")
85-
]
86-
"SomeAttribute(Number = 42, Bool = false)"
87-
88-
[<Fact>]
89-
member _.``Mixed named parameters with and without IsLiteral suffix``() =
90-
verifyAttribute "SomeAttribute"
91-
[
92-
("Number", "42");
93-
("NumberIsLiteral", "true");
94-
("Text", "hello")
95-
]
96-
"SomeAttribute(Number = 42, Text = \"hello\")"
97-
9882
[<Fact>]
9983
member _.``No parameters``() =
10084
verifyAttribute "SomeAttribute" [] "SomeAttribute()"
@@ -115,6 +99,40 @@ type WriteCodeFragmentCSharpTests() =
11599
member _.``Escaped string parameters``() =
116100
verifyAttribute "SomeAttribute" [("_Parameter1", "\"uno\"")] "SomeAttribute(\"\\\"uno\\\"\")"
117101
// this should look like: SomeAttribute("\"uno\"")
102+
103+
[<Fact>]
104+
member _.``Named parameters with _IsLiteral suffix``() =
105+
verifyAttribute "SomeAttribute" [("Bool", "true"); ("Bool_IsLiteral", "true")] "SomeAttribute(Bool = true)"
106+
107+
[<Fact>]
108+
member _.``Multiple named parameters with _IsLiteral suffix``() =
109+
verifyAttribute "SomeAttribute"
110+
[
111+
("Number", "42");
112+
("Number_IsLiteral", "true");
113+
("Bool", "false");
114+
("Bool_IsLiteral", "true")
115+
]
116+
"SomeAttribute(Number = 42, Bool = false)"
117+
118+
[<Fact>]
119+
member _.``Mixed named parameters with and without _IsLiteral suffix``() =
120+
verifyAttribute "SomeAttribute"
121+
[
122+
("Number", "42");
123+
("Number_IsLiteral", "true");
124+
("Text", "hello")
125+
]
126+
"SomeAttribute(Number = 42, Text = \"hello\")"
127+
128+
[<Fact>]
129+
member _.``Enum _IsLiteral suffix``() =
130+
verifyAttribute "SomeAttribute"
131+
[
132+
("EnumValue", "System.StringComparison.OrdinalIgnoreCase");
133+
("EnumValue_IsLiteral", "true")
134+
]
135+
"SomeAttribute(EnumValue = System.StringComparison.OrdinalIgnoreCase)"
118136

119137

120138
type WriteCodeFragmentVisualBasicTests() =
@@ -148,27 +166,36 @@ type WriteCodeFragmentVisualBasicTests() =
148166
// this should look like: SomeAttribute("\"uno\"")
149167

150168
[<Fact>]
151-
member _.``Named parameters with IsLiteral suffix``() =
152-
verifyAttribute "SomeAttribute" [("Bool", "true"); ("BoolIsLiteral", "true")] "SomeAttribute(Bool = true)"
169+
member _.``Named parameters with _IsLiteral suffix``() =
170+
verifyAttribute "SomeAttribute" [("Bool", "true"); ("Bool_IsLiteral", "true")] "SomeAttribute(Bool = true)"
153171

154172
[<Fact>]
155-
member _.``Multiple named parameters with IsLiteral suffix``() =
173+
member _.``Multiple named parameters with _IsLiteral suffix``() =
156174
verifyAttribute "SomeAttribute"
157175
[
158176
("Number", "42");
159-
("NumberIsLiteral", "true");
177+
("Number_IsLiteral", "true");
160178
("Bool", "false");
161-
("BoolIsLiteral", "true")
179+
("Bool_IsLiteral", "true")
162180
]
163181
"SomeAttribute(Number = 42, Bool = false)"
164182

165183
[<Fact>]
166-
member _.``Mixed named parameters with and without IsLiteral suffix``() =
184+
member _.``Mixed named parameters with and without _IsLiteral suffix``() =
167185
verifyAttribute "SomeAttribute"
168186
[
169187
("Number", "42");
170-
("NumberIsLiteral", "true");
188+
("Number_IsLiteral", "true");
171189
("Text", "hello")
172190
]
173191
"SomeAttribute(Number = 42, Text = \"hello\")"
192+
193+
[<Fact>]
194+
member _.``Enum _IsLiteral suffix``() =
195+
verifyAttribute "SomeAttribute"
196+
[
197+
("EnumValue", "System.StringComparison.OrdinalIgnoreCase");
198+
("EnumValue_IsLiteral", "true")
199+
]
200+
"SomeAttribute(EnumValue = System.StringComparison.OrdinalIgnoreCase)"
174201

0 commit comments

Comments
 (0)