| Index: visual_studio/NativeClientVSAddIn/NaCl.Build.CPPTasks/XamlParser.cs
|
| diff --git a/visual_studio/NativeClientVSAddIn/NaCl.Build.CPPTasks/XamlParser.cs b/visual_studio/NativeClientVSAddIn/NaCl.Build.CPPTasks/XamlParser.cs
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..099d4dfe816826ee68d8b923c14725ada6270734
|
| --- /dev/null
|
| +++ b/visual_studio/NativeClientVSAddIn/NaCl.Build.CPPTasks/XamlParser.cs
|
| @@ -0,0 +1,152 @@
|
| +using System;
|
| +using System.Collections.Generic;
|
| +using System.Linq;
|
| +using System.Text;
|
| +
|
| +using Microsoft.Build.Framework;
|
| +using System.Xaml;
|
| +using Microsoft.Build.Framework.XamlTypes;
|
| +using Microsoft.Build.Utilities;
|
| +
|
| +namespace NaCl.Build.CPPTasks
|
| +{
|
| + class XamlParser
|
| + {
|
| + public XamlParser(string path)
|
| + {
|
| + // load and store properties from xaml file
|
| + m_parsedBuildRule = (Rule)XamlServices.Load(path);
|
| +
|
| + // NOTE:
|
| + // There are MSBuild classes which support command line building,
|
| + // argument switch encapsulation and more. Code within VCToolTask,
|
| + // a hidden interface, uses some these classes to generate command line
|
| + // switches given project settings. As the VCToolTask class is a hidden
|
| + // class and the MSBuild documentation is very sparse, we are going
|
| + // with a small custom solution. For reference see the
|
| + // Microsoft.Build.Tasks.Xaml, Microsoft.Build.Framework.XamlTypes namespaces.
|
| +
|
| + // move the properties to a property name keyed dictionary for faster lookup
|
| + ToolProperties = new Dictionary<string, PropertyWrapper>();
|
| + ToolProperties = m_parsedBuildRule.Properties.ToDictionary(x => x.Name, x => (new PropertyWrapper(x.GetType(), x)));
|
| +
|
| + InitFunctionMap();
|
| + }
|
| +
|
| + private void InitFunctionMap()
|
| + {
|
| + m_typeFunctionMap = new Dictionary<Type, Action<CommandLineBuilder, BaseProperty, string>>
|
| + {
|
| + { typeof(StringListProperty), GenerateArgumentStringList },
|
| + { typeof(StringProperty), GenerateArgumentString },
|
| + { typeof(IntProperty), GenerateArgumentString },
|
| + { typeof(BoolProperty), GenerateArgumentBool },
|
| + { typeof(EnumProperty), GenerateArgumentEnum }
|
| + };
|
| + }
|
| +
|
| + public string Parse(ITaskItem taskItem)
|
| + {
|
| + CommandLineBuilder builder = new CommandLineBuilder();
|
| +
|
| + foreach (string name in taskItem.MetadataNames)
|
| + {
|
| + string value = taskItem.GetMetadata(name);
|
| + AppendArgumentForProperty(builder, name, value);
|
| + }
|
| +
|
| + string result = builder.ToString();
|
| + result = result.Replace('\\', '/'); // posix paths
|
| + return result;
|
| + }
|
| +
|
| + private string AppendArgumentForProperty(CommandLineBuilder builder, string name, string value)
|
| + {
|
| + PropertyWrapper current;
|
| + ToolProperties.TryGetValue(name, out current);
|
| + if (current != null && value.Length > 0)
|
| + {
|
| + // call appropriate function for type
|
| + m_typeFunctionMap[current.PropertyType](builder, current.Property, value);
|
| + }
|
| + return string.Empty;
|
| + }
|
| +
|
| + private void GenerateArgumentEnum(CommandLineBuilder builder, BaseProperty property, string value)
|
| + {
|
| + var result = ((EnumProperty)property).AdmissibleValues.Find(x => (x.Name == value));
|
| + if (result != null)
|
| + {
|
| + builder.AppendSwitchUnquotedIfNotNull(m_parsedBuildRule.SwitchPrefix, result.Switch);
|
| + }
|
| + }
|
| +
|
| + // helper for string-based properties
|
| + private void AppendStringValue(CommandLineBuilder builder, BaseProperty property, string subtype, string value)
|
| + {
|
| + value = value.Trim();
|
| +
|
| + // could cache this SubType test off in property wrapper or somewhere if performance were an issue
|
| + if (subtype == "file" || subtype == "folder")
|
| + {
|
| + builder.AppendSwitchIfNotNull(m_parsedBuildRule.SwitchPrefix + property.Switch + property.Separator, value);
|
| + }
|
| + else
|
| + {
|
| + builder.AppendSwitchUnquotedIfNotNull(m_parsedBuildRule.SwitchPrefix + property.Switch + property.Separator, value);
|
| + }
|
| + }
|
| +
|
| + private void GenerateArgumentStringList(CommandLineBuilder builder, BaseProperty property, string value)
|
| + {
|
| + string [] arguments = value.Split(';');
|
| +
|
| + foreach (string argument in arguments)
|
| + {
|
| + if (argument.Length > 0)
|
| + {
|
| + StringListProperty casted = (StringListProperty)property;
|
| + AppendStringValue(builder, property, casted.Subtype, argument);
|
| + }
|
| + }
|
| + }
|
| +
|
| + private void GenerateArgumentString(CommandLineBuilder builder, BaseProperty property, string value)
|
| + {
|
| + // could cache this SubType test off in property wrapper or somewhere if performance were an issue
|
| + StringProperty casted = (StringProperty)property;
|
| + AppendStringValue(builder, property, casted.Subtype, value);
|
| + }
|
| +
|
| + private void GenerateArgumentBool(CommandLineBuilder builder, BaseProperty property, string value)
|
| + {
|
| + if (value == "true")
|
| + {
|
| + builder.AppendSwitchUnquotedIfNotNull(m_parsedBuildRule.SwitchPrefix, property.Switch);
|
| + }
|
| + else if (value == "false" && ((BoolProperty)property).ReverseSwitch != null)
|
| + {
|
| + builder.AppendSwitchUnquotedIfNotNull(m_parsedBuildRule.SwitchPrefix, ((BoolProperty)property).ReverseSwitch);
|
| + }
|
| + }
|
| +
|
| + // to store off MSBuild property type and allow faster searching on them
|
| + private class PropertyWrapper
|
| + {
|
| + public PropertyWrapper(Type newType, BaseProperty newProperty)
|
| + {
|
| + PropertyType = newType;
|
| + Property = newProperty;
|
| + }
|
| + public Type PropertyType { get; set; }
|
| + public BaseProperty Property { get; set; }
|
| + } // class
|
| +
|
| + private Rule m_parsedBuildRule;
|
| + private Dictionary<string, PropertyWrapper> ToolProperties { get; set; }
|
| +
|
| + // function mapping for easy property function calling
|
| + private Dictionary<Type, Action<CommandLineBuilder, BaseProperty, string>> m_typeFunctionMap;
|
| + } // XamlParser
|
| +} // namespace NaCl.Build.CPPTasks
|
| +
|
|
|