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

Commit7396db7

Browse files
committed
Fixesdotnet#283 - Changing target framework causes incorrect binding redirects to be added to app.config
Ensures that when the F# project system updates the app.config file for the project. It correctly handles the binding redirects.1. If autogeneratebindingredirects is set in the project then the project system leaves it to the build.2. For projects without autogeneratebindingredirects it adds a bindingredirect for fsharp.core for each possible version of fsharp.core, depending on the target framework
1 parent1bc99dc commit7396db7

File tree

4 files changed

+110
-87
lines changed

4 files changed

+110
-87
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ type MultiTargeting() =
7373
use project= TheTests.CreateProject(projFile,"true", ccn, sp)
7474

7575
letvalidate(fn:System.Runtime.Versioning.FrameworkName)eR eS=
76-
let(name,runtime,sku)= project.DetermineRuntimeAndSKU(fn.ToString())
76+
let(runtime,sku)= project.DetermineRuntimeAndSKU(fn.ToString())
7777
Assert.AreEqual(eR, runtime)
7878
Assert.AreEqual(eS, sku)
7979
validate(new System.Runtime.Versioning.FrameworkName(".NETFramework",new System.Version(4,0)))"v4.0"".NETFramework,Version=v4.0"

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

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,61 +3305,57 @@ string newTargetFrameworkMoniker
33053305
bool.TryParse(projectMgr.BuildProject.GetPropertyValue("AutoGenerateBindingRedirects"),outautoGenerateBindingRedirects);
33063306

33073307
#ifFX_ATLEAST_45
3308-
// update FSharp.Core only if we are addressing '.NETFramework' as opposed to e.g. Silverlight or Portable
3309-
if(frameworkName.Identifier==".NETFramework")
3310-
{
3311-
// In reality for FSharp.Core compatibility with .NetFramework selection looks like this:
3312-
// 2 is incompatible with 4
3313-
// 4.0 is incompatible with 4.5
3314-
// 4.5 is compatible with 4.5.1 and 4.5.2 and 4.6
3315-
varlower=oldFrameworkName.Version<frameworkName.Version?oldFrameworkName.Version:frameworkName.Version;
3316-
varupper=oldFrameworkName.Version<frameworkName.Version?frameworkName.Version:oldFrameworkName.Version;
3317-
varhasIncompatibleFsCore=(lower.Major!=upper.Major)||(lower.Major==4&&(lower.Minor<5&&upper.Minor>=5));
3308+
// In reality for FSharp.Core compatibility with .NetFramework selection looks like this:
3309+
// 2 is incompatible with 4
3310+
// 4.0 is incompatible with 4.5
3311+
// 4.5 is compatible with 4.5.1 and 4.5.2 and 4.6
3312+
varlower=oldFrameworkName.Version<frameworkName.Version?oldFrameworkName.Version:frameworkName.Version;
3313+
varupper=oldFrameworkName.Version<frameworkName.Version?frameworkName.Version:oldFrameworkName.Version;
3314+
varhasIncompatibleFsCore=(lower.Major!=upper.Major)||(lower.Major==4&&(lower.Minor<5&&upper.Minor>=5));
33183315

3319-
if(hasIncompatibleFsCore)
3320-
{
3321-
varnewVersion=
3322-
frameworkName.Version.Major>=4?
3323-
(frameworkName.Version.Minor<5?newVersion(4,3,0,0):newVersion(4,4,0,0)):newVersion(2,3,0,0);
3316+
if(hasIncompatibleFsCore)
3317+
{
3318+
varnewVersion=
3319+
frameworkName.Version.Major>=4?
3320+
(frameworkName.Version.Minor<5?newVersion(4,3,0,0):newVersion(4,4,0,0)):newVersion(2,3,0,0);
3321+
targetFSharpCoreVersion=newVersion.ToString();
33243322

3325-
if(projectMgr.CanUseTargetFSharpCoreReference)
3326-
{
3327-
// this project controls version of FSharp.Core with project level property TargetFSharpCoreVersion- set it
3328-
projectMgr.SetProjectProperty(ProjectFileConstants.TargetFSharpCoreVersion,newVersion.ToString());
3329-
}
3330-
else
3331-
{
3332-
// project doesn't use TargetFSharpCoreVersion - fix the reference explicitly
3333-
varfsCoreName=newSystem.Reflection.AssemblyName(string.Format("FSharp.Core, Culture=neutral, PublicKeyToken={0}",Utilities.FsCorePublicKeyToken));
3323+
if(projectMgr.CanUseTargetFSharpCoreReference)
3324+
{
3325+
// this project controls version of FSharp.Core with project level property TargetFSharpCoreVersion- set it
3326+
projectMgr.SetProjectProperty(ProjectFileConstants.TargetFSharpCoreVersion,targetFSharpCoreVersion);
3327+
}
3328+
else
3329+
{
3330+
// project doesn't use TargetFSharpCoreVersion - fix the reference explicitly
3331+
varfsCoreName=newSystem.Reflection.AssemblyName(string.Format("FSharp.Core, Culture=neutral, PublicKeyToken={0}",Utilities.FsCorePublicKeyToken));
33343332

3335-
varvsProj=(VSLangProj.VSProject)projectMgr.Object;
3333+
varvsProj=(VSLangProj.VSProject)projectMgr.Object;
33363334

3337-
varreferences=vsProj.References;
3335+
varreferences=vsProj.References;
33383336

3339-
// replace existing fscore with one that has matching version with current target framework
3340-
varexistingFsCore=
3341-
Microsoft.VisualStudio.FSharp.LanguageService.UIThread.DoOnUIThread(
3342-
()=>references
3343-
.OfType<Automation.OAAssemblyReference>()
3344-
.FirstOrDefault(r=>r.Name==fsCoreName.Name&&r.PublicKeyToken==Utilities.FsCorePublicKeyToken&&r.Culture==fsCoreName.CultureName)
3345-
);
3337+
// replace existing fscore with one that has matching version with current target framework
3338+
varexistingFsCore=
3339+
Microsoft.VisualStudio.FSharp.LanguageService.UIThread.DoOnUIThread(
3340+
()=>references
3341+
.OfType<Automation.OAAssemblyReference>()
3342+
.FirstOrDefault(r=>r.Name==fsCoreName.Name&&r.PublicKeyToken==Utilities.FsCorePublicKeyToken&&r.Culture==fsCoreName.CultureName)
3343+
);
33463344

3347-
if(existingFsCore!=null)
3345+
if(existingFsCore!=null)
3346+
{
3347+
Microsoft.VisualStudio.FSharp.LanguageService.UIThread.DoOnUIThread(()=>
33483348
{
3349-
Microsoft.VisualStudio.FSharp.LanguageService.UIThread.DoOnUIThread(()=>
3350-
{
3351-
// save copyLocal value - after calling existingFsCore.Remove() becomes invalid and can raise exceptions
3352-
varcopyLocal=existingFsCore.CopyLocal;
3353-
existingFsCore.Remove();
3354-
fsCoreName.Version=newVersion;
3355-
3356-
// stores assembly FQN
3357-
varnewRef=references.Add(fsCoreName.FullName);
3358-
newRef.CopyLocal=copyLocal;
3359-
});
3360-
}
3349+
// save copyLocal value - after calling existingFsCore.Remove() becomes invalid and can raise exceptions
3350+
varcopyLocal=existingFsCore.CopyLocal;
3351+
existingFsCore.Remove();
3352+
fsCoreName.Version=newVersion;
3353+
3354+
// stores assembly FQN
3355+
varnewRef=references.Add(fsCoreName.FullName);
3356+
newRef.CopyLocal=copyLocal;
3357+
});
33613358
}
3362-
targetFSharpCoreVersion=newVersion.ToString();
33633359
}
33643360
}
33653361
#endif

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

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
4848
let mutabledocument:System.Xml.Linq.XDocument=null
4949
let mutablebuffer:IVsTextLines=null
5050
let mutablerdtCookie:uint32=0u
51-
51+
5252
memberprivatex.InitDocData(itemid,filename)=
5353
let mutablehr= VSConstants.E_FAIL
5454
letrdt= site.GetService(typeof<SVsRunningDocumentTable>):?> IVsRunningDocumentTable
@@ -304,22 +304,66 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
304304
fixupSku runtimeNode
305305

306306
!dirty
307-
307+
308308
memberx.EnsureSupportedRuntimeElement(version:string,sku:string)=
309-
309+
310310
letdocument= fileHolder.GetXml()
311-
311+
312312
// First, add the <startup> node. We assume that the root element is the
313313
// <configuration> element.
314-
314+
315315
letroot= document.Root
316316
letdirty= LangConfigFile.PatchUpXml(root, version, sku)
317-
if dirtythen isDirty<- dirty
318-
317+
if dirtythen isDirty<- dirty
318+
319319
/// Updates list of binding redirects to the config file. Content of list is governed by the major version of target framework.
320-
memberx.EnsureHasBindingRedirects(majorVersion,minorVersion,targetFSharpCoreVersion,autoGenerateBindingRedirects)=
320+
memberx.EnsureHasBindingRedirects(targetFSharpCoreVersion,autoGenerateBindingRedirects)=
321321

322322
ifnot autoGenerateBindingRedirectsthen
323+
324+
// Binding redirects depend on target framework
325+
letbindingRedirects=
326+
[
327+
// How to compute the binding redirects for an app.config file
328+
// ===========================================================
329+
//
330+
// Appconfig files appear by default in a console application and can be added to other F# projects.
331+
// Some test frameworks make use of the for library projects
332+
// If the project property <AutoGenerateBindingRedirects> is set to true then this code is not needed
333+
// However, for those projects that don't have it turned on this is how we compute the binding redirects to generate.
334+
//
335+
// The assembly version number scheme, evolved in a somewhat haphazard way:
336+
// .Net 2 fsharp.core.dll has the version# 2.0.0.0 for VS2010 and 2.3.0.0 for VS2012 and up
337+
// .Net 4 fsharp.core.dll has the version# 4.3.0.0 for VS2012, 4.3.1 for VS 2013 and 4.4.0.0
338+
//
339+
// Portable libraries are much different
340+
// There is a systematic scheme for portable libries from VS2013+Oob3.1.2 forward
341+
// It is: 3.Profile.Major.Minor
342+
// Profile is .net framework profile number I.e 7,47,78 and 259
343+
// Major.minor is the matching FSharp language major.minor version
344+
//
345+
// However in VS 2012 we released a Portable library which was profile 47 it has the version 2.3.5.0 in VS2013 it was updated to 2.3.5.1
346+
// and in VS 2013 we released an additional portable library based on the Windows 8 profile 7 with the version number 3.3.1.0
347+
//
348+
// Binding redirects are computed based on target fsharp core an fsharp core will be redirected to the target fsharp.core if it is "compatible"
349+
// Each desktop fsharp.core is a superset of the previous desktop fsharp.core dll's and is thus "compatible"
350+
// Each desktop fsharp.core.dll is also a superset of the portable libraries that shipped with it.
351+
//
352+
// The table below represents the appropriate redirections
353+
// If the target version is between TagetMin and TargetMax inclusive then the redirects list contains the appropriate redirects
354+
//
355+
//TargetMin, targetMax, redirects
356+
"2.3.0.0","2.3.0.0",["2.0.0.0";"2.0.0.0"]
357+
"2.3.5.1","2.3.5.1",["2.3.5.0";"2.3.5.1"]
358+
"3.7.4.0","3.7.4.0",["3.3.1.0";"3.7.4.0"]
359+
"3.47.4.0","3.47.4.0",["2.3.5.0";"2.3.5.1";"3.47.4.0"]
360+
"3.78.4.0","3.78.4.0",["3.78.3.1";"3.78.4.0"]
361+
"3.259.4.0","3.259.4.0",["3.259.3.1";"3.259.4.0";"4.3.0.0"]
362+
"4.3.0.0","4.4.0.0",["2.0.0.0";"2.3.5.0";"4.0.0.0";"4.3.1.0"]
363+
"4.3.1.0","4.4.0.0",["3.3.1.0";"2.3.5.1";"3.78.3.1";"3.259.3.1"]
364+
"4.4.0.0","4.4.0.0",["3.47.4.0";"3.78.4.0";"3.259.4.0";"4.3.1.0";"4.4.0.0"]
365+
]|> Seq.where(fun(min,max,_)-> targetFSharpCoreVersion>= min&& targetFSharpCoreVersion<= max)
366+
323367
// some helpers to simplify work with XLinq
324368
letxname= System.Xml.Linq.XName.Get
325369
letxnameAsmV1 name= xname("{urn:schemas-microsoft-com:asm.v1}"+ name)
@@ -332,21 +376,6 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
332376
]
333377

334378
// depending on major version of target framework we need to populate corresponding binding redirects in config
335-
letredirects=
336-
if majorVersion>=4then
337-
[
338-
"2.0.0.0", targetFSharpCoreVersion
339-
"2.3.5.0", targetFSharpCoreVersion
340-
"4.0.0.0", targetFSharpCoreVersion
341-
]@if minorVersion>=5&& targetFSharpCoreVersion<>"4.3.1.0"then
342-
["4.3.1.0", targetFSharpCoreVersion]
343-
else
344-
[]
345-
else
346-
[
347-
"2.0.0.0","2.3.0.0"
348-
]
349-
350379
letOldVersion="oldVersion"
351380
letNewVersion="newVersion"
352381
letBindingRedirect="bindingRedirect"
@@ -402,19 +431,22 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
402431
let_fsCoreIdentity= create dependentAssembly(xnameAsmV1 AssemblyIdentity) fsCoreAttributes
403432
dependentAssembly
404433

405-
for redirectin redirectsdo
406-
createRedirect fsharpCoreDependentAssemblyElement redirect
434+
letredirects=
435+
seq{
436+
for_,_,redirectsin bindingRedirectsdo
437+
yield! redirects
438+
}
439+
440+
redirects|> Seq.iter(fun r->if r<> targetFSharpCoreVersionthen createRedirect fsharpCoreDependentAssemblyElement(r, targetFSharpCoreVersion))
407441

408442
memberx.IsDirty()= isDirty
409-
443+
410444
memberx.Save()=
411445
lethr= fileHolder.SaveChanges()
412446
if ErrorHandler.Succeeded(hr)then
413447
isDirty<-false
414448
hr
415-
449+
416450
interface IDisposablewith
417451
memberx.Dispose()=
418452
(fileHolder:> IDisposable).Dispose()
419-
420-

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,9 +1844,9 @@ See also ...\SetupAuthoring\FSharp\Registry\FSProjSys_Registration.wxs, e.g.
18441844
let(_,res)= mtservice.GetInstallableFrameworkForTargetFx(targetFrameworkMoniker)
18451845
res
18461846

1847-
(frameworkName,runtime,if String.IsNullOrEmpty(sku)thennullelse sku)
1847+
(runtime,if String.IsNullOrEmpty(sku)thennullelse sku)
18481848

1849-
memberinternalx.DoFixupAppConfigOnTargetFXChange(frameworkName:System.Runtime.Versioning.FrameworkName,runtime:string,sku:string,targetFSharpCoreVersion:string,autoGenerateBindingRedirects:bool)=
1849+
memberinternalx.DoFixupAppConfigOnTargetFXChange(runtime:string,sku:string,targetFSharpCoreVersion:string,autoGenerateBindingRedirects:bool)=
18501850
let mutableres= VSConstants.E_FAIL
18511851
letspecialFiles= x:> IVsProjectSpecialFiles
18521852
// We only want to force-generate an AppConfig file if the output type is EXE;
@@ -1869,7 +1869,7 @@ See also ...\SetupAuthoring\FSharp\Registry\FSProjSys_Registration.wxs, e.g.
18691869
letnode= x.NodeFromItemId(itemid)
18701870
System.Diagnostics.Debug.Assert(node<>null,"No project node for the item?")
18711871
if node<>nullthen
1872-
langConfigFile.EnsureHasBindingRedirects(frameworkName.Version.Major, frameworkName.Version.Minor,targetFSharpCoreVersion, autoGenerateBindingRedirects)
1872+
langConfigFile.EnsureHasBindingRedirects(targetFSharpCoreVersion, autoGenerateBindingRedirects)
18731873
res<- langConfigFile.Save()
18741874

18751875
// if we couldn't find the file, but we don't need it, then just ignore
@@ -1880,13 +1880,8 @@ See also ...\SetupAuthoring\FSharp\Registry\FSProjSys_Registration.wxs, e.g.
18801880
res
18811881

18821882
overridex.FixupAppConfigOnTargetFXChange(targetFrameworkMoniker,targetFSharpCoreVersion,autoGenerateBindingRedirects)=
1883-
letframeworkName=new System.Runtime.Versioning.FrameworkName(targetFrameworkMoniker)
1884-
// Spec says to do this only if the framework family is ".NETFramework"
1885-
if String.Compare(frameworkName.Identifier,".NETFramework",true, CultureInfo.InvariantCulture)=0then
1886-
let(frameworkName,runtime,sku)= x.DetermineRuntimeAndSKU(targetFrameworkMoniker)
1887-
x.DoFixupAppConfigOnTargetFXChange(frameworkName, runtime, sku, targetFSharpCoreVersion, autoGenerateBindingRedirects)
1888-
else
1889-
VSConstants.S_OK
1883+
let(runtime,sku)= x.DetermineRuntimeAndSKU(targetFrameworkMoniker)
1884+
x.DoFixupAppConfigOnTargetFXChange(runtime, sku, targetFSharpCoreVersion, autoGenerateBindingRedirects)
18901885

18911886
overridex.SetHostObject(targetName,taskName,hostObject)=
18921887
#if DEBUG

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp