Skip to content

Commit 19c3ca7

Browse files
Merge pull request #105 from microsoft/users/richsta/noplatform
Support for project types with no platforms.
2 parents d24f6fe + 6c4ef88 commit 19c3ca7

23 files changed

+194
-31
lines changed

src/Microsoft.VisualStudio.SolutionPersistence/Model/ConfigurationRuleFollower.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ internal readonly ref struct ConfigurationRuleFollower(IReadOnlyList<Configurati
3030
return value == "*" ? solutionBuildType : value.NullIfEmpty();
3131
}
3232

33-
internal readonly string? GetProjectPlatform(string solutionBuildType, string solutionPlatform)
33+
internal readonly string? GetProjectPlatform(string? solutionBuildType = null, string? solutionPlatform = null)
3434
{
3535
string value = this.GetDimensionValue(BuildDimension.Platform, solutionBuildType, solutionPlatform);
3636
return value == "*" ? solutionPlatform : value.NullIfEmpty();

src/Microsoft.VisualStudio.SolutionPersistence/Model/ModelHelper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,9 @@ internal static ConfigurationRule CreateNoBuildRule()
122122
{
123123
return new ConfigurationRule(BuildDimension.Build, solutionBuildType: string.Empty, solutionPlatform: string.Empty, projectValue: bool.FalseString);
124124
}
125+
126+
internal static ConfigurationRule CreateNoPlatformsRule()
127+
{
128+
return new ConfigurationRule(BuildDimension.Platform, solutionBuildType: string.Empty, solutionPlatform: string.Empty, projectValue: PlatformNames.Missing);
129+
}
125130
}

src/Microsoft.VisualStudio.SolutionPersistence/Model/PlatformNames.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ namespace Microsoft.VisualStudio.SolutionPersistence.Model;
66
internal static class PlatformNames
77
{
88
internal const string All = "*";
9+
10+
// Some project types do not support platforms, so this either indicates
11+
// the project type doesn't support platforms or that the platform mapping is missing.
912
internal const string Missing = "?";
1013

14+
// Used if the project type doesn't support platforms.
15+
internal const string Default = nameof(Default);
16+
1117
internal const string AnyCPU = nameof(AnyCPU);
1218
internal const string AnySpaceCPU = "Any CPU";
1319
internal const string Win32 = nameof(Win32);
@@ -35,6 +41,8 @@ internal static bool TryGetKnown(StringSpan platform, [NotNullWhen(true)] out st
3541
{
3642
All => All,
3743
Missing => Missing,
44+
Default => Default,
45+
AnyCPU => AnyCPU,
3846
AnySpaceCPU => AnySpaceCPU,
3947
Win32 => Win32,
4048
x64 => x64,

src/Microsoft.VisualStudio.SolutionPersistence/Model/ProjectType.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public sealed class ProjectType(Guid projectTypeId, IReadOnlyList<ConfigurationR
3232
/// Gets rules to determine the default configurations for projects of this type.
3333
/// </summary>
3434
/// <remarks>
35-
/// If a project type should not build, it should have a single rule with Build set to false.
35+
/// If a project type should not build, it should have a single rule with Build set to <see langword="false"/>.
3636
/// </remarks>
3737
public IReadOnlyList<ConfigurationRule> ConfigurationRules { get; } = rules;
3838

@@ -51,8 +51,8 @@ public sealed class ProjectType(Guid projectTypeId, IReadOnlyList<ConfigurationR
5151
public string? Extension { get; init; }
5252

5353
/// <summary>
54-
/// Gets references a base project type to inherit its configuration rules and project type id.
55-
/// This uses the Name or Extension of the base project type to find it.
54+
/// Gets a references to a base project type to inherit its configuration rules and project type id.
55+
/// This uses the <see cref="Name"/> or <see cref="Extension"/> of the base project type to find it.
5656
/// </summary>
5757
public string? BasedOn { get; init; }
5858
}

src/Microsoft.VisualStudio.SolutionPersistence/Model/ProjectTypeTable.BuiltInTypes.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ internal sealed partial class ProjectTypeTable
88
{
99
internal static readonly ConfigurationRule[] NoBuildRules = [ModelHelper.CreateNoBuildRule()];
1010

11+
internal static readonly ConfigurationRule NoPlatformsRule = ModelHelper.CreateNoPlatformsRule();
12+
1113
internal static readonly Guid VCXProj = new Guid("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942");
1214
internal static readonly Guid SolutionFolder = new Guid("2150E333-8FDC-42A3-9474-1A3956D46DE8");
1315

@@ -87,6 +89,7 @@ internal sealed partial class ProjectTypeTable
8789
new ProjectType(new Guid("00D1A9C2-B5F0-4AF3-8072-F6C62B433612"), NoBuildRules) { Name = "SQL", Extension = ".sqlproj" },
8890
new ProjectType(new Guid("0C603C2C-620A-423B-A800-4F3E2F6281F1"), NoBuildRules) { Name = "U-SQL-DB", Extension = ".usqldbproj" },
8991
new ProjectType(new Guid("182E2583-ECAD-465B-BB50-91101D7C24CE"), NoBuildRules) { Name = "U-SQL", Extension = ".usqlproj" },
92+
new ProjectType(new Guid("F14B399A-7131-4C87-9E4B-1186C45EF12D"), [NoPlatformsRule]) { Name = "SSRS", Extension = ".rptproj" },
9093

9194
// Azure project types
9295
new ProjectType(new Guid("A07B5EB6-E848-4116-A8D0-A826331D98C6"), NoBuildRules) { Name = "Fabric", Extension = ".sfproj" },

src/Microsoft.VisualStudio.SolutionPersistence/Model/StringTable.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,10 @@ internal void AddString(string str)
6969
{
7070
_ = this.GetString(str);
7171
}
72+
73+
// Used to test the string table.
74+
internal bool Contains(string str)
75+
{
76+
return this.strings.Contains(str);
77+
}
7278
}

src/Microsoft.VisualStudio.SolutionPersistence/Serializer/SlnV12/SlnV12Extensions.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,10 @@ static void SetProjectConfigurationPlatforms(SolutionModel solution, SolutionPro
253253
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, buildType, platform, BuildTypeNames.Missing));
254254
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, buildType, platform, PlatformNames.Missing));
255255

256-
// In the old .sln file the default configuration is not to build unless there is a build line.
257-
// This rule will get overwritten by the build line if it exists.
256+
// In the old .sln file the default configuration is not to build/deploy unless there is a build/deploy line.
257+
// This rule will get overwritten by the build/deploy line if it exists.
258258
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Build, buildType, platform, bool.FalseString));
259+
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Deploy, buildType, platform, bool.FalseString));
259260
}
260261
}
261262
}
@@ -336,6 +337,11 @@ void ParseProjectConfigLine(SolutionModel solutionModel, string name, string val
336337
projectModel.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, solutionBuildType, solutionPlatform, projectBuildType));
337338
projectModel.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, solutionBuildType, solutionPlatform, projectPlatform));
338339
}
340+
else if (!value.IsNullOrEmpty())
341+
{
342+
// If the project configuration does not have a platform, just set the build type.
343+
projectModel.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, solutionBuildType, solutionPlatform, value));
344+
}
339345

340346
break;
341347
case ConfigLineType.Build:
@@ -454,18 +460,15 @@ not SectionName.ExtensibilityGlobals and
454460
continue;
455461
}
456462

457-
bool isMissing = mapping.BuildType == BuildTypeNames.Missing || mapping.Platform == PlatformNames.Missing;
458-
459463
// Default project mapping in SLN was to use "Any CPU"
460-
string platform = mapping.Platform;
461-
if (platform == PlatformNames.AnyCPU)
462-
{
463-
platform = PlatformNames.AnySpaceCPU;
464-
}
464+
string platform =
465+
mapping.Platform == PlatformNames.AnyCPU ? PlatformNames.AnySpaceCPU :
466+
mapping.Platform;
465467

