diff --git a/src/Build/BackEnd/Components/RequestBuilder/BatchingEngine.cs b/src/Build/BackEnd/Components/RequestBuilder/BatchingEngine.cs index 3e676950ea5..1e41d597a96 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/BatchingEngine.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/BatchingEngine.cs @@ -5,10 +5,10 @@ using System.Collections.Generic; using Microsoft.Build.Collections; -using ElementLocation = Microsoft.Build.Construction.ElementLocation; using Microsoft.Build.Evaluation; using Microsoft.Build.Execution; using Microsoft.Build.Shared; +using Microsoft.Build.Construction; namespace Microsoft.Build.BackEnd { @@ -80,7 +80,7 @@ internal static List PrepareBatchingBuckets ( List batchableObjectParameters, Lookup lookup, - ElementLocation elementLocation + IInternalLocation elementLocation ) { return PrepareBatchingBuckets(batchableObjectParameters, lookup, null, elementLocation); @@ -101,7 +101,7 @@ internal static List PrepareBatchingBuckets List batchableObjectParameters, Lookup lookup, string implicitBatchableItemType, - ElementLocation elementLocation + IInternalLocation elementLocation ) { if (batchableObjectParameters == null) @@ -204,7 +204,7 @@ private static Dictionary> GetItemLists // Value is [struct MetadataReference] HashSet consumedItemReferenceNames, Lookup lookup, - ElementLocation elementLocation + IInternalLocation elementLocation ) { // The keys in this hashtable are the names of the items that we will batch on. @@ -299,7 +299,7 @@ private static List BucketConsumedItems Lookup lookup, Dictionary> itemListsToBeBatched, Dictionary consumedMetadataReferences, - ElementLocation elementLocation + IInternalLocation elementLocation ) { ErrorUtilities.VerifyThrow(itemListsToBeBatched.Count > 0, "Need item types consumed by the batchable object."); @@ -382,7 +382,7 @@ private static Dictionary GetItemMetadataValues ( ProjectItemInstance item, Dictionary consumedMetadataReferences, - ElementLocation elementLocation + IInternalLocation elementLocation ) { var itemMetadataValues = new Dictionary(consumedMetadataReferences.Count, MSBuildNameIgnoreCaseComparer.Default); diff --git a/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/ItemGroupIntrinsicTask.cs b/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/ItemGroupIntrinsicTask.cs index f96e90a2822..4e9d8b9b2aa 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/ItemGroupIntrinsicTask.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/ItemGroupIntrinsicTask.cs @@ -6,7 +6,6 @@ using System.Collections.Immutable; using System.Linq; using Microsoft.Build.Collections; -using ElementLocation = Microsoft.Build.Construction.ElementLocation; using Microsoft.Build.Execution; using Microsoft.Build.Framework; using Microsoft.Build.Shared; @@ -15,6 +14,7 @@ using ProjectItemInstanceFactory = Microsoft.Build.Execution.ProjectItemInstance.TaskItem.ProjectItemInstanceFactory; using EngineFileUtilities = Microsoft.Build.Internal.EngineFileUtilities; using TargetLoggingContext = Microsoft.Build.BackEnd.Logging.TargetLoggingContext; +using Microsoft.Build.Construction; namespace Microsoft.Build.BackEnd { @@ -47,6 +47,7 @@ public ItemGroupIntrinsicTask(ProjectItemGroupTaskInstance taskInstance, TargetL /// The lookup used for evaluation and as a destination for these items. internal override void ExecuteTask(Lookup lookup) { + var location = _taskInstance.Location; foreach (ProjectItemGroupTaskItemInstance child in _taskInstance.Items) { List buckets = null; @@ -55,7 +56,7 @@ internal override void ExecuteTask(Lookup lookup) { List parameterValues = new List(); GetBatchableValuesFromBuildItemGroupChild(parameterValues, child); - buckets = BatchingEngine.PrepareBatchingBuckets(parameterValues, lookup, child.ItemType, _taskInstance.Location); + buckets = BatchingEngine.PrepareBatchingBuckets(parameterValues, lookup, child.ItemType, location); // "Execute" each bucket foreach (ItemBucket bucket in buckets) @@ -174,14 +175,14 @@ private void ExecuteAdd(ProjectItemGroupTaskItemInstance child, ItemBucket bucke bucket.Expander, ExpanderOptions.ExpandAll, Project.Directory, - metadataInstance.Location, + metadataInstance, LoggingContext.LoggingService, LoggingContext.BuildEventContext, FileSystems.Default); if (condition) { - string evaluatedValue = bucket.Expander.ExpandIntoStringLeaveEscaped(metadataInstance.Value, ExpanderOptions.ExpandAll, metadataInstance.Location); + string evaluatedValue = bucket.Expander.ExpandIntoStringLeaveEscaped(metadataInstance.Value, ExpanderOptions.ExpandAll, metadataInstance); // This both stores the metadata so we can add it to all the items we just created later, and // exposes this metadata to further metadata evaluations in subsequent loop iterations. @@ -319,7 +320,7 @@ private void ExecuteModify(ProjectItemGroupTaskItemInstance child, ItemBucket bu if (condition) { - string evaluatedValue = bucket.Expander.ExpandIntoStringLeaveEscaped(metadataInstance.Value, ExpanderOptions.ExpandAll, metadataInstance.Location); + string evaluatedValue = bucket.Expander.ExpandIntoStringLeaveEscaped(metadataInstance.Value, ExpanderOptions.ExpandAll, metadataInstance); metadataToSet[metadataInstance.Name] = Lookup.MetadataModification.CreateFromNewValue(evaluatedValue); } } @@ -512,7 +513,7 @@ private List FindItemsMatchingSpecification ( ICollection items, string specification, - ElementLocation specificationLocation, + IInternalLocation specificationLocation, Expander expander ) { diff --git a/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/PropertyGroupIntrinsicTask.cs b/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/PropertyGroupIntrinsicTask.cs index 14feb6aa094..e430005655c 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/PropertyGroupIntrinsicTask.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/PropertyGroupIntrinsicTask.cs @@ -50,7 +50,8 @@ internal override void ExecuteTask(Lookup lookup) // Find all the metadata references in order to create buckets List parameterValues = new List(); GetBatchableValuesFromProperty(parameterValues, property); - buckets = BatchingEngine.PrepareBatchingBuckets(parameterValues, lookup, property.Location); + buckets = BatchingEngine.PrepareBatchingBuckets(parameterValues, lookup, property); + var propertyLocation = property.ConditionLocation; // "Execute" each bucket foreach (ItemBucket bucket in buckets) @@ -62,7 +63,7 @@ internal override void ExecuteTask(Lookup lookup) bucket.Expander, ExpanderOptions.ExpandAll, Project.Directory, - property.ConditionLocation, + propertyLocation, LoggingContext.LoggingService, LoggingContext.BuildEventContext, FileSystems.Default); @@ -74,12 +75,12 @@ internal override void ExecuteTask(Lookup lookup) ProjectErrorUtilities.VerifyThrowInvalidProject ( !ReservedPropertyNames.IsReservedProperty(property.Name), - property.Location, + property, "CannotModifyReservedProperty", property.Name ); - string evaluatedValue = bucket.Expander.ExpandIntoStringLeaveEscaped(property.Value, ExpanderOptions.ExpandAll, property.Location); + string evaluatedValue = bucket.Expander.ExpandIntoStringLeaveEscaped(property.Value, ExpanderOptions.ExpandAll, property); if (LogTaskInputs && !LoggingContext.LoggingService.OnlyLogCriticalEvents) { diff --git a/src/Build/BackEnd/Components/RequestBuilder/TargetEntry.cs b/src/Build/BackEnd/Components/RequestBuilder/TargetEntry.cs index d3a925b34a8..40e4add4def 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/TargetEntry.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/TargetEntry.cs @@ -424,7 +424,7 @@ internal async Task ExecuteTarget(ITaskBuilder taskBuilder, BuildRequestEntry re // Generate the batching buckets. Note that each bucket will get a lookup based on the baseLookup. This lookup will be in its // own scope, which we will collapse back down into the baseLookup at the bottom of the function. - List buckets = BatchingEngine.PrepareBatchingBuckets(GetBatchableParametersForTarget(), _baseLookup, _target.Location); + List buckets = BatchingEngine.PrepareBatchingBuckets(GetBatchableParametersForTarget(), _baseLookup, _target); WorkUnitResult aggregateResult = new WorkUnitResult(); TargetLoggingContext targetLoggingContext = null; @@ -617,7 +617,7 @@ internal async Task ExecuteTarget(ITaskBuilder taskBuilder, BuildRequestEntry re // Also, we are using the baseLookup, which has possibly had changes made to it since the project started. Because of this, the // set of outputs calculated here may differ from those which would have been calculated at the beginning of the target. It is // assumed the user intended this. - List batchingBuckets = BatchingEngine.PrepareBatchingBuckets(GetBatchableParametersForTarget(), _baseLookup, _target.Location); + List batchingBuckets = BatchingEngine.PrepareBatchingBuckets(GetBatchableParametersForTarget(), _baseLookup, _target); if (keepDupes) { diff --git a/src/Build/BackEnd/Components/RequestBuilder/TargetUpToDateChecker.cs b/src/Build/BackEnd/Components/RequestBuilder/TargetUpToDateChecker.cs index 9013bc11272..220dc17e282 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/TargetUpToDateChecker.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/TargetUpToDateChecker.cs @@ -7,12 +7,12 @@ using System.Linq; using Microsoft.Build.Collections; +using Microsoft.Build.Construction; using Microsoft.Build.Evaluation; using Microsoft.Build.Execution; using Microsoft.Build.Framework; using Microsoft.Build.Shared; -using ElementLocation = Microsoft.Build.Construction.ElementLocation; using ProjectItemInstanceFactory = Microsoft.Build.Execution.ProjectItemInstance.TaskItem.ProjectItemInstanceFactory; namespace Microsoft.Build.BackEnd @@ -391,8 +391,10 @@ out List targetOutputItemSpecs { // break down the input/output specifications along the standard separator, after expanding all embedded properties // and item metadata - var targetInputs = bucket.Expander.ExpandIntoStringListLeaveEscaped(TargetInputSpecification, ExpanderOptions.ExpandPropertiesAndMetadata, _targetToAnalyze.InputsLocation); - var targetOutputs = bucket.Expander.ExpandIntoStringListLeaveEscaped(TargetOutputSpecification, ExpanderOptions.ExpandPropertiesAndMetadata, _targetToAnalyze.OutputsLocation); + var inputLocation = _targetToAnalyze.InputsLocation; + var outputLocation = _targetToAnalyze.OutputsLocation; + var targetInputs = bucket.Expander.ExpandIntoStringListLeaveEscaped(TargetInputSpecification, ExpanderOptions.ExpandPropertiesAndMetadata, inputLocation); + var targetOutputs = bucket.Expander.ExpandIntoStringListLeaveEscaped(TargetOutputSpecification, ExpanderOptions.ExpandPropertiesAndMetadata, outputLocation); itemVectorTransformsInTargetInputs = new ItemVectorPartitionCollection(MSBuildNameIgnoreCaseComparer.Default); @@ -406,7 +408,7 @@ out List targetOutputItemSpecs out itemVectorsInTargetInputs, itemVectorTransformsInTargetInputs, out discreteItemsInTargetInputs, - _targetToAnalyze.InputsLocation); + inputLocation); // figure out which of the outputs are: // 1) item vectors (with or without transforms) @@ -417,7 +419,7 @@ out List targetOutputItemSpecs out itemVectorsInTargetOutputs, null /* don't want transforms separated */, out discreteItemsInTargetOutputs, - _targetToAnalyze.OutputsLocation); + outputLocation); // list out all the output item-specs targetOutputItemSpecs = GetItemSpecsFromItemVectors(itemVectorsInTargetOutputs); @@ -785,7 +787,7 @@ private void SeparateItemVectorsFromDiscreteItems out ItemVectorPartitionCollection itemVectors, ItemVectorPartitionCollection itemVectorTransforms, out Dictionary discreteItems, - ElementLocation elementLocation + IInternalLocation elementLocation ) { itemVectors = new ItemVectorPartitionCollection(MSBuildNameIgnoreCaseComparer.Default); diff --git a/src/Build/BackEnd/Components/RequestBuilder/TaskBuilder.cs b/src/Build/BackEnd/Components/RequestBuilder/TaskBuilder.cs index 5fdd1a3e145..9bbc0b814f7 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/TaskBuilder.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/TaskBuilder.cs @@ -306,7 +306,7 @@ private async Task ExecuteTask(TaskExecutionMode mode, Lookup lo } List taskParameterValues = CreateListOfParameterValues(); - buckets = BatchingEngine.PrepareBatchingBuckets(taskParameterValues, lookup, _targetChildInstance.Location); + buckets = BatchingEngine.PrepareBatchingBuckets(taskParameterValues, lookup, _targetChildInstance); Dictionary lookupHash = null; @@ -645,7 +645,7 @@ private async Task InitializeAndExecuteTask(TaskLoggingContext t { if (!_taskExecutionHost.InitializeForBatch(taskLoggingContext, bucket, taskIdentityParameters)) { - ProjectErrorUtilities.ThrowInvalidProject(_targetChildInstance.Location, "TaskDeclarationOrUsageError", _taskNode.Name); + ProjectErrorUtilities.ThrowInvalidProject(_targetChildInstance, "TaskDeclarationOrUsageError", _taskNode.Name); } try @@ -740,7 +740,7 @@ private async Task ExecuteInstantiatedTask(ITaskExecutionHost ta if (!taskExecutionHost.SetTaskParameters(_taskNode.ParametersForBuild)) { // The task cannot be initialized. - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _targetChildInstance.Location, "TaskParametersError", _taskNode.Name, String.Empty); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _targetChildInstance, "TaskParametersError", _taskNode.Name, String.Empty); } else { @@ -866,7 +866,7 @@ private async Task ExecuteInstantiatedTask(ITaskExecutionHost ta else if (type == typeof(CircularDependencyException)) { _continueOnError = ContinueOnError.ErrorAndStop; - ProjectErrorUtilities.ThrowInvalidProject(taskLoggingContext.Task.Location, "CircularDependency", taskLoggingContext.TargetLoggingContext.Target.Name); + ProjectErrorUtilities.ThrowInvalidProject(taskLoggingContext.Task, "CircularDependency", taskLoggingContext.TargetLoggingContext.Target.Name); } else if (type == typeof(InvalidProjectFileException)) { @@ -1084,14 +1084,15 @@ private bool GatherTaskOutputs(ITaskExecutionHost taskExecutionHost, TaskExecuti if (taskOutputItemInstance != null) { // expand all embedded properties, item metadata and item vectors in the item type name + var itemTypeLocation = taskOutputItemInstance.ItemTypeLocation; outputTargetIsItem = true; - outputTargetName = bucket.Expander.ExpandIntoStringAndUnescape(taskOutputItemInstance.ItemType, ExpanderOptions.ExpandAll, taskOutputItemInstance.ItemTypeLocation); + outputTargetName = bucket.Expander.ExpandIntoStringAndUnescape(taskOutputItemInstance.ItemType, ExpanderOptions.ExpandAll, itemTypeLocation); taskParameterName = taskOutputItemInstance.TaskParameter; ProjectErrorUtilities.VerifyThrowInvalidProject ( outputTargetName.Length > 0, - taskOutputItemInstance.ItemTypeLocation, + itemTypeLocation, "InvalidEvaluatedAttributeValue", outputTargetName, taskOutputItemInstance.ItemType, @@ -1105,13 +1106,14 @@ private bool GatherTaskOutputs(ITaskExecutionHost taskExecutionHost, TaskExecuti outputTargetIsItem = false; // expand all embedded properties, item metadata and item vectors in the property name - outputTargetName = bucket.Expander.ExpandIntoStringAndUnescape(taskOutputPropertyInstance.PropertyName, ExpanderOptions.ExpandAll, taskOutputPropertyInstance.PropertyNameLocation); + var propertyNameLocation = taskOutputPropertyInstance.PropertyNameLocation; + outputTargetName = bucket.Expander.ExpandIntoStringAndUnescape(taskOutputPropertyInstance.PropertyName, ExpanderOptions.ExpandAll, propertyNameLocation); taskParameterName = taskOutputPropertyInstance.TaskParameter; ProjectErrorUtilities.VerifyThrowInvalidProject ( outputTargetName.Length > 0, - taskOutputPropertyInstance.PropertyNameLocation, + propertyNameLocation, "InvalidEvaluatedAttributeValue", outputTargetName, taskOutputPropertyInstance.PropertyName, @@ -1121,12 +1123,13 @@ private bool GatherTaskOutputs(ITaskExecutionHost taskExecutionHost, TaskExecuti } string unexpandedTaskParameterName = taskParameterName; - taskParameterName = bucket.Expander.ExpandIntoStringAndUnescape(taskParameterName, ExpanderOptions.ExpandAll, taskOutputSpecification.TaskParameterLocation); + var taskParaLocation = taskOutputSpecification.TaskParameterLocation; + taskParameterName = bucket.Expander.ExpandIntoStringAndUnescape(taskParameterName, ExpanderOptions.ExpandAll, taskParaLocation); ProjectErrorUtilities.VerifyThrowInvalidProject ( taskParameterName.Length > 0, - taskOutputSpecification.TaskParameterLocation, + taskParaLocation, "InvalidEvaluatedAttributeValue", taskParameterName, unexpandedTaskParameterName, @@ -1184,14 +1187,15 @@ ItemBucket bucket ProjectTaskOutputItemInstance taskItemInstance = taskOutputSpecification as ProjectTaskOutputItemInstance; if (taskItemInstance != null) { + var taskParaLocation = taskItemInstance.TaskParameterLocation; // This is an output item. // Expand only with properties first, so that expressions like Include="@(foo)" will transfer the metadata of the "foo" items as well, not just their item specs. - var outputItemSpecs = bucket.Expander.ExpandIntoStringListLeaveEscaped(taskParameterAttribute, ExpanderOptions.ExpandPropertiesAndMetadata, taskItemInstance.TaskParameterLocation); + var outputItemSpecs = bucket.Expander.ExpandIntoStringListLeaveEscaped(taskParameterAttribute, ExpanderOptions.ExpandPropertiesAndMetadata, taskParaLocation); ProjectItemInstanceFactory itemFactory = new ProjectItemInstanceFactory(_buildRequestEntry.RequestConfiguration.Project, itemName); foreach (string outputItemSpec in outputItemSpecs) { - ICollection items = bucket.Expander.ExpandIntoItemsLeaveEscaped(outputItemSpec, itemFactory, ExpanderOptions.ExpandItems, taskItemInstance.TaskParameterLocation); + ICollection items = bucket.Expander.ExpandIntoItemsLeaveEscaped(outputItemSpec, itemFactory, ExpanderOptions.ExpandItems, taskParaLocation); lookup.AddNewItemsOfItemType(itemName, items); } @@ -1201,11 +1205,12 @@ ItemBucket bucket // This is an output property. ProjectTaskOutputPropertyInstance taskPropertyInstance = (ProjectTaskOutputPropertyInstance)taskOutputSpecification; - string taskParameterValue = bucket.Expander.ExpandIntoStringAndUnescape(taskParameterAttribute, ExpanderOptions.ExpandAll, taskPropertyInstance.TaskParameterLocation); + var taskPropertyLocation = taskPropertyInstance.TaskParameterLocation; + string taskParameterValue = bucket.Expander.ExpandIntoStringAndUnescape(taskParameterAttribute, ExpanderOptions.ExpandAll, taskPropertyLocation); if (!String.IsNullOrEmpty(taskParameterValue)) { - lookup.SetProperty(ProjectPropertyInstance.Create(propertyName, taskParameterValue, taskPropertyInstance.TaskParameterLocation, _buildRequestEntry.RequestConfiguration.Project.IsImmutable)); + lookup.SetProperty(ProjectPropertyInstance.Create(propertyName, taskParameterValue, taskPropertyLocation, _buildRequestEntry.RequestConfiguration.Project.IsImmutable)); } } } diff --git a/src/Build/Construction/ProjectChooseElement.cs b/src/Build/Construction/ProjectChooseElement.cs index def7d686cff..f15667f40fc 100644 --- a/src/Build/Construction/ProjectChooseElement.cs +++ b/src/Build/Construction/ProjectChooseElement.cs @@ -116,7 +116,7 @@ internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElem nestingDepth++; // This should really be an OM error, with no error number. But it's so obscure, it's not worth a new string. - ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= ProjectParser.MaximumChooseNesting, immediateParent.Location, "ChooseOverflow", ProjectParser.MaximumChooseNesting); + ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= ProjectParser.MaximumChooseNesting, immediateParent, "ChooseOverflow", ProjectParser.MaximumChooseNesting); } } diff --git a/src/Build/Construction/ProjectElement.cs b/src/Build/Construction/ProjectElement.cs index 8327feda09e..0cb463bd72c 100644 --- a/src/Build/Construction/ProjectElement.cs +++ b/src/Build/Construction/ProjectElement.cs @@ -15,7 +15,7 @@ namespace Microsoft.Build.Construction /// /// Abstract base class for MSBuild construction object model elements. /// - public abstract class ProjectElement : IProjectElement, ILinkableObject + public abstract class ProjectElement : IInternalLocation, IProjectElement, ILinkableObject { /// /// Parent container object. @@ -299,6 +299,8 @@ internal set internal ProjectElementLink Link => _xmlSource?.Link; + IElementLocation IInternalLocation.Location => Location; + /// /// /// diff --git a/src/Build/Construction/ProjectElementContainer.cs b/src/Build/Construction/ProjectElementContainer.cs index 3c4c0d6f269..fb3083a0928 100644 --- a/src/Build/Construction/ProjectElementContainer.cs +++ b/src/Build/Construction/ProjectElementContainer.cs @@ -464,7 +464,7 @@ internal void AddToXml(ProjectElement child) // Make sure we're not trying to add multiple attributes with the same name ProjectErrorUtilities.VerifyThrowInvalidProject(!XmlElement.HasAttribute(child.XmlElement.Name), - XmlElement.Location, "InvalidChildElementDueToDuplication", child.XmlElement.Name, ElementName); + XmlElement, "InvalidChildElementDueToDuplication", child.XmlElement.Name, ElementName); SetElementAsAttributeValue(child); } diff --git a/src/Build/Construction/ProjectItemDefinitionElement.cs b/src/Build/Construction/ProjectItemDefinitionElement.cs index 2f93312bc32..62f3fa7b371 100644 --- a/src/Build/Construction/ProjectItemDefinitionElement.cs +++ b/src/Build/Construction/ProjectItemDefinitionElement.cs @@ -77,7 +77,7 @@ public ProjectMetadataElement AddMetadata(string name, string unevaluatedValue, if (expressAsAttribute) { - ProjectMetadataElement.ValidateValidMetadataAsAttributeName(name, ElementName, Location); + ProjectMetadataElement.ValidateValidMetadataAsAttributeName(name, ElementName, this); } ProjectMetadataElement metadata = ContainingProject.CreateMetadataElement(name); diff --git a/src/Build/Construction/ProjectItemElement.cs b/src/Build/Construction/ProjectItemElement.cs index dd7f7f6ea6c..0d1460108af 100644 --- a/src/Build/Construction/ProjectItemElement.cs +++ b/src/Build/Construction/ProjectItemElement.cs @@ -394,7 +394,7 @@ public ProjectMetadataElement AddMetadata(string name, string unevaluatedValue, if (expressAsAttribute) { - ProjectMetadataElement.ValidateValidMetadataAsAttributeName(name, ElementName, Location); + ProjectMetadataElement.ValidateValidMetadataAsAttributeName(name, ElementName, this); } ProjectMetadataElement metadata = ContainingProject.CreateMetadataElement(name); diff --git a/src/Build/Construction/ProjectMetadataElement.cs b/src/Build/Construction/ProjectMetadataElement.cs index 9657cc1a647..423badd0907 100644 --- a/src/Build/Construction/ProjectMetadataElement.cs +++ b/src/Build/Construction/ProjectMetadataElement.cs @@ -65,7 +65,7 @@ public string Name { if (value) { - ValidateValidMetadataAsAttributeName(Name, Parent?.ElementName ?? "null" , Parent?.Location); + ValidateValidMetadataAsAttributeName(Name, Parent?.ElementName ?? "null" , Parent); } base.ExpressedAsAttribute = value; } @@ -129,7 +129,7 @@ internal void ChangeName(string newName) if (ExpressedAsAttribute) { - ValidateValidMetadataAsAttributeName(newName, Parent.ElementName, Parent.Location); + ValidateValidMetadataAsAttributeName(newName, Parent.ElementName, Parent); } // Because the element was created from our special XmlDocument, we know it's @@ -139,7 +139,7 @@ internal void ChangeName(string newName) ReplaceElement(newElement); } - internal static void ValidateValidMetadataAsAttributeName(string name, string parentName, IElementLocation parentLocation) + internal static void ValidateValidMetadataAsAttributeName(string name, string parentName, IInternalLocation parentLocation) { if (!AttributeNameIsValidMetadataName(name)) { diff --git a/src/Build/Construction/ProjectRootElement.cs b/src/Build/Construction/ProjectRootElement.cs index 389f1f3cf6e..3bf2d95f3ab 100644 --- a/src/Build/Construction/ProjectRootElement.cs +++ b/src/Build/Construction/ProjectRootElement.cs @@ -1900,7 +1900,7 @@ internal List GetImplicitImportNodes(ProjectRootElement cu return nodes; } - private static IEnumerable ParseSdks(string sdks, IElementLocation sdkLocation) + private static IEnumerable ParseSdks(string sdks, IInternalLocation sdkLocation) { foreach (string sdk in sdks.Split(MSBuildConstants.SemicolonChar).Select(i => i.Trim())) { diff --git a/src/Build/Definition/Project.cs b/src/Build/Definition/Project.cs index ff29b8ec3a5..7588b4c3b3d 100644 --- a/src/Build/Definition/Project.cs +++ b/src/Build/Definition/Project.cs @@ -2744,7 +2744,7 @@ private List GetItemProvenance(string itemToMatch, IEnumerable // TODO: cache result? private ProvenanceResult ComputeProvenanceResult(string itemToMatch, ProjectItemElement itemElement) { - ProvenanceResult SingleItemSpecProvenance(string itemSpec, IElementLocation elementLocation, Operation operation) + ProvenanceResult SingleItemSpecProvenance(string itemSpec, IInternalLocation elementLocation, Operation operation) { if (elementLocation != null && !string.IsNullOrEmpty(itemSpec)) { diff --git a/src/Build/Definition/ProjectItem.cs b/src/Build/Definition/ProjectItem.cs index 0b3c28e1562..abdcab3e213 100644 --- a/src/Build/Definition/ProjectItem.cs +++ b/src/Build/Definition/ProjectItem.cs @@ -492,7 +492,7 @@ string IItem.GetMetadataValueEscaped(string name) { Expander expander = new Expander(null, null, new BuiltInMetadataTable(this), FileSystems.Default); - value = expander.ExpandIntoStringLeaveEscaped(metadatum.EvaluatedValueEscaped, ExpanderOptions.ExpandBuiltInMetadata, metadatum.Location); + value = expander.ExpandIntoStringLeaveEscaped(metadatum.EvaluatedValueEscaped, ExpanderOptions.ExpandBuiltInMetadata, metadatum); } else if (metadatum != null) { diff --git a/src/Build/Definition/ProjectMetadata.cs b/src/Build/Definition/ProjectMetadata.cs index 2e5f4c958ae..1d80c10fa40 100644 --- a/src/Build/Definition/ProjectMetadata.cs +++ b/src/Build/Definition/ProjectMetadata.cs @@ -18,7 +18,7 @@ namespace Microsoft.Build.Evaluation /// Never used to represent built-in metadata, like %(Filename). There is always a backing XML object. /// [DebuggerDisplay("{Name}={EvaluatedValue} [{_xml.Value}]")] - public class ProjectMetadata : IEquatable, IMetadatum + public class ProjectMetadata : IEquatable, IMetadatum, IInternalLocation { /// /// Parent item or item definition that this metadatum lives in. @@ -266,6 +266,8 @@ internal string EvaluatedValueEscaped get => Link != null ? Link.EvaluatedValueEscaped : _evaluatedValueEscaped; } + IElementLocation IInternalLocation.Location => Location; + #region IEquatable Members /// diff --git a/src/Build/Definition/Toolset.cs b/src/Build/Definition/Toolset.cs index 77d32963bf6..ecc61d9828f 100644 --- a/src/Build/Definition/Toolset.cs +++ b/src/Build/Definition/Toolset.cs @@ -1065,7 +1065,7 @@ private void LoadAndRegisterFromTasksFile(string[] defaultTaskFiles, ILoggingSer { ProjectErrorUtilities.ThrowInvalidProject ( - elementXml.Location, + elementXml, "UnrecognizedElement", elementXml.XmlElement.Name ); diff --git a/src/Build/ElementLocation/ElementLocation.cs b/src/Build/ElementLocation/ElementLocation.cs index 3b5a286956a..ccd02a7c515 100644 --- a/src/Build/ElementLocation/ElementLocation.cs +++ b/src/Build/ElementLocation/ElementLocation.cs @@ -83,6 +83,8 @@ internal static ElementLocation EmptyLocation get { return s_emptyElementLocation; } } + IElementLocation IInternalLocation.Location => this; + /// /// Get reasonable hash code. /// @@ -171,7 +173,7 @@ internal static ElementLocation FactoryForDeserialization(ITranslator translator /// internal static ElementLocation Create(string file) { - return Create(file, 0, 0); + return string.IsNullOrEmpty(file) ? EmptyLocation : new ElementLocation.SmallElementLocation(file, 0, 0); } /// @@ -185,7 +187,7 @@ internal static ElementLocation Create(string file) /// internal static ElementLocation Create(string file, int line, int column) { - if (string.IsNullOrEmpty(file) && line == 0 && column == 0) + if (line == 0 && column == 0 && string.IsNullOrEmpty(file)) { return EmptyLocation; } @@ -371,4 +373,10 @@ public override int Column } } } + + // internal interface + internal interface IInternalLocation + { + public IElementLocation Location { get; } + } } diff --git a/src/Build/ElementLocation/RegistryLocation.cs b/src/Build/ElementLocation/RegistryLocation.cs index d6577196d97..81dbd388596 100644 --- a/src/Build/ElementLocation/RegistryLocation.cs +++ b/src/Build/ElementLocation/RegistryLocation.cs @@ -74,6 +74,8 @@ public string LocationString get { return registryPath; } } + public IElementLocation Location => this; + #region INodePacketTranslatable Members /// diff --git a/src/Build/ElementLocation/XmlAttributeWithLocation.cs b/src/Build/ElementLocation/XmlAttributeWithLocation.cs index 25820d1d1bb..fdb1755615b 100644 --- a/src/Build/ElementLocation/XmlAttributeWithLocation.cs +++ b/src/Build/ElementLocation/XmlAttributeWithLocation.cs @@ -4,13 +4,14 @@ using System; using System.Xml; using System.Diagnostics; +using Microsoft.Build.Shared; namespace Microsoft.Build.Construction { /// /// Derivation of XmlAttribute to implement IXmlLineInfo /// - internal class XmlAttributeWithLocation : XmlAttribute, IXmlLineInfo + internal class XmlAttributeWithLocation : XmlAttribute, IInternalLocation, IXmlLineInfo { /// /// Line, column, file information @@ -81,6 +82,8 @@ internal ElementLocation Location } } + IElementLocation IInternalLocation.Location => Location; + /// /// Whether location is available. /// IXmlLineInfo member. @@ -90,4 +93,4 @@ public bool HasLineInfo() return Location.Line != 0; } } -} \ No newline at end of file +} diff --git a/src/Build/ElementLocation/XmlElementWithLocation.cs b/src/Build/ElementLocation/XmlElementWithLocation.cs index 7da601d28b2..2a1ed223dc7 100644 --- a/src/Build/ElementLocation/XmlElementWithLocation.cs +++ b/src/Build/ElementLocation/XmlElementWithLocation.cs @@ -5,6 +5,7 @@ using System.Xml; using System.Diagnostics; using Microsoft.Build.ObjectModelRemoting; +using Microsoft.Build.Shared; namespace Microsoft.Build.Construction { @@ -17,7 +18,7 @@ namespace Microsoft.Build.Construction /// C# doesn't currently allow covariance in method overloading, only on delegates. /// The caller must bravely downcast. /// - internal class XmlElementWithLocation : XmlElement, IXmlLineInfo, ILinkedXml + internal class XmlElementWithLocation : XmlElement, IInternalLocation, IXmlLineInfo, ILinkedXml { /// /// Line, column, file information @@ -101,6 +102,8 @@ internal ElementLocation Location } } + IElementLocation IInternalLocation.Location => Location; + /// /// Whether location is available. /// IXmlLineInfo member. diff --git a/src/Build/Evaluation/ConditionEvaluator.cs b/src/Build/Evaluation/ConditionEvaluator.cs index 8eb493e6398..ae03b1fb43f 100644 --- a/src/Build/Evaluation/ConditionEvaluator.cs +++ b/src/Build/Evaluation/ConditionEvaluator.cs @@ -15,6 +15,7 @@ namespace Microsoft.Build.Evaluation using ElementLocation = Microsoft.Build.Construction.ElementLocation; using Microsoft.Build.Shared; using Microsoft.Build.Shared.FileSystem; + using Microsoft.Build.Construction; internal static class ConditionEvaluator { @@ -175,7 +176,7 @@ internal static bool EvaluateCondition Expander expander, ExpanderOptions expanderOptions, string evaluationDirectory, - ElementLocation elementLocation, + IInternalLocation location, ILoggingService loggingServices, BuildEventContext buildEventContext, IFileSystem fileSystem, @@ -190,7 +191,7 @@ internal static bool EvaluateCondition expanderOptions, null /* do not collect conditioned properties */, evaluationDirectory, - elementLocation, + location, loggingServices, buildEventContext, fileSystem, @@ -212,7 +213,7 @@ internal static bool EvaluateConditionCollectingConditionedProperties ExpanderOptions expanderOptions, Dictionary> conditionedPropertiesTable, string evaluationDirectory, - ElementLocation elementLocation, + IInternalLocation elementLocation, ILoggingService loggingServices, BuildEventContext buildEventContext, IFileSystem fileSystem, @@ -337,7 +338,7 @@ internal interface IConditionEvaluationState string EvaluationDirectory { get; } - ElementLocation ElementLocation { get; } + IInternalLocation ElementLocation { get; } /// /// Table of conditioned properties and their values. @@ -390,7 +391,7 @@ internal class ConditionEvaluationState : IConditionEvaluationState public string EvaluationDirectory { get; } - public ElementLocation ElementLocation { get; } + public IInternalLocation ElementLocation { get; } public IFileSystem FileSystem { get; } @@ -414,7 +415,7 @@ internal ConditionEvaluationState ExpanderOptions expanderOptions, Dictionary> conditionedPropertiesInProject, string evaluationDirectory, - ElementLocation elementLocation, + IInternalLocation element, IFileSystem fileSystem, ProjectRootElementCacheBase projectRootElementCache = null ) @@ -422,14 +423,14 @@ internal ConditionEvaluationState ErrorUtilities.VerifyThrowArgumentNull(condition, nameof(condition)); ErrorUtilities.VerifyThrowArgumentNull(expander, nameof(expander)); ErrorUtilities.VerifyThrowArgumentNull(evaluationDirectory, nameof(evaluationDirectory)); - ErrorUtilities.VerifyThrowArgumentNull(elementLocation, nameof(elementLocation)); + ErrorUtilities.VerifyThrowArgumentNull(element, nameof(element)); Condition = condition; _expander = expander; _expanderOptions = expanderOptions; ConditionedPropertiesInProject = conditionedPropertiesInProject; // May be null EvaluationDirectory = evaluationDirectory; - ElementLocation = elementLocation; + ElementLocation = element; LoadedProjectsCache = projectRootElementCache; FileSystem = fileSystem; } diff --git a/src/Build/Evaluation/Conditionals/Parser.cs b/src/Build/Evaluation/Conditionals/Parser.cs index ac231b18964..98b6747419c 100644 --- a/src/Build/Evaluation/Conditionals/Parser.cs +++ b/src/Build/Evaluation/Conditionals/Parser.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using Microsoft.Build.Construction; using Microsoft.Build.Framework; using Microsoft.Build.Shared; using ElementLocation = Microsoft.Build.Construction.ElementLocation; @@ -42,7 +43,7 @@ internal sealed class Parser { private Scanner _lexer; private ParserOptions _options; - private ElementLocation _elementLocation; + private IInternalLocation _element; internal int errorPosition = 0; // useful for unit tests #region REMOVE_COMPAT_WARNING @@ -93,7 +94,7 @@ internal Parser() // You pass in the expression you want to parse, and you get an // ExpressionTree out the back end. // - internal GenericExpressionNode Parse(string expression, ParserOptions optionSettings, ElementLocation elementLocation) + internal GenericExpressionNode Parse(string expression, ParserOptions optionSettings, IInternalLocation element) { // We currently have no support (and no scenarios) for disallowing property references // in Conditions. @@ -101,19 +102,19 @@ internal GenericExpressionNode Parse(string expression, ParserOptions optionSett "Properties should always be allowed."); _options = optionSettings; - _elementLocation = elementLocation; + _element = element; _lexer = new Scanner(expression, _options); if (!_lexer.Advance()) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, _lexer.GetErrorResource(), expression, errorPosition, _lexer.UnexpectedlyFound); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, _lexer.GetErrorResource(), expression, errorPosition, _lexer.UnexpectedlyFound); } GenericExpressionNode node = Expr(expression); if (!_lexer.IsNext(Token.TokenType.EndOfInput)) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } return node; } @@ -141,7 +142,7 @@ private GenericExpressionNode Expr(string expression) // Log a warning regarding the fact the expression may have been evaluated // incorrectly in earlier version of MSBuild - LoggingServices.LogWarning(_logBuildEventContext, null, new BuildEventFileInfo(_elementLocation), "ConditionMaybeEvaluatedIncorrectly", expression); + LoggingServices.LogWarning(_logBuildEventContext, null, new BuildEventFileInfo(_element.Location), "ConditionMaybeEvaluatedIncorrectly", expression); } #endregion @@ -177,7 +178,7 @@ private GenericExpressionNode BooleanTerm(string expression) if (node == null) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } if (!_lexer.IsNext(Token.TokenType.EndOfInput)) @@ -199,7 +200,7 @@ private GenericExpressionNode BooleanTermPrime(string expression, GenericExpress if (rhs == null) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } OperatorExpressionNode andNode = new AndExpressionNode(); @@ -221,7 +222,7 @@ private GenericExpressionNode RelationalExpr(string expression) if (lhs == null) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } OperatorExpressionNode node = RelationalOperation(expression); @@ -284,7 +285,7 @@ private GenericExpressionNode Factor(string expression) if (!Same(expression, Token.TokenType.LeftParenthesis)) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", _lexer.IsNextString(), errorPosition); return null; } var arglist = new List(); @@ -292,7 +293,7 @@ private GenericExpressionNode Factor(string expression) if (!Same(expression, Token.TokenType.RightParenthesis)) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); return null; } return new FunctionCallExpressionNode(current.String, arglist); @@ -305,7 +306,7 @@ private GenericExpressionNode Factor(string expression) else { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } } else if (Same(expression, Token.TokenType.Not)) @@ -315,7 +316,7 @@ private GenericExpressionNode Factor(string expression) if (expr == null) { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } notNode.LeftChild = expr; return notNode; @@ -323,7 +324,7 @@ private GenericExpressionNode Factor(string expression) else { errorPosition = _lexer.GetErrorPosition(); - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } return null; } @@ -384,11 +385,11 @@ private bool Same(string expression, Token.TokenType token) errorPosition = _lexer.GetErrorPosition(); if (_lexer.UnexpectedlyFound != null) { - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, _lexer.GetErrorResource(), expression, errorPosition, _lexer.UnexpectedlyFound); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, _lexer.GetErrorResource(), expression, errorPosition, _lexer.UnexpectedlyFound); } else { - ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, _lexer.GetErrorResource(), expression, errorPosition); + ProjectErrorUtilities.VerifyThrowInvalidProject(false, _element, _lexer.GetErrorResource(), expression, errorPosition); } } return true; diff --git a/src/Build/Evaluation/Evaluator.cs b/src/Build/Evaluation/Evaluator.cs index e72f28469c6..5b2937f5425 100644 --- a/src/Build/Evaluation/Evaluator.cs +++ b/src/Build/Evaluation/Evaluator.cs @@ -839,7 +839,7 @@ private void PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) { foreach (string propertyName in _expander.ExpandIntoStringListLeaveEscaped(currentProjectOrImport.TreatAsLocalProperty, ExpanderOptions.ExpandProperties, currentProjectOrImport.TreatAsLocalPropertyLocation)) { - XmlUtilities.VerifyThrowProjectValidElementName(propertyName, currentProjectOrImport.Location); + XmlUtilities.VerifyThrowProjectValidElementName(propertyName, currentProjectOrImport); _data.GlobalPropertiesToTreatAsLocal.Add(propertyName); } } @@ -1288,21 +1288,21 @@ private void EvaluatePropertyElement(ProjectPropertyElement propertyElement) // it is the same as what we are setting the value on. Note: This needs to be set before we expand the property we are currently setting. _expander.UsedUninitializedProperties.CurrentlyEvaluatingPropertyElementName = propertyElement.Name; - string evaluatedValue = _expander.ExpandIntoStringLeaveEscaped(propertyElement.Value, ExpanderOptions.ExpandProperties, propertyElement.Location); + string evaluatedValue = _expander.ExpandIntoStringLeaveEscaped(propertyElement.Value, ExpanderOptions.ExpandProperties, propertyElement); // If we are going to set a property to a value other than null or empty we need to check to see if it has been used // during evaluation. if (evaluatedValue.Length > 0 && _expander.WarnForUninitializedProperties) { // Is the property we are currently setting in the list of properties which have been used but not initialized - IElementLocation elementWhichUsedProperty; + IInternalLocation elementWhichUsedProperty; bool isPropertyInList = _expander.UsedUninitializedProperties.Properties.TryGetValue(propertyElement.Name, out elementWhichUsedProperty); if (isPropertyInList) { // Once we are going to warn for a property once, remove it from the list so we do not add it again. _expander.UsedUninitializedProperties.Properties.Remove(propertyElement.Name); - _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(propertyElement.Location), "UsedUninitializedProperty", propertyElement.Name, elementWhichUsedProperty.LocationString); + _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(propertyElement.Location), "UsedUninitializedProperty", propertyElement.Name, elementWhichUsedProperty.Location.LocationString); } } @@ -1399,7 +1399,7 @@ private void EvaluateItemDefinitionElement(ProjectItemDefinitionElement itemDefi { if (EvaluateCondition(metadataElement, ExpanderOptions.ExpandPropertiesAndMetadata, ParserOptions.AllowPropertiesAndCustomMetadata)) { - string evaluatedValue = _expander.ExpandIntoStringLeaveEscaped(metadataElement.Value, ExpanderOptions.ExpandPropertiesAndCustomMetadata, itemDefinitionElement.Location); + string evaluatedValue = _expander.ExpandIntoStringLeaveEscaped(metadataElement.Value, ExpanderOptions.ExpandPropertiesAndCustomMetadata, itemDefinitionElement); M predecessor = itemDefinition.GetMetadata(metadataElement.Name); @@ -1767,7 +1767,7 @@ static bool HasProperty(string value, CompareInfo compareInfo) => if (mode == SdkReferencePropertyExpansionMode.DefaultExpand) mode = SdkReferencePropertyExpansionMode.ExpandUnescape; - static string EvaluateProperty(string value, IElementLocation location, + static string EvaluateProperty(string value, IInternalLocation location, Expander expander, SdkReferencePropertyExpansionMode mode) { if (value == null) @@ -1789,12 +1789,10 @@ static string EvaluateProperty(string value, IElementLocation location, } } - IElementLocation sdkReferenceOrigin = importElement.SdkLocation; - sdkReference = new SdkReference( - EvaluateProperty(sdkReference.Name, sdkReferenceOrigin, _expander, mode), - EvaluateProperty(sdkReference.Version, sdkReferenceOrigin, _expander, mode), - EvaluateProperty(sdkReference.MinimumVersion, sdkReferenceOrigin, _expander, mode) + EvaluateProperty(sdkReference.Name, importElement, _expander, mode), + EvaluateProperty(sdkReference.Version, importElement, _expander, mode), + EvaluateProperty(sdkReference.MinimumVersion, importElement, _expander, mode) ); } } @@ -1808,7 +1806,7 @@ static string EvaluateProperty(string value, IElementLocation location, { // We throw using e.Message because e.Message already contains the stack trace // https://github.com/dotnet/msbuild/pull/6763 - ProjectErrorUtilities.ThrowInvalidProject(importElement.SdkLocation, "SDKResolverCriticalFailure", e.Message); + ProjectErrorUtilities.ThrowInvalidProject(importElement, "SDKResolverCriticalFailure", e.Message); } if (!sdkResult.Success) @@ -1835,7 +1833,7 @@ static string EvaluateProperty(string value, IElementLocation location, return; } - ProjectErrorUtilities.ThrowInvalidProject(importElement.SdkLocation, "CouldNotResolveSdk", sdkReference.ToString()); + ProjectErrorUtilities.ThrowInvalidProject(importElement, "CouldNotResolveSdk", sdkReference.ToString()); } if (sdkResult.Path == null) @@ -1976,7 +1974,7 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri imports = new List(); string importExpressionEscaped = _expander.ExpandIntoStringLeaveEscaped(unescapedExpression, ExpanderOptions.ExpandProperties, importElement.ProjectLocation); - ElementLocation importLocationInProject = importElement.Location; + // ElementLocation importLocationInProject = importElement.Location; if (String.IsNullOrWhiteSpace(importExpressionEscaped)) { @@ -2004,7 +2002,7 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri return LoadImportsResult.ImportExpressionResolvedToNothing; } - ProjectErrorUtilities.ThrowInvalidProject(importLocationInProject, "InvalidAttributeValue", String.Empty, XMakeAttributes.project, XMakeElements.import); + ProjectErrorUtilities.ThrowInvalidProject(importElement, "InvalidAttributeValue", String.Empty, XMakeAttributes.project, XMakeElements.import); } bool atleastOneImportIgnored = false; @@ -2028,7 +2026,7 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri } catch (Exception ex) when (ExceptionHandling.IsIoRelatedException(ex)) { - ProjectErrorUtilities.ThrowInvalidProject(importLocationInProject, "InvalidAttributeValueWithException", EscapingUtilities.UnescapeAll(importExpressionEscapedItem), XMakeAttributes.project, XMakeElements.import, ex.Message); + ProjectErrorUtilities.ThrowInvalidProject(importElement, "InvalidAttributeValueWithException", EscapingUtilities.UnescapeAll(importExpressionEscapedItem), XMakeAttributes.project, XMakeElements.import, ex.Message); } if (importFilesEscaped.Length == 0) @@ -2073,14 +2071,14 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri } catch (Exception ex) when (ExceptionHandling.IsIoRelatedException(ex)) { - ProjectErrorUtilities.ThrowInvalidProject(importLocationInProject, "InvalidAttributeValueWithException", importFileUnescaped, XMakeAttributes.project, XMakeElements.import, ex.Message); + ProjectErrorUtilities.ThrowInvalidProject(importElement, "InvalidAttributeValueWithException", importFileUnescaped, XMakeAttributes.project, XMakeElements.import, ex.Message); } // If a file is included twice, or there is a cycle of imports, we ignore all but the first import // and issue a warning to that effect. if (String.Equals(_projectRootElement.FullPath, importFileUnescaped, StringComparison.OrdinalIgnoreCase) /* We are trying to import ourselves */) { - _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(importLocationInProject), "SelfImport", importFileUnescaped); + _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(importElement.Location), "SelfImport", importFileUnescaped); atleastOneImportIgnored = true; continue; @@ -2097,12 +2095,12 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri // Get the full path of the MSBuild file that has this import. string importedBy = importElement.ContainingProject.FullPath ?? String.Empty; - _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(importLocationInProject), "ImportIntroducesCircularity", importFileUnescaped, importedBy); + _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(importElement.Location), "ImportIntroducesCircularity", importFileUnescaped, importedBy); // Throw exception if the project load settings requires us to stop the evaluation of a project when circular imports are detected. if ((_loadSettings & ProjectLoadSettings.RejectCircularImports) != 0) { - ProjectErrorUtilities.ThrowInvalidProject(importLocationInProject, "ImportIntroducesCircularity", importFileUnescaped, importedBy); + ProjectErrorUtilities.ThrowInvalidProject(importElement, "ImportIntroducesCircularity", importFileUnescaped, importedBy); } // Ignore this import and no more further processing on it. @@ -2124,7 +2122,7 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri parenthesizedProjectLocation = "[" + _projectRootElement.FullPath + "]"; } // TODO: Detect if the duplicate import came from an SDK attribute - _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(importLocationInProject), "DuplicateImport", importFileUnescaped, previouslyImportedAt.Location.LocationString, parenthesizedProjectLocation); + _evaluationLoggingContext.LogWarning(null, new BuildEventFileInfo(importElement.Location), "DuplicateImport", importFileUnescaped, previouslyImportedAt.Location.LocationString, parenthesizedProjectLocation); duplicateImport = true; } @@ -2242,7 +2240,7 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri continue; } - ProjectErrorUtilities.ThrowInvalidProject(importLocationInProject, "ImportedProjectNotFound", + ProjectErrorUtilities.ThrowInvalidProject(importElement, "ImportedProjectNotFound", importFileUnescaped, importExpressionEscaped); } else @@ -2295,7 +2293,7 @@ private LoadImportsResult ExpandAndLoadImportsFromUnescapedImportExpression(stri if (ex.InnerException != null) { // Otherwise a more generic message, still pointing to the location of the import tag - ProjectErrorUtilities.ThrowInvalidProject(importLocationInProject, "InvalidImportedProjectFile", + ProjectErrorUtilities.ThrowInvalidProject(importElement, "InvalidImportedProjectFile", importFileUnescaped, ex.InnerException.Message); } @@ -2389,7 +2387,8 @@ private bool EvaluateCondition(ProjectElement element, string condition, Expande return true; } - using (_evaluationProfiler.TrackCondition(element.ConditionLocation, condition)) + IInternalLocation location = element.ConditionLocation; + using (_evaluationProfiler.TrackCondition(element, condition)) { bool result = ConditionEvaluator.EvaluateCondition ( @@ -2398,7 +2397,7 @@ private bool EvaluateCondition(ProjectElement element, string condition, Expande _expander, expanderOptions, GetCurrentDirectoryForConditionEvaluation(element), - element.ConditionLocation, + element, _evaluationLoggingContext.LoggingService, _evaluationLoggingContext.BuildEventContext, _evaluationContext.FileSystem @@ -2428,7 +2427,7 @@ private bool EvaluateConditionCollectingConditionedProperties(ProjectElement ele return EvaluateCondition(element, condition, expanderOptions, parserOptions); } - using (_evaluationProfiler.TrackCondition(element.ConditionLocation, condition)) + using (_evaluationProfiler.TrackCondition(element, condition)) { bool result = ConditionEvaluator.EvaluateConditionCollectingConditionedProperties ( @@ -2438,7 +2437,7 @@ private bool EvaluateConditionCollectingConditionedProperties(ProjectElement ele expanderOptions, _data.ConditionedProperties, GetCurrentDirectoryForConditionEvaluation(element), - element.ConditionLocation, + element, _evaluationLoggingContext.LoggingService, _evaluationLoggingContext.BuildEventContext, _evaluationContext.FileSystem, @@ -2520,7 +2519,7 @@ private void ThrowForImportedProjectWithSearchPathsNotFound(ProjectImportPathMat stringifiedListOfSearchPaths, configLocation); #else - ProjectErrorUtilities.ThrowInvalidProject(importElement.ProjectLocation, "ImportedProjectFromExtensionsPathNotFound", + ProjectErrorUtilities.ThrowInvalidProject(importElement, "ImportedProjectFromExtensionsPathNotFound", importExpandedWithDefaultPath, relativeProjectPath, searchPathMatch.MsBuildPropertyFormat, diff --git a/src/Build/Evaluation/Expander.cs b/src/Build/Evaluation/Expander.cs index 1e18aba7c7c..dd6f840178e 100644 --- a/src/Build/Evaluation/Expander.cs +++ b/src/Build/Evaluation/Expander.cs @@ -13,6 +13,7 @@ using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using Microsoft.Build.Collections; +using Microsoft.Build.Construction; using Microsoft.Build.Evaluation.Context; using Microsoft.Build.Execution; using Microsoft.Build.Internal; @@ -416,7 +417,7 @@ internal static bool ExpressionContainsItemVector(string expression) /// /// If ExpanderOptions.BreakOnNotEmpty was passed, expression was going to be non-empty, and it broke out early, returns null. Otherwise the result can be trusted. /// - internal string ExpandIntoStringAndUnescape(string expression, ExpanderOptions options, IElementLocation elementLocation) + internal string ExpandIntoStringAndUnescape(string expression, ExpanderOptions options, IInternalLocation elementLocation) { string result = ExpandIntoStringLeaveEscaped(expression, options, elementLocation); @@ -430,7 +431,7 @@ internal string ExpandIntoStringAndUnescape(string expression, ExpanderOptions o /// /// If ExpanderOptions.BreakOnNotEmpty was passed, expression was going to be non-empty, and it broke out early, returns null. Otherwise the result can be trusted. /// - internal string ExpandIntoStringLeaveEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation) + internal string ExpandIntoStringLeaveEscaped(string expression, ExpanderOptions options, IInternalLocation elementLocation) { if (expression.Length == 0) { @@ -451,7 +452,7 @@ internal string ExpandIntoStringLeaveEscaped(string expression, ExpanderOptions /// Used only for unit tests. Expands the property expression (including any metadata expressions) and returns /// the result typed (i.e. not converted into a string if the result is a function return). /// - internal object ExpandPropertiesLeaveTypedAndEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation) + internal object ExpandPropertiesLeaveTypedAndEscaped(string expression, ExpanderOptions options, IInternalLocation elementLocation) { if (expression.Length == 0) { @@ -470,7 +471,7 @@ internal object ExpandPropertiesLeaveTypedAndEscaped(string expression, Expander /// Use this form when the result is going to be processed further, for example by matching against the file system, /// so literals must be distinguished, and you promise to unescape after that. /// - internal SemiColonTokenizer ExpandIntoStringListLeaveEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation) + internal SemiColonTokenizer ExpandIntoStringListLeaveEscaped(string expression, ExpanderOptions options, IInternalLocation elementLocation) { ErrorUtilities.VerifyThrow((options & ExpanderOptions.BreakOnNotEmpty) == 0, "not supported"); @@ -483,7 +484,7 @@ internal SemiColonTokenizer ExpandIntoStringListLeaveEscaped(string expression, /// If the expression is empty, returns an empty list. /// If ExpanderOptions.BreakOnNotEmpty was passed, expression was going to be non-empty, and it broke out early, returns null. Otherwise the result can be trusted. /// - internal IList ExpandIntoTaskItemsLeaveEscaped(string expression, ExpanderOptions options, IElementLocation elementLocation) + internal IList ExpandIntoTaskItemsLeaveEscaped(string expression, ExpanderOptions options, IInternalLocation elementLocation) { return ExpandIntoItemsLeaveEscaped(expression, (IItemFactory)TaskItemFactory.Instance, options, elementLocation); } @@ -498,7 +499,7 @@ internal IList ExpandIntoTaskItemsLeaveEscaped(string expression, Expa /// so literals must be distinguished, and you promise to unescape after that. /// /// Type of items to return. - internal IList ExpandIntoItemsLeaveEscaped(string expression, IItemFactory itemFactory, ExpanderOptions options, IElementLocation elementLocation) + internal IList ExpandIntoItemsLeaveEscaped(string expression, IItemFactory itemFactory, ExpanderOptions options, IInternalLocation elementLocation) where T : class, IItem { if (expression.Length == 0) @@ -538,7 +539,7 @@ internal IList ExpandIntoItemsLeaveEscaped(string expression, IItemFactory { // The expression is not of the form @(itemName). Therefore, just // treat it as a string, and create a new item from that string. - T itemToAdd = itemFactory.CreateItem(split, elementLocation.File); + T itemToAdd = itemFactory.CreateItem(split, elementLocation.Location.File); result.Add(itemToAdd); } @@ -571,7 +572,7 @@ internal IList ExpandIntoItemsLeaveEscaped(string expression, IItemFactory /// have an item type set on it, it will be given the item type of the item vector to use. /// /// Type of the items that should be returned. - internal IList ExpandSingleItemVectorExpressionIntoItems(string expression, IItemFactory itemFactory, ExpanderOptions options, bool includeNullItems, out bool isTransformExpression, IElementLocation elementLocation) + internal IList ExpandSingleItemVectorExpressionIntoItems(string expression, IItemFactory itemFactory, ExpanderOptions options, bool includeNullItems, out bool isTransformExpression, IInternalLocation elementLocation) where T : class, IItem { if (expression.Length == 0) @@ -586,14 +587,14 @@ internal IList ExpandSingleItemVectorExpressionIntoItems(string expression } internal static ExpressionShredder.ItemExpressionCapture ExpandSingleItemVectorExpressionIntoExpressionCapture( - string expression, ExpanderOptions options, IElementLocation elementLocation) + string expression, ExpanderOptions options, IInternalLocation elementLocation) { return ItemExpander.ExpandSingleItemVectorExpressionIntoExpressionCapture(expression, options, elementLocation); } internal IList ExpandExpressionCaptureIntoItems( ExpressionShredder.ItemExpressionCapture expressionCapture, IItemProvider items, IItemFactory itemFactory, - ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, IElementLocation elementLocation) + ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, IInternalLocation elementLocation) where S : class, IItem where T : class, IItem { @@ -603,7 +604,7 @@ internal IList ExpandExpressionCaptureIntoItems( internal bool ExpandExpressionCapture( ExpressionShredder.ItemExpressionCapture expressionCapture, - IElementLocation elementLocation, + IInternalLocation elementLocation, ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, @@ -768,7 +769,7 @@ private static void AddArgument(List arguments, SpanBasedStringBuilder a /// Returns an array of unexpanded arguments. /// If there are no arguments, returns an empty array. /// - private static string[] ExtractFunctionArguments(IElementLocation elementLocation, string expressionFunction, string argumentsString) + private static string[] ExtractFunctionArguments(IInternalLocation elementLocation, string expressionFunction, string argumentsString) { int argumentsContentLength = argumentsString.Length; @@ -870,7 +871,7 @@ private static class MetadataExpander /// Used to specify what to expand. /// The location information for error reporting purposes. /// The string with item metadata expanded in-place, escaped. - internal static string ExpandMetadataLeaveEscaped(string expression, IMetadataTable metadata, ExpanderOptions options, IElementLocation elementLocation) + internal static string ExpandMetadataLeaveEscaped(string expression, IMetadataTable metadata, ExpanderOptions options, IInternalLocation elementLocation) { try { @@ -1072,7 +1073,7 @@ internal static string ExpandPropertiesLeaveEscaped( string expression, IPropertyProvider properties, ExpanderOptions options, - IElementLocation elementLocation, + IInternalLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem) { @@ -1108,7 +1109,7 @@ internal static object ExpandPropertiesLeaveTypedAndEscaped( string expression, IPropertyProvider properties, ExpanderOptions options, - IElementLocation elementLocation, + IInternalLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem) { @@ -1267,7 +1268,7 @@ internal static object ExpandPropertyBody( object propertyValue, IPropertyProvider properties, ExpanderOptions options, - IElementLocation elementLocation, + IInternalLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem) { @@ -1455,7 +1456,7 @@ internal static string ConvertToString(object valueToConvert) /// /// Look up a simple property reference by the name of the property, e.g. "Foo" when expanding $(Foo). /// - private static object LookupProperty(IPropertyProvider properties, string propertyName, IElementLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties) + private static object LookupProperty(IPropertyProvider properties, string propertyName, IInternalLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties) { return LookupProperty(properties, propertyName, 0, propertyName.Length - 1, elementLocation, usedUninitializedProperties); } @@ -1463,7 +1464,7 @@ private static object LookupProperty(IPropertyProvider properties, string pro /// /// Look up a simple property reference by the name of the property, e.g. "Foo" when expanding $(Foo). /// - private static object LookupProperty(IPropertyProvider properties, string propertyName, int startIndex, int endIndex, IElementLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties) + private static object LookupProperty(IPropertyProvider properties, string propertyName, int startIndex, int endIndex, IInternalLocation elementLocation, UsedUninitializedProperties usedUninitializedProperties) { T property = properties.GetProperty(propertyName, startIndex, endIndex); @@ -1521,14 +1522,15 @@ private static object LookupProperty(IPropertyProvider properties, string pro /// never been saved) then returns empty string. /// If the property name is not one of those properties, returns empty string. /// - private static object ExpandMSBuildThisFileProperty(string propertyName, IElementLocation elementLocation) + private static object ExpandMSBuildThisFileProperty(string propertyName, IInternalLocation elementLocation) { if (!ReservedPropertyNames.IsReservedProperty(propertyName)) { return String.Empty; } - if (elementLocation.File.Length == 0) + var location = elementLocation.Location; + if (location.File.Length == 0) { return String.Empty; } @@ -1539,27 +1541,27 @@ private static object ExpandMSBuildThisFileProperty(string propertyName, IElemen // all different lengths, this sequence is efficient. if (String.Equals(propertyName, ReservedPropertyNames.thisFile, StringComparison.OrdinalIgnoreCase)) { - value = Path.GetFileName(elementLocation.File); + value = Path.GetFileName(location.File); } else if (String.Equals(propertyName, ReservedPropertyNames.thisFileName, StringComparison.OrdinalIgnoreCase)) { - value = Path.GetFileNameWithoutExtension(elementLocation.File); + value = Path.GetFileNameWithoutExtension(location.File); } else if (String.Equals(propertyName, ReservedPropertyNames.thisFileFullPath, StringComparison.OrdinalIgnoreCase)) { - value = FileUtilities.NormalizePath(elementLocation.File); + value = FileUtilities.NormalizePath(location.File); } else if (String.Equals(propertyName, ReservedPropertyNames.thisFileExtension, StringComparison.OrdinalIgnoreCase)) { - value = Path.GetExtension(elementLocation.File); + value = Path.GetExtension(location.File); } else if (String.Equals(propertyName, ReservedPropertyNames.thisFileDirectory, StringComparison.OrdinalIgnoreCase)) { - value = FileUtilities.EnsureTrailingSlash(Path.GetDirectoryName(elementLocation.File)); + value = FileUtilities.EnsureTrailingSlash(Path.GetDirectoryName(location.File)); } else if (String.Equals(propertyName, ReservedPropertyNames.thisFileDirectoryNoRoot, StringComparison.OrdinalIgnoreCase)) { - string directory = Path.GetDirectoryName(elementLocation.File); + string directory = Path.GetDirectoryName(location.File); int rootLength = Path.GetPathRoot(directory).Length; value = FileUtilities.EnsureTrailingNoLeadingSlash(directory, rootLength); } @@ -1576,7 +1578,7 @@ private static object ExpandMSBuildThisFileProperty(string propertyName, IElemen /// "TaskLocation" is the name of the value. The name of the value and the preceding "@" may be omitted if /// the default value is desired. /// - private static string ExpandRegistryValue(string registryExpression, IElementLocation elementLocation) + private static string ExpandRegistryValue(string registryExpression, IInternalLocation elementLocation) { // Remove "Registry:" prefix string registryLocation = registryExpression.Substring(9); @@ -1660,7 +1662,7 @@ private static string ExpandRegistryValue(string registryExpression, IElementLoc /// /// Given a string like "Registry:HKEY_LOCAL_MACHINE\Software\Vendor\Tools@TaskLocation", returns String.Empty, as FEATURE_WIN32_REGISTRY is off. /// - private static string ExpandRegistryValue(string registryExpression, IElementLocation elementLocation) + private static string ExpandRegistryValue(string registryExpression, IInternalLocation elementLocation) { return String.Empty; } @@ -1762,7 +1764,7 @@ internal static IEnumerable> Transform(Expander expande /// Type of the items that should be returned. internal static IList ExpandSingleItemVectorExpressionIntoItems( Expander expander, string expression, IItemProvider items, IItemFactory itemFactory, ExpanderOptions options, - bool includeNullEntries, out bool isTransformExpression, IElementLocation elementLocation) + bool includeNullEntries, out bool isTransformExpression, IInternalLocation elementLocation) where S : class, IItem where T : class, IItem { @@ -1779,7 +1781,7 @@ internal static IList ExpandSingleItemVectorExpressionIntoItems( } internal static ExpressionShredder.ItemExpressionCapture ExpandSingleItemVectorExpressionIntoExpressionCapture( - string expression, ExpanderOptions options, IElementLocation elementLocation) + string expression, ExpanderOptions options, IInternalLocation elementLocation) { if (((options & ExpanderOptions.ExpandItems) == 0) || (expression.Length == 0)) { @@ -1815,7 +1817,7 @@ internal static ExpressionShredder.ItemExpressionCapture ExpandSingleItemVectorE internal static IList ExpandExpressionCaptureIntoItems( ExpressionShredder.ItemExpressionCapture expressionCapture, Expander expander, IItemProvider items, IItemFactory itemFactory, - ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, IElementLocation elementLocation) + ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, IInternalLocation elementLocation) where S : class, IItem where T : class, IItem { @@ -1855,7 +1857,7 @@ internal static IList ExpandExpressionCaptureIntoItems( if (expandedItemVector.Length > 0) { - T newItem = itemFactory.CreateItem(expandedItemVector, elementLocation.File); + T newItem = itemFactory.CreateItem(expandedItemVector, elementLocation.Location.File); result.Add(newItem); } @@ -1881,13 +1883,13 @@ internal static IList ExpandExpressionCaptureIntoItems( if (itemSpec != null && originalItem == null) { // We have an itemspec, but no base item - result.Add(itemFactory.CreateItem(itemSpec, elementLocation.File)); + result.Add(itemFactory.CreateItem(itemSpec, elementLocation.Location.File)); } else if (itemSpec != null && originalItem != null) { result.Add(itemSpec.Equals(originalItem.EvaluatedIncludeEscaped) - ? itemFactory.CreateItem(originalItem, elementLocation.File) // itemspec came from direct item reference, no transforms - : itemFactory.CreateItem(itemSpec, originalItem, elementLocation.File)); // itemspec came from a transform and is different from its original item + ? itemFactory.CreateItem(originalItem, elementLocation.Location.File) // itemspec came from direct item reference, no transforms + : itemFactory.CreateItem(itemSpec, originalItem, elementLocation.Location.File)); // itemspec came from a transform and is different from its original item } else if (includeNullEntries) { @@ -1925,7 +1927,7 @@ internal static bool ExpandExpressionCapture( Expander expander, ExpressionShredder.ItemExpressionCapture expressionCapture, IItemProvider evaluatedItems, - IElementLocation elementLocation, + IInternalLocation elementLocation, ExpanderOptions options, bool includeNullEntries, out bool isTransformExpression, @@ -2004,7 +2006,7 @@ out List> itemsFromCapture /// If ExpanderOptions.BreakOnNotEmpty was passed, expression was going to be non-empty, and it broke out early, returns null. Otherwise the result can be trusted. /// /// Type of the items provided. - internal static string ExpandItemVectorsIntoString(Expander expander, string expression, IItemProvider items, ExpanderOptions options, IElementLocation elementLocation) + internal static string ExpandItemVectorsIntoString(Expander expander, string expression, IItemProvider items, ExpanderOptions options, IInternalLocation elementLocation) where T : class, IItem { if ((options & ExpanderOptions.ExpandItems) == 0 || expression.Length == 0) @@ -2057,7 +2059,7 @@ internal static string ExpandItemVectorsIntoString(Expander expander, s /// Prepare the stack of transforms that will be executed on a given set of items. /// /// class, IItem. - private static Stack> PrepareTransformStackFromMatch(IElementLocation elementLocation, ExpressionShredder.ItemExpressionCapture match) + private static Stack> PrepareTransformStackFromMatch(IInternalLocation elementLocation, ExpressionShredder.ItemExpressionCapture match) where S : class, IItem { // There's something wrong with the expression, and we ended up with no function names @@ -2105,7 +2107,7 @@ private static bool ExpandExpressionCaptureIntoStringBuilder( Expander expander, ExpressionShredder.ItemExpressionCapture capture, IItemProvider evaluatedItems, - IElementLocation elementLocation, + IInternalLocation elementLocation, SpanBasedStringBuilder builder, ExpanderOptions options ) @@ -2172,13 +2174,13 @@ internal static class IntrinsicItemFunctions /// Delegate that represents the signature of all item transformation functions /// This is used to support calling the functions by name. /// - public delegate IEnumerable> ItemTransformFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments); + public delegate IEnumerable> ItemTransformFunction(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments); /// /// Get a delegate to the given item transformation function by supplying the name and the /// Item type that should be used. /// - internal static ItemTransformFunction GetItemTransformFunction(IElementLocation elementLocation, string functionName, Type itemType) + internal static ItemTransformFunction GetItemTransformFunction(IInternalLocation elementLocation, string functionName, Type itemType) { ItemTransformFunction transformFunction = null; string qualifiedFunctionName = itemType.FullName + "::" + functionName; @@ -2262,7 +2264,7 @@ var resultantItem in /// /// Intrinsic function that returns the number of items in the list. /// - internal static IEnumerable> Count(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Count(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { yield return new Pair(Convert.ToString(itemsOfType.Count(), CultureInfo.InvariantCulture), null /* no base item */); } @@ -2271,7 +2273,7 @@ internal static IEnumerable> Count(Expander expander, IEle /// Intrinsic function that returns the specified built-in modifer value of the items in itemsOfType /// Tuple is {current item include, item under transformation}. /// - internal static IEnumerable> ItemSpecModifierFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> ItemSpecModifierFunction(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2324,7 +2326,7 @@ internal static IEnumerable> ItemSpecModifierFunction(Expander

/// Intrinsic function that returns the subset of items that actually exist on disk. /// - internal static IEnumerable> Exists(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Exists(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2371,7 +2373,7 @@ internal static IEnumerable> Exists(Expander expander, IEl ///

/// Intrinsic function that combines the existing paths of the input items with a given relative path. /// - internal static IEnumerable> Combine(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Combine(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2395,7 +2397,7 @@ internal static IEnumerable> Combine(Expander expander, IE /// /// Intrinsic function that returns all ancestor directories of the given items. /// - internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2471,7 +2473,7 @@ internal static IEnumerable> GetPathsOfAllDirectoriesAbove(Expan /// Intrinsic function that returns the DirectoryName of the items in itemsOfType /// UNDONE: This can be removed in favor of a built-in %(DirectoryName) metadata in future. /// - internal static IEnumerable> DirectoryName(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> DirectoryName(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2538,7 +2540,7 @@ internal static IEnumerable> DirectoryName(Expander expand /// /// Intrinsic function that returns the contents of the metadata in specified in argument[0]. /// - internal static IEnumerable> Metadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Metadata(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2595,7 +2597,7 @@ internal static IEnumerable> Metadata(Expander expander, I /// Intrinsic function that returns only the items from itemsOfType that have distinct Item1 in the Tuple /// Using a case sensitive comparison. /// - internal static IEnumerable> DistinctWithCase(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> DistinctWithCase(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { return DistinctWithComparer(expander, elementLocation, includeNullEntries, functionName, itemsOfType, arguments, StringComparer.Ordinal); } @@ -2604,7 +2606,7 @@ internal static IEnumerable> DistinctWithCase(Expander exp /// Intrinsic function that returns only the items from itemsOfType that have distinct Item1 in the Tuple /// Using a case insensitive comparison. /// - internal static IEnumerable> Distinct(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Distinct(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { return DistinctWithComparer(expander, elementLocation, includeNullEntries, functionName, itemsOfType, arguments, StringComparer.OrdinalIgnoreCase); } @@ -2613,7 +2615,7 @@ internal static IEnumerable> Distinct(Expander expander, I /// Intrinsic function that returns only the items from itemsOfType that have distinct Item1 in the Tuple /// Using a case insensitive comparison. /// - internal static IEnumerable> DistinctWithComparer(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments, StringComparer comparer) + internal static IEnumerable> DistinctWithComparer(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments, StringComparer comparer) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2634,7 +2636,7 @@ internal static IEnumerable> DistinctWithComparer(Expander /// /// Intrinsic function reverses the item list. /// - internal static IEnumerable> Reverse(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> Reverse(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); foreach (Pair item in itemsOfType.Reverse()) @@ -2646,7 +2648,7 @@ internal static IEnumerable> Reverse(Expander expander, IE /// /// Intrinsic function that transforms expressions like the %(foo) in @(Compile->'%(foo)'). /// - internal static IEnumerable> ExpandQuotedExpressionFunction(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> ExpandQuotedExpressionFunction(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2688,7 +2690,7 @@ internal static IEnumerable> ExpandQuotedExpressionFunction(Expa /// internal static IEnumerable> ExecuteStringFunction( Expander expander, - IElementLocation elementLocation, + IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, @@ -2728,7 +2730,7 @@ internal static IEnumerable> ExecuteStringFunction( /// /// Intrinsic function that returns the items from itemsOfType with their metadata cleared, i.e. only the itemspec is retained. /// - internal static IEnumerable> ClearMetadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> ClearMetadata(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments == null || arguments.Length == 0, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2745,7 +2747,7 @@ internal static IEnumerable> ClearMetadata(Expander expand /// Intrinsic function that returns only those items that have a not-blank value for the metadata specified /// Using a case insensitive comparison. /// - internal static IEnumerable> HasMetadata(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> HasMetadata(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 1, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2782,7 +2784,7 @@ internal static IEnumerable> HasMetadata(Expander expander /// Intrinsic function that returns only those items have the given metadata value /// Using a case insensitive comparison. /// - internal static IEnumerable> WithMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> WithMetadataValue(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 2, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2818,7 +2820,7 @@ internal static IEnumerable> WithMetadataValue(Expander ex /// Intrinsic function that returns a boolean to indicate if any of the items have the given metadata value /// Using a case insensitive comparison. /// - internal static IEnumerable> AnyHaveMetadataValue(Expander expander, IElementLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) + internal static IEnumerable> AnyHaveMetadataValue(Expander expander, IInternalLocation elementLocation, bool includeNullEntries, string functionName, IEnumerable> itemsOfType, string[] arguments) { ProjectErrorUtilities.VerifyThrowInvalidProject(arguments?.Length == 2, elementLocation, "InvalidItemFunctionSyntax", functionName, arguments == null ? 0 : arguments.Length); @@ -2886,7 +2888,7 @@ internal class TransformFunction /// /// The element location of the transform expression. /// - private IElementLocation _elementLocation; + private IInternalLocation _elementLocation; /// /// The name of the function that this class will call. @@ -2896,7 +2898,7 @@ internal class TransformFunction /// /// TransformFunction constructor. /// - public TransformFunction(IElementLocation elementLocation, string functionName, IntrinsicItemFunctions.ItemTransformFunction transform, string[] arguments) + public TransformFunction(IInternalLocation elementLocation, string functionName, IntrinsicItemFunctions.ItemTransformFunction transform, string[] arguments) { _elementLocation = elementLocation; _functionName = functionName; @@ -2915,7 +2917,7 @@ public string[] Arguments /// /// The element location of the transform expression. /// - public IElementLocation ElementLocation + public IInternalLocation elementLocation { get { return _elementLocation; } } @@ -2949,12 +2951,12 @@ private class MetadataMatchEvaluator /// /// Location of the match. /// - private IElementLocation _elementLocation; + private IInternalLocation _elementLocation; /// /// Constructor. /// - internal MetadataMatchEvaluator(string itemSpec, IItem sourceOfMetadata, IElementLocation elementLocation) + internal MetadataMatchEvaluator(string itemSpec, IItem sourceOfMetadata, IInternalLocation elementLocation) { _itemSpec = itemSpec; _sourceOfMetadata = sourceOfMetadata; @@ -3231,7 +3233,7 @@ internal string Receiver /// internal static Function ExtractPropertyFunction( string expressionFunction, - IElementLocation elementLocation, + IInternalLocation elementLocation, object propertyValue, UsedUninitializedProperties usedUnInitializedProperties, IFileSystem fileSystem) @@ -3353,7 +3355,7 @@ internal static Function ExtractPropertyFunction( /// /// Execute the function on the given instance. /// - internal object Execute(object objectInstance, IPropertyProvider properties, ExpanderOptions options, IElementLocation elementLocation) + internal object Execute(object objectInstance, IPropertyProvider properties, ExpanderOptions options, IInternalLocation elementLocation) { object functionResult = String.Empty; object[] args = null; @@ -3452,7 +3454,7 @@ internal object Execute(object objectInstance, IPropertyProvider properties, // specified the file name. This is syntactic sugar so they don't have to always // include $(MSBuildThisFileDirectory) as a parameter. // - string startingDirectory = String.IsNullOrWhiteSpace(elementLocation.File) ? String.Empty : Path.GetDirectoryName(elementLocation.File); + string startingDirectory = String.IsNullOrWhiteSpace(elementLocation.Location.File) ? String.Empty : Path.GetDirectoryName(elementLocation.Location.File); args = new [] { @@ -4753,7 +4755,7 @@ private static Type GetTypeFromAssembly(string typeName, string candidateAssembl /// Extracts the name, arguments, binding flags, and invocation type for an indexer /// Also extracts the remainder of the expression that is not part of this indexer. /// - private static void ConstructIndexerFunction(string expressionFunction, IElementLocation elementLocation, object propertyValue, int methodStartIndex, int indexerEndIndex, ref FunctionBuilder functionBuilder) + private static void ConstructIndexerFunction(string expressionFunction, IInternalLocation elementLocation, object propertyValue, int methodStartIndex, int indexerEndIndex, ref FunctionBuilder functionBuilder) { string argumentsContent = expressionFunction.Substring(1, indexerEndIndex - 1); string remainder = expressionFunction.Substring(methodStartIndex); @@ -4796,7 +4798,7 @@ private static void ConstructIndexerFunction(string expressionFunction, IElement /// Extracts the name, arguments, binding flags, and invocation type for a static or instance function. /// Also extracts the remainder of the expression that is not part of this function. /// - private static void ConstructFunction(IElementLocation elementLocation, string expressionFunction, int argumentStartIndex, int methodStartIndex, ref FunctionBuilder functionBuilder) + private static void ConstructFunction(IInternalLocation elementLocation, string expressionFunction, int argumentStartIndex, int methodStartIndex, ref FunctionBuilder functionBuilder) { // The unevaluated and unexpanded arguments for this function string[] functionArguments; @@ -5178,13 +5180,13 @@ internal class UsedUninitializedProperties /// internal UsedUninitializedProperties() { - Properties = new Dictionary(StringComparer.OrdinalIgnoreCase); + Properties = new Dictionary(StringComparer.OrdinalIgnoreCase); } /// /// Hash set of properties which have been used before being initialized. /// - internal IDictionary Properties + internal IDictionary Properties { get; set; diff --git a/src/Build/Evaluation/ItemSpec.cs b/src/Build/Evaluation/ItemSpec.cs index fbc0b6f6b1a..bb396a1ef4b 100644 --- a/src/Build/Evaluation/ItemSpec.cs +++ b/src/Build/Evaluation/ItemSpec.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Build.Construction; using Microsoft.Build.Globbing; using Microsoft.Build.Internal; using Microsoft.Build.Shared; @@ -141,7 +142,7 @@ private bool InitReferencedItemsIfNecessary() /// /// The xml attribute where this itemspec comes from /// - public IElementLocation ItemSpecLocation { get; } + public IInternalLocation ItemSpecLocation { get; } /// The string containing item syntax /// Expects the expander to have a default item factory set @@ -151,7 +152,7 @@ private bool InitReferencedItemsIfNecessary() public ItemSpec( string itemSpec, Expander expander, - IElementLocation itemSpecLocation, + IInternalLocation itemSpecLocation, string projectDirectory, bool expandProperties = true) { @@ -162,7 +163,7 @@ public ItemSpec( Fragments = BuildItemFragments(itemSpecLocation, projectDirectory, expandProperties); } - private List BuildItemFragments(IElementLocation itemSpecLocation, string projectDirectory, bool expandProperties) + private List BuildItemFragments(IInternalLocation itemSpecLocation, string projectDirectory, bool expandProperties) { // Code corresponds to Evaluator.CreateItemsFromInclude var evaluatedItemspecEscaped = ItemSpecString; @@ -247,7 +248,7 @@ private List BuildItemFragments(IElementLocation itemSpecLocat private ItemExpressionFragment ProcessItemExpression( string expression, - IElementLocation elementLocation, + IInternalLocation elementLocation, string projectDirectory, out bool isItemListExpression) { diff --git a/src/Build/Evaluation/LazyItemEvaluator.cs b/src/Build/Evaluation/LazyItemEvaluator.cs index ada3da6a27f..553442a42d5 100644 --- a/src/Build/Evaluation/LazyItemEvaluator.cs +++ b/src/Build/Evaluation/LazyItemEvaluator.cs @@ -83,8 +83,8 @@ LazyItemEvaluator lazyEvaluator return true; } MSBuildEventSource.Log.EvaluateConditionStart(condition); - - using (lazyEvaluator._evaluationProfiler.TrackCondition(element.ConditionLocation, condition)) + var conditionLocation = element.ConditionLocation; + using (lazyEvaluator._evaluationProfiler.TrackCondition(conditionLocation, condition)) { bool result = ConditionEvaluator.EvaluateCondition ( @@ -93,7 +93,7 @@ LazyItemEvaluator lazyEvaluator expander, expanderOptions, GetCurrentDirectoryForConditionEvaluation(element, lazyEvaluator), - element.ConditionLocation, + element, lazyEvaluator._loggingContext.LoggingService, lazyEvaluator._loggingContext.BuildEventContext, lazyEvaluator.FileSystem @@ -618,7 +618,7 @@ private RemoveOperation BuildRemoveOperation(string rootDirectory, ProjectItemEl return new RemoveOperation(operationBuilder, this); } - private void ProcessItemSpec(string rootDirectory, string itemSpec, IElementLocation itemSpecLocation, OperationBuilder builder) + private void ProcessItemSpec(string rootDirectory, string itemSpec, IInternalLocation itemSpecLocation, OperationBuilder builder) { builder.ItemSpec = new ItemSpec(itemSpec, _outerExpander, itemSpecLocation, rootDirectory); @@ -645,7 +645,7 @@ private static IEnumerable GetExpandedMetadataValuesAndConditions(IColle yield return expander.ExpandIntoStringLeaveEscaped( metadatumElement.Value, expanderOptions, - metadatumElement.Location); + metadatumElement); yield return expander.ExpandIntoStringLeaveEscaped( metadatumElement.Condition, @@ -671,7 +671,7 @@ private void ProcessMetadataElements(ProjectItemElement itemElement, OperationBu } } - private void AddItemReferences(string expression, OperationBuilder operationBuilder, IElementLocation elementLocation) + private void AddItemReferences(string expression, OperationBuilder operationBuilder, IInternalLocation elementLocation) { if (expression.Length == 0) { diff --git a/src/Build/Evaluation/Profiler/EvaluationProfiler.cs b/src/Build/Evaluation/Profiler/EvaluationProfiler.cs index 1082b9e2876..fbf3e8e5d10 100644 --- a/src/Build/Evaluation/Profiler/EvaluationProfiler.cs +++ b/src/Build/Evaluation/Profiler/EvaluationProfiler.cs @@ -72,9 +72,9 @@ public IDisposable TrackElement(ProjectElement element) /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IDisposable TrackCondition(IElementLocation location, string condition) + public IDisposable TrackCondition(IInternalLocation element, string condition) { - return _shouldTrackElements ? new EvaluationFrame(this, CurrentLocation.WithFileLineAndCondition(location.File, location.Line, condition)) : null; + return _shouldTrackElements ? new EvaluationFrame(this, CurrentLocation.WithFileLineAndCondition(element.Location.File, element.Location.Line, condition)) : null; } /// diff --git a/src/Build/Evaluation/ProjectParser.cs b/src/Build/Evaluation/ProjectParser.cs index 761ef477d6f..0e269e90b2a 100644 --- a/src/Build/Evaluation/ProjectParser.cs +++ b/src/Build/Evaluation/ProjectParser.cs @@ -128,13 +128,13 @@ private void Parse() XmlElementWithLocation element = _document.DocumentElement as XmlElementWithLocation; ProjectErrorUtilities.VerifyThrowInvalidProject(element != null, ElementLocation.Create(_document.FullPath), "NoRootProjectElement", XMakeElements.project); - ProjectErrorUtilities.VerifyThrowInvalidProject(element.Name != XMakeElements.visualStudioProject, element.Location, "ProjectUpgradeNeeded", _project.FullPath); - ProjectErrorUtilities.VerifyThrowInvalidProject(element.LocalName == XMakeElements.project, element.Location, "UnrecognizedElement", element.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(element.Name != XMakeElements.visualStudioProject, element, "ProjectUpgradeNeeded", _project.FullPath); + ProjectErrorUtilities.VerifyThrowInvalidProject(element.LocalName == XMakeElements.project, element, "UnrecognizedElement", element.Name); // If a namespace was specified it must be the default MSBuild namespace. if (!ProjectXmlUtilities.VerifyValidProjectNamespace(element)) { - ProjectErrorUtilities.ThrowInvalidProject(element.Location, "ProjectMustBeInMSBuildXmlNamespace", + ProjectErrorUtilities.ThrowInvalidProject(element, "ProjectMustBeInMSBuildXmlNamespace", XMakeAttributes.defaultXmlNamespace); } else @@ -195,11 +195,11 @@ private void Parse() case XMakeElements.error: case XMakeElements.warning: case XMakeElements.message: - ProjectErrorUtilities.ThrowInvalidProject(childElement.Location, "ErrorWarningMessageNotSupported", childElement.Name); + ProjectErrorUtilities.ThrowInvalidProject(childElement, "ErrorWarningMessageNotSupported", childElement.Name); break; default: - ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, childElement.ParentNode.Name, childElement.Location); + ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, childElement.ParentNode.Name, childElement); break; } } @@ -218,7 +218,7 @@ private ProjectPropertyGroupElement ParseProjectPropertyGroupElement(XmlElementW { ProjectXmlUtilities.VerifyThrowProjectAttributes(childElement, ValidAttributesOnlyConditionAndLabel); XmlUtilities.VerifyThrowProjectValidElementName(childElement); - ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(childElement.Name) && !ReservedPropertyNames.IsReservedProperty(childElement.Name), childElement.Location, "CannotModifyReservedProperty", childElement.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(childElement.Name) && !ReservedPropertyNames.IsReservedProperty(childElement.Name), childElement, "CannotModifyReservedProperty", childElement.Name); // All children inside a property are ignored, since they are only part of its value ProjectPropertyElement property = new ProjectPropertyElement(childElement, propertyGroup, _project); @@ -283,26 +283,26 @@ private ProjectItemElement ParseProjectItemElement(XmlElementWithLocation elemen if (exclusiveAttributeCount > 1) { XmlAttributeWithLocation errorAttribute = remove.Length > 0 ? (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.remove] : (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.update]; - ProjectErrorUtilities.ThrowInvalidProject(errorAttribute.Location, "InvalidAttributeExclusive"); + ProjectErrorUtilities.ThrowInvalidProject(errorAttribute, "InvalidAttributeExclusive"); } // Include, remove, or update must be present unless inside a target - ProjectErrorUtilities.VerifyThrowInvalidProject(exclusiveAttributeCount == 1 || belowTarget, element.Location, "IncludeRemoveOrUpdate", exclusiveItemOperation, itemType); + ProjectErrorUtilities.VerifyThrowInvalidProject(exclusiveAttributeCount == 1 || belowTarget, element, "IncludeRemoveOrUpdate", exclusiveItemOperation, itemType); // Exclude must be missing, unless Include exists ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(exclude.Length == 0 || include.Length > 0, (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.exclude]); // If we have an Include attribute at all, it must have non-zero length - ProjectErrorUtilities.VerifyThrowInvalidProject(include.Length > 0 || element.Attributes[XMakeAttributes.include] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.include, itemType); + ProjectErrorUtilities.VerifyThrowInvalidProject(include.Length > 0 || element.Attributes[XMakeAttributes.include] == null, element, "MissingRequiredAttribute", XMakeAttributes.include, itemType); // If we have a Remove attribute at all, it must have non-zero length - ProjectErrorUtilities.VerifyThrowInvalidProject(remove.Length > 0 || element.Attributes[XMakeAttributes.remove] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.remove, itemType); + ProjectErrorUtilities.VerifyThrowInvalidProject(remove.Length > 0 || element.Attributes[XMakeAttributes.remove] == null, element, "MissingRequiredAttribute", XMakeAttributes.remove, itemType); // If we have an Update attribute at all, it must have non-zero length - ProjectErrorUtilities.VerifyThrowInvalidProject(update.Length > 0 || element.Attributes[XMakeAttributes.update] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.update, itemType); + ProjectErrorUtilities.VerifyThrowInvalidProject(update.Length > 0 || element.Attributes[XMakeAttributes.update] == null, element, "MissingRequiredAttribute", XMakeAttributes.update, itemType); XmlUtilities.VerifyThrowProjectValidElementName(element); - ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(itemType), element.Location, "CannotModifyReservedItem", itemType); + ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(itemType), element, "CannotModifyReservedItem", itemType); ProjectItemElement item = new ProjectItemElement(element, parent, _project); @@ -391,9 +391,9 @@ private ProjectMetadataElement ParseProjectMetadataElement(XmlElementWithLocatio XmlUtilities.VerifyThrowProjectValidElementName(element); - ProjectErrorUtilities.VerifyThrowInvalidProject(!(parent is ProjectItemElement) || ((ProjectItemElement)parent).Remove.Length == 0, element.Location, "ChildElementsBelowRemoveNotAllowed", element.Name); - ProjectErrorUtilities.VerifyThrowInvalidProject(!FileUtilities.ItemSpecModifiers.IsItemSpecModifier(element.Name), element.Location, "ItemSpecModifierCannotBeCustomMetadata", element.Name); - ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(element.Name), element.Location, "CannotModifyReservedItemMetadata", element.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(!(parent is ProjectItemElement) || ((ProjectItemElement)parent).Remove.Length == 0, element, "ChildElementsBelowRemoveNotAllowed", element.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(!FileUtilities.ItemSpecModifiers.IsItemSpecModifier(element.Name), element, "ItemSpecModifierCannotBeCustomMetadata", element.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(element.Name), element, "CannotModifyReservedItemMetadata", element.Name); ProjectMetadataElement metadatum = new ProjectMetadataElement(element, parent, _project); @@ -401,7 +401,7 @@ private ProjectMetadataElement ParseProjectMetadataElement(XmlElementWithLocatio if (parent is ProjectItemDefinitionElement) { bool containsItemVector = Expander.ExpressionContainsItemVector(metadatum.Value); - ProjectErrorUtilities.VerifyThrowInvalidProject(!containsItemVector, element.Location, "MetadataDefinitionCannotContainItemVectorExpression", metadatum.Value, metadatum.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(!containsItemVector, element, "MetadataDefinitionCannotContainItemVectorExpression", metadatum.Value, metadatum.Name); } return metadatum; @@ -424,7 +424,7 @@ private ProjectImportGroupElement ParseProjectImportGroupElement(XmlElementWithL ProjectErrorUtilities.VerifyThrowInvalidProject ( childElement.Name == XMakeElements.import, - childElement.Location, + childElement, "UnrecognizedChildElement", childElement.Name, element.Name @@ -446,7 +446,7 @@ private ProjectImportElement ParseProjectImportElement(XmlElementWithLocation el ProjectErrorUtilities.VerifyThrowInvalidProject ( parent is ProjectRootElement || parent is ProjectImportGroupElement, - element.Location, + element, "UnrecognizedParentElement", parent, element @@ -507,7 +507,7 @@ private UsingTaskParameterGroupElement ParseUsingTaskParameterGroupElement(XmlEl private ProjectUsingTaskElement ParseProjectUsingTaskElement(XmlElementWithLocation element) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnUsingTask); - ProjectErrorUtilities.VerifyThrowInvalidProject(element.GetAttribute(XMakeAttributes.taskName).Length > 0, element.Location, "ProjectTaskNameEmpty"); + ProjectErrorUtilities.VerifyThrowInvalidProject(element.GetAttribute(XMakeAttributes.taskName).Length > 0, element, "ProjectTaskNameEmpty"); string assemblyName = element.GetAttribute(XMakeAttributes.assemblyName); string assemblyFile = element.GetAttribute(XMakeAttributes.assemblyFile); @@ -515,7 +515,7 @@ private ProjectUsingTaskElement ParseProjectUsingTaskElement(XmlElementWithLocat ProjectErrorUtilities.VerifyThrowInvalidProject ( (assemblyName.Length > 0) ^ (assemblyFile.Length > 0), - element.Location, + element, "UsingTaskAssemblySpecification", XMakeElements.usingTask, XMakeAttributes.assemblyName, @@ -557,7 +557,7 @@ private ProjectUsingTaskElement ParseProjectUsingTaskElement(XmlElementWithLocat foundTaskElement = true; break; default: - ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element.Location); + ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element); break; } @@ -596,7 +596,7 @@ private ProjectTargetElement ParseProjectTargetElement(XmlElementWithLocation el case XMakeElements.propertyGroup: if (onError != null) { - ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); + ProjectErrorUtilities.ThrowInvalidProject(onError, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectPropertyGroupElement(childElement, target); @@ -605,7 +605,7 @@ private ProjectTargetElement ParseProjectTargetElement(XmlElementWithLocation el case XMakeElements.itemGroup: if (onError != null) { - ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); + ProjectErrorUtilities.ThrowInvalidProject(onError, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectItemGroupElement(childElement, target); @@ -622,13 +622,13 @@ private ProjectTargetElement ParseProjectTargetElement(XmlElementWithLocation el break; case XMakeElements.itemDefinitionGroup: - ProjectErrorUtilities.ThrowInvalidProject(childElement.Location, "ItemDefinitionGroupNotLegalInsideTarget", childElement.Name); + ProjectErrorUtilities.ThrowInvalidProject(childElement, "ItemDefinitionGroupNotLegalInsideTarget", childElement.Name); break; default: if (onError != null) { - ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); + ProjectErrorUtilities.ThrowInvalidProject(onError, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectTaskElement(childElement, target); @@ -651,7 +651,7 @@ private ProjectTaskElement ParseProjectTaskElement(XmlElementWithLocation elemen ProjectErrorUtilities.VerifyThrowInvalidProject ( !XMakeAttributes.IsBadlyCasedSpecialTaskAttribute(attribute.Name), - attribute.Location, + attribute, "BadlyCasedSpecialTaskAttribute", attribute.Name, element.Name, @@ -663,7 +663,7 @@ private ProjectTaskElement ParseProjectTaskElement(XmlElementWithLocation elemen foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { - ProjectErrorUtilities.VerifyThrowInvalidProject(childElement.Name == XMakeElements.output, childElement.Location, "UnrecognizedChildElement", childElement.Name, task.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(childElement.Name == XMakeElements.output, childElement, "UnrecognizedChildElement", childElement.Name, task.Name); ProjectOutputElement output = ParseProjectOutputElement(childElement, task); @@ -688,7 +688,7 @@ private ProjectOutputElement ParseProjectOutputElement(XmlElementWithLocation el ProjectErrorUtilities.VerifyThrowInvalidProject ( (String.IsNullOrWhiteSpace(itemNameAttribute?.Value) && !String.IsNullOrWhiteSpace(propertyNameAttribute?.Value)) || (!String.IsNullOrWhiteSpace(itemNameAttribute?.Value) && String.IsNullOrWhiteSpace(propertyNameAttribute?.Value)), - element.Location, + element, "InvalidTaskOutputSpecification", parent.Name ); @@ -696,7 +696,7 @@ private ProjectOutputElement ParseProjectOutputElement(XmlElementWithLocation el ProjectXmlUtilities.VerifyThrowProjectAttributeEitherMissingOrNotEmpty(element, itemNameAttribute, XMakeAttributes.itemName); ProjectXmlUtilities.VerifyThrowProjectAttributeEitherMissingOrNotEmpty(element, propertyNameAttribute, XMakeAttributes.propertyName); - ProjectErrorUtilities.VerifyThrowInvalidProject(String.IsNullOrWhiteSpace(propertyNameAttribute?.Value) || !ReservedPropertyNames.IsReservedProperty(propertyNameAttribute.Value), element.Location, "CannotModifyReservedProperty", propertyNameAttribute?.Value); + ProjectErrorUtilities.VerifyThrowInvalidProject(String.IsNullOrWhiteSpace(propertyNameAttribute?.Value) || !ReservedPropertyNames.IsReservedProperty(propertyNameAttribute.Value), element, "CannotModifyReservedProperty", propertyNameAttribute?.Value); return new ProjectOutputElement(element, parent, _project); } @@ -773,7 +773,7 @@ private ProjectChooseElement ParseProjectChooseElement(XmlElementWithLocation el ProjectChooseElement choose = new ProjectChooseElement(element, parent, _project); nestingDepth++; - ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= MaximumChooseNesting, element.Location, "ChooseOverflow", MaximumChooseNesting); + ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= MaximumChooseNesting, element, "ChooseOverflow", MaximumChooseNesting); bool foundWhen = false; bool foundOtherwise = false; @@ -785,26 +785,26 @@ private ProjectChooseElement ParseProjectChooseElement(XmlElementWithLocation el switch (childElement.Name) { case XMakeElements.when: - ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise, childElement.Location, "WhenNotAllowedAfterOtherwise"); + ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise, childElement, "WhenNotAllowedAfterOtherwise"); child = ParseProjectWhenElement(childElement, choose, nestingDepth); foundWhen = true; break; case XMakeElements.otherwise: - ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise, childElement.Location, "MultipleOtherwise"); + ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise, childElement, "MultipleOtherwise"); foundOtherwise = true; child = ParseProjectOtherwiseElement(childElement, choose, nestingDepth); break; default: - ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element.Location); + ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element); break; } choose.AppendParentedChildNoChecks(child); } - ProjectErrorUtilities.VerifyThrowInvalidProject(foundWhen, element.Location, "ChooseMustContainWhen"); + ProjectErrorUtilities.VerifyThrowInvalidProject(foundWhen, element, "ChooseMustContainWhen"); return choose; } @@ -861,7 +861,7 @@ private void ParseWhenOtherwiseChildren(XmlElementWithLocation element, ProjectE break; default: - ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element.Location); + ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element); break; } @@ -878,7 +878,7 @@ private ProjectExtensionsElement ParseProjectExtensionsElement(XmlElementWithLoc // files. We don't. ProjectXmlUtilities.VerifyThrowProjectNoAttributes(element); - ProjectErrorUtilities.VerifyThrowInvalidProject(!_seenProjectExtensions, element.Location, "DuplicateProjectExtensions"); + ProjectErrorUtilities.VerifyThrowInvalidProject(!_seenProjectExtensions, element, "DuplicateProjectExtensions"); _seenProjectExtensions = true; // All children inside ProjectExtensions are ignored, since they are only part of its value @@ -892,7 +892,7 @@ private ProjectSdkElement ParseProjectSdkElement(XmlElementWithLocation element) { if (string.IsNullOrEmpty(element.GetAttribute(XMakeAttributes.sdkName))) { - ProjectErrorUtilities.ThrowInvalidProject(element.Location, "InvalidSdkElementName", element.Name); + ProjectErrorUtilities.ThrowInvalidProject(element, "InvalidSdkElementName", element.Name); } return new ProjectSdkElement(element, _project, _project); diff --git a/src/Build/Instance/ProjectItemGroupTaskMetadataInstance.cs b/src/Build/Instance/ProjectItemGroupTaskMetadataInstance.cs index f414ad75367..c287cb7b9b6 100644 --- a/src/Build/Instance/ProjectItemGroupTaskMetadataInstance.cs +++ b/src/Build/Instance/ProjectItemGroupTaskMetadataInstance.cs @@ -14,7 +14,7 @@ namespace Microsoft.Build.Execution /// Immutable. /// [DebuggerDisplay("{_name} Value={_value} Condition={_condition}")] - public class ProjectItemGroupTaskMetadataInstance : ITranslatable + public class ProjectItemGroupTaskMetadataInstance : IInternalLocation, ITranslatable { /// /// Name of the metadatum @@ -123,6 +123,8 @@ public ElementLocation ConditionLocation { return _conditionLocation; } } + IElementLocation IInternalLocation.Location => Location; + /// /// Deep clone /// diff --git a/src/Build/Instance/ProjectPropertyGroupTaskPropertyInstance.cs b/src/Build/Instance/ProjectPropertyGroupTaskPropertyInstance.cs index 33e254f876c..41879cf8239 100644 --- a/src/Build/Instance/ProjectPropertyGroupTaskPropertyInstance.cs +++ b/src/Build/Instance/ProjectPropertyGroupTaskPropertyInstance.cs @@ -14,7 +14,7 @@ namespace Microsoft.Build.Execution /// Immutable. /// [DebuggerDisplay("{_name}={Value} Condition={_condition}")] - public class ProjectPropertyGroupTaskPropertyInstance : ITranslatable + public class ProjectPropertyGroupTaskPropertyInstance : IInternalLocation, ITranslatable { /// /// Name of the property @@ -121,6 +121,8 @@ public ElementLocation ConditionLocation get { return _conditionLocation; } } + IElementLocation IInternalLocation.Location => Location; + /// /// Deep clone /// diff --git a/src/Build/Instance/ProjectPropertyInstance.cs b/src/Build/Instance/ProjectPropertyInstance.cs index 037cdac44a2..1d1e529a9e5 100644 --- a/src/Build/Instance/ProjectPropertyInstance.cs +++ b/src/Build/Instance/ProjectPropertyInstance.cs @@ -202,7 +202,7 @@ internal static ProjectPropertyInstance Create(string name, string escapedValue, /// an invalid project file exception. /// Creates mutable object. /// - internal static ProjectPropertyInstance Create(string name, string escapedValue, ElementLocation location) + internal static ProjectPropertyInstance Create(string name, string escapedValue, IInternalLocation location) { return Create(name, escapedValue, false, location, isImmutable: false); } @@ -211,7 +211,7 @@ internal static ProjectPropertyInstance Create(string name, string escapedValue, /// Called during project build time to create a property. Reserved properties will cause /// an invalid project file exception. /// - internal static ProjectPropertyInstance Create(string name, string escapedValue, ElementLocation location, bool isImmutable) + internal static ProjectPropertyInstance Create(string name, string escapedValue, IInternalLocation location, bool isImmutable) { return Create(name, escapedValue, false, location, isImmutable); } @@ -288,7 +288,7 @@ internal ProjectPropertyElement ToProjectPropertyElement(ProjectElementContainer /// as it should never be needed for any subsequent messages, and is just extra bulk. /// Inherits mutability from project if any. /// - private static ProjectPropertyInstance Create(string name, string escapedValue, bool mayBeReserved, ElementLocation location, bool isImmutable) + private static ProjectPropertyInstance Create(string name, string escapedValue, bool mayBeReserved, IInternalLocation location, bool isImmutable) { // Does not check immutability as this is only called during build (which is already protected) or evaluation ErrorUtilities.VerifyThrowArgumentNull(escapedValue, nameof(escapedValue)); diff --git a/src/Build/Instance/ProjectTargetInstance.cs b/src/Build/Instance/ProjectTargetInstance.cs index dd3dffc3cc5..861bf175719 100644 --- a/src/Build/Instance/ProjectTargetInstance.cs +++ b/src/Build/Instance/ProjectTargetInstance.cs @@ -20,7 +20,7 @@ namespace Microsoft.Build.Execution /// This is an immutable class. /// [DebuggerDisplay("Name={_name} Count={_children.Count} Condition={_condition} Inputs={_inputs} Outputs={_outputs} DependsOnTargets={_dependsOnTargets} BeforeTargets={_beforeTargets} AfterTargets={_afterTargets}")] - public sealed class ProjectTargetInstance : IImmutable, IKeyed, ITranslatable + public sealed class ProjectTargetInstance : IInternalLocation, IImmutable, IKeyed, ITranslatable { /// /// Name of the target @@ -460,6 +460,8 @@ internal bool ParentProjectSupportsReturnsAttribute { return _parentProjectSupportsReturnsAttribute; } } + IElementLocation IInternalLocation.Location => Location; + /// /// Creates a ProjectTargetElement representing this instance. Attaches it to the specified root element. /// diff --git a/src/Build/Instance/ProjectTargetInstanceChild.cs b/src/Build/Instance/ProjectTargetInstanceChild.cs index 8c4a36af614..7e0de6001e8 100644 --- a/src/Build/Instance/ProjectTargetInstanceChild.cs +++ b/src/Build/Instance/ProjectTargetInstanceChild.cs @@ -12,7 +12,7 @@ namespace Microsoft.Build.Execution /// Type for ProjectTaskInstance and ProjectPropertyGroupTaskInstance and ProjectItemGroupTaskInstance /// allowing them to be used in a single collection of target children /// - public abstract class ProjectTargetInstanceChild : ITranslatable + public abstract class ProjectTargetInstanceChild : IInternalLocation, ITranslatable { /// /// Condition on the element @@ -41,6 +41,8 @@ public string FullPath /// public abstract ElementLocation ConditionLocation { get; } + IElementLocation IInternalLocation.Location => Location; + void ITranslatable.Translate(ITranslator translator) { // all subclasses should be translateable diff --git a/src/Build/Instance/TaskFactories/AssemblyTaskFactory.cs b/src/Build/Instance/TaskFactories/AssemblyTaskFactory.cs index 802539f6077..f665c90e4e5 100644 --- a/src/Build/Instance/TaskFactories/AssemblyTaskFactory.cs +++ b/src/Build/Instance/TaskFactories/AssemblyTaskFactory.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Threading.Tasks; +using Microsoft.Build.Construction; using Microsoft.Build.Execution; using Microsoft.Build.Framework; using Microsoft.Build.Shared; @@ -463,7 +464,7 @@ internal bool TaskNameCreatableByFactory(string taskName, IDictionary /// Validates the given set of parameters, logging the appropriate errors as necessary. /// - private static void VerifyThrowIdentityParametersValid(IDictionary identityParameters, IElementLocation errorLocation, string taskName, string runtimeName, string architectureName) + private static void VerifyThrowIdentityParametersValid(IDictionary identityParameters, IInternalLocation errorLocation, string taskName, string runtimeName, string architectureName) { // validate the task factory parameters if (identityParameters?.Count > 0) diff --git a/src/Build/Instance/TaskRegistry.cs b/src/Build/Instance/TaskRegistry.cs index a44626cccae..edce5604d37 100644 --- a/src/Build/Instance/TaskRegistry.cs +++ b/src/Build/Instance/TaskRegistry.cs @@ -363,7 +363,7 @@ IFileSystem fileSystem catch (ArgumentException ex) { // Invalid chars in AssemblyFile path - ProjectErrorUtilities.ThrowInvalidProject(projectUsingTaskXml.Location, "InvalidAttributeValueWithException", assemblyFile, XMakeAttributes.assemblyFile, XMakeElements.usingTask, ex.Message); + ProjectErrorUtilities.ThrowInvalidProject(projectUsingTaskXml, "InvalidAttributeValueWithException", assemblyFile, XMakeAttributes.assemblyFile, XMakeElements.usingTask, ex.Message); } RegisteredTaskRecord.ParameterGroupAndTaskElementRecord parameterGroupAndTaskElementRecord = null; diff --git a/src/Build/Xml/ProjectXmlUtilities.XmlElementChildIterator.cs b/src/Build/Xml/ProjectXmlUtilities.XmlElementChildIterator.cs index c139c1366fd..311abe04599 100644 --- a/src/Build/Xml/ProjectXmlUtilities.XmlElementChildIterator.cs +++ b/src/Build/Xml/ProjectXmlUtilities.XmlElementChildIterator.cs @@ -95,7 +95,7 @@ private XmlElementWithLocation GetNextNode(XmlNode child) } if (_throwForInvalidNodeTypes) { - ThrowProjectInvalidChildElement(child.Name, _element.Name, _element.Location); + ThrowProjectInvalidChildElement(child.Name, _element.Name, _element); } break; } diff --git a/src/Build/Xml/ProjectXmlUtilities.cs b/src/Build/Xml/ProjectXmlUtilities.cs index 3c1528a3064..d0a47a0bf47 100644 --- a/src/Build/Xml/ProjectXmlUtilities.cs +++ b/src/Build/Xml/ProjectXmlUtilities.cs @@ -38,7 +38,7 @@ internal static void VerifyThrowProjectNoChildElements(XmlElementWithLocation el { foreach (var child in GetVerifyThrowProjectChildElements(element)) { - ThrowProjectInvalidChildElement(child.Name, element.Name, element.Location); + ThrowProjectInvalidChildElement(child.Name, element.Name, element); } } @@ -48,13 +48,13 @@ internal static void VerifyThrowProjectNoChildElements(XmlElementWithLocation el /// internal static void ThrowProjectInvalidChildElementDueToDuplicate(XmlElementWithLocation child) { - ProjectErrorUtilities.ThrowInvalidProject(child.Location, "InvalidChildElementDueToDuplication", child.Name, child.ParentNode.Name); + ProjectErrorUtilities.ThrowInvalidProject(child, "InvalidChildElementDueToDuplication", child.Name, child.ParentNode.Name); } /// /// Throw an invalid project exception indicating that the child is not valid beneath the element /// - internal static void ThrowProjectInvalidChildElement(string name, string parentName, ElementLocation location) + internal static void ThrowProjectInvalidChildElement(string name, string parentName, IInternalLocation location) { ProjectErrorUtilities.ThrowInvalidProject(location, "UnrecognizedChildElement", name, parentName); } @@ -91,7 +91,7 @@ internal static void VerifyThrowProjectAttributeEitherMissingOrNotEmpty(XmlEleme ProjectErrorUtilities.VerifyThrowInvalidProject ( attribute == null || attribute.Value.Length > 0, - attribute?.Location, + attribute == null ? ElementLocation.EmptyLocation : attribute, "InvalidAttributeValue", String.Empty, attributeName, @@ -130,7 +130,7 @@ internal static void VerifyThrowProjectInvalidAttribute(bool condition, XmlAttri /// internal static void VerifyThrowProjectRequiredAttribute(XmlElementWithLocation element, string attributeName) { - ProjectErrorUtilities.VerifyThrowInvalidProject(element.GetAttribute(attributeName).Length > 0, element.Location, "MissingRequiredAttribute", attributeName, element.Name); + ProjectErrorUtilities.VerifyThrowInvalidProject(element.GetAttribute(attributeName).Length > 0, element, "MissingRequiredAttribute", attributeName, element.Name); } /// @@ -149,7 +149,7 @@ internal static void VerifyThrowProjectAttributes(XmlElementWithLocation element /// internal static void ThrowProjectInvalidAttribute(XmlAttributeWithLocation attribute) { - ProjectErrorUtilities.ThrowInvalidProject(attribute.Location, "UnrecognizedAttribute", attribute.Name, attribute.OwnerElement.Name); + ProjectErrorUtilities.ThrowInvalidProject(attribute, "UnrecognizedAttribute", attribute.Name, attribute.OwnerElement.Name); } /// diff --git a/src/Shared/IElementLocation.cs b/src/Shared/IElementLocation.cs index b9b26cfd74b..16fb1b291d1 100644 --- a/src/Shared/IElementLocation.cs +++ b/src/Shared/IElementLocation.cs @@ -13,7 +13,7 @@ namespace Microsoft.Build.Shared /// This is not public because the current implementation only provides correct data for unedited projects. /// DO NOT make it public without considering a solution to this problem. /// - internal interface IElementLocation : ITranslatable + internal interface IElementLocation : Construction.IInternalLocation, ITranslatable { /// /// The file from which this particular element originated. It may diff --git a/src/Shared/ProjectErrorUtilities.cs b/src/Shared/ProjectErrorUtilities.cs index 540b26f71d1..af0ae40d8e5 100644 --- a/src/Shared/ProjectErrorUtilities.cs +++ b/src/Shared/ProjectErrorUtilities.cs @@ -12,6 +12,7 @@ * * ******************************************************************************/ +using Microsoft.Build.Construction; using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException; namespace Microsoft.Build.Shared @@ -37,7 +38,7 @@ internal static class ProjectErrorUtilities internal static void VerifyThrowInvalidProject ( bool condition, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName ) { @@ -52,7 +53,7 @@ string resourceName /// internal static void ThrowInvalidProject ( - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0 ) @@ -70,7 +71,7 @@ T1 arg0 internal static void VerifyThrowInvalidProject ( bool condition, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0 ) @@ -87,7 +88,7 @@ T1 arg0 /// internal static void ThrowInvalidProject ( - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1 @@ -106,7 +107,7 @@ T2 arg1 /// internal static void ThrowInvalidProject ( - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1, @@ -127,7 +128,7 @@ T3 arg2 /// internal static void ThrowInvalidProject ( - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1, @@ -146,7 +147,7 @@ T4 arg3 /// internal static void ThrowInvalidProject ( - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, params object[] args ) @@ -165,7 +166,7 @@ params object[] args internal static void VerifyThrowInvalidProject ( bool condition, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1 @@ -186,7 +187,7 @@ T2 arg1 internal static void VerifyThrowInvalidProject ( bool condition, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1, @@ -209,7 +210,7 @@ T3 arg2 internal static void VerifyThrowInvalidProject ( bool condition, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1, @@ -234,7 +235,7 @@ internal static void VerifyThrowInvalidProject ( bool condition, string errorSubCategoryResourceName, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName ) { @@ -259,7 +260,7 @@ internal static void VerifyThrowInvalidProject ( bool condition, string errorSubCategoryResourceName, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0 ) @@ -287,7 +288,7 @@ internal static void VerifyThrowInvalidProject ( bool condition, string errorSubCategoryResourceName, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1 @@ -317,7 +318,7 @@ internal static void VerifyThrowInvalidProject ( bool condition, string errorSubCategoryResourceName, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1, @@ -349,7 +350,7 @@ internal static void VerifyThrowInvalidProject ( bool condition, string errorSubCategoryResourceName, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, T1 arg0, T2 arg1, @@ -382,7 +383,7 @@ T4 arg3 private static void ThrowInvalidProject ( string errorSubCategoryResourceName, - IElementLocation elementLocation, + IInternalLocation elementLocation, string resourceName, params object[] args ) @@ -406,8 +407,8 @@ params object[] args string errorCode; string helpKeyword; string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(out errorCode, out helpKeyword, resourceName, args); - - throw new InvalidProjectFileException(elementLocation.File, elementLocation.Line, elementLocation.Column, 0 /* Unknown end line */, 0 /* Unknown end column */, message, errorSubCategory, errorCode, helpKeyword); + var location = elementLocation.Location; + throw new InvalidProjectFileException(location.File, location.Line, location.Column, 0 /* Unknown end line */, 0 /* Unknown end column */, message, errorSubCategory, errorCode, helpKeyword); } } } diff --git a/src/Shared/XmlUtilities.cs b/src/Shared/XmlUtilities.cs index 2695d35d4b0..676af5e3fa5 100644 --- a/src/Shared/XmlUtilities.cs +++ b/src/Shared/XmlUtilities.cs @@ -85,7 +85,7 @@ internal static void VerifyThrowArgumentValidElementName(string name) /// /// Note that our restrictions are more stringent than the XML Standard's restrictions. /// - internal static void VerifyThrowProjectValidElementName(string name, IElementLocation location) + internal static void VerifyThrowProjectValidElementName(string name, IInternalLocation location) { ErrorUtilities.VerifyThrowArgumentLength(name, nameof(name)); int firstInvalidCharLocation = LocateFirstInvalidElementNameCharacter(name); @@ -110,7 +110,7 @@ internal static void VerifyThrowProjectValidElementName(XmlElementWithLocation e if (-1 != firstInvalidCharLocation) { - ProjectErrorUtilities.ThrowInvalidProject(element.Location, "NameInvalid", name, name[firstInvalidCharLocation]); + ProjectErrorUtilities.ThrowInvalidProject(element, "NameInvalid", name, name[firstInvalidCharLocation]); } }