<commit_before>﻿// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//-----------------------------------------------------------------------
// </copyright>
// <summary>Implementation of ITaskExecutionHost for executing tasks in-proc.</summary>
//-----------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;

using Microsoft.Build.Execution;
using Microsoft.Build.Exceptions;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Construction;
using Microsoft.Build.BackEnd.Logging;
using System.Globalization;
using System.Reflection;
#if FEATURE_APPDOMAIN
using System.Runtime.Remoting;
#endif

using TaskItem = Microsoft.Build.Execution.ProjectItemInstance.TaskItem;

namespace Microsoft.Build.BackEnd
{
    /// <summary>
    /// The TaskExecutionHost is responsible for instantiating tasks, setting their parameters and gathering outputs using
    /// reflection, and executing the task in the appropriate context.The TaskExecutionHost does not deal with any part of the task declaration or
    /// XML.
    /// </summary>
    internal class TaskExecutionHost : ITaskExecutionHost, IDisposable
    {
        /// <summary>
        /// Time interval in miliseconds to wait between receiving a cancelation signal and emitting the first warning that a non-cancelable task has not finished
        /// </summary>
        private const int CancelFirstWarningWaitInterval = 5000;

        /// <summary>
        /// Time interval in miliseconds between subsequent warnings that a non-cancelable task has not finished
        /// </summary>
        private const int CancelWarningWaitInterval = 15000;

        /// <summary>
        /// Whether to log task input parameters.  Can either be set through an environment variable 
        /// or by the BuildParameters.
        /// </summary>
        private bool _logTaskInputs;

#if FEATURE_APPDOMAIN
        /// <summary>
        /// Resolver to assist in resolving types when a new appdomain is created
        /// </summary>
        private TaskEngineAssemblyResolver _resolver;
#endif

        /// <summary>
        /// The interface used to call back into the build engine.
        /// </summary>
        private IBuildEngine2 _buildEngine;

        /// <summary>
        /// The project instance in whose context we are executing
        /// </summary>
        private ProjectInstance _projectInstance;

        // Items required for all batches of a task

        /// <summary>
        /// The logging context for the target.
        /// </summary>
        private TargetLoggingContext _targetLoggingContext;

        /// <summary>
        /// The logging context for the task.
        /// </summary>
        private TaskLoggingContext _taskLoggingContext;

        /// <summary>
        /// The registration which handles the callback when task cancellation is invoked.
        /// </summary>
        private CancellationTokenRegistration _cancellationTokenRegistration;

        /// <summary>
        /// The name of the task to execute.
        /// </summary>
        private string _taskName;

        /// <summary>
        /// The XML location of the task element.
        /// </summary>
        private ElementLocation _taskLocation;

        /// <summary>
        /// The arbitrary task host object.
        /// </summary>
        private ITaskHost _taskHost;

        // Items required for a particular batch of a task

        /// <summary>
        /// The bucket used to evaluate items and properties.
        /// </summary>
        private ItemBucket _batchBucket;

        // Items used to execute the task

        /// <summary>
        /// The task type retrieved from the assembly.
        /// </summary>
        private TaskFactoryWrapper _taskFactoryWrapper;

        /// <summary>
        /// The instantiated task class.
        /// </summary>
        private ITask _taskInstance;

        /// <summary>
        /// The continueOnError flag
        /// </summary>
        private bool _continueOnError;

        /// <summary>
        /// Set to true if the execution has been cancelled.
        /// </summary>
        private bool _cancelled;

        /// <summary>
        /// Event which is signalled when a task is not executing.  Used for cancellation.
        /// </summary>
        private ManualResetEvent _taskExecutionIdle = new ManualResetEvent(true);

        /// <summary>
        /// The task items that we remoted across the appdomain boundary
        /// we use this list to disconnect the task items once we're done.
        /// </summary>
        private List<TaskItem> _remotedTaskItems;

