예제 #1
0
        public static Filter CreateFilter(XmlNode elementNode, Element parent, TargetCallStack callStack)
        {
            if (elementNode == null)
            {
                throw new ArgumentNullException("elementNode");
            }
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }

            string filterName = elementNode.Name;

            FilterBuilder builder = FilterBuilders[filterName];

            if (builder == null)
            {
                Location location = parent.Project.LocationMap.GetLocation(elementNode);
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                       ResourceUtils.GetString("NA1082"), filterName), location);
            }

            Filter filter = (Filter)builder.CreateFilter();

            filter.Parent           = parent;
            filter.Project          = parent.Project;
            filter.CallStack        = callStack;
            filter.NamespaceManager = parent.Project.NamespaceManager;
            filter.Initialize(elementNode);

            // check whether the type (or its base class) is deprecated
            ObsoleteAttribute obsoleteAttribute = (ObsoleteAttribute)
                                                  Attribute.GetCustomAttribute(filter.GetType(),
                                                                               typeof(ObsoleteAttribute), true);

            if (obsoleteAttribute != null)
            {
                Location location        = parent.Project.LocationMap.GetLocation(elementNode);
                string   obsoleteMessage = string.Format(CultureInfo.InvariantCulture,
                                                         ResourceUtils.GetString("NA1079"), filterName,
                                                         obsoleteAttribute.Message);
                if (obsoleteAttribute.IsError)
                {
                    throw new BuildException(obsoleteMessage, location);
                }
                else
                {
                    if (callStack.CurrentFrame != null && callStack.CurrentFrame.TaskCallStack.CurrentFrame != null)
                    {
                        callStack.CurrentFrame.TaskCallStack.CurrentFrame.Task.Log(Level.Warning, "{0} {1}", location, obsoleteMessage);
                    }
                    else
                    {
                        (parent.Project as ITargetLogger).Log(Level.Warning, "{0} {1}", location, obsoleteMessage);
                    }
                }
            }
            return(filter);
        }
예제 #2
0
        /// <summary>
        /// Creates a new <see cref="Task" /> instance for the given XML and
        /// <see cref="Project" />.
        /// </summary>
        /// <param name="taskNode">The XML to initialize the task with.</param>
        /// <param name="proj">The <see cref="Project" /> that the <see cref="Task" /> belongs to.</param>
        /// <param name="targetCallStack">The current target call stack.  Needed for accessing thread and target properties.</param>
        /// <returns>
        /// The new <see cref="Task" /> instance.
        /// </returns>
        public static Task CreateTask(XmlNode taskNode, Project proj, TargetCallStack targetCallStack)
        {
            if (taskNode == null)
            {
                throw new ArgumentNullException("taskNode");
            }
            if (proj == null)
            {
                throw new ArgumentNullException("proj");
            }

            string taskName = taskNode.Name;

            TaskBuilder builder = TaskBuilders[taskName];

            if (builder == null)
            {
                Location location = proj.LocationMap.GetLocation(taskNode);
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                       ResourceUtils.GetString("NA1083"), taskName), location);
            }

            Task task = builder.CreateTask();

            task.Project          = proj;
            task.CallStack        = targetCallStack;
            task.NamespaceManager = proj.NamespaceManager;

            // check whether the task (or its base class) is deprecated
            ObsoleteAttribute obsoleteAttribute = (ObsoleteAttribute)
                                                  Attribute.GetCustomAttribute(task.GetType(),
                                                                               typeof(ObsoleteAttribute), true);

            if (obsoleteAttribute != null)
            {
                Location location        = proj.LocationMap.GetLocation(taskNode);
                string   obsoleteMessage = string.Format(CultureInfo.InvariantCulture,
                                                         ResourceUtils.GetString("NA1086"), taskName,
                                                         obsoleteAttribute.Message);
                if (obsoleteAttribute.IsError)
                {
                    throw new BuildException(obsoleteMessage, location);
                }
                else
                {
                    if (targetCallStack.CurrentFrame != null && targetCallStack.CurrentFrame.TaskCallStack.CurrentFrame != null)
                    {
                        targetCallStack.CurrentFrame.TaskCallStack.CurrentFrame.Task.Log(Level.Warning, "{0} {1}", location, obsoleteMessage);
                    }
                    else
                    {
                        (proj as ITargetLogger).Log(Level.Warning, "{0} {1}", location, obsoleteMessage);
                    }
                }
            }

            return(task);
        }
예제 #3
0
        /// <summary>
        /// Creates the <see cref="DataTypeBase"/> instance.
        /// </summary>
        /// <param name="elementNode">The element XML node.</param>
        /// <param name="proj">The current project.</param>
        /// <param name="targetCallStack">The current target call stack.  Needed for accessing thread and target properties.</param>
        /// <returns>The created instance.</returns>
        /// <exception cref="System.ArgumentNullException">If elementNode or proj is <c>null</c>.
        /// </exception>
        /// <exception cref="BuildException">If no builder for the elment can be found.
        /// </exception>
        public static DataTypeBase CreateDataType(XmlNode elementNode, Project proj, TargetCallStack targetCallStack)
        {
            if (elementNode == null)
            {
                throw new ArgumentNullException("elementNode");
            }
            if (proj == null)
            {
                throw new ArgumentNullException("proj");
            }

            string dataTypeName = elementNode.Name;

            DataTypeBaseBuilder builder = DataTypeBuilders[dataTypeName];

            if (builder == null)
            {
                Location location = proj.LocationMap.GetLocation(elementNode);
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                       ResourceUtils.GetString("NA1081"), dataTypeName), location);
            }

            DataTypeBase element = (DataTypeBase)builder.CreateDataTypeBase();

            element.Project          = proj;
            element.CallStack        = targetCallStack;
            element.NamespaceManager = proj.NamespaceManager;

            // check whether the type (or its base class) is deprecated
            ObsoleteAttribute obsoleteAttribute = (ObsoleteAttribute)
                                                  Attribute.GetCustomAttribute(element.GetType(),
                                                                               typeof(ObsoleteAttribute), true);

            if (obsoleteAttribute != null)
            {
                Location location        = proj.LocationMap.GetLocation(elementNode);
                string   obsoleteMessage = string.Format(CultureInfo.InvariantCulture,
                                                         ResourceUtils.GetString("NA1085"), dataTypeName,
                                                         obsoleteAttribute.Message);
                if (obsoleteAttribute.IsError)
                {
                    throw new BuildException(obsoleteMessage, location);
                }
                else
                {
                    if (targetCallStack.CurrentFrame != null && targetCallStack.CurrentFrame.TaskCallStack.CurrentFrame != null)
                    {
                        targetCallStack.CurrentFrame.TaskCallStack.CurrentFrame.Task.Log(Level.Warning, "{0} {1}", location, obsoleteMessage);
                    }
                    else
                    {
                        (proj as ITargetLogger).Log(Level.Warning, "{0} {1}", location, obsoleteMessage);
                    }
                }
            }
            return(element);
        }
예제 #4
0
        /// <summary>
        /// Clones this stack.  This method is probably thread-safe.
        /// </summary>
        public override object Clone()
        {
            var clone = new TargetCallStack(this.Project);

            PopulateClone(this, clone);

            clone.ThreadProperties.Inherit(this.ThreadProperties, new StringCollection());

            return(clone);
        }
예제 #5
0
        /// <summary>
        /// Creates and executes the embedded (child XML nodes) elements.
        /// </summary>
        protected virtual void ExecuteChildTasks(TargetCallStack callStack)
        {
            foreach (XmlNode childNode in XmlNode)
            {
                //we only care about xmlnodes (elements) that are of the right namespace.
                if (!(childNode.NodeType == XmlNodeType.Element) || !childNode.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant")))
                {
                    continue;
                }

                // ignore any private xml elements (by def. this includes any property with a BuildElementAttribute (name).
                if (IsPrivateXmlElement(childNode))
                {
                    continue;
                }

                if (TypeFactory.TaskBuilders.Contains(childNode.Name))
                {
                    // create task instance
                    Task task = CreateChildTask(childNode, callStack);
                    // for now, we should assume null tasks are because of
                    // incomplete metadata about the XML
                    if (task != null)
                    {
                        task.Parent = this;
                        // execute task
                        task.Execute();
                    }
                }
                else if (TypeFactory.DataTypeBuilders.Contains(childNode.Name))
                {
                    // we are an datatype declaration
                    DataTypeBase dataType = CreateChildDataTypeBase(childNode, this.CallStack);

                    Log(Level.Debug, "Adding a {0} reference with id '{1}'.", childNode.Name, dataType.ID);
                    if (!Project.DataTypeReferences.Contains(dataType.ID))
                    {
                        Project.DataTypeReferences.Add(dataType.ID, dataType);
                    }
                    else
                    {
                        Project.DataTypeReferences[dataType.ID] = dataType; // overwrite with the new reference.
                    }
                }
                else
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           ResourceUtils.GetString("NA1071"), childNode.Name),
                                             Project.GetLocation(childNode));
                }
            }
        }