466-
string prjCfgPlatString = $"{mapping.BuildType}|{platform}";
468+
// If just the platform is missing, the project doesn't support platforms and only the build type should be written.
469+
string prjCfgPlatString = platform == PlatformNames.Missing ? mapping.BuildType : $"{mapping.BuildType}|{platform}";
467470

468-
if (!isMissing)
471+
if (mapping.BuildType != BuildTypeNames.Missing)
469472
{
470473
WriteProperty(propertyBag, projectId, entry.SlnKey, ActiveCfgSuffix, prjCfgPlatString);
471474
}

src/Microsoft.VisualStudio.SolutionPersistence/Serializer/Xml/Keywords.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ internal enum Keyword
3737
Extension,
3838
BasedOn,
3939
IsBuildable,
40+
SupportsPlatform,
4041

4142
// Configuration properties
4243
Configuration,
@@ -87,6 +88,7 @@ static Keywords()
8788
new(nameof(Keyword.Extension), Keyword.Extension),
8889
new(nameof(Keyword.BasedOn), Keyword.BasedOn),
8990
new(nameof(Keyword.IsBuildable), Keyword.IsBuildable),
91+
new(nameof(Keyword.SupportsPlatform), Keyword.SupportsPlatform),
9092
new(nameof(Keyword.Configuration), Keyword.Configuration),
9193
new(nameof(Keyword.Dimension), Keyword.Dimension),
9294
new(nameof(Keyword.BuildType), Keyword.BuildType),
@@ -125,6 +127,8 @@ internal static StringTable WithSolutionConstants(this StringTable stringTable)
125127
stringTable.AddString(BuildTypeNames.Debug);
126128
stringTable.AddString(BuildTypeNames.Release);
127129
stringTable.AddString(PlatformNames.All);
130+
stringTable.AddString(PlatformNames.Missing);
131+
stringTable.AddString(PlatformNames.Default);
128132
stringTable.AddString(PlatformNames.AnyCPU);
129133
stringTable.AddString(PlatformNames.AnySpaceCPU);
130134
stringTable.AddString(PlatformNames.Win32);

src/Microsoft.VisualStudio.SolutionPersistence/Serializer/Xml/Slnx.xsd

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
<xs:element name="Folder" type="Folder" minOccurs="0" maxOccurs="unbounded" />
88
<xs:group ref="PropertiesGroup" minOccurs="0" maxOccurs="unbounded"/>
99
</xs:choice>
10-
<xs:attribute name="Description"/>
11-
<xs:attribute name="SolutionId" />
12-
<xs:attribute name="VisualStudioVersion" />
13-
<xs:attribute name="MinimalVisualStudioVersion" />
10+
<xs:attribute name="Description" type="xs:string" />
11+
<xs:attribute name="Version" type="xs:string" />
1412
</xs:complexType>
1513
</xs:element>
1614

@@ -38,7 +36,8 @@
3836
<xs:attribute name="Name" type="xs:string" />
3937
<xs:attribute name="Extension" type="xs:string" />
4038
<xs:attribute name="BasedOn" type="xs:string" />
41-
<xs:attribute name="IsBuildable" type="xs:string" default="True" />
39+
<xs:attribute name="IsBuildable" type="xs:boolean" default="true" use="optional" />
40+
<xs:attribute name="SupportsPlatform" type="xs:boolean" default="true" use="optional" />
4241
</xs:complexType>
4342

4443
<xs:complexType name="Folder">

src/Microsoft.VisualStudio.SolutionPersistence/Serializer/Xml/SlnxSerializerSettings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ public readonly struct SlnxSerializerSettings(SlnxSerializerSettings settings)
1515
{
1616
/// <summary>
1717
/// Gets a value indicating whether to keep whitespace when writing the solution file.
18-
/// If this is true, the solution file will be written with the same whitespace as the original file.
19-
/// Default is true.
18+
/// If this is <see langword="true"/>, the solution file will be written with the same whitespace as the original file.
19+
/// Default is <see langword="true"/>.
2020
/// </summary>
2121
public bool? PreserveWhitespace { get; init; } = settings.PreserveWhitespace;
2222

0 commit comments

Comments
 (0)