        /// <summary>
        /// We need access to the build component host so that we can get at the 
        /// task host node provider when running a task wrapped by TaskHostTask
        /// </summary>
        private IBuildComponentHost _buildComponentHost;

        /// <summary>
        /// The set of intrinsic tasks mapped for this process.
        /// </summary>
        private Dictionary<string, TaskFactoryWrapper> _intrinsicTasks = new Dictionary<string, TaskFactoryWrapper>(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// Constructor
        /// </summary>
        internal TaskExecutionHost(IBuildComponentHost host)
        {
            _buildComponentHost = host;
            if (host != null && host.BuildParameters != null)
            {
                _logTaskInputs = host.BuildParameters.LogTaskInputs;
            }

            // If this is false, check the environment variable to see if it's there:
            if (!_logTaskInputs)
            {
                _logTaskInputs = (Environment.GetEnvironmentVariable("MSBUILDLOGTASKINPUTS") == "1");
            }
        }

        /// <summary>
        /// Constructor, for unit testing only.  
        /// </summary>
        internal TaskExecutionHost()
        {
            // do nothing
        }

        /// <summary>
        /// Finalizer
        /// </summary>
        ~TaskExecutionHost()
        {
            Debug.Fail("Unexpected finalization.  Dispose should already have been called.");
            Dispose(false);
        }

        /// <summary>
        /// Flag to determine whether or not to log task inputs.
        /// </summary>
        public bool LogTaskInputs
        {
            get
            {
                return _logTaskInputs;
            }
        }

        /// <summary>
        /// The associated project.
        /// </summary>
        ProjectInstance ITaskExecutionHost.ProjectInstance
        {
            get
            {
                return _projectInstance;
            }
        }

        /// <summary>
        /// Gets the task instance
        /// </summary>
        internal ITask TaskInstance<commit_msg>Disable exception from TaskExecutionHost finalizer<commit_after>﻿// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//-----------------------------------------------------------------------
// </copyright>
// <summary>Implementation of ITaskExecutionHost for executing tasks in-proc.</summary>
//-----------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;

using Microsoft.Build.Execution;
using Microsoft.Build.Exceptions;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Construction;
using Microsoft.Build.BackEnd.Logging;
using System.Globalization;
using System.Reflection;
#if FEATURE_APPDOMAIN
using System.Runtime.Remoting;
#endif

using TaskItem = Microsoft.Build.Execution.ProjectItemInstance.TaskItem;

namespace Microsoft.Build.BackEnd
{
    /// <summary>
    /// The TaskExecutionHost is responsible for instantiating tasks, setting their parameters and gathering outputs using
    /// reflection, and executing the task in the appropriate context.The TaskExecutionHost does not deal with any part of the task declaration or
    /// XML.
    /// </summary>
    internal class TaskExecutionHost : ITaskExecutionHost, IDisposable
    {
        /// <summary>
        /// Time interval in miliseconds to wait between receiving a cancelation signal and emitting the first warning that a non-cancelable task has not finished
        /// </summary>
        private const int CancelFirstWarningWaitInterval = 5000;

        /// <summary>
        /// Time interval in miliseconds between subsequent warnings that a non-cancelable task has not finished
        /// </summary>
        private const int CancelWarningWaitInterval = 15000;

        /// <summary>
        /// Whether to log task input parameters.  Can either be set through an environment variable 
        /// or by the BuildParameters.
        /// </summary>
        private bool _logTaskInputs;

#if FEATURE_APPDOMAIN
        /// <summary>
        /// Resolver to assist in resolving types when a new appdomain is created
        /// </summary>
        private TaskEngineAssemblyResolver _resolver;
#endif

        /// <summary>
        /// The interface used to call back into the build engine.
        /// </summary>
        private IBuildEngine2 _buildEngine;

        /// <summary>
        /// The project instance in whose context we are executing
        /// </summary>
        private ProjectInstance _projectInstance;

        // Items required for all batches of a task

        /// <summary>
        /// The logging context for the target.
        /// </summary>
        private TargetLoggingContext _targetLoggingContext;

        /// <summary>
        /// The logging context for the task.
        /// </summary>
        private TaskLoggingContext _taskLoggingContext;

        /// <summary>
        /// The registration which handles the callback when task cancellation is invoked.
        /// </summary>
        private CancellationTokenRegistration _cancellationTokenRegistration;

        /// <summary>
        /// The name of the task to execute.
        /// </summary>
        private string _taskName;

        /// <summary>
        /// The XML location of the task element.
        /// </summary>
        private ElementLocation _taskLocation;

        /// <summary>
        /// The arbitrary task host object.
        /// </summary>
        private ITaskHost _taskHost;

        // Items required for a particular batch of a task

        /// <summary>
        /// The bucket used to evaluate items and properties.
        /// </summary>
        private ItemBucket _batchBucket;

        // Items used to execute the task

        /// <summary>
        /// The task type retrieved from the assembly.
        /// </summary>
        private TaskFactoryWrapper _taskFactoryWrapper;

        /// <summary>
        /// The instantiated task class.
        /// </summary>
        private ITask _taskInstance;

        /// <summary>
        /// The continueOnError flag
        /// </summary>
        private bool _continueOnError;

        /// <summary>
        /// Set to true if the execution has been cancelled.
        /// </summary>
        private bool _cancelled;

        /// <summary>
        /// Event which is signalled when a task is not executing.  Used for cancellation.
        /// </summary>
        private ManualResetEvent _taskExecutionIdle = new ManualResetEvent(true);

        /// <summary>
        /// The task items that we remoted across the appdomain boundary
        /// we use this list to disconnect the task items once we're done.
        /// </summary>
        private List<TaskItem> _remotedTaskItems;

        /// <summary>
        /// We need access to the build component host so that we can get at the 
        /// task host node provider when running a task wrapped by TaskHostTask
        /// </summary>
        private IBuildComponentHost _buildComponentHost;

        /// <summary>
        /// The set of intrinsic tasks mapped for this process.
        /// </summary>
        private Dictionary<string, TaskFactoryWrapper> _intrinsicTasks = new Dictionary<string, TaskFactoryWrapper>(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// Constructor
        /// </summary>
        internal TaskExecutionHost(IBuildComponentHost host)
        {
            _buildComponentHost = host;
            if (host != null && host.BuildParameters != null)
            {
                _logTaskInputs = host.BuildParameters.LogTaskInputs;
            }

            // If this is false, check the environment variable to see if it's there:
            if (!_logTaskInputs)
            {
                _logTaskInputs = (Environment.GetEnvironmentVariable("MSBUILDLOGTASKINPUTS") == "1");
            }
        }

        /// <summary>
        /// Constructor, for unit testing only.  
        /// </summary>
        internal TaskExecutionHost()
        {
            // do nothing
        }

        /// <summary>
        /// Finalizer
        /// </summary>
        ~TaskExecutionHost()
        {
            // Debug.Fail("Unexpected finalization.  Dispose should already have been called.");
            Dispose(false);
        }

        /// <summary>
        /// Flag to determine whether or not to log task inputs.
        /// </summary>
        public bool LogTaskInputs
        {
            get
            {
                return _logTaskInputs;
            }
        }

        /// <summary>
        /// The associated project.
        /// </summary>
        ProjectInstance ITaskExecutionHost.ProjectInstance
        {
            get
            {
                return _projectInstance;
            }
        }

        /// <summary>
        /// Gets the task instance
        /// </summary>
        internal ITask TaskInstance
{'fraction_non_alphanumeric': 0.11106448454329276, 'fraction_numerical': 0.0015386767380053154, 'mean_word_length': 1.7700503680743898, 'pattern_counts': {'":': 0, '<': 127, '<?xml version=': 0, '>': 127, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1694414', 'n_tokens_mistral': 3355, 'n_tokens_neox': 3260, 'n_words': 1167}