예제 #6
0
 /// <summary>
 /// Executes this target, after acquiring any necessary locks.
 /// </summary>
 /// <param name="callStack">The current call stack on which this target will be pused</param>
 /// <param name="logger">The logger this target and its stasks will use for logging messages</param>
 /// <param name="arguments">Optionally, the arguments to provide to the target.  Should match those required by <see cref="Parameters"/></param>
 /// <exception cref="ArgumentException">If one of the non-defaulted parameters is not satisfied by an argument.</exception>
 public void Execute(TargetCallStack callStack, ITargetLogger logger, IList <CallArgument> arguments = null)
 {
     if (this.Locked)
     {
         lock (this)
         {
             this.DoExecute(callStack, logger, arguments);
         }
     }
     else
     {
         this.DoExecute(callStack, logger, arguments);
     }
 }
예제 #7
0
        /// <summary>
        /// Extracts up the paramters specified in <see cref="Parameters"/> from <paramref name="arguments"/>
        /// and ddds the necessary properties to the call stack's target properties.
        /// </summary>
        /// <param name="arguments">The arguments being passed in to the this target</param>
        /// <param name="callStack">The call stack where the properties will be placed</param>
        /// <exception cref="ArgumentException">If one of the non-defaulted parameters is not satisfied by an argument.</exception>
        private void PrepareArguments(IList <CallArgument> arguments, TargetCallStack callStack)
        {
            if (this.Parameters == null || !this.Parameters.Parameters.Any())
            {
                return;
            }

            var accessor = new PropertyAccessor(this.Project, callStack);

            var matchedProperties = new HashSet <String>();

            foreach (var param in this.Parameters.Parameters)
            {
                if (matchedProperties.Contains(param.PropertyName))
                {
                    throw new BuildException(String.Format(@"Paramter ""{0}"" was declared more than once", param.PropertyName));
                }

                matchedProperties.Add(param.PropertyName);

                CallArgument arg = null;

                if (arguments != null)
                {
                    arg = arguments.FirstOrDefault(a => a.PropertyName.Equals(param.PropertyName));
                }

                if (arg == null && param.DefaultValue != null)
                {
                    accessor.Set(param.PropertyName, param.DefaultValue, PropertyScope.Target, false, true);
                }
                else if (arg != null)
                {
                    if (arguments.Count(a => a.PropertyName.Equals(arg.PropertyName)) > 1)
                    {
                        throw new ArgumentException(String.Format(@"Argument ""{0}"" was specified more than once.", param.PropertyName));
                    }

                    accessor.Set(param.PropertyName, arg.PropertyValue, PropertyScope.Target, false, true);
                }
                else
                {
                    throw new ArgumentException(String.Format(@"Target ""{0}"" requires parameter ""{1}"" but it was not provided and has no default.", this.Name, param.PropertyName));
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Registers the project with <see cref="TypeFactory" />, and optionally
        /// scan the <see cref="Project.BaseDirectory" /> for extension assemblies.
        /// </summary>
        /// <param name="project">The project to work from.</param>
        /// <param name="scan">Specified whether to scan the <see cref="Project.BaseDirectory" /> for extension assemblies.</param>
        /// <param name="targetCallStack">The current target call stack.  Needed for accessing thread and target properties.</param>
        internal static void AddProject(Project project, bool scan, TargetCallStack targetCallStack)
        {
            if (!scan || String.IsNullOrEmpty(project.BaseDirectory))
            {
                return;
            }

            LoadTasksTask loadTasks = new LoadTasksTask();

            loadTasks.Project          = project;
            loadTasks.CallStack        = targetCallStack;
            loadTasks.NamespaceManager = project.NamespaceManager;
            loadTasks.Parent           = project;
            loadTasks.FailOnError      = false;
            loadTasks.Threshold        = (project.Threshold == Level.Debug) ?
                                         Level.Debug : Level.Warning;

            string tasksDir       = Path.Combine(project.BaseDirectory, "extensions");
            string commonTasksDir = Path.Combine(tasksDir, "common");

            // scan framework-neutral and version-neutral assemblies
            ScanDir(Path.Combine(commonTasksDir, "neutral"), loadTasks,
                    false);

            // skip further processing if runtime framework has not yet
            // been set
            if (project.RuntimeFramework == null)
            {
                return;
            }

            // scan framework-neutral but version-specific assemblies
            ScanDir(Path.Combine(commonTasksDir, project.RuntimeFramework.
                                 ClrVersion.ToString(2)), loadTasks, false);

            string frameworkTasksDir = Path.Combine(tasksDir,
                                                    project.RuntimeFramework.Family);

            // scan framework-specific but version-neutral assemblies
            ScanDir(Path.Combine(frameworkTasksDir, "neutral"), loadTasks,
                    false);

            // scan framework-specific and version-specific assemblies
            ScanDir(Path.Combine(frameworkTasksDir, project.RuntimeFramework
                                 .Version.ToString()), loadTasks, false);
        }
예제 #9
0
 /// <summary>
 /// Creates the child task specified by the passed XmlNode.
 /// </summary>
 /// <param name="node">The node specifiing the task.</param>
 /// <returns>The created task instance.</returns>
 protected virtual Task CreateChildTask(XmlNode node, TargetCallStack callStack)
 {
     return(Project.CreateTask(node, callStack));
 }
예제 #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ExpressionEvaluator"/> class.
 /// </summary>
 /// <param name="project">The project.</param>
 /// <param name="properties">The projects properties.</param>
 /// <param name="state">The state.</param>
 /// <param name="visiting">The visiting.</param>
 /// <param name="targetCallStack">The call stack needed for executing certain functions along the way</param>
 public ExpressionEvaluator(Project project, PropertyAccessor properties, Hashtable state, Stack visiting, TargetCallStack targetCallStack)
     : base(project, targetCallStack)
 {
     _properties = properties;
     _state      = state;
     _visiting   = visiting;
 }
예제 #11
0
        /// <summary>
        /// Executes this target
        /// </summary>
        /// <param name="callStack">The current call stack on which this target will be pused</param>
        /// <param name="logger">The logger this target and its stasks will use for logging messages</param>
        /// <param name="arguments">Optionally, the arguments to provide to the target.  Should match those required by <see cref="Parameters"/></param>
        /// <exception cref="ArgumentException">If one of the non-defaulted parameters is not satisfied by an argument.</exception>
        private void DoExecute(TargetCallStack callStack, ITargetLogger logger, IList <CallArgument> arguments = null)
        {
            var propertyAccessor = new PropertyAccessor(this.Project, callStack);

            var sw = Stopwatch.StartNew();

            if (IfDefined(propertyAccessor) && !UnlessDefined(propertyAccessor))
            {
                try
                {
                    using (callStack.Push(this, logger))
                    {
                        this.PrepareArguments(arguments, callStack);

                        Project.OnTargetStarted(this, new TargetBuildEventArgs(this, sw));
                        logger.OnTargetLoggingStarted(this, new TargetBuildEventArgs(this, sw));

                        var paramtersDone = false;

                        // select all the task nodes and execute them
                        foreach (XmlNode childNode in XmlNode)
                        {
                            if (!(childNode.NodeType == XmlNodeType.Element) || !childNode.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant")))
                            {
                                continue;
                            }

                            if (childNode.Name.Equals("parameters"))
                            {
                                if (paramtersDone)
                                {
                                    throw new BuildException("parameters must appear before all tasks", this.Location);
                                }

                                continue;
                            }
                            else
                            {
                                paramtersDone = true;
                                if (TypeFactory.TaskBuilders.Contains(childNode.Name))
                                {
                                    Task task = Project.CreateTask(childNode, this, callStack);
                                    if (task != null)
                                    {
                                        task.Execute();
                                    }
                                }
                                else if (TypeFactory.DataTypeBuilders.Contains(childNode.Name))
                                {
                                    DataTypeBase dataType = Project.CreateDataTypeBase(childNode, callStack);
                                    logger.Log(Level.Verbose, "Adding a {0} reference with id '{1}'.",
                                               childNode.Name, dataType.ID);
                                    if (!Project.DataTypeReferences.Contains(dataType.ID))
                                    {
                                        Project.DataTypeReferences.Add(dataType.ID, dataType);
                                    }
                                    else
                                    {
                                        Project.DataTypeReferences[dataType.ID] = dataType; // overwrite with the new reference.
                                    }
                                }
                                else
                                {
                                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                                           ResourceUtils.GetString("NA1071"),
                                                                           childNode.Name), Project.LocationMap.GetLocation(childNode));
                                }
                            }
                        }
                    }
                }
                finally
                {
                    _executed = true;
                    sw.Stop();
                    Project.OnTargetFinished(this, new TargetBuildEventArgs(this, sw));
                    logger.OnTargetLoggingFinished(this, new TargetBuildEventArgs(this, sw));
                }
            }
        }
예제 #12
0
 public BackwardsCompatiblePropertyAccessor(Project project, PropertyAccessor accessor, TargetCallStack callstack)
     : base(project, PropertyScope.Global)
 {
     this.PropertyAccessor = accessor;
     this.TargetCallStack  = callstack;
 }
예제 #13
0
        private static void CheckDeprecation(string functionName, MethodInfo function, Project project, TargetCallStack callstack)
        {
            // check whether the function is deprecated
            ObsoleteAttribute obsoleteAttribute = (ObsoleteAttribute)
                                                  Attribute.GetCustomAttribute(function,
                                                                               typeof(ObsoleteAttribute), true);

            // if function itself is not deprecated, check if its declaring
            // type is deprecated
            if (obsoleteAttribute == null)
            {
                obsoleteAttribute = (ObsoleteAttribute)
                                    Attribute.GetCustomAttribute(function.DeclaringType,
                                                                 typeof(ObsoleteAttribute), true);
            }

            if (obsoleteAttribute != null)
            {
                string obsoleteMessage = string.Format(CultureInfo.InvariantCulture,
                                                       ResourceUtils.GetString("NA1087"), functionName,
                                                       obsoleteAttribute.Message);
                if (obsoleteAttribute.IsError)
                {
                    throw new BuildException(obsoleteMessage, Location.UnknownLocation);
                }
                else
                {
                    if (callstack.CurrentFrame != null && callstack.CurrentFrame.TaskCallStack.CurrentFrame != null)
                    {
                        callstack.CurrentFrame.TaskCallStack.CurrentFrame.Task.Log(Level.Warning, obsoleteMessage);
                    }
                    else
                    {
                        (project as ITargetLogger).Log(Level.Warning, obsoleteMessage);
                    }
                }
            }
        }
예제 #14
0
        /// <summary>
        /// Looks up a function by name and argument count.
        /// </summary>
        /// <param name="functionName">The name of the function to lookup, including namespace prefix.</param>
        /// <param name="args">The argument of the function to lookup.</param>
        /// <param name="project">The <see cref="Project" /> in which the function is invoked.</param>
        /// <param name="callstack">The current call stack</param>
        /// <returns>
        /// A <see cref="MethodInfo" /> representing the function, or
        /// <see langword="null" /> if a function with the given name and
        /// arguments does not exist.
        /// </returns>
        internal static MethodInfo LookupFunction(string functionName, FunctionArgument[] args, Project project, TargetCallStack callstack)
        {
            object function = _methodInfoCollection[functionName];

            if (function == null)
            {
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                       ResourceUtils.GetString("NA1052"), functionName));
            }

            MethodInfo mi = function as MethodInfo;

            if (mi != null)
            {
                if (mi.GetParameters().Length == args.Length)
                {
                    CheckDeprecation(functionName, mi, project, callstack);
                    return(mi);
                }
            }
            else
            {
                ArrayList matches = (ArrayList)function;
                for (int i = 0; i < matches.Count; i++)
                {
                    mi = (MethodInfo)matches [i];
                    if (mi.GetParameters().Length == args.Length)
                    {
                        CheckDeprecation(functionName, mi, project, callstack);
                        return(mi);
                    }
                }
            }

            throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                   ResourceUtils.GetString("NA1044"), functionName, args.Length));
        }
