in src/Build/Evaluation/Evaluator.cs [948:1196]
private void PerformDepthFirstPass(ProjectRootElement currentProjectOrImport)
{
// We accumulate InitialTargets from the project and each import
IList<string> initialTargets = _expander.ExpandIntoStringListLeaveEscaped(currentProjectOrImport.InitialTargets, ExpanderOptions.ExpandProperties, currentProjectOrImport.InitialTargetsLocation);
_initialTargetsList.AddRange(initialTargets);
if (!s_ignoreTreatAsLocalProperty)
{
IList<string> globalPropertiesToTreatAsLocals = _expander.ExpandIntoStringListLeaveEscaped(currentProjectOrImport.TreatAsLocalProperty, ExpanderOptions.ExpandProperties, currentProjectOrImport.TreatAsLocalPropertyLocation);
foreach (string propertyName in globalPropertiesToTreatAsLocals)
{
XmlUtilities.VerifyThrowProjectValidElementName(propertyName, currentProjectOrImport.Location);
_data.GlobalPropertiesToTreatAsLocal.Add(propertyName);
}
}
UpdateDefaultTargets(currentProjectOrImport);
#if FEATURE_MSBUILD_DEBUGGER
if (DebuggerManager.DebuggingEnabled)
{
// Create a state for every element processed during the properties pass
foreach (ProjectElement element in currentProjectOrImport.AllChildren)
{
if (
element is ProjectPropertyGroupElement ||
element is ProjectPropertyElement ||
element is ProjectImportGroupElement ||
element is ProjectImportElement ||
element is ProjectChooseElement ||
element is ProjectWhenElement || // although Whens are encountered again during the item pass, the condition is only evaluated on the first pass, hence, property locals only
element is ProjectOtherwiseElement
)
{
// Skip any that are somewhere below targets; those will be defined later
if (!(element is ProjectTargetElement) &&
element.AllParents.FirstOrDefault(delegate (ProjectElementContainer current) { return (current != null && current is ProjectTargetElement); }) == null)
{
DebuggerManager.DefineState(element.Location, element.Location.LocationString, s_propertyPassLocalsTypes);
}
}
}
// Bake the property pass states so we can enter them
DebuggerManager.BakeStates(Path.GetFileNameWithoutExtension(currentProjectOrImport.FullPath));
}
#endif
IList<ProjectImportElement> implicitImports = new List<ProjectImportElement>();
if (!String.IsNullOrWhiteSpace(currentProjectOrImport.Sdk))
{
// SDK imports are added implicitly where they are evaluated at the top and bottom as if they are in the XML
//
foreach (string sdk in currentProjectOrImport.Sdk.Split(';').Select(i => i.Trim()))
{
if (String.IsNullOrWhiteSpace(sdk))
{
ProjectErrorUtilities.ThrowInvalidProject(currentProjectOrImport.SdkLocation, "InvalidSdkFormat", currentProjectOrImport.Sdk);
}
int slashIndex = sdk.LastIndexOf("/", StringComparison.Ordinal);
string sdkName = slashIndex > 0 ? sdk.Substring(0, slashIndex) : sdk;
// TODO: do something other than just ignore the version
if (sdkName.Contains("/"))
{
ProjectErrorUtilities.ThrowInvalidProject(currentProjectOrImport.SdkLocation, "InvalidSdkFormat", currentProjectOrImport.Sdk);
}
implicitImports.Add(ProjectImportElement.CreateImplicit("Sdk.props", currentProjectOrImport, ImplicitImportLocation.Top, sdkName));
implicitImports.Add(ProjectImportElement.CreateImplicit("Sdk.targets", currentProjectOrImport, ImplicitImportLocation.Bottom, sdkName));
}
}
foreach (var import in implicitImports.Where(i => i.ImplicitImportLocation == ImplicitImportLocation.Top))
{
EvaluateImportElement(currentProjectOrImport.DirectoryPath, import);
}
foreach (ProjectElement element in currentProjectOrImport.Children)
{
ProjectPropertyGroupElement propertyGroup = element as ProjectPropertyGroupElement;
if (propertyGroup != null)
{
EvaluatePropertyGroupElement(propertyGroup);
continue;
}
ProjectItemGroupElement itemGroup = element as ProjectItemGroupElement;
if (itemGroup != null)
{
_itemGroupElements.Add(itemGroup);
#if FEATURE_MSBUILD_DEBUGGER
if (DebuggerManager.DebuggingEnabled)
{
DebuggerManager.DefineState(element.Location, element.Location.LocationString, s_itemPassLocalsTypes);
foreach (ProjectItemElement item in itemGroup.Items)
{
DebuggerManager.DefineState(item.Location, item.Location.LocationString, s_itemPassLocalsTypes);
foreach (ProjectMetadataElement metadatum in item.Metadata)
{
DebuggerManager.DefineState(metadatum.Location, metadatum.Location.LocationString, s_itemPassLocalsTypes);
}
}
}
#endif
continue;
}
ProjectItemDefinitionGroupElement itemDefinitionGroup = element as ProjectItemDefinitionGroupElement;
if (itemDefinitionGroup != null)
{
_itemDefinitionGroupElements.Add(itemDefinitionGroup);
#if FEATURE_MSBUILD_DEBUGGER
if (DebuggerManager.DebuggingEnabled)
{
DebuggerManager.DefineState(element.Location, element.Location.LocationString, s_itemDefinitionPassLocalsTypes);
foreach (ProjectItemDefinitionElement itemDefinition in itemDefinitionGroup.ItemDefinitions)
{
DebuggerManager.DefineState(itemDefinition.Location, itemDefinition.Location.LocationString, s_itemDefinitionPassLocalsTypes);
foreach (ProjectMetadataElement metadatum in itemDefinition.Metadata)
{
DebuggerManager.DefineState(metadatum.Location, metadatum.Location.LocationString, s_itemDefinitionPassLocalsTypes);
}
}
}
#endif
continue;
}
ProjectTargetElement target = element as ProjectTargetElement;
if (target != null)
{
#if FEATURE_MSBUILD_DEBUGGER
if (DebuggerManager.DebuggingEnabled)
{
DebuggerManager.DefineState(element.Location, element.Location.LocationString, s_itemPassLocalsTypes);
foreach (ProjectElement child in (target.AllChildren))
{
DebuggerManager.DefineState(child.Location, child.Location.LocationString, s_itemPassLocalsTypes);
}
}
#endif
if (_projectSupportsReturnsAttribute.ContainsKey(currentProjectOrImport))
{
_projectSupportsReturnsAttribute[currentProjectOrImport] |= (target.Returns != null);
}
else
{
_projectSupportsReturnsAttribute[currentProjectOrImport] = (target.Returns != null);
}
_targetElements.Add(target);
continue;
}
ProjectImportElement import = element as ProjectImportElement;
if (import != null)
{
EvaluateImportElement(currentProjectOrImport.DirectoryPath, import);
continue;
}
ProjectImportGroupElement importGroup = element as ProjectImportGroupElement;
if (importGroup != null)
{
EvaluateImportGroupElement(currentProjectOrImport.DirectoryPath, importGroup);
continue;
}
ProjectUsingTaskElement usingTask = element as ProjectUsingTaskElement;
if (usingTask != null)
{
#if FEATURE_MSBUILD_DEBUGGER
if (DebuggerManager.DebuggingEnabled)
{
DebuggerManager.DefineState(element.Location, element.Location.LocationString, s_itemPassLocalsTypes);
}
#endif
_usingTaskElements.Add(new Pair<string, ProjectUsingTaskElement>(currentProjectOrImport.DirectoryPath, usingTask));
continue;
}
ProjectChooseElement choose = element as ProjectChooseElement;
if (choose != null)
{
#if FEATURE_MSBUILD_DEBUGGER
if (DebuggerManager.DebuggingEnabled)
{
// Already defined states for all choose children that were relevant to the
// property pass; now the ones relevant to the item pass, which get the item pass locals
foreach (ProjectElement child in choose.AllChildren)
{
if (child is ProjectItemGroupElement ||
child is ProjectItemElement ||
child is ProjectMetadataElement)
{
DebuggerManager.DefineState(child.Location, child.Location.LocationString, s_itemPassLocalsTypes);
}
}
}
#endif
EvaluateChooseElement(choose);
continue;
}
if (element is ProjectExtensionsElement)
{
continue;
}
ErrorUtilities.ThrowInternalError("Unexpected child type");
}
foreach (var import in implicitImports.Where(i => i.ImplicitImportLocation == ImplicitImportLocation.Bottom))
{
EvaluateImportElement(currentProjectOrImport.DirectoryPath, import);
}
#if FEATURE_MSBUILD_DEBUGGER
if (DebuggerManager.DebuggingEnabled)
{
DebuggerManager.BakeStates(Path.GetFileNameWithoutExtension(currentProjectOrImport.FullPath));
}
#endif
}