public void TestLoadXml()
 {
     TaskParser tp = new TaskParser();
     string s = @"<ProjectSchemaDefinitions xmlns=`clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework` xmlns:x=`http://schemas.microsoft.com/winfx/2006/xaml` xmlns:sys=`clr-namespace:System;assembly=mscorlib` xmlns:impl=`clr-namespace:Microsoft.VisualStudio.Project.Contracts.Implementation;assembly=Microsoft.VisualStudio.Project.Contracts.Implementation`>
                    <Rule Name=`TaskGeneratorLoadTest`>
                      <BoolProperty Name=`TestProperty1` Switch=`tp` />
                    </Rule>
                  </ProjectSchemaDefinitions>";
     Assert.True(tp.Parse(s.Replace("`", "\""), "TaskGeneratorLoadTest")); // "File failed to load correctly."
 }
 public TaskGenerator()
 {
     this.propertiesTypesToIgnore = new string[] { "AdditionalOptions" };
     this.platform = string.Empty;
     this.dependencyList = new Dictionary<string, Property>(StringComparer.OrdinalIgnoreCase);
     this.errorLog = new LinkedList<string>();
     this.taskParser = new TaskParser();
     this.relationsParser = new RelationsParser();
 }
Exemple #3
0
        public CommandLineGenerator(Rule rule, Dictionary <string, Object> parameterValues)
        {
            ErrorUtilities.VerifyThrowArgumentNull(rule, nameof(rule));
            ErrorUtilities.VerifyThrowArgumentNull(parameterValues, nameof(parameterValues));

            // Parse the Xaml file
            var  parser  = new TaskParser();
            bool success = parser.ParseXamlDocument(rule);

            ErrorUtilities.VerifyThrow(success, "Unable to parse specified file or contents.");

            // Generate the switch order list
            _switchOrderList = parser.SwitchOrderList;

            foreach (Property property in parser.Properties)
            {
                if (parameterValues.TryGetValue(property.Name, out object value))
                {
                    var switchToAdd = new CommandLineToolSwitch();
                    if (!String.IsNullOrEmpty(property.Reversible) && String.Equals(property.Reversible, "true", StringComparison.OrdinalIgnoreCase))
                    {
                        switchToAdd.Reversible = true;
                    }

                    switchToAdd.IncludeInCommandLine = property.IncludeInCommandLine;
                    switchToAdd.Separator            = property.Separator;
                    switchToAdd.DisplayName          = property.DisplayName;
                    switchToAdd.Description          = property.Description;
                    if (!String.IsNullOrEmpty(property.Required) && String.Equals(property.Required, "true", StringComparison.OrdinalIgnoreCase))
                    {
                        switchToAdd.Required = true;
                    }

                    switchToAdd.FallbackArgumentParameter = property.Fallback;
                    switchToAdd.FalseSuffix = property.FalseSuffix;
                    switchToAdd.TrueSuffix  = property.TrueSuffix;
                    if (!String.IsNullOrEmpty(property.SwitchName))
                    {
                        switchToAdd.SwitchValue = property.Prefix + property.SwitchName;
                    }

                    switchToAdd.IsValid = true;

                    // Based on the switch type, cast the value and set as appropriate
                    switch (property.Type)
                    {
                    case PropertyType.Boolean:
                        switchToAdd.Type         = CommandLineToolSwitchType.Boolean;
                        switchToAdd.BooleanValue = (bool)value;
                        if (!String.IsNullOrEmpty(property.ReverseSwitchName))
                        {
                            switchToAdd.ReverseSwitchValue = property.Prefix + property.ReverseSwitchName;
                        }

                        break;

                    case PropertyType.Integer:
                        switchToAdd.Type   = CommandLineToolSwitchType.Integer;
                        switchToAdd.Number = (int)value;
                        if (!String.IsNullOrEmpty(property.Min))
                        {
                            if (switchToAdd.Number < Convert.ToInt32(property.Min, System.Threading.Thread.CurrentThread.CurrentCulture))
                            {
                                switchToAdd.IsValid = false;
                            }
                        }

                        if (!String.IsNullOrEmpty(property.Max))
                        {
                            if (switchToAdd.Number > Convert.ToInt32(property.Max, System.Threading.Thread.CurrentThread.CurrentCulture))
                            {
                                switchToAdd.IsValid = false;
                            }
                        }

                        break;

                    case PropertyType.ItemArray:
                        switchToAdd.Type          = CommandLineToolSwitchType.ITaskItemArray;
                        switchToAdd.TaskItemArray = (ITaskItem[])value;
                        break;

                    case PropertyType.None:
                        break;

                    case PropertyType.String:
                        switchToAdd.Type = CommandLineToolSwitchType.String;
                        switchToAdd.ReverseSwitchValue = property.Prefix + property.ReverseSwitchName;
                        if (property.Values.Count > 0)
                        {
                            string enumValueToSelect = (string)value;

                            switchToAdd.Value = (string)value;
                            switchToAdd.AllowMultipleValues = true;

                            // Find the matching value in the enum
                            foreach (Value enumValue in property.Values)
                            {
                                if (String.Equals(enumValue.Name, enumValueToSelect, StringComparison.OrdinalIgnoreCase))
                                {
                                    if (!String.IsNullOrEmpty(enumValue.SwitchName))
                                    {
                                        switchToAdd.SwitchValue = enumValue.Prefix + enumValue.SwitchName;
                                    }
                                    else
                                    {
                                        switchToAdd = null;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            switchToAdd.Value = (string)value;
                        }

                        break;

                    case PropertyType.StringArray:
                        switchToAdd.Type       = CommandLineToolSwitchType.StringArray;
                        switchToAdd.StringList = (string[])value;
                        break;
                    }

                    if (switchToAdd != null)
                    {
                        _activeCommandLineToolSwitches[property.Name] = switchToAdd;
                    }
                }
            }
        }
        public CommandLineGenerator(Rule rule, Dictionary <string, object> parameterValues)
        {
            this.activeCommandLineToolSwitches = new Dictionary <string, CommandLineToolSwitch>(StringComparer.OrdinalIgnoreCase);
            this.additionalOptions             = string.Empty;
            Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(rule, "rule");
            Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(parameterValues, "parameterValues");
            TaskParser parser = new TaskParser();

            Microsoft.Build.Shared.ErrorUtilities.VerifyThrow(parser.ParseXamlDocument(rule), "Unable to parse specified file or contents.");
            this.switchOrderList = parser.SwitchOrderList;
            this.activeCommandLineToolSwitches = new Dictionary <string, CommandLineToolSwitch>(StringComparer.OrdinalIgnoreCase);
            foreach (Property property in parser.Properties)
            {
                object obj2 = null;
                if (parameterValues.TryGetValue(property.Name, out obj2))
                {
                    CommandLineToolSwitch switch2 = new CommandLineToolSwitch();
                    if (!string.IsNullOrEmpty(property.Reversible) && string.Equals(property.Reversible, "true", StringComparison.OrdinalIgnoreCase))
                    {
                        switch2.Reversible = true;
                    }
                    switch2.Separator   = property.Separator;
                    switch2.DisplayName = property.DisplayName;
                    switch2.Description = property.Description;
                    if (!string.IsNullOrEmpty(property.Required) && string.Equals(property.Required, "true", StringComparison.OrdinalIgnoreCase))
                    {
                        switch2.Required = true;
                    }
                    switch2.FallbackArgumentParameter = property.Fallback;
                    switch2.FalseSuffix = property.FalseSuffix;
                    switch2.TrueSuffix  = property.TrueSuffix;
                    if (!string.IsNullOrEmpty(property.SwitchName))
                    {
                        switch2.SwitchValue = property.Prefix + property.SwitchName;
                    }
                    switch2.IsValid = true;
                    switch (property.Type)
                    {
                    case PropertyType.Boolean:
                        switch2.Type         = CommandLineToolSwitchType.Boolean;
                        switch2.BooleanValue = (bool)obj2;
                        if (!string.IsNullOrEmpty(property.ReverseSwitchName))
                        {
                            switch2.ReverseSwitchValue = property.Prefix + property.ReverseSwitchName;
                        }
                        break;

                    case PropertyType.String:
                        switch2.Type = CommandLineToolSwitchType.String;
                        switch2.ReverseSwitchValue = property.Prefix + property.ReverseSwitchName;
                        if (property.Values.Count > 0)
                        {
                            string b = (string)obj2;
                            switch2.Value = (string)obj2;
                            switch2.AllowMultipleValues = true;
                            foreach (Value value2 in property.Values)
                            {
                                if (string.Equals(value2.Name, b, StringComparison.OrdinalIgnoreCase))
                                {
                                    if (!string.IsNullOrEmpty(value2.SwitchName))
                                    {
                                        switch2.SwitchValue = value2.Prefix + value2.SwitchName;
                                    }
                                    else
                                    {
                                        switch2 = null;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            switch2.Value = (string)obj2;
                        }
                        break;

                    case PropertyType.Integer:
                        switch2.Type   = CommandLineToolSwitchType.Integer;
                        switch2.Number = (int)obj2;
                        if (!string.IsNullOrEmpty(property.Min) && (switch2.Number < Convert.ToInt32(property.Min, Thread.CurrentThread.CurrentCulture)))
                        {
                            switch2.IsValid = false;
                        }
                        if (!string.IsNullOrEmpty(property.Max) && (switch2.Number > Convert.ToInt32(property.Max, Thread.CurrentThread.CurrentCulture)))
                        {
                            switch2.IsValid = false;
                        }
                        break;

                    case PropertyType.StringArray:
                        switch2.Type       = CommandLineToolSwitchType.StringArray;
                        switch2.StringList = (string[])obj2;
                        break;

                    case PropertyType.ItemArray:
                        switch2.Type          = CommandLineToolSwitchType.ITaskItemArray;
                        switch2.TaskItemArray = (ITaskItem[])obj2;
                        break;
                    }
                    if (switch2 != null)
                    {
                        this.activeCommandLineToolSwitches[property.Name] = switch2;
                    }
                }
            }
        }
 public bool Initialize(string taskName, IDictionary<string, TaskPropertyInfo> taskParameters, string taskElementContents, IBuildEngine taskFactoryLoggingHost)
 {
     CompilerResults results;
     Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(taskName, "taskName");
     Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(taskParameters, "taskParameters");
     TaskLoggingHelper helper = new TaskLoggingHelper(taskFactoryLoggingHost, taskName) {
         TaskResources = Microsoft.Build.Shared.AssemblyResources.PrimaryResources,
         HelpKeywordPrefix = "MSBuild."
     };
     if (taskElementContents == null)
     {
         helper.LogErrorWithCodeFromResources("Xaml.MissingTaskBody", new object[0]);
         return false;
     }
     this.TaskElementContents = taskElementContents.Trim();
     TaskParser parser = new TaskParser();
     parser.Parse(this.TaskElementContents, taskName);
     this.TaskName = parser.GeneratedTaskName;
     this.TaskNamespace = parser.Namespace;
     CodeCompileUnit compileUnit = new TaskGenerator(parser).GenerateCode();
     Assembly assembly = Assembly.LoadWithPartialName("System");
     Assembly assembly2 = Assembly.LoadWithPartialName("Microsoft.Build.Framework");
     Assembly assembly3 = Assembly.LoadWithPartialName("Microsoft.Build.Utilities.V4.0");
     Assembly assembly4 = Assembly.LoadWithPartialName("Microsoft.Build.Tasks.V4.0");
     CompilerParameters parameters = new CompilerParameters(new string[] { assembly.Location, assembly2.Location, assembly3.Location, assembly4.Location }) {
         GenerateInMemory = true,
         TreatWarningsAsErrors = false
     };
     CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
     bool flag = Environment.GetEnvironmentVariable("MSBUILDWRITEXAMLTASK") == "1";
     if (flag)
     {
         using (StreamWriter writer = new StreamWriter(taskName + "_XamlTask.cs"))
         {
             CodeGeneratorOptions options = new CodeGeneratorOptions {
                 BlankLinesBetweenMembers = true,
                 BracingStyle = "C"
             };
             provider.GenerateCodeFromCompileUnit(compileUnit, writer, options);
         }
         results = provider.CompileAssemblyFromFile(parameters, new string[] { taskName + "_XamlTask.cs" });
     }
     else
     {
         results = provider.CompileAssemblyFromDom(parameters, new CodeCompileUnit[] { compileUnit });
     }
     try
     {
         this.taskAssembly = results.CompiledAssembly;
     }
     catch (FileNotFoundException)
     {
     }
     if (this.taskAssembly == null)
     {
         StringBuilder builder = new StringBuilder();
         builder.AppendLine();
         foreach (CompilerError error in results.Errors)
         {
             if (!error.IsWarning)
             {
                 if (flag)
                 {
                     builder.AppendLine(string.Format(Thread.CurrentThread.CurrentUICulture, "({0},{1}) {2}", new object[] { error.Line, error.Column, error.ErrorText }));
                 }
                 else
                 {
                     builder.AppendLine(error.ErrorText);
                 }
             }
         }
         helper.LogErrorWithCodeFromResources("Xaml.TaskCreationFailed", new object[] { builder.ToString() });
     }
     return !helper.HasLoggedErrors;
 }
        /// <summary>
        /// MSBuild engine will call this to initialize the factory. This should initialize the factory enough so that the factory can be asked
        ///  whether or not task names can be created by the factory.
        /// </summary>
        public bool Initialize(string taskName, IDictionary<string, TaskPropertyInfo> taskParameters, string taskElementContents, IBuildEngine taskFactoryLoggingHost)
        {
            ErrorUtilities.VerifyThrowArgumentNull(taskName, "taskName");
            ErrorUtilities.VerifyThrowArgumentNull(taskParameters, "taskParameters");

            TaskLoggingHelper log = new TaskLoggingHelper(taskFactoryLoggingHost, taskName);
            log.TaskResources = AssemblyResources.PrimaryResources;
            log.HelpKeywordPrefix = "MSBuild.";

            if (taskElementContents == null)
            {
                log.LogErrorWithCodeFromResources("Xaml.MissingTaskBody");
                return false;
            }

            TaskElementContents = taskElementContents.Trim();

            // Attempt to load the task
            TaskParser parser = new TaskParser();

            bool parseSuccessful = parser.Parse(TaskElementContents, taskName);

            TaskName = parser.GeneratedTaskName;
            TaskNamespace = parser.Namespace;
            TaskGenerator generator = new TaskGenerator(parser);

            CodeCompileUnit dom = generator.GenerateCode();

            string pathToMSBuildBinaries = ToolLocationHelper.GetPathToBuildTools(ToolLocationHelper.CurrentToolsVersion);

            // create the code generator options    
            // Since we are running msbuild 12.0 these had better load.
            CompilerParameters compilerParameters = new CompilerParameters
                (
                    new string[]
                    {
                        "System.dll",
                        Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Framework.dll"),
                        Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Utilities.Core.dll"),
                        Path.Combine(pathToMSBuildBinaries, "Microsoft.Build.Tasks.Core.dll")
                    }

                );

            compilerParameters.GenerateInMemory = true;
            compilerParameters.TreatWarningsAsErrors = false;

            // create the code provider
            CodeDomProvider codegenerator = CodeDomProvider.CreateProvider("cs");
            CompilerResults results;
            bool debugXamlTask = Environment.GetEnvironmentVariable("MSBUILDWRITEXAMLTASK") == "1";
            if (debugXamlTask)
            {
                using (StreamWriter outputWriter = new StreamWriter(taskName + "_XamlTask.cs"))
                {
                    CodeGeneratorOptions options = new CodeGeneratorOptions();
                    options.BlankLinesBetweenMembers = true;
                    options.BracingStyle = "C";

                    codegenerator.GenerateCodeFromCompileUnit(dom, outputWriter, options);
                }

                results = codegenerator.CompileAssemblyFromFile(compilerParameters, taskName + "_XamlTask.cs");
            }
            else
            {
                results = codegenerator.CompileAssemblyFromDom(compilerParameters, new[] { dom });
            }

            try
            {
                _taskAssembly = results.CompiledAssembly;
            }
            catch (FileNotFoundException)
            {
                // This occurs if there is a failure to compile the assembly.  We just pass through because we will take care of the failure below.
            }

            if (_taskAssembly == null)
            {
                StringBuilder errorList = new StringBuilder();
                errorList.AppendLine();
                foreach (CompilerError error in results.Errors)
                {
                    if (error.IsWarning)
                    {
                        continue;
                    }

                    if (debugXamlTask)
                    {
                        errorList.AppendLine(String.Format(Thread.CurrentThread.CurrentUICulture, "({0},{1}) {2}", error.Line, error.Column, error.ErrorText));
                    }
                    else
                    {
                        errorList.AppendLine(error.ErrorText);
                    }
                }

                log.LogErrorWithCodeFromResources("Xaml.TaskCreationFailed", errorList.ToString());
            }

            return !log.HasLoggedErrors;
        }
        /// <summary>
        /// Creates a generator that generates a command-line based on the specified Xaml file and parameters.
        /// </summary>
        public CommandLineGenerator(Rule rule, Dictionary<string, Object> parameterValues)
        {
            ErrorUtilities.VerifyThrowArgumentNull(rule, "rule");
            ErrorUtilities.VerifyThrowArgumentNull(parameterValues, "parameterValues");

            // Parse the Xaml file
            TaskParser parser = new TaskParser();
            bool success = parser.ParseXamlDocument(rule);
            ErrorUtilities.VerifyThrow(success, "Unable to parse specified file or contents.");

            // Generate the switch order list
            _switchOrderList = parser.SwitchOrderList;

            _activeCommandLineToolSwitches = new Dictionary<string, CommandLineToolSwitch>(StringComparer.OrdinalIgnoreCase);
            foreach (Property property in parser.Properties)
            {
                Object value = null;
                if (parameterValues.TryGetValue(property.Name, out value))
                {
                    CommandLineToolSwitch switchToAdd = new CommandLineToolSwitch();
                    if (!String.IsNullOrEmpty(property.Reversible) && String.Equals(property.Reversible, "true", StringComparison.OrdinalIgnoreCase))
                    {
                        switchToAdd.Reversible = true;
                    }

                    switchToAdd.IncludeInCommandLine = property.IncludeInCommandLine;
                    switchToAdd.Separator = property.Separator;
                    switchToAdd.DisplayName = property.DisplayName;
                    switchToAdd.Description = property.Description;
                    if (!String.IsNullOrEmpty(property.Required) && String.Equals(property.Required, "true", StringComparison.OrdinalIgnoreCase))
                    {
                        switchToAdd.Required = true;
                    }

                    switchToAdd.FallbackArgumentParameter = property.Fallback;
                    switchToAdd.FalseSuffix = property.FalseSuffix;
                    switchToAdd.TrueSuffix = property.TrueSuffix;
                    if (!String.IsNullOrEmpty(property.SwitchName))
                    {
                        switchToAdd.SwitchValue = property.Prefix + property.SwitchName;
                    }

                    switchToAdd.IsValid = true;

                    // Based on the switch type, cast the value and set as appropriate
                    switch (property.Type)
                    {
                        case PropertyType.Boolean:
                            switchToAdd.Type = CommandLineToolSwitchType.Boolean;
                            switchToAdd.BooleanValue = (bool)value;
                            if (!String.IsNullOrEmpty(property.ReverseSwitchName))
                            {
                                switchToAdd.ReverseSwitchValue = property.Prefix + property.ReverseSwitchName;
                            }

                            break;

                        case PropertyType.Integer:
                            switchToAdd.Type = CommandLineToolSwitchType.Integer;
                            switchToAdd.Number = (int)value;
                            if (!String.IsNullOrEmpty(property.Min))
                            {
                                if (switchToAdd.Number < Convert.ToInt32(property.Min, System.Threading.Thread.CurrentThread.CurrentCulture))
                                {
                                    switchToAdd.IsValid = false;
                                }
                            }

                            if (!String.IsNullOrEmpty(property.Max))
                            {
                                if (switchToAdd.Number > Convert.ToInt32(property.Max, System.Threading.Thread.CurrentThread.CurrentCulture))
                                {
                                    switchToAdd.IsValid = false;
                                }
                            }

                            break;

                        case PropertyType.ItemArray:
                            switchToAdd.Type = CommandLineToolSwitchType.ITaskItemArray;
                            switchToAdd.TaskItemArray = (ITaskItem[])value;
                            break;

                        case PropertyType.None:
                            break;

                        case PropertyType.String:
                            switchToAdd.Type = CommandLineToolSwitchType.String;
                            switchToAdd.ReverseSwitchValue = property.Prefix + property.ReverseSwitchName;
                            if (property.Values.Count > 0)
                            {
                                string enumValueToSelect = (string)value;

                                switchToAdd.Value = (string)value;
                                switchToAdd.AllowMultipleValues = true;

                                // Find the matching value in the enum
                                foreach (Value enumValue in property.Values)
                                {
                                    if (String.Equals(enumValue.Name, enumValueToSelect, StringComparison.OrdinalIgnoreCase))
                                    {
                                        if (!String.IsNullOrEmpty(enumValue.SwitchName))
                                        {
                                            switchToAdd.SwitchValue = enumValue.Prefix + enumValue.SwitchName;
                                        }
                                        else
                                        {
                                            switchToAdd = null;
                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                switchToAdd.Value = (string)value;
                            }

                            break;

                        case PropertyType.StringArray:
                            switchToAdd.Type = CommandLineToolSwitchType.StringArray;
                            switchToAdd.StringList = (string[])value;
                            break;
                    }

                    if (switchToAdd != null)
                    {
                        _activeCommandLineToolSwitches[property.Name] = switchToAdd;
                    }
                }
            }
        }
 /// <summary>
 /// used for testing. Will load snippets of xml into the task generator
 /// </summary>
 /// <param name="s"></param>
 /// <returns></returns>
 public static TaskParser LoadAndParse(string s, string desiredRule)
 {
     TaskParser tp = new TaskParser();
     tp.Parse(s.Replace("`", "\""), desiredRule);
     return tp;
 }
Exemple #9
0
 /// <summary>
 /// Constructor that takes a parser
 /// </summary>
 internal TaskGenerator(TaskParser parser)
 {
     _taskParser = parser;
 }