/// <summary> /// Create a list of actions parsed from the specific target object /// </summary> /// <param name="argumentsRaw">List of arguments raw</param> /// <param name="enableMultiAction">Determine whether the parse can have more than one action per line</param> /// <param name="maps">Map of actions</param> /// <param name="initialExtraArguments">Return all arguments that are in init, that is, before any action</param> /// <returns>List of ActionParsed</returns> public IEnumerable <ActionParsed> Parse(IEnumerable <ArgumentRaw> argumentsRaw, bool enableMultiAction, IEnumerable <ActionMap> maps, out IEnumerable <ArgumentRaw> initialExtraArguments) { var actionsMapped = new List <ActionParsed>(); var mapsDefaults = maps.Where(map => map.IsDefault); var initialExtraArgumentsAux = new List <ArgumentRaw>(); initialExtraArguments = initialExtraArgumentsAux; // map the actions that are default if has default arguments if (argumentsRaw.Count() == 0) { foreach (var map in mapsDefaults) { var actionCallerDefault = new ActionParsed(map.MapName, map, null, 0); actionsMapped.Add(actionCallerDefault); } } else { //var argumentsRawDefault = new List<ArgumentRaw>(); List <ActionParsed> lastFounds = null; List <ActionParsed> defaultsCallers = null; bool continueSearchToNextAction = true; var index = 0; foreach (var argRaw in argumentsRaw) { ArgumentRaw argRawAction = null; // found all actions that has the same name (e.g: overrides methods). // ** use ValueRaw because de Value property has the value scaped when is action // ** and ValueRaw mantein the original value: // ** Value: \exists-method-scaped -> exists-method-scaped // ** ValueRaw: \exists-method-scaped -> \exists-method-scaped var founds = maps.Where(map => map.ActionName == argRaw.ValueRaw).ToList(); if (argRaw.Format == ArgumentFormat.Unnamed && founds.Count > 0 && continueSearchToNextAction) { argRawAction = argRaw; } // consider initial args as LEVEL 0 // $ --id 10 action 1 // 1) "--id 10" : LEVEL 0 // 2) "action 1" : LEVEL 1 if (index == 0 && initialExtraArgumentsAux.Any()) { index = 1; } if (argRawAction != null) { lastFounds = new List <ActionParsed>(); foreach (var actionMap in founds) { var actionCaller = new ActionParsed(actionMap.MapName, actionMap, argRaw, index); lastFounds.Add(actionCaller); actionsMapped.Add(actionCaller); } index++; } else if (lastFounds != null) { foreach (var actionMap in lastFounds) { actionMap.AddArgumentRaw(argRaw); } } else if (defaultsCallers == null) { if (mapsDefaults.Any()) { defaultsCallers = new List <ActionParsed>(); foreach (var map in mapsDefaults) { var actionCallerDefault = new ActionParsed(map.MapName, map, null, index); actionCallerDefault.AddArgumentRaw(argRaw); defaultsCallers.Add(actionCallerDefault); actionsMapped.Add(actionCallerDefault); } index++; } else if (actionsMapped.Count == 0 && initialExtraArguments != null) { initialExtraArgumentsAux.Add(argRaw); } } else if (defaultsCallers != null) { foreach (var caller in defaultsCallers) { caller.AddArgumentRaw(argRaw); } } // disable the search to the next action if (!enableMultiAction) { continueSearchToNextAction = false; } } } foreach (var action in actionsMapped) { var argumentsMapped = this.argumentParser.Parse(action.GetArgumentsRaw(), action.ActionMap.EnablePositionalArgs, action.ActionMap.ArgumentsMaps); var argumentsExtras = argumentsMapped.Where(f => f.ParsingType == ArgumentParsedType.NotMapped); var arguments = argumentsMapped.Where(f => f.ParsingType != ArgumentParsedType.NotMapped); action.Arguments = arguments; action.ArgumentsExtras = argumentsExtras; action.ParsingStates = GetState(action); } return(actionsMapped); }
private void ProcessValue(IEnumerator <ArgumentRaw> enumerator, IEnumerable <ArgumentRaw> argumentsRaw, ref int i, ArgumentRaw argRaw, ArgumentMap map, ArgumentParsed argMapped) { Type typeOriginal = ReflectionHelper.GetTypeOrTypeOfNullable(map.Type); if (argRaw.Value == null && typeOriginal != typeof(bool)) { argMapped.Value = ReflectionHelper.GetDefaultForType(map.Type); } else { var value = argRaw.Value; var hasInvalidInput = false; var hasUnsuporttedType = false; object valueConverted = null; var iDelegate = i; Action <int> actionConvertSuccess = (int position) => { if (position > 0) { enumerator.MoveNext(); iDelegate++; argMapped.AddRaw(enumerator.Current); } }; if (ReflectionHelper.IsEnum(map.Type)) { var values = new List <string>() { argRaw.Value }; values.AddRange(GetUnamedValues(argumentsRaw, i + 1)); var valueArray = values.ToArray(); argMapped.ValueParsed = ArgumentParsed.GetValueRaw(valueArray); valueConverted = ConverterHelper.TryConvertEnum(map.Type, valueArray, out hasInvalidInput, actionConvertSuccess); i = iDelegate; } else if (map.Type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(map.Type)) { var values = new List <string>() { argRaw.Value }; values.AddRange(GetUnamedValues(argumentsRaw, i + 1)); var valueArray = values.ToArray(); argMapped.ValueParsed = ArgumentParsed.GetValueRaw(valueArray); valueConverted = ConverterHelper.TryConvertCollection(map.Type, valueArray, out hasInvalidInput, out hasUnsuporttedType, actionConvertSuccess); i = iDelegate; } else { valueConverted = ConverterHelper.TryConvertPrimitives(map.Type, value, out hasInvalidInput, out hasUnsuporttedType); } argMapped.HasInvalidInput = hasInvalidInput; argMapped.HasUnsuporttedType = hasUnsuporttedType; if (!hasInvalidInput && !hasUnsuporttedType) { argMapped.Value = valueConverted; } } }
/// <summary> /// Find the best valid property reference by raw. /// OBS: This rule does not exist for the methods by which the parameters /// of the best methods are already references. /// </summary> /// <param name="level">Level to search</param> /// <param name="raw">Raw reference</param> /// <returns>The best argument parsed</returns> private ArgumentParsed GetFirstValidArgumentParsedByRawInLevel(ParseResult.Level level, ArgumentRaw raw) { var list = new List <ArgumentParsed>(); foreach (var cmd in level.Commands) { foreach (var prop in cmd.Properties) { if (prop.AllRaw.Any() && prop.AllRaw.First() == raw) { list.Add(prop); } } } return(list.OrderByDescending(a => a.AllRaw.Count()).FirstOrDefault()); }