/Microsoft.Build/Microsoft.Build/Microsoft/Build/BackEnd/TargetEntry.cs
C# | 532 lines | 502 code | 30 blank | 0 comment | 97 complexity | 49420a7750c483ccf9cef9c2263b35c4 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0
- namespace Microsoft.Build.BackEnd
- {
- using Microsoft.Build.BackEnd.Logging;
- using Microsoft.Build.Collections;
- using Microsoft.Build.Debugging;
- using Microsoft.Build.Evaluation;
- using Microsoft.Build.Exceptions;
- using Microsoft.Build.Execution;
- using Microsoft.Build.Framework;
- using Microsoft.Build.Shared;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime;
- using System.Runtime.CompilerServices;
-
- [DebuggerDisplay("Name={targetSpecification.TargetName} State={state} Result={targetResult.ResultCode}")]
- internal class TargetEntry : IEquatable<TargetEntry>
- {
- private Microsoft.Build.BackEnd.Lookup baseLookup;
- private bool cancelled;
- private object cancelLock = new object();
- private ITaskBuilder currentTaskBuilder;
- private Expander<ProjectPropertyInstance, ProjectItemInstance> expander;
- private IBuildComponentHost host;
- private Stack<Microsoft.Build.BackEnd.Lookup.Scope> legacyCallTargetScopes;
- private TargetEntry parentTarget;
- private BuildRequestEntry requestEntry;
- private TargetEntryState state;
- private ProjectTargetInstance target;
- private ITargetBuilderCallback targetBuilderCallback;
- private TargetResult targetResult;
- private TargetSpecification targetSpecification;
-
- internal TargetEntry(BuildRequestEntry requestEntry, ITargetBuilderCallback targetBuilderCallback, TargetSpecification targetSpecification, Microsoft.Build.BackEnd.Lookup baseLookup, TargetEntry parentTarget, IBuildComponentHost host, bool stopProcessingOnCompletion)
- {
- ErrorUtilities.VerifyThrowArgumentNull(requestEntry, "requestEntry");
- ErrorUtilities.VerifyThrowArgumentNull(targetBuilderCallback, "targetBuilderCallback");
- ErrorUtilities.VerifyThrowArgumentNull(targetSpecification, "targetName");
- ErrorUtilities.VerifyThrowArgumentNull(baseLookup, "lookup");
- ErrorUtilities.VerifyThrowArgumentNull(host, "host");
- this.requestEntry = requestEntry;
- this.targetBuilderCallback = targetBuilderCallback;
- this.targetSpecification = targetSpecification;
- this.parentTarget = parentTarget;
- this.expander = new Expander<ProjectPropertyInstance, ProjectItemInstance>(baseLookup.ReadOnlyLookup, baseLookup.ReadOnlyLookup);
- this.state = TargetEntryState.Dependencies;
- this.baseLookup = baseLookup;
- this.host = host;
- this.StopProcessingOnCompletion = stopProcessingOnCompletion;
- }
-
- internal void CancelTarget()
- {
- this.cancelled = true;
- ITaskBuilder currentTaskBuilder = this.currentTaskBuilder;
- if (currentTaskBuilder != null)
- {
- currentTaskBuilder.CancelTask();
- }
- }
-
- internal void EnterLegacyCallTargetScope(Microsoft.Build.BackEnd.Lookup lookup)
- {
- if (this.legacyCallTargetScopes == null)
- {
- this.legacyCallTargetScopes = new Stack<Microsoft.Build.BackEnd.Lookup.Scope>();
- }
- this.legacyCallTargetScopes.Push(lookup.EnterScope("EnterLegacyCallTargetScope()"));
- }
-
- public bool Equals(TargetEntry other)
- {
- return string.Equals(this.Name, other.Name, StringComparison.OrdinalIgnoreCase);
- }
-
- internal void ExecuteTarget(ITaskBuilder taskBuilder, BuildRequestEntry requestEntry, ProjectLoggingContext projectLoggingContext)
- {
- this.VerifyState(this.state, TargetEntryState.Execution);
- List<ItemBucket> list = BatchingEngine.PrepareBatchingBuckets(this.GetBatchableParametersForTarget(), this.baseLookup, this.target.Location);
- TaskResultCode skipped = TaskResultCode.Skipped;
- Exception exception = null;
- TargetLoggingContext targetLoggingContext = null;
- bool success = false;
- int count = list.Count;
- string projectFullPath = requestEntry.RequestConfiguration.ProjectFullPath;
- string parentTargetName = null;
- if ((this.ParentEntry != null) && (this.ParentEntry.Target != null))
- {
- parentTargetName = this.ParentEntry.Target.Name;
- }
- for (int i = 0; i < count; i++)
- {
- ItemBucket bucket = list[i];
- if (skipped == TaskResultCode.StopWithError)
- {
- break;
- }
- targetLoggingContext = projectLoggingContext.LogTargetBatchStarted(projectFullPath, this.target, parentTargetName);
- TaskResult result = null;
- success = false;
- Microsoft.Build.BackEnd.Lookup.Scope scope = null;
- Microsoft.Build.BackEnd.Lookup.Scope scope2 = null;
- try
- {
- ItemDictionary<ProjectItemInstance> dictionary;
- ItemDictionary<ProjectItemInstance> dictionary2;
- DependencyAnalysisResult analysis = new TargetUpToDateChecker(requestEntry.RequestConfiguration.Project, this.target, targetLoggingContext.LoggingService, targetLoggingContext.BuildEventContext).PerformDependencyAnalysis(bucket, out dictionary, out dictionary2);
- switch (analysis)
- {
- case DependencyAnalysisResult.SkipUpToDate:
- case DependencyAnalysisResult.IncrementalBuild:
- case DependencyAnalysisResult.FullBuild:
- break;
-
- case DependencyAnalysisResult.SkipNoInputs:
- case DependencyAnalysisResult.SkipNoOutputs:
- {
- success = true;
- continue;
- }
- default:
- {
- continue;
- }
- }
- Microsoft.Build.BackEnd.Lookup lookupForInference = bucket.Lookup;
- Microsoft.Build.BackEnd.Lookup lookupForExecution = bucket.Lookup.Clone();
- scope = lookupForInference.EnterScope("ExecuteTarget() Inference");
- scope2 = lookupForExecution.EnterScope("ExecuteTarget() Execution");
- if (analysis == DependencyAnalysisResult.IncrementalBuild)
- {
- foreach (string str3 in dictionary2.ItemTypes)
- {
- lookupForInference.PopulateWithItems(str3, dictionary2[str3]);
- }
- foreach (string str4 in dictionary.ItemTypes)
- {
- lookupForExecution.PopulateWithItems(str4, dictionary[str4]);
- }
- }
- result = this.ProcessBucket(taskBuilder, targetLoggingContext, this.GetTaskExecutionMode(analysis), lookupForInference, lookupForExecution);
- if (analysis != DependencyAnalysisResult.SkipUpToDate)
- {
- if ((result.ResultCode == TaskResultCode.StopWithError) || (result.ResultCode == TaskResultCode.Cancelled))
- {
- skipped = TaskResultCode.StopWithError;
- exception = result.Exception;
- }
- else if (((result.ResultCode == TaskResultCode.ContinueWithError) || (result.ResultCode == TaskResultCode.Success)) && (skipped != TaskResultCode.StopWithError))
- {
- skipped = TaskResultCode.Success;
- }
- else
- {
- ErrorUtilities.VerifyThrow(result.ResultCode == TaskResultCode.Skipped, "Task result should have been 'Skipped', was {0}.", result);
- }
- }
- else if (skipped == TaskResultCode.Skipped)
- {
- skipped = TaskResultCode.Success;
- }
- scope.LeaveScope();
- scope = null;
- scope2.LeaveScope();
- scope2 = null;
- success = (result != null) && ((result.ResultCode == TaskResultCode.Success) || (result.ResultCode == TaskResultCode.ContinueWithError));
- }
- catch (InvalidProjectFileException exception2)
- {
- targetLoggingContext.LogInvalidProjectFileError(exception2);
- if (scope != null)
- {
- scope.LeaveScope();
- }
- if (scope2 != null)
- {
- scope2.LeaveScope();
- }
- skipped = TaskResultCode.StopWithError;
- }
- finally
- {
- if ((targetLoggingContext != null) && (i < (count - 1)))
- {
- targetLoggingContext.LogTargetBatchFinished(projectFullPath, success, null);
- targetLoggingContext = null;
- }
- }
- }
- List<ProjectItemInstance.TaskItem> list2 = new List<ProjectItemInstance.TaskItem>();
- try
- {
- this.LeaveLegacyCallTargetScopes();
- foreach (ItemBucket bucket2 in list)
- {
- bucket2.LeaveScope();
- }
- string returns = this.target.Returns;
- IElementLocation returnsLocation = this.target.ReturnsLocation;
- if ((returns == null) && !this.target.ParentProjectSupportsReturnsAttribute)
- {
- returns = this.target.Outputs;
- returnsLocation = this.target.OutputsLocation;
- }
- if (!string.IsNullOrEmpty(returns))
- {
- bool flag2 = ConditionEvaluator.EvaluateCondition<ProjectPropertyInstance, ProjectItemInstance>(this.target.KeepDuplicateOutputs, ParserOptions.AllowPropertiesAndItemLists, this.expander, ExpanderOptions.ExpandPropertiesAndItems, requestEntry.ProjectRootDirectory, this.target.KeepDuplicateOutputsLocation, projectLoggingContext.LoggingService, projectLoggingContext.BuildEventContext);
- List<ItemBucket> list3 = BatchingEngine.PrepareBatchingBuckets(this.GetBatchableParametersForTarget(), this.baseLookup, this.target.Location);
- if (flag2)
- {
- foreach (ItemBucket bucket3 in list3)
- {
- list2.AddRange(bucket3.Expander.ExpandIntoTaskItemsLeaveEscaped(returns, ExpanderOptions.ExpandAll, returnsLocation));
- }
- }
- else
- {
- HashSet<ProjectItemInstance.TaskItem> set = new HashSet<ProjectItemInstance.TaskItem>();
- foreach (ItemBucket bucket4 in list3)
- {
- foreach (ProjectItemInstance.TaskItem item in bucket4.Expander.ExpandIntoTaskItemsLeaveEscaped(returns, ExpanderOptions.ExpandAll, returnsLocation))
- {
- if (!set.Contains(item))
- {
- list2.Add(item);
- set.Add(item);
- }
- }
- }
- }
- }
- }
- finally
- {
- if (targetLoggingContext != null)
- {
- targetLoggingContext.LogTargetBatchFinished(projectFullPath, success, ((list2 != null) && (list2.Count > 0)) ? list2 : null);
- }
- }
- TargetResultCode failure = TargetResultCode.Skipped;
- switch (skipped)
- {
- case TaskResultCode.Success:
- failure = TargetResultCode.Success;
- break;
-
- case TaskResultCode.StopWithError:
- failure = TargetResultCode.Failure;
- break;
-
- default:
- ErrorUtilities.VerifyThrow(skipped == TaskResultCode.Skipped, "Aggregate result should have been 'Skipped', was {0}.", skipped);
- ErrorUtilities.VerifyThrow(failure == TargetResultCode.Skipped, "Target result should have been 'Skipped', was {0}.", failure);
- break;
- }
- this.targetResult = new TargetResult(list2.ToArray(), exception, failure);
- if (failure == TargetResultCode.Failure)
- {
- this.state = TargetEntryState.ErrorExecution;
- }
- else
- {
- this.state = TargetEntryState.Completed;
- }
- }
-
- internal TargetResult GatherResults()
- {
- this.VerifyState(this.state, TargetEntryState.Completed);
- ErrorUtilities.VerifyThrow(this.legacyCallTargetScopes == null, "We should have already left any legacy call target scopes.");
- return this.targetResult;
- }
-
- private List<string> GetBatchableParametersForTarget()
- {
- List<string> list = new List<string>();
- if (this.target.Inputs.Length > 0)
- {
- list.Add(this.target.Inputs);
- }
- if (this.target.Outputs.Length > 0)
- {
- list.Add(this.target.Outputs);
- }
- if ((this.target.Returns != null) && (this.target.Returns.Length > 0))
- {
- list.Add(this.target.Returns);
- }
- return list;
- }
-
- internal List<TargetSpecification> GetDependencies(ProjectLoggingContext projectLoggingContext)
- {
- this.VerifyState(this.state, TargetEntryState.Dependencies);
- this.GetTargetInstance();
- if (ExpressionShredder.ContainsMetadataExpressionOutsideTransform(this.target.Condition))
- {
- ProjectErrorUtilities.ThrowInvalidProject(this.target.ConditionLocation, "TargetConditionHasInvalidMetadataReference", this.target.Name, this.target.Condition);
- }
- if (!ConditionEvaluator.EvaluateCondition<ProjectPropertyInstance, ProjectItemInstance>(this.target.Condition, ParserOptions.AllowPropertiesAndItemLists, this.expander, ExpanderOptions.ExpandPropertiesAndItems, this.requestEntry.ProjectRootDirectory, this.target.ConditionLocation, projectLoggingContext.LoggingService, projectLoggingContext.BuildEventContext))
- {
- this.targetResult = new TargetResult(new ProjectItemInstance.TaskItem[0], TargetResultCode.Skipped);
- this.state = TargetEntryState.Completed;
- if (!projectLoggingContext.LoggingService.OnlyLogCriticalEvents)
- {
- string str = this.expander.ExpandIntoStringAndUnescape(this.target.Condition, ExpanderOptions.ExpandPropertiesAndItems, this.target.ConditionLocation);
- projectLoggingContext.LogComment(MessageImportance.Low, "TargetSkippedFalseCondition", new object[] { this.target.Name, this.target.Condition, str });
- }
- return new List<TargetSpecification>();
- }
- IList<string> list = this.expander.ExpandIntoStringListLeaveEscaped(this.target.DependsOnTargets, ExpanderOptions.ExpandPropertiesAndItems, this.target.DependsOnTargetsLocation);
- List<TargetSpecification> list2 = new List<TargetSpecification>(list.Count);
- foreach (string str2 in list)
- {
- string targetName = EscapingUtilities.UnescapeAll(str2);
- list2.Add(new TargetSpecification(targetName, this.target.DependsOnTargetsLocation));
- }
- this.state = TargetEntryState.Execution;
- return list2;
- }
-
- internal List<TargetSpecification> GetErrorTargets(ProjectLoggingContext projectLoggingContext)
- {
- this.VerifyState(this.state, TargetEntryState.ErrorExecution);
- ErrorUtilities.VerifyThrow(this.legacyCallTargetScopes == null, "We should have already left any legacy call target scopes.");
- List<TargetSpecification> list = new List<TargetSpecification>(this.target.OnErrorChildren.Count);
- foreach (ProjectOnErrorInstance instance in this.target.OnErrorChildren)
- {
- if (ConditionEvaluator.EvaluateCondition<ProjectPropertyInstance, ProjectItemInstance>(instance.Condition, ParserOptions.AllowPropertiesAndItemLists, this.expander, ExpanderOptions.ExpandPropertiesAndItems, this.requestEntry.ProjectRootDirectory, instance.ConditionLocation, projectLoggingContext.LoggingService, projectLoggingContext.BuildEventContext))
- {
- foreach (string str in this.expander.ExpandIntoStringListLeaveEscaped(instance.ExecuteTargets, ExpanderOptions.ExpandPropertiesAndItems, instance.ExecuteTargetsLocation))
- {
- string targetName = EscapingUtilities.UnescapeAll(str);
- list.Add(new TargetSpecification(targetName, instance.ExecuteTargetsLocation));
- }
- continue;
- }
- }
- if (this.targetResult == null)
- {
- this.targetResult = new TargetResult(new ProjectItemInstance.TaskItem[0], null, TargetResultCode.Failure);
- }
- this.state = TargetEntryState.Completed;
- return list;
- }
-
- private void GetTargetInstance()
- {
- this.requestEntry.RequestConfiguration.Project.Targets.TryGetValue(this.targetSpecification.TargetName, out this.target);
- ProjectErrorUtilities.VerifyThrowInvalidProject(this.target != null, this.targetSpecification.ReferenceLocation ?? this.requestEntry.RequestConfiguration.Project.ProjectFileLocation, "TargetDoesNotExist", this.targetSpecification.TargetName);
- }
-
- private TaskExecutionMode GetTaskExecutionMode(DependencyAnalysisResult analysis)
- {
- TaskExecutionMode inferOutputsOnly;
- if ((analysis == DependencyAnalysisResult.SkipUpToDate) || (analysis == DependencyAnalysisResult.IncrementalBuild))
- {
- inferOutputsOnly = TaskExecutionMode.InferOutputsOnly;
- }
- else
- {
- inferOutputsOnly = TaskExecutionMode.ExecuteTaskAndGatherOutputs;
- }
- if ((analysis != DependencyAnalysisResult.FullBuild) && (analysis != DependencyAnalysisResult.IncrementalBuild))
- {
- return inferOutputsOnly;
- }
- return (inferOutputsOnly | TaskExecutionMode.ExecuteTaskAndGatherOutputs);
- }
-
- internal void LeaveLegacyCallTargetScopes()
- {
- if (this.legacyCallTargetScopes != null)
- {
- while (this.legacyCallTargetScopes.Count != 0)
- {
- this.legacyCallTargetScopes.Pop().LeaveScope();
- }
- this.legacyCallTargetScopes = null;
- }
- }
-
- internal void MarkForError()
- {
- ErrorUtilities.VerifyThrow(this.state != TargetEntryState.Completed, "State must not be Completed. State is {0}.", this.state);
- this.state = TargetEntryState.ErrorExecution;
- }
-
- private TaskResult ProcessBucket(ITaskBuilder taskBuilder, TargetLoggingContext targetLoggingContext, TaskExecutionMode mode, Microsoft.Build.BackEnd.Lookup lookupForInference, Microsoft.Build.BackEnd.Lookup lookupForExecution)
- {
- TaskResult result = new TaskResult(TaskResultCode.Success);
- try
- {
- this.currentTaskBuilder = taskBuilder;
- for (int i = 0; (i < this.target.Children.Count) && !this.cancelled; i++)
- {
- ProjectTargetInstanceChild task = this.target.Children[i];
- if (DebuggerManager.DebuggingEnabled)
- {
- DebuggerManager.EnterState(task.Location, lookupForExecution.GlobalsForDebugging);
- }
- result = taskBuilder.ExecuteTask(targetLoggingContext, this.requestEntry, this.targetBuilderCallback, task, mode, lookupForInference, lookupForExecution);
- if (DebuggerManager.DebuggingEnabled)
- {
- DebuggerManager.LeaveState(task.Location);
- }
- if ((result.ResultCode != TaskResultCode.Success) && (result.ResultCode != TaskResultCode.ContinueWithError))
- {
- break;
- }
- }
- if (this.cancelled)
- {
- result = new TaskResult(TaskResultCode.Cancelled);
- }
- }
- finally
- {
- this.currentTaskBuilder = null;
- }
- return result;
- }
-
- private void VerifyState(TargetEntryState actual, TargetEntryState expected)
- {
- ErrorUtilities.VerifyThrow(actual == expected, "Expected state {1}. Got {0}", actual, expected);
- }
-
- internal bool ErrorTarget
- {
- [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- get
- {
- return this.<ErrorTarget>k__BackingField;
- }
- [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- set
- {
- this.<ErrorTarget>k__BackingField = value;
- }
- }
-
- internal Microsoft.Build.BackEnd.Lookup Lookup
- {
- [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- get
- {
- return this.baseLookup;
- }
- }
-
- internal string Name
- {
- get
- {
- return this.targetSpecification.TargetName;
- }
- }
-
- internal TargetEntry ParentEntry
- {
- [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- get
- {
- return this.parentTarget;
- }
- }
-
- internal IElementLocation ReferenceLocation
- {
- get
- {
- return this.targetSpecification.ReferenceLocation;
- }
- }
-
- internal BuildRequestEntry RequestEntry
- {
- [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- get
- {
- return this.requestEntry;
- }
- }
-
- internal TargetResult Result
- {
- [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- get
- {
- return this.targetResult;
- }
- }
-
- internal TargetEntryState State
- {
- [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- get
- {
- return this.state;
- }
- }
-
- internal bool StopProcessingOnCompletion
- {
- [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- get
- {
- return this.<StopProcessingOnCompletion>k__BackingField;
- }
- [CompilerGenerated, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
- set
- {
- this.<StopProcessingOnCompletion>k__BackingField = value;
- }
- }
-
- internal ProjectTargetInstance Target
- {
- get
- {
- if (this.target == null)
- {
- this.GetTargetInstance();
- }
- return this.target;
- }
- }
- }
- }
-