/// <summary>
        /// Defualt Constructor
        /// </summary>
        public ArgumentModelAnalyzer()
        {
            _TargetType   = typeof(T);
            this._Options = new List <Option>();
            this._Verbs   = new List <Verb>();

            this._VerbDefinitions   = VerbDefinitionAttributeHelper.ExtractPropertiesMarkedWithVerbAttribute(this._TargetType);
            this._OptionDefinitions = OptionDefinitionAttributeHelper.ExtractPropertiesMarkedWithOptionAttribute(this._TargetType);
        }
예제 #2
0
        /// <summary>
        /// Executes the parse for the given key/arguments
        /// </summary>
        /// <returns></returns>
        protected override object ParseFromTokens(IEnumerable <Token> targetTokens)
        {
            // instance the value
            var returnValue = Activator.CreateInstance(this._Model.TargetType);

            // no token: return the empty option class
            if (!targetTokens.Any())
            {
                return(returnValue);
            }

            // I need to parse the options
            var tokens = targetTokens.Skip(1).ToList();

            // get properties to map
            var optionDefinitions = OptionDefinitionAttributeHelper.ExtractPropertiesMarkedWithOptionAttribute(this._Model.TargetType);
            Dictionary <PropertyInfo, OptionDefinitionAttribute> alreadyConsidered = new Dictionary <PropertyInfo, OptionDefinitionAttribute>();

            foreach (var token in tokens)
            {
                // find corresponding attribute
                var attribute      = AssertOptionAttributeExists(targetTokens.First().Name, token, optionDefinitions);
                var targetProperty = optionDefinitions.Single(x => x.Value.Code == token.Name || x.Value.LongCode == token.Name).Key;

                // parse the value
                var optionParser = new OptionParser(Option.FromAttribute(attribute).OnTargetProperty(targetProperty.PropertyType));
                var outputValue  = optionParser.Parse(token.AsNaturalString());

                // update the value
                targetProperty.SetValue(returnValue, outputValue);

                // already managed
                alreadyConsidered.Add(targetProperty, attribute);
            }

            // considered not managed
            foreach (var opt in optionDefinitions)
            {
                var definition = alreadyConsidered.Values.SingleOrDefault(x => x.Code == opt.Value.Code);
                if (definition != null)
                {
                    continue;
                }
                if (opt.Value.Mandatory)
                {
                    throw new InvalidCLIArgumentException($"Mandatory option {opt.Value.Code} not found in {this._Model.TargetType.Name}", "opt.Value.Code");
                }
                if (opt.Value.DefaultValue != null)
                {
                    var targetProperty = opt.Key;
                    targetProperty.SetValue(returnValue, opt.Value.DefaultValue);
                }
            }

            return(returnValue);
        }
예제 #3
0
        public void FromClassWithPropertyMarkedAsOption_PropertyIsExtracted()
        {
            //******** GIVEN
            var    targetType       = typeof(ParserTestOnMixedArgs.TestArguments);
            string testPropertyName = "UseSingleFileAsOutput";

            //******** PRECONDITION
            Assert.IsNotNull(targetType.GetProperty(testPropertyName), "Precondition: the target type doesn't contain the test property");

            //******** WHEN
            var extractedProperties = OptionDefinitionAttributeHelper.ExtractPropertiesMarkedWithOptionAttribute(targetType);

            //******** ASSERT
            Assert.IsNotNull(extractedProperties);
            Assert.IsTrue(extractedProperties.Count(x => x.Key.Name == testPropertyName) > 0, $"Unable to find property {testPropertyName} inside extracted list");
        }
        /// <summary>
        /// Analyze the type and build the usage model
        /// </summary>
        public void Analyze()
        {
            foreach (var v in _VerbDefinitions)
            {
                if (_Verbs.Exists(x => x.Name == v.Value.Name))
                {
                    throw new InvalidOperationException($"Verb {v.Value.Name} already analyzed");
                }
                var verb = Verb.FromAttribute(v.Value).OnTargetProperty(v.Key.PropertyType);
                // get options
                var optionDefinitionForCUrrentVerb = OptionDefinitionAttributeHelper.ExtractPropertiesMarkedWithOptionAttribute(v.Key.PropertyType);
                foreach (var otp in optionDefinitionForCUrrentVerb)
                {
                    verb.AddOptionFromAttribute(otp.Value, otp.Key.PropertyType);
                }

                // get examples
                ICLIArguments concreteSettings = Activator.CreateInstance(v.Key.PropertyType) as ICLIArguments;
                if (concreteSettings == null)
                {
                    throw new InvalidOperationException($"Unable to instance {v.Key.PropertyType.Name}: is not a valid {typeof(ICLIArguments).Name}");
                }
                concreteSettings.Examples.ToList().ForEach(x => verb.AddExample(x));

                this._Verbs.Add(verb);
            }

            foreach (var opt in this._OptionDefinitions)
            {
                if (this._Options.Exists(x => x.Code == opt.Value.Code))
                {
                    throw new InvalidOperationException($"Option {opt.Value.Code} already analyzed");
                }
                var option = Option.FromAttribute(opt.Value).OnTargetProperty(opt.Key.PropertyType);
                this._Options.Add(option);
            }
        }