Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit635e2de

Browse files
committed
Merge branch 'master' into fsharp4
2 parentse10b8d0 +7e2a0db commit635e2de

File tree

5 files changed

+144
-21
lines changed

5 files changed

+144
-21
lines changed

‎vsintegration/src/unittests/TestLib.Utils.fs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ module Asserts =
4747
| Some(msg)-> Assert.Fail(msg)
4848
| None->()
4949

50+
letAssertBuildSuccessful(result:Microsoft.VisualStudio.FSharp.ProjectSystem.BuildResult)=
51+
Assert.IsTrue(result.IsSuccessful,"Expected build to succeed")
52+
5053
moduleUIStuff=
5154
letSetupSynchronizationContext()=
5255
Microsoft.VisualStudio.FSharp.LanguageService.UIThread.InitUnitTestingMode()

‎vsintegration/src/unittests/Tests.ProjectSystem.RoundTrip.fs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ type RoundTrip() =
100100
CompileItem@"A\qux.fs"]
101101
this.``FsprojRoundtrip.PositiveTest``(MSBuildItems origItems, MSBuildItems expectedItems)
102102

103+
[<Test>]
104+
memberpublicthis.``FsprojRoundTrip.Regression.FoldersWithSameName``()=
105+
letitems= MSBuildItems[CompileItem@"First\Second\bar.fs"
106+
CompileItem@"Second\qux.fs"]
107+
this.``FsprojRoundtrip.PositiveTest``(items, items)
108+
109+
[<Test>]
110+
memberpublicthis.``FsprojRoundTrip.Regression.FoldersWithSameName2``()=
111+
letitems= MSBuildItems[CompileItem@"First\First\bar.fs"]
112+
this.``FsprojRoundtrip.PositiveTest``(items, items)
113+
103114
memberthis.``Fsproj.NegativeTest``(items:MSBuildItems)=
104115
DoWithTempFile"Test.fsproj"(fun file->
105116
File.AppendAllText(file, TheTests.SimpleFsprojText([],[], items.ToString()))

‎vsintegration/src/unittests/Tests.ProjectSystem.UpToDate.fs‎

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type UpToDate() =
5959
File.AppendAllText(embedPath,"some embedded resource")
6060

6161
Assert.IsFalse(config.IsUpToDate(logger,true))
62-
project.Build(configNameDebug, output,"Build")|>ignore
62+
project.Build(configNameDebug, output,"Build")|>AssertBuildSuccessful
6363
Assert.IsTrue(config.IsUpToDate(logger,true))
6464

6565
// None items should not affect up-to-date (unless captured by well-known items, e.g. App.config)
@@ -111,7 +111,7 @@ type UpToDate() =
111111

112112
project.SetConfiguration(config.ConfigCanonicalName);
113113
Assert.IsFalse(config.IsUpToDate(logger,true))
114-
project.Build(configNameDebug, output,"Build")|>ignore
114+
project.Build(configNameDebug, output,"Build")|>AssertBuildSuccessful
115115
Assert.IsTrue(config.IsUpToDate(logger,true))
116116

117117
for pathin[verPath; keyPath]do
@@ -146,7 +146,7 @@ type UpToDate() =
146146
File.AppendAllText(absFilePath,"printfn\"hello\"")
147147

148148
Assert.IsFalse(config.IsUpToDate(logger,true))
149-
project.Build(configNameDebug, output,"Build")|>ignore
149+
project.Build(configNameDebug, output,"Build")|>AssertBuildSuccessful
150150
Assert.IsTrue(config.IsUpToDate(logger,true))
151151

152152
// touch proj file
@@ -177,7 +177,7 @@ type UpToDate() =
177177
letconfig1= project1.ConfigProvider.GetProjectConfiguration(configNameDebug)
178178

179179
Assert.IsFalse(config1.IsUpToDate(logger,true))
180-
project1.Build(configNameDebug, output,"Build")|>ignore
180+
project1.Build(configNameDebug, output,"Build")|>AssertBuildSuccessful
181181
Assert.IsTrue(config1.IsUpToDate(logger,true))
182182

183183
letoutput1= Path.Combine(project1.ProjectFolder,"bin\\debug", project1.OutputFileName)
@@ -196,7 +196,7 @@ type UpToDate() =
196196
letstartTime= DateTime.Now
197197

198198
Assert.IsFalse(config2.IsUpToDate(logger,true))
199-
project2.Build(configNameDebug, output,"Build")|>ignore
199+
project2.Build(configNameDebug, output,"Build")|>AssertBuildSuccessful
200200
Assert.IsTrue(config2.IsUpToDate(logger,true))
201201

202202
// reference is updated
@@ -214,6 +214,9 @@ type UpToDate() =
214214
[<Test>]
215215
memberpublicthis.OutputFiles()=
216216
this.MakeProjectAndDo(["file1.fs"],[],@"
217+
<ItemGroup>
218+
<None Include=""App.config"" />
219+
</ItemGroup>
217220
<PropertyGroup>
218221
<DocumentationFile>bin\Debug\Test.XML</DocumentationFile>
219222
<DebugSymbols>true</DebugSymbols>
@@ -224,22 +227,25 @@ type UpToDate() =
224227
letoutput= VsMocks.vsOutputWindowPane(ref[])
225228
letlogger= OutputWindowLogger.CreateUpToDateCheckLogger(output)
226229
letsourcePath= Path.Combine(project.ProjectFolder,"file1.fs")
230+
letappConfigPath= Path.Combine(project.ProjectFolder,"App.config")
227231

228232
letexeObjPath= Path.Combine(project.ProjectFolder,"obj\\x86\\debug", project.OutputFileName)
229233
letexeBinpath= Path.Combine(project.ProjectFolder,"bin\\debug\\", project.OutputFileName)
230234
letpdbObjPath= Regex.Replace(exeObjPath,"exe$","pdb")
231235
letpdbBinPath= Regex.Replace(exeBinpath,"exe$","pdb")
232236
letxmlDocPath= Regex.Replace(exeBinpath,"exe$","xml")
237+
letexeConfigPath= Regex.Replace(exeBinpath,"exe$","exe.config")
233238

234239
File.AppendAllText(sourcePath,"printfn\"hello\"")
240+
File.AppendAllText(appConfigPath,"""<?xml version="1.0" encoding="utf-8" ?><configuration></configuration>""")
235241

236242
Assert.IsFalse(config.IsUpToDate(logger,true))
237-
project.Build(configNameDebug, output,"Build")|>ignore
243+
project.Build(configNameDebug, output,"Build")|>AssertBuildSuccessful
238244
Assert.IsTrue(config.IsUpToDate(logger,true))
239245

240246
letstartTime= DateTime.Now
241247

242-
for pathin[exeObjPath; exeBinpath; pdbObjPath; pdbBinPath; xmlDocPath]do
248+
for pathin[exeObjPath; exeBinpath; pdbObjPath; pdbBinPath; xmlDocPath; exeConfigPath]do
243249
printfn"Testing output%s" path
244250

245251
// touch file
@@ -283,25 +289,25 @@ type UpToDate() =
283289
Assert.IsFalse(debugConfigAnyCPU.IsUpToDate(logger,true))
284290
Assert.IsFalse(releaseConfigAnyCPU.IsUpToDate(logger,true))
285291

286-
project.Build(configNameDebugx86, output,"Build")|>ignore
292+
project.Build(configNameDebugx86, output,"Build")|>AssertBuildSuccessful
287293
Assert.IsTrue(debugConfigx86.IsUpToDate(logger,true))
288294
Assert.IsFalse(releaseConfigx86.IsUpToDate(logger,true))
289295
Assert.IsFalse(debugConfigAnyCPU.IsUpToDate(logger,true))
290296
Assert.IsFalse(releaseConfigAnyCPU.IsUpToDate(logger,true))
291297

292-
project.Build(configNameReleasex86, output,"Build")|>ignore
298+
project.Build(configNameReleasex86, output,"Build")|>AssertBuildSuccessful
293299
Assert.IsTrue(debugConfigx86.IsUpToDate(logger,true))
294300
Assert.IsTrue(releaseConfigx86.IsUpToDate(logger,true))
295301
Assert.IsFalse(debugConfigAnyCPU.IsUpToDate(logger,true))
296302
Assert.IsFalse(releaseConfigAnyCPU.IsUpToDate(logger,true))
297303

298-
project.Build(configNameDebugAnyCPU, output,"Build")|>ignore
304+
project.Build(configNameDebugAnyCPU, output,"Build")|>AssertBuildSuccessful
299305
Assert.IsTrue(debugConfigx86.IsUpToDate(logger,true))
300306
Assert.IsTrue(releaseConfigx86.IsUpToDate(logger,true))
301307
Assert.IsTrue(debugConfigAnyCPU.IsUpToDate(logger,true))
302308
Assert.IsFalse(releaseConfigAnyCPU.IsUpToDate(logger,true))
303309

304-
project.Build(configNameReleaseAnyCPU, output,"Build")|>ignore
310+
project.Build(configNameReleaseAnyCPU, output,"Build")|>AssertBuildSuccessful
305311
Assert.IsTrue(debugConfigx86.IsUpToDate(logger,true))
306312
Assert.IsTrue(releaseConfigx86.IsUpToDate(logger,true))
307313
Assert.IsTrue(debugConfigAnyCPU.IsUpToDate(logger,true))
@@ -320,3 +326,55 @@ type UpToDate() =
320326

321327
Assert.IsFalse(config.IsFastUpToDateCheckEnabled())
322328
))
329+
330+
[<TestFixture>]
331+
type``UpToDate PreserveNewest``()=
332+
333+
[<Test>]
334+
memberpublicthis.IsUpToDatePreserveNewest()=
335+
336+
lettest(input,inputTimestamp)(output,outputTimestamp)=
337+
letlogs= ref[]
338+
letoutputPanel= VsMocks.vsOutputWindowPane(logs)
339+
letlogger= OutputWindowLogger.CreateUpToDateCheckLogger(outputPanel)
340+
341+
lettryTimestamp(path:string)(_l:OutputWindowLogger)=
342+
lettoN=function Some d-> Nullable<_>(d)| None-> Nullable<_>()
343+
match pathwith
344+
| xwhen x= input-> toN inputTimestamp
345+
| xwhen x= output-> toN outputTimestamp
346+
|_-> failwithf"unexpected%s" path
347+
348+
letu= ProjectConfig.IsUpToDatePreserveNewest(logger,(Func<_,_,_>(tryTimestamp)), input, output)
349+
u,!logs
350+
351+
letnow= System.DateTime.Now
352+
letbefore= now.AddHours(-1.0)
353+
354+
let``no input->not up-to-date and log``=
355+
letu,logs= test("readme.md", None)("leggimi.md", None)
356+
Assert.IsFalse(u)
357+
logs
358+
|> List.exists(fun s-> s.Contains("readme.md")&& s.Contains("can't find expected input"))
359+
|> Assert.IsTrue
360+
361+
let``no output->not up-to-date and log``=
362+
letu,logs= test("from.txt", Some now)("to.txt", None)
363+
Assert.IsFalse(u)
364+
logs
365+
|> List.exists(fun s-> s.Contains("to.txt")&& s.Contains("can't find expected output"))
366+
|> Assert.IsTrue
367+
368+
let``a newer version of output file is ok``=
369+
letu,logs= test("before.doc", Some before)("after.doc", Some now)
370+
Assert.True(u)
371+
logs|> AssertEqual[]
372+
373+
let``stale output file->not up-to-date and log``=
374+
letu,logs= test("logo.png", Some now)("animatedlogo.gif", Some before)
375+
Assert.IsFalse(u)
376+
logs
377+
|> List.exists(fun s-> s.Contains("animatedlogo.gif")&& s.Contains("stale"))
378+
|> Assert.IsTrue
379+
380+
()

‎vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/Project/ProjectConfig.cs‎

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ public virtual int QueryDebugTargets(uint grfLaunch, uint cTargets, VsDebugTarge
11971197
publicvirtualintOpenOutputGroup(stringszCanonicalName,outIVsOutputGroupppIVsOutputGroup)
11981198
{
11991199
ppIVsOutputGroup=null;
1200-
// Search through our list of groups to find the one they are lookingforgroupName
1200+
// Search through our list of groups to find the one they are lookingfor groupName
12011201
foreach(OutputGroupgroupinOutputGroups)
12021202
{
12031203
stringgroupName;
@@ -1458,7 +1458,7 @@ private static bool IsPossibleOutputGroup(string groupName)
14581458
returnnull;
14591459
}
14601460

1461-
internalboolGetUTDCheckInputs(refHashSet<string>inputs)
1461+
internalboolGetUTDCheckInputs(HashSet<string>inputs)
14621462
{
14631463
// the project file itself
14641464
inputs.Add(Utilities.CanonicalizeFileNameNoThrow(this.project.BuildProject.FullPath));
@@ -1527,8 +1527,10 @@ internal bool GetUTDCheckInputs(ref HashSet<string> inputs)
15271527
returntrue;
15281528
}
15291529

1530-
internalboolGetUTDCheckOutputs(refHashSet<string>outputs,HashSet<string>inputs)
1530+
internalvoidGetUTDCheckOutputs(HashSet<string>inputs,HashSet<string>outputs,outList<Tuple<string,string>>preserveNewestOutputs)
15311531
{
1532+
preserveNewestOutputs=newList<Tuple<string,string>>();
1533+
15321534
// Output groups give us the paths to the following outputs
15331535
// result EXE or DLL in "obj" dir
15341536
// PDB file in "obj" dir (if project is configured to create this)
@@ -1546,15 +1548,29 @@ internal bool GetUTDCheckOutputs(ref HashSet<string> outputs, HashSet<string> in
15461548
varoutputAssembly=this.project.GetOutputAssembly(this.ConfigCanonicalName);
15471549
outputs.Add(Utilities.CanonicalizeFileNameNoThrow(outputAssembly));
15481550

1551+
boolisExe=outputAssembly.EndsWith(".exe",StringComparison.OrdinalIgnoreCase);
1552+
15491553
// final PDB path
15501554
if(this.DebugSymbols&&
1551-
(outputAssembly.EndsWith(".exe",StringComparison.OrdinalIgnoreCase)||outputAssembly.EndsWith(".dll",StringComparison.OrdinalIgnoreCase)))
1555+
(isExe||outputAssembly.EndsWith(".dll",StringComparison.OrdinalIgnoreCase)))
15521556
{
15531557
varpdbPath=outputAssembly.Remove(outputAssembly.Length-4)+".pdb";
15541558
outputs.Add(Utilities.CanonicalizeFileNameNoThrow(pdbPath));
15551559
}
15561560

1557-
returntrue;
1561+
if(isExe)
1562+
{
1563+
varappConfig=inputs.FirstOrDefault(x=>String.Compare(Path.GetFileName(x),"app.config",StringComparison.OrdinalIgnoreCase)==0);
1564+
if(appConfig!=null)
1565+
{
1566+
// the app.config is not removed from the inputs to maintain
1567+
// the same behavior of a C# project:
1568+
// When a app.config is changed, after the build, the project
1569+
// is not up-to-date until a rebuild
1570+
varexeConfig=Utilities.CanonicalizeFileNameNoThrow(outputAssembly+".config");
1571+
preserveNewestOutputs.Add(Tuple.Create(appConfig,exeConfig));
1572+
}
1573+
}
15581574
}
15591575

15601576
// there is a well-known property users can specify that signals for UTD check to be disabled
@@ -1584,12 +1600,12 @@ internal bool IsUpToDate(OutputWindowLogger logger, bool testing)
15841600
}
15851601

15861602
varinputs=newHashSet<string>(StringComparer.OrdinalIgnoreCase);
1587-
if(!GetUTDCheckInputs(refinputs))
1603+
if(!GetUTDCheckInputs(inputs))
15881604
returnfalse;
15891605

15901606
varoutputs=newHashSet<string>(StringComparer.OrdinalIgnoreCase);
1591-
if(!GetUTDCheckOutputs(refoutputs,inputs))
1592-
returnfalse;
1607+
List<Tuple<string,string>>preserveNewestOutputs;
1608+
GetUTDCheckOutputs(inputs,outputs,outpreserveNewestOutputs);
15931609

15941610
// determine the oldest output timestamp
15951611
DateTimestalestOutputTime=DateTime.MaxValue.ToUniversalTime();
@@ -1625,13 +1641,48 @@ internal bool IsUpToDate(OutputWindowLogger logger, bool testing)
16251641
freshestInputTime=timeStamp.Value;
16261642
}
16271643

1644+
// check 1-1 Preserve Newest mappings
1645+
foreach(varkvinpreserveNewestOutputs)
1646+
{
1647+
if(!IsUpToDatePreserveNewest(logger,TryGetLastWriteTimeUtc,kv.Item1,kv.Item2))
1648+
returnfalse;
1649+
}
1650+
16281651
logger.WriteLine("Freshest input: {0}",freshestInputTime.ToLocalTime());
16291652
logger.WriteLine("Stalest output: {0}",stalestOutputTime.ToLocalTime());
16301653
logger.WriteLine("Up to date: {0}",freshestInputTime<=stalestOutputTime);
16311654

1632-
// if all outputs are younger than allinuts, we are up to date
1655+
// if all outputs are younger than allinputs, we are up to date
16331656
returnfreshestInputTime<=stalestOutputTime;
16341657
}
1658+
1659+
publicstaticboolIsUpToDatePreserveNewest(OutputWindowLoggerlogger,Func<string,OutputWindowLogger,DateTime?>tryGetLastWriteTimeUtc,stringinput,stringoutput)
1660+
{
1661+
varinputTime=tryGetLastWriteTimeUtc(input,logger);
1662+
if(!inputTime.HasValue)
1663+
{
1664+
logger.WriteLine("Declaring project NOT up to date, can't find expected input {0}",input);
1665+
returnfalse;
1666+
}
1667+
1668+
varoutputTime=tryGetLastWriteTimeUtc(output,logger);
1669+
if(!outputTime.HasValue)
1670+
{
1671+
logger.WriteLine("Declaring project NOT up to date, can't find expected output {0}",output);
1672+
returnfalse;
1673+
}
1674+
1675+
varinputTimeValue=inputTime.Value;
1676+
varoutputTimeValue=outputTime.Value;
1677+
1678+
if(outputTimeValue<inputTimeValue)
1679+
{
1680+
logger.WriteLine("Declaring project NOT up to date, ouput {0} is stale",output);
1681+
returnfalse;
1682+
}
1683+
1684+
returntrue;
1685+
}
16351686
}
16361687

16371688
internalclassClassLibraryCannotBeStartedDirectlyException:COMException

‎vsintegration/src/vs/FsPkgs/FSharp.Project/FS/MSBuildUtilities.fs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ type internal MSBuildUtilities() =
120120
// push folder
121121
Inc(curPathParts)
122122
curPathParts.Add(pathParts.[curPathParts.Count])// e.g. transition from A\ to A\D\E\bar.fs
123-
ifnot(alreadyRenderedFolders.Add(curPathParts))&& throwIfCannotRenderthen
123+
ifnot(alreadyRenderedFolders.Add(new List<string>(curPathParts)))&& throwIfCannotRenderthen
124124
raise<|new InvalidOperationException(String.Format(FSharpSR.GetString(FSharpSR.ProjectRenderFolderMultiple), projectNode.ProjectFile, bi.Include))
125125
Inc(curPathParts)
126126
if bi.ItemType= ProjectFileConstants.Folderthen

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp