// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using CommandLine.Infrastructure; using CSharpx; namespace CommandLine.Core { enum SpecificationType { Option, Value } enum TargetType { Switch, Scalar, Sequence } abstract class Specification { private readonly SpecificationType tag; private readonly bool required; private readonly bool hidden; private readonly Maybe min; private readonly Maybe max; private readonly Maybe defaultValue; private readonly string helpText; private readonly string metaValue; private readonly IEnumerable enumValues; /// This information is denormalized to decouple Specification from PropertyInfo. private readonly Type conversionType; private readonly TargetType targetType; protected Specification(SpecificationType tag, bool required, Maybe min, Maybe max, Maybe defaultValue, string helpText, string metaValue, IEnumerable enumValues, Type conversionType, TargetType targetType, bool hidden = false) { this.tag = tag; this.required = required; this.min = min; this.max = max; this.defaultValue = defaultValue; this.conversionType = conversionType; this.targetType = targetType; this.helpText = helpText; this.metaValue = metaValue; this.enumValues = enumValues; this.hidden = hidden; } public SpecificationType Tag { get { return tag; } } public bool Required { get { return required; } } public Maybe Min { get { return min; } } public Maybe Max { get { return max; } } public Maybe DefaultValue { get { return defaultValue; } } public string HelpText { get { return helpText; } } public string MetaValue { get { return metaValue; } } public IEnumerable EnumValues { get { return enumValues; } } public Type ConversionType { get { return conversionType; } } public TargetType TargetType { get { return targetType; } } public bool Hidden { get { return hidden; } } public static Specification FromProperty(PropertyInfo property) { var attrs = property.GetCustomAttributes(true); var oa = attrs.OfType(); if (oa.Count() == 1) { var spec = OptionSpecification.FromAttribute(oa.Single(), property.PropertyType, ReflectionHelper.GetNamesOfEnum(property.PropertyType)); if (spec.ShortName.Length == 0 && spec.LongName.Length == 0) { return spec.WithLongName(property.Name.ToLowerInvariant()); } return spec; } var va = attrs.OfType(); if (va.Count() == 1) { return ValueSpecification.FromAttribute(va.Single(), property.PropertyType, property.PropertyType.GetTypeInfo().IsEnum ? Enum.GetNames(property.PropertyType) : Enumerable.Empty()); } throw new InvalidOperationException(); } } }