Exemplo n.º 1
0
        public static object GetValueFromArgsArray(string[] args, int offsetInArray, ref int currentLogicalPosition, PropertyInfo targetType)
        {
            ActualArgumentAttribute value = targetType.GetCustomAttribute <ActualArgumentAttribute>();
            object argValue = null;

            if (!value.IsCollection)
            {
                argValue = GetValueForProperty(args[offsetInArray + currentLogicalPosition], targetType);
                currentLogicalPosition++;
            }
            else
            {
                // we are going to support just string lists.
                int indexLastEntry = args.Length;
                for (int i = offsetInArray + currentLogicalPosition; i < args.Length; i++)
                {
                    if (args[i][0] == '-')
                    {
                        // stop at the first additional argument
                        indexLastEntry = i;
                        break;
                    }
                }

                // create the list
                string[] list = new string[indexLastEntry - currentLogicalPosition - offsetInArray];
                Array.Copy(args, offsetInArray + currentLogicalPosition, list, 0, indexLastEntry - currentLogicalPosition - offsetInArray);

                argValue = new List <string>(list);
                currentLogicalPosition = indexLastEntry;
            }

            return(Convert.ChangeType(argValue, targetType.PropertyType));
        }
Exemplo n.º 2
0
        public static void ScanTypeForProperties <TOptions>(out TypeArgumentInfo tInfo)
        {
            tInfo = new TypeArgumentInfo();
            PropertyInfo[] propertiesOnType = typeof(TOptions).GetTypeInfo().GetProperties(BindingFlags.Instance | BindingFlags.Public);

            // first of all, find the commandArgument, if any.
            tInfo.ActionArgument = FindCommandProperty(propertiesOnType);

            // we want to be able to support empty groups.
            if (tInfo.ActionArgument != null && IsEnum(tInfo.ActionArgument.PropertyType))
            {
                // get the values of the enum.
                var enumValues = Enum.GetValues(tInfo.ActionArgument.PropertyType);

                // Sort the enum by the enum values
                Array.Sort(enumValues);

                // add them to the dictionary now to make sure we preserve the order
                foreach (var val in enumValues)
                {
                    if (!tInfo.ArgumentGroups.ContainsKey(val.ToString()))
                    {
                        tInfo.ArgumentGroups.Add(val.ToString(), new ArgumentGroupInfo());
                    }
                }
            }

            // parse the rest of the properties
            foreach (var property in propertiesOnType)
            {
                // get the group containing this property (note: more than one group can have the same property)
                // this allows common required parameters

                var groupsWhereThePropertyIsParticipating = GetGroupsForProperty(tInfo, property);

                var actualAttribs = property.GetCustomAttributes <ActualArgumentAttribute>().ToList();
                if (actualAttribs.Count > 1)
                {
                    throw new ArgumentException($"Only one of Required/Optional attribute are allowed per property ({property.Name}). [Red!Help information might be incorrect!]");
                }

                // if we have no attributes on that property, move on
                ActualArgumentAttribute baseAttrib = actualAttribs.FirstOrDefault();
                if (baseAttrib == null)
                {
                    continue;
                }

                // add the property to add the groups it is a part of
                if (baseAttrib is RequiredArgumentAttribute)
                {
                    foreach (ArgumentGroupInfo grpPropInfo in groupsWhereThePropertyIsParticipating)
                    {
                        // do we have an override for this property? If we do, use that, otherwise use the regular one.
                        if (!grpPropInfo.OverridePositions.TryGetValue(property, out int requiredPositionIndex))
                        {
                            requiredPositionIndex = (int)baseAttrib.GetArgumentId();
                        }

                        if (grpPropInfo.RequiredArguments.ContainsKey(requiredPositionIndex))
                        {
                            throw new ArgumentException("Two required arguments share the same position!!");
                        }

                        grpPropInfo.RequiredArguments[requiredPositionIndex] = property;
                    }
                }
                else if (baseAttrib is OptionalArgumentAttribute)
                {
                    foreach (ArgumentGroupInfo grpPropInfo in groupsWhereThePropertyIsParticipating)
                    {
                        if (grpPropInfo.OptionalArguments.ContainsKey((string)baseAttrib.GetArgumentId()))
                        {
                            throw new ArgumentException("Two optional arguments share the same name!!");
                        }

                        grpPropInfo.OptionalArguments[(string)baseAttrib.GetArgumentId()] = property;
                    }
                }
            }

            ArgumentGroupInfo grp;

            // remove the empty one, if empty
            if (tInfo.ArgumentGroups.TryGetValue(string.Empty, out grp))
            {
                if (grp.OptionalArguments.Count == 0 && grp.RequiredArguments.Count == 0)
                {
                    tInfo.ArgumentGroups.Remove(string.Empty);
                }
            }
        }