예제 #15
0
 protected virtual DataTypeBase CreateChildDataTypeBase(XmlNode node, TargetCallStack callStack)
 {
     return(Project.CreateDataTypeBase(node, callStack));
 }
예제 #16
0
 /// <summary>
 /// Executes this instance.
 /// </summary>
 public virtual void Execute(TargetCallStack callStack)
 {
     ExecuteChildTasks(callStack);
 }
예제 #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FunctionSetBase"/> class.
 /// </summary>
 /// <param name="project">The current project.</param>
 /// <param name="properties">The projects properties.</param>
 /// <param name="callStack">The target call stack</param>
 protected FunctionSetBase(Project project, PropertyAccessor properties, TargetCallStack callStack)
 {
     _project             = project;
     this.PropertyAccesor = properties;
     this.CallStack       = callStack;
 }
예제 #18
0
 /// <summary>
 /// Create a new instance of <see cref="PropertyAccessor"/>
 /// </summary>
 /// <param name="project">The project from which to obtain global properties</param>
 /// <param name="callStack">The call stack from which to obtain thread and target properties</param>
 public PropertyAccessor(Project project, TargetCallStack callStack)
 {
     this.project   = project;
     this.callStack = callStack;
 }
예제 #19
0
 /// <summary>
 /// Adds any task assemblies in the project base directory
 /// and its <c>tasks</c> subdirectory.
 /// </summary>
 /// <param name="project">The project to work from.</param>
 internal static void AddProject(Project project, TargetCallStack targetCallStack)
 {
     AddProject(project, true, targetCallStack);
 }