in vsintegration/src/FSharp.ProjectSystem.Base/Project/ConfigProvider.cs [162:238]
public virtual int AddCfgsOfCfgName(string name, string cloneName, int fPrivate)
{
// We need to QE/QS the project file
if (!this.ProjectMgr.QueryEditProjectFile(false))
{
throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
}
// Get all configs
this.project.BuildProject.ReevaluateIfNecessary();
List<Microsoft.Build.Construction.ProjectPropertyGroupElement> configGroup = new List<Microsoft.Build.Construction.ProjectPropertyGroupElement>(this.project.BuildProject.Xml.PropertyGroups);
// platform -> property group
var configToClone = new Dictionary<string,Microsoft.Build.Construction.ProjectPropertyGroupElement>(StringComparer.Ordinal);
if (cloneName != null)
{
// Find the configuration to clone
foreach (var currentConfig in configGroup)
{
// Only care about conditional property groups
if (currentConfig.Condition == null || currentConfig.Condition.Length == 0)
continue;
var configCanonicalName = ConfigCanonicalName.OfCondition(currentConfig.Condition);
// Skip if it isn't the group we want
if (String.Compare(configCanonicalName.ConfigName, cloneName, StringComparison.OrdinalIgnoreCase) != 0)
continue;
if (!configToClone.ContainsKey(configCanonicalName.Platform))
configToClone.Add(configCanonicalName.Platform, currentConfig);
}
}
var platforms = GetPlatformsFromProject();
if (platforms.Length == 0) platforms = new[] { String.Empty };
foreach (var platform in platforms)
{
// If we have any property groups to clone, and we do not have sourec for this platform, skip
if (configToClone.Count > 0 && !configToClone.ContainsKey(platform)) continue;
var newCanonicalName = new ConfigCanonicalName(name, platform);
Microsoft.Build.Construction.ProjectPropertyGroupElement newConfig = null;
if (configToClone.ContainsKey(platform))
{
// Clone the configuration settings
newConfig = this.project.ClonePropertyGroup(configToClone[platform]);
//Will be added later with the new values to the path
foreach (Microsoft.Build.Construction.ProjectPropertyElement property in newConfig.Properties)
{
if (property.Name.Equals("OutputPath", StringComparison.OrdinalIgnoreCase))
{
property.Parent.RemoveChild(property);
}
}
}
else
{
// no source to clone from, lets just create a new empty config
PopulateEmptyConfig(ref newConfig);
if (!String.IsNullOrEmpty(newCanonicalName.MSBuildPlatform))
newConfig.AddProperty(ProjectFileConstants.PlatformTarget, newCanonicalName.PlatformTarget);
}
//add the output path
this.AddOutputPath(newConfig, name);
// Set the condition that will define the new configuration
string newCondition = newCanonicalName.ToMSBuildCondition();
newConfig.Condition = newCondition;
}
NotifyOnCfgNameAdded(name);
return VSConstants.S_OK;
}