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

Commited47354

Browse files
committed
Fix fordotnet#121: Unify build action conversion logic used by BuildActionConverter and BuildActionTypeConverter
Details, from Kevin:The issue was caused by interactions between BuildActionTypeConverter and BuildActionConverter.BuildActionConverter is used to map strings to BuildAction for use in the FSharp project system.BuildActionTypeConverter is used to map strings to VSLangProj.prjBuildAction for use by the VS infrastructure. BuildActionType converter knows nothing about BuildActions registered by the F# project system.The fix is to have the BuildActionTypeConverter delegate to BuildActionConverter to translate VSLangProj.prjBuildAction to BuildActionsRegistered by the F# project system.Longer term, we should consider a cleanup activity to make the FSharpProjectSystem use VSLangProj.prjBuildAction rather than BuildAction (changeset 1316292)
1 parent6cd2878 commited47354

File tree

4 files changed

+163
-40
lines changed

4 files changed

+163
-40
lines changed

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

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,14 +528,68 @@ type Miscellaneous() =
528528
use project= project
529529
letvalues= project.BuildActionConverter.GetStandardValues()
530530
letlist= values|> Seq.cast|> Seq.map(fun(ba: BuildAction)-> ba.Name)|> Seq.toList
531-
letexpected=["Compile";"Content";"EmbeddedResource";"None";"MyBuildAction";"MyBuildAction3"]
531+
// expected list of build actions is union of standard actions, custom actions, and "extended" standard actions (populated from, e.g., WPF or Fakes)
532+
// this is not exhaustive (exhaustive list is not static), but covers the main equivalence classes
533+
letexpected=["Compile";"Content";"EmbeddedResource";"None";"MyBuildAction";"MyBuildAction3";"Resource";"SplashScreen";"Fakes"]
532534
if expected|> List.forall(fun i-> List.exists((=)i) list)|>notthen
533535
lets0= sprintf"%A" expected
534536
lets1= sprintf"%A" list
535537
Assert.Fail(s0+"<>"+ s1)
536538
()
537539
)
538540

541+
[<Test>]
542+
memberpublicthis.TestBuildActionConversions()=
543+
544+
letreplace(pattern:string)(replacement:string)(input:string)= Regex.Replace(input, pattern, replacement)
545+
546+
letgetBuildableNodeProps project caption=
547+
letnode= TheTests.FindNodeWithCaption(project, caption)
548+
letprops= node.CreatePropertiesObject()
549+
props:?> BuildableNodeProperties
550+
551+
letcheckNotStandardBuildAction buildAction=
552+
Assert.IsFalse(VSLangProj.prjBuildAction.prjBuildActionNone= buildAction,"Unexpected None match")
553+
Assert.IsFalse(VSLangProj.prjBuildAction.prjBuildActionCompile= buildAction,"Unexpected Compile match")
554+
Assert.IsFalse(VSLangProj.prjBuildAction.prjBuildActionContent= buildAction,"Unexpected Content match")
555+
Assert.IsFalse(VSLangProj.prjBuildAction.prjBuildActionEmbeddedResource= buildAction,"Unexpected EmbeddedResource match")
556+
557+
DoWithTempFile"Test.fsproj"(fun file->
558+
lettext=
559+
TheTests.FsprojTextWithProjectReferences(["Compile.fs";"None.fs";"Resource.fs";"SplashSceen.fs";"Dude.fs"],[],[],"")
560+
|> replace"Compile\s+Include='([a-zA-Z]+)\.fs'""$1 Include='$1.fs'"
561+
File.AppendAllText(file, text)
562+
letsp,cnn= VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
563+
letproject= TheTests.CreateProject(file,"false", cnn, sp)
564+
use project= project
565+
566+
// test proper behavior from project file
567+
letnode= getBuildableNodeProps project"Compile.fs"
568+
Assert.IsTrue(node.BuildAction= VSLangProj.prjBuildAction.prjBuildActionCompile,"Compile build action failed")
569+
Assert.IsTrue(node.ItemType="Compile","Compile item type failed")
570+
571+
letnode= getBuildableNodeProps project"None.fs"
572+
Assert.IsTrue(node.BuildAction= VSLangProj.prjBuildAction.prjBuildActionNone,"None build action failed")
573+
Assert.IsTrue(node.ItemType="None","None item type failed")
574+
575+
letnode= getBuildableNodeProps project"Resource.fs"
576+
checkNotStandardBuildAction node.BuildAction
577+
Assert.IsTrue(node.ItemType="Resource","Resource item type failed")
578+
579+
letnode= getBuildableNodeProps project"Dude.fs"
580+
checkNotStandardBuildAction node.BuildAction
581+
Assert.IsTrue(node.ItemType="Dude","Dude item type failed")
582+
583+
// test handling of bogus values
584+
node.BuildAction<-enum100
585+
Assert.IsTrue(node.BuildAction= VSLangProj.prjBuildAction.prjBuildActionNone,"Bogus build action not mapped to None")
586+
587+
node.ItemType<-"Wibble"
588+
Assert.IsTrue(node.ItemType="None","Bogus item type not mapped to None")
589+
590+
()
591+
)
592+
539593
[<Test>]
540594
memberthis.``WildcardsInProjectFile.ThrowingCase``()=
541595
DoWithTempFile"Test.fsproj"(fun file->

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

Lines changed: 98 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
usingMicrosoft.VisualStudio.Designer.Interfaces;
77
usingSystem;
88
usingSystem.Collections;
9+
usingSystem.Collections.Generic;
910
usingSystem.ComponentModel;
1011
usingSystem.Drawing;
1112
usingSystem.Globalization;
1213
usingSystem.IO;
14+
usingSystem.Linq;
1315
usingSystem.Runtime.InteropServices;
1416
usingSystem.Windows.Forms;
1517
usingSystem.Xml;
@@ -464,7 +466,7 @@ public VSLangProj.prjBuildAction BuildAction
464466
{
465467
get
466468
{
467-
varres=BuildActionTypeConverter.Instance.ConvertFromString(this.Node.ItemNode.ItemName);
469+
varres=BuildActionTypeConverter.Instance.ConvertFromString(this.Node.ProjectMgr.BuildActionConverter,this.Node.ItemNode.ItemName);
468470
if(resisVSLangProj.prjBuildAction)
469471
{
470472
return(VSLangProj.prjBuildAction)res;
@@ -473,7 +475,7 @@ public VSLangProj.prjBuildAction BuildAction
473475
}
474476
set
475477
{
476-
this.Node.ItemNode.ItemName=BuildActionTypeConverter.Instance.ConvertToString(value);
478+
this.Node.ItemNode.ItemName=BuildActionTypeConverter.Instance.ConvertToString(this.Node.ProjectMgr.BuildActionConverter,value);
477479
}
478480
}
479481

@@ -483,11 +485,11 @@ public virtual string ItemType
483485
{
484486
get
485487
{
486-
returnBuildActionTypeConverter.Instance.ConvertToString(this.BuildAction);
488+
returnBuildActionTypeConverter.Instance.ConvertToString(this.Node.ProjectMgr.BuildActionConverter,this.BuildAction);
487489
}
488490
set
489491
{
490-
varres=BuildActionTypeConverter.Instance.ConvertFromString(value);
492+
varres=BuildActionTypeConverter.Instance.ConvertFromString(this.Node.ProjectMgr.BuildActionConverter,value);
491493
if(resisVSLangProj.prjBuildAction)
492494
{
493495
this.BuildAction=(VSLangProj.prjBuildAction)res;
@@ -527,65 +529,123 @@ public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
527529

528530
publicoverrideboolCanConvertFrom(ITypeDescriptorContextcontext,TypesourceType)
529531
{
530-
if(sourceType==typeof(string))
531-
{
532-
returntrue;
533-
}
534-
returnbase.CanConvertFrom(context,sourceType);
532+
return(sourceType==typeof(string))?true:base.CanConvertFrom(context,sourceType);
535533
}
536534

537535
publicoverrideboolCanConvertTo(ITypeDescriptorContextcontext,TypedestinationType)
538536
{
539-
returnbase.CanConvertTo(context,destinationType);
537+
return(destinationType==typeof(string))?true:base.CanConvertTo(context,destinationType);
540538
}
541539

542540
publicoverrideobjectConvertTo(ITypeDescriptorContextcontext,CultureInfoculture,objectvalue,TypedestinationType)
543541
{
544542
if(destinationType==typeof(string))
545543
{
546-
switch((VSLangProj.prjBuildAction)value)
547-
{
548-
caseVSLangProj.prjBuildAction.prjBuildActionCompile:
549-
return"Compile";
550-
caseVSLangProj.prjBuildAction.prjBuildActionContent:
551-
return"Content";
552-
caseVSLangProj.prjBuildAction.prjBuildActionEmbeddedResource:
553-
return"EmbeddedResource";
554-
caseVSLangProj.prjBuildAction.prjBuildActionNone:
555-
return"None";
556-
}
544+
varreply=ConvertToString(GetBuildActionConverter(context),value);
545+
if(reply!=null)returnreply;
557546
}
558547
returnbase.ConvertTo(context,culture,value,destinationType);
559548
}
560549

561-
publicoverrideobjectConvertFrom(ITypeDescriptorContextcontext,CultureInfoculture,objectvalue)
550+
publicstringConvertToString(BuildActionConverterbuildActionConverter,objectvalue)
562551
{
563-
if(valueisstring)
552+
switch((VSLangProj.prjBuildAction)value)
564553
{
565-
stringstrVal=(string)value;
566-
if(strVal.Equals("Compile",StringComparison.OrdinalIgnoreCase))
554+
caseVSLangProj.prjBuildAction.prjBuildActionCompile:
555+
return"Compile";
556+
caseVSLangProj.prjBuildAction.prjBuildActionContent:
557+
return"Content";
558+
caseVSLangProj.prjBuildAction.prjBuildActionEmbeddedResource:
559+
return"EmbeddedResource";
560+
caseVSLangProj.prjBuildAction.prjBuildActionNone:
561+
return"None";
562+
default:
563+
if(buildActionConverter!=null)
567564
{
568-
returnVSLangProj.prjBuildAction.prjBuildActionCompile;
569-
}
570-
elseif(strVal.Equals("Content",StringComparison.OrdinalIgnoreCase))
571-
{
572-
returnVSLangProj.prjBuildAction.prjBuildActionContent;
565+
// Not standard buildAction, so must have been registered.
566+
// Convert it to the name of the BuildAction at position index in the StandardValues from the BuildActionConverter
567+
intindex=(int)value;
568+
varactions=buildActionConverter.RegisteredBuildActions;
569+
if(index>=0&&index<actions.Count)
570+
{
571+
returnactions[index].Name;
572+
}
573573
}
574-
elseif(strVal.Equals("EmbeddedResource",StringComparison.OrdinalIgnoreCase))
574+
return"None";
575+
}
576+
}
577+
578+
publicoverrideobjectConvertFrom(ITypeDescriptorContextcontext,CultureInfoculture,objectvalue)
579+
{
580+
if(valueisstring)
581+
{
582+
varreply=ConvertFromString(GetBuildActionConverter(context),(string)value);
583+
if(reply!=null)returnreply;
584+
}
585+
returnbase.ConvertFrom(context,culture,value);
586+
}
587+
588+
publicobjectConvertFromString(BuildActionConverterbuildActionConverter,stringvalue)
589+
{
590+
if(value.Equals("Compile",StringComparison.OrdinalIgnoreCase))
591+
{
592+
returnVSLangProj.prjBuildAction.prjBuildActionCompile;
593+
}
594+
elseif(value.Equals("Content",StringComparison.OrdinalIgnoreCase))
595+
{
596+
returnVSLangProj.prjBuildAction.prjBuildActionContent;
597+
}
598+
elseif(value.Equals("EmbeddedResource",StringComparison.OrdinalIgnoreCase))
599+
{
600+
returnVSLangProj.prjBuildAction.prjBuildActionEmbeddedResource;
601+
}
602+
elseif(value.Equals("None",StringComparison.OrdinalIgnoreCase))
603+
{
604+
returnVSLangProj.prjBuildAction.prjBuildActionNone;
605+
}
606+
else
607+
{
608+
if(buildActionConverter!=null)
575609
{
576-
returnVSLangProj.prjBuildAction.prjBuildActionEmbeddedResource;
610+
// Not standard buildAction, so must have been registered.
611+
// Convert it to the index in the StandardValues from the BuildActionConverter.
612+
varactions=buildActionConverter.RegisteredBuildActions;
613+
varreply=actions.ToList().FindIndex(i=>value.Equals(i.Name,StringComparison.OrdinalIgnoreCase));
614+
if(reply!=-1)return(VSLangProj.prjBuildAction)reply;
577615
}
578-
elseif(strVal.Equals("None",StringComparison.OrdinalIgnoreCase))
616+
}
617+
returnVSLangProj.prjBuildAction.prjBuildActionNone;
618+
}
619+
620+
publicoverrideStandardValuesCollectionGetStandardValues(ITypeDescriptorContextcontext)
621+
{
622+
varbuildActionConverter=GetBuildActionConverter(context);
623+
if(buildActionConverter!=null)
624+
{
625+
varresults=newList<VSLangProj.prjBuildAction>();
626+
foreach(varainbuildActionConverter.RegisteredBuildActions)
579627
{
580-
returnVSLangProj.prjBuildAction.prjBuildActionNone;
628+
results.Add((VSLangProj.prjBuildAction)this.ConvertFrom(context,CultureInfo.CurrentUICulture,a.Name));
581629
}
630+
returnnewStandardValuesCollection(results);
631+
}
632+
else
633+
{
634+
returnnewStandardValuesCollection(new[]{VSLangProj.prjBuildAction.prjBuildActionNone,VSLangProj.prjBuildAction.prjBuildActionCompile,VSLangProj.prjBuildAction.prjBuildActionContent,VSLangProj.prjBuildAction.prjBuildActionEmbeddedResource});
582635
}
583-
returnbase.ConvertFrom(context,culture,value);
584636
}
585637

586-
publicoverrideStandardValuesCollectionGetStandardValues(ITypeDescriptorContextcontext)
638+
privatestaticBuildActionConverterGetBuildActionConverter(ITypeDescriptorContextcontext)
587639
{
588-
returnnewStandardValuesCollection(new[]{VSLangProj.prjBuildAction.prjBuildActionNone,VSLangProj.prjBuildAction.prjBuildActionCompile,VSLangProj.prjBuildAction.prjBuildActionContent,VSLangProj.prjBuildAction.prjBuildActionEmbeddedResource});
640+
if(context!=null)
641+
{
642+
BuildableNodePropertiesnodeProperties=context.InstanceasBuildableNodeProperties;
643+
if(nodeProperties!=null)
644+
{
645+
returnnodeProperties.Node.ProjectMgr.BuildActionConverter;
646+
}
647+
}
648+
returnnull;
589649
}
590650
}
591651

@@ -1553,4 +1613,4 @@ public override string FullPath
15531613
}
15541614
#endregion
15551615
}
1556-
}
1616+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ ProjectRootElement convertedProject
644644
{
645645
//Now iterate through the project items and copy them to the new location
646646
//All projects under the solution retain its folder hierarchy
647-
vartypes=new[]{"Compile","None","Content","EmbeddedResource","BaseApplicationManifest","ApplicationDefinition","Page"};
647+
vartypes=new[]{"Compile","None","Content","EmbeddedResource","Resource","BaseApplicationManifest","ApplicationDefinition","Page"};
648648

649649
varmetadataLookup=
650650
convertedProject

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
usingSystem.Windows.Forms;
1515
usingSystem.Xml;
1616
usingSystem.Diagnostics;
17+
usingSystem.Collections.ObjectModel;
1718

1819
// NOTE:
1920
// When converting, System.TypeConverter.Convert* passes us CultureInfo.CurrentCulture - this is wrong!
@@ -143,6 +144,14 @@ internal class BuildActionConverter : TypeConverter
143144
{
144145
List<BuildAction>buildActions=newList<BuildAction>();
145146

147+
publicReadOnlyCollection<BuildAction>RegisteredBuildActions
148+
{
149+
get
150+
{
151+
returnbuildActions.AsReadOnly();
152+
}
153+
}
154+
146155
publicBuildActionConverter()
147156
{
148157
ResetBuildActionsToDefaults();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp