Skip to content

Commit 176d669

Browse files
authored
issue# 4591 - Resx files are not working for fsharp project (#4595)
1 parent 92e6d6a commit 176d669

File tree

4 files changed

+112
-25
lines changed

4 files changed

+112
-25
lines changed

build-everything.proj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161

6262
<!-- +++++++++++++++++++++++ Project selection for testing +++++++++++++++++++++++++++++++ -->
6363

64-
<ItemGroup Condition="'$(TEST_NET40_COREUNIT_SUITE)'=='1'" >
64+
<ItemGroup Condition="'$(TEST_NET40_COMPILERUNIT_SUITE)'=='1'" >
6565
<ProjectsWithNet40 Include="tests/FSharp.Core.UnitTests/FSharp.Core.Unittests.fsproj"/>
6666
<ProjectsWithNet40 Include="tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj"/>
6767
</ItemGroup>

build.cmd

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ echo SNEXE32: %SNEXE32%
841841
echo SNEXE64: %SNEXE64%
842842
echo
843843

844-
if "%TEST_NET40_COMPILERUNIT_SUITE%" == "0" if "%TEST_FCS%" == "0" if "%TEST_NET40_COREUNIT_SUITE%" == "0" if "%TEST_CORECLR_COREUNIT_SUITE%" == "0" if "%TEST_VS_IDEUNIT_SUITE%" == "0" if "%TEST_NET40_FSHARP_SUITE%" == "0" if "%TEST_NET40_FSHARPQA_SUITE%" == "0" goto :success
844+
if "%TEST_NET40_COMPILERUNIT_SUITE%" == "0" if "%TEST_FCS%" == "0" if "%TEST_NET40_COREUNIT_SUITE%" == "0" if "TEST_CORECLR_FSHARP_SUITE" == "0" if "%TEST_CORECLR_COREUNIT_SUITE%" == "0" if "%TEST_VS_IDEUNIT_SUITE%" == "0" if "%TEST_NET40_FSHARP_SUITE%" == "0" if "%TEST_NET40_FSHARPQA_SUITE%" == "0" goto :success
845845

846846
if "%no_test%" == "1" goto :success
847847

@@ -996,38 +996,49 @@ if "%TEST_NET40_COMPILERUNIT_SUITE%" == "1" (
996996
echo -----------------------------------------------------------------
997997
goto :failure
998998
)
999-
)
1000-
1001-
REM ---------------- net40-coreunit -----------------------
1002-
1003-
if "%TEST_NET40_COREUNIT_SUITE%" == "1" (
1004999

10051000
set OUTPUTARG=
10061001
set ERRORARG=
10071002
set OUTPUTFILE=
10081003
set ERRORFILE=
1009-
set XMLFILE=!RESULTSDIR!\test-net40-coreunit-results.xml
1004+
set XMLFILE=!RESULTSDIR!\test-net40-buildunit-results.xml
10101005
if "%CI%" == "1" (
1011-
set ERRORFILE=!RESULTSDIR!\test-net40-coreunit-errors.log
1012-
set OUTPUTFILE=!RESULTSDIR!\test-net40-coreunit-output.log
1006+
set OUTPUTFILE=!RESULTSDIR!\test-net40-buildunit-output.log
1007+
set ERRORFILE=!RESULTSDIR!\test-net40-buildunit-errors.log
10131008
set ERRORARG=--err:"!ERRORFILE!"
10141009
set OUTPUTARG=--output:"!OUTPUTFILE!"
10151010
)
1016-
1011+
set ERRORFILE=!RESULTSDIR!\test-net40-buildunit-errors.log
10171012
echo "!NUNIT3_CONSOLE!" --verbose --framework:V4.0 --result:"!XMLFILE!;format=nunit3" !OUTPUTARG! !ERRORARG! --work:"!FSCBINPATH!" "!FSCBINPATH!\FSharp.Build.UnitTests.dll" !WHERE_ARG_NUNIT!
10181013
"!NUNIT3_CONSOLE!" --verbose --framework:V4.0 --result:"!XMLFILE!;format=nunit3" !OUTPUTARG! !ERRORARG! --work:"!FSCBINPATH!" "!FSCBINPATH!\FSharp.Build.UnitTests.dll" !WHERE_ARG_NUNIT!
10191014

1020-
10211015
if errorlevel 1 (
10221016
echo -----------------------------------------------------------------
10231017
type "!OUTPUTFILE!"
10241018
echo -----------------------------------------------------------------
10251019
type "!ERRORFILE!"
10261020
echo -----------------------------------------------------------------
1027-
echo Error: Running tests net40-coreunit failed, see logs above -- FAILED
1021+
echo Error: Running tests net40-compilernit failed, see logs above -- FAILED
10281022
echo -----------------------------------------------------------------
10291023
goto :failure
10301024
)
1025+
)
1026+
1027+
REM ---------------- net40-coreunit -----------------------
1028+
1029+
if "%TEST_NET40_COREUNIT_SUITE%" == "1" (
1030+
1031+
set OUTPUTARG=
1032+
set ERRORARG=
1033+
set OUTPUTFILE=
1034+
set ERRORFILE=
1035+
set XMLFILE=!RESULTSDIR!\test-net40-coreunit-results.xml
1036+
if "%CI%" == "1" (
1037+
set ERRORFILE=!RESULTSDIR!\test-net40-coreunit-errors.log
1038+
set OUTPUTFILE=!RESULTSDIR!\test-net40-coreunit-output.log
1039+
set ERRORARG=--err:"!ERRORFILE!"
1040+
set OUTPUTARG=--output:"!OUTPUTFILE!"
1041+
)
10311042

10321043
echo "!NUNIT3_CONSOLE!" --verbose --framework:V4.0 --result:"!XMLFILE!;format=nunit3" !OUTPUTARG! !ERRORARG! --work:"!FSCBINPATH!" "!FSCBINPATH!\FSharp.Core.UnitTests.dll" !WHERE_ARG_NUNIT!
10331044
"!NUNIT3_CONSOLE!" --verbose --framework:V4.0 --result:"!XMLFILE!;format=nunit3" !OUTPUTARG! !ERRORARG! --work:"!FSCBINPATH!" "!FSCBINPATH!\FSharp.Core.UnitTests.dll" !WHERE_ARG_NUNIT!

src/fsharp/FSharp.Build/WriteCodeFragment.fs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type WriteCodeFragment() =
3333
| _ -> sb.Append(c)) (StringBuilder().Append("\""))
3434
sb.Append("\"").ToString()
3535

36-
static member GenerateAttribute (item:ITaskItem) =
36+
static member GenerateAttribute (item:ITaskItem, language:string) =
3737
let attributeName = item.ItemSpec
3838
let args =
3939
// mimicking the behavior from https://github.com/Microsoft/msbuild/blob/70ce7e9ccb891b63f0859f1f7f0b955693ed3742/src/Tasks/WriteCodeFragment.cs#L355-L415
@@ -73,7 +73,11 @@ type WriteCodeFragment() =
7373
| (0, _) -> combinedNamedParameters // only named arguments
7474
| (_, 0) -> combinedOrderedParameters // only positional arguments
7575
| (_, _) -> combinedOrderedParameters + ", " + combinedNamedParameters // both positional and named arguments
76-
sprintf "[<assembly: %s(%s)>]" attributeName args
76+
match language.ToLowerInvariant() with
77+
| "f#" -> sprintf "[<assembly: %s(%s)>]" attributeName args
78+
| "c#" -> sprintf "[assembly: %s(%s)]" attributeName args
79+
| "vb" -> sprintf "<Assembly: %s(%s)>" attributeName args
80+
| _ -> failwith "Language name must be one of F#, C# or VB"
7781

7882
// adding this property to maintain API equivalence with the MSBuild task
7983
member this.Language
@@ -93,27 +97,32 @@ type WriteCodeFragment() =
9397
with get() = _outputFile
9498
and set(value) = _outputFile <- value
9599

100+
96101
interface ITask with
97102
member this.BuildEngine
98103
with get() = _buildEngine
99104
and set(value) = _buildEngine <- value
105+
100106
member this.HostObject
101107
with get() = _hostObject
102108
and set(value) = _hostObject <- value
109+
103110
member this.Execute() =
104111
try
105112
if isNull _outputFile && isNull _outputDirectory then failwith "Output location must be specified"
106-
if _language.ToLowerInvariant() <> "f#" then failwith "Language name must be F#"
107-
let boilerplate = @"// <auto-generated>
113+
let boilerplate =
114+
match _language.ToLowerInvariant() with
115+
| "f#" -> "// <auto-generated>\n// Generated by the FSharp WriteCodeFragment class.\n// </auto-generated>\nnamespace FSharp\n\nopen System\nopen System.Reflection\n"
116+
| "c#" -> "// <auto-generated>\n// Generated by the FSharp WriteCodeFragment class.\n// </auto-generated>\n\nusing System;\nusing System.Reflection;"
117+
| "vb" -> "'------------------------------------------------------------------------------\n' <auto-generated>\n' Generated by the FSharp WriteCodeFragment class.\n' </auto-generated>\n'------------------------------------------------------------------------------\n\nOption Strict Off\nOption Explicit On\n\nImports System\nImports System.Reflection"
118+
| _ -> failwith "Language name must be one of F#, C# or VB"
108119

109-
namespace FSharp
110-
111-
open System
112-
open System.Reflection"
113120
let sb = StringBuilder().AppendLine(boilerplate).AppendLine()
114-
let code = Array.fold (fun (sb:StringBuilder) (item:ITaskItem) -> sb.AppendLine(WriteCodeFragment.GenerateAttribute item)) sb _assemblyAttributes
115-
code.AppendLine().AppendLine("do()") |> ignore
121+
let code = Array.fold (fun (sb:StringBuilder) (item:ITaskItem) -> sb.AppendLine(WriteCodeFragment.GenerateAttribute (item, _language.ToLowerInvariant()))) sb _assemblyAttributes
122+
123+
if _language.ToLowerInvariant() = "f#" then code.AppendLine("do()") |> ignore
116124
let fileName = _outputFile.ItemSpec
125+
117126
let outputFileItem =
118127
if not (isNull _outputFile) && not (isNull _outputDirectory) && not (Path.IsPathRooted(fileName)) then
119128
TaskItem(Path.Combine(_outputDirectory.ItemSpec, fileName)) :> ITaskItem
@@ -122,12 +131,14 @@ open System.Reflection"
122131
TaskItem(tempFile) :> ITaskItem
123132
else
124133
_outputFile
134+
125135
let codeText = code.ToString()
126136
let alreadyExists = (try File.Exists fileName && File.ReadAllText(fileName) = codeText with _ -> false)
127137
if not alreadyExists then
128138
File.WriteAllText(fileName, codeText)
129139
_outputFile <- outputFileItem
130140
true
141+
131142
with e ->
132143
printf "Error writing code fragment: %s" (e.ToString())
133144
false

tests/FSharp.Build.UnitTests/WriteCodeFragmentTests.fs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ open Microsoft.FSharp.Build
88
open NUnit.Framework
99

1010
[<TestFixture>]
11-
type WriteCodeFragmentTests()=
11+
type WriteCodeFragmentFSharpTests() =
1212

1313
let verifyAttribute (attributeName:string) (parameters:(string*string) list) (expectedAttributeText:string) =
1414
let taskItem = TaskItem(attributeName)
1515
parameters |> List.iter (fun (key, value) -> taskItem.SetMetadata(key, value))
16-
let actualAttributeText = WriteCodeFragment.GenerateAttribute (taskItem :> ITaskItem)
16+
let actualAttributeText = WriteCodeFragment.GenerateAttribute (taskItem :> ITaskItem, "f#")
1717
let fullExpectedAttributeText = "[<assembly: " + expectedAttributeText + ">]"
1818
Assert.AreEqual(fullExpectedAttributeText, actualAttributeText)
1919

@@ -37,3 +37,68 @@ type WriteCodeFragmentTests()=
3737
member this.``Escaped string parameters``() =
3838
verifyAttribute "SomeAttribute" [("_Parameter1", "\"uno\"")] "SomeAttribute(\"\\\"uno\\\"\")"
3939
// this should look like: SomeAttribute("\"uno\"")
40+
41+
42+
[<TestFixture>]
43+
type WriteCodeFragmentCSharpTests() =
44+
45+
let verifyAttribute (attributeName:string) (parameters:(string*string) list) (expectedAttributeText:string) =
46+
let taskItem = TaskItem(attributeName)
47+
parameters |> List.iter (fun (key, value) -> taskItem.SetMetadata(key, value))
48+
let actualAttributeText = WriteCodeFragment.GenerateAttribute (taskItem :> ITaskItem, "c#")
49+
let fullExpectedAttributeText = "[assembly: " + expectedAttributeText + "]"
50+
Assert.AreEqual(fullExpectedAttributeText, actualAttributeText)
51+
52+
[<Test>]
53+
member this.``No parameters``() =
54+
verifyAttribute "SomeAttribute" [] "SomeAttribute()"
55+
56+
[<Test>]
57+
member this.``Skipped and out of order positional parameters``() =
58+
verifyAttribute "SomeAttribute" [("_Parameter3", "3"); ("_Parameter5", "5"); ("_Parameter2", "2")] "SomeAttribute(null, \"2\", \"3\", null, \"5\")"
59+
60+
[<Test>]
61+
member this.``Named parameters``() =
62+
verifyAttribute "SomeAttribute" [("One", "1"); ("Two", "2")] "SomeAttribute(One = \"1\", Two = \"2\")"
63+
64+
[<Test>]
65+
member this.``Named and positional parameters``() =
66+
verifyAttribute "SomeAttribute" [("One", "1"); ("_Parameter2", "2.2"); ("Two", "2")] "SomeAttribute(null, \"2.2\", One = \"1\", Two = \"2\")"
67+
68+
[<Test>]
69+
member this.``Escaped string parameters``() =
70+
verifyAttribute "SomeAttribute" [("_Parameter1", "\"uno\"")] "SomeAttribute(\"\\\"uno\\\"\")"
71+
// this should look like: SomeAttribute("\"uno\"")
72+
73+
74+
[<TestFixture>]
75+
type WriteCodeFragmentVisualBasicTests() =
76+
77+
let verifyAttribute (attributeName:string) (parameters:(string*string) list) (expectedAttributeText:string) =
78+
let taskItem = TaskItem(attributeName)
79+
parameters |> List.iter (fun (key, value) -> taskItem.SetMetadata(key, value))
80+
let actualAttributeText = WriteCodeFragment.GenerateAttribute (taskItem :> ITaskItem, "vb")
81+
let fullExpectedAttributeText = "<Assembly: " + expectedAttributeText + ">"
82+
Assert.AreEqual(fullExpectedAttributeText, actualAttributeText)
83+
84+
[<Test>]
85+
member this.``No parameters``() =
86+
verifyAttribute "SomeAttribute" [] "SomeAttribute()"
87+
88+
[<Test>]
89+
member this.``Skipped and out of order positional parameters``() =
90+
verifyAttribute "SomeAttribute" [("_Parameter3", "3"); ("_Parameter5", "5"); ("_Parameter2", "2")] "SomeAttribute(null, \"2\", \"3\", null, \"5\")"
91+
92+
[<Test>]
93+
member this.``Named parameters``() =
94+
verifyAttribute "SomeAttribute" [("One", "1"); ("Two", "2")] "SomeAttribute(One = \"1\", Two = \"2\")"
95+
96+
[<Test>]
97+
member this.``Named and positional parameters``() =
98+
verifyAttribute "SomeAttribute" [("One", "1"); ("_Parameter2", "2.2"); ("Two", "2")] "SomeAttribute(null, \"2.2\", One = \"1\", Two = \"2\")"
99+
100+
[<Test>]
101+
member this.``Escaped string parameters``() =
102+
verifyAttribute "SomeAttribute" [("_Parameter1", "\"uno\"")] "SomeAttribute(\"\\\"uno\\\"\")"
103+
// this should look like: SomeAttribute("\"uno\"")
104+

0 commit comments

Comments
 (0)