private static ParamInfo[] PrecomputeTypes(ParameterInfo[] parameterInfos)
        {
            var  precomputed = new ParamInfo[parameterInfos.Length];
            bool foundTail   = false;

            for (int i = parameterInfos.Length - 1; i >= 0; i--)
            {
                var       parameterInfo = parameterInfos[i];
                var       arg           = parameterInfo.ParameterType;
                ParamKind kind;

                if (arg == typeof(IReadOnlyList <ICommand>))
                {
                    kind = ParamKind.SpecialArguments;
                }
                else if (arg == typeof(ICommand))
                {
                    kind = ParamKind.NormalCommand;
                }
                else if (arg.IsArray)
                {
                    kind = ParamKind.NormalArray;
                }
                else if (arg.IsEnum ||
                         BasicTypes.Contains(arg) ||
                         BasicTypes.Contains(UnwrapParamType(arg)))
                {
                    kind = ParamKind.NormalParam;
                }
                // TODO How to distinguish between special type and dependency?
                else if (AdvancedTypes.Contains(arg))
                {
                    kind = ParamKind.NormalParam;
                }
                else
                {
                    kind = ParamKind.Dependency;
                }

                if (kind.IsNormal())
                {
                    // If we have the last normal parameter, check if it fits the criteria
                    // to be extened to a tail string.
                    // If it does not, we set foundTail to true anyway, since no other
                    // fitting parameter would be a tail anymore
                    if (!foundTail && arg == typeof(string))
                    {
                        kind = ParamKind.NormalTailString;
                    }
                    foundTail = true;
                }

                precomputed[i] = new ParamInfo(
                    parameterInfo,
                    kind,
                    parameterInfo.IsOptional || parameterInfo.GetCustomAttribute <ParamArrayAttribute>() != null);
            }

            return(precomputed);
        }
Beispiel #2
0
 private void PrecomputeTypes()
 {
     for (int i = 0; i < CommandParameter.Length; i++)
     {
         ref var paramInfo = ref CommandParameter[i];
         var     arg       = paramInfo.Type;
         if (arg == typeof(IReadOnlyList <ICommand>))
         {
             paramInfo.Kind = ParamKind.SpecialArguments;
         }
         else if (arg == typeof(IReadOnlyList <Type>))
         {
             paramInfo.Kind = ParamKind.SpecialReturns;
         }
         else if (arg == typeof(ICommand))
         {
             paramInfo.Kind = ParamKind.NormalCommand;
         }
         else if (arg.IsArray)
         {
             paramInfo.Kind = ParamKind.NormalArray;
         }
         else if (arg.IsEnum ||
                  BasicTypes.Contains(arg) ||
                  BasicTypes.Contains(UnwrapParamType(arg)))
         {
             paramInfo.Kind = ParamKind.NormalParam;
         }
         // TODO How to distinguish between special type and dependency?
         else if (AdvancedTypes.Contains(arg))
         {
             paramInfo.Kind = ParamKind.NormalParam;
         }
         else
         {
             paramInfo.Kind = ParamKind.Dependency;
         }
     }
Beispiel #3
0
        private static ParamInfo[] PrecomputeTypes(ParameterInfo[] parameterInfos)
        {
            var  precomputed = new ParamInfo[parameterInfos.Length];
            bool foundTail   = false;

            for (int i = parameterInfos.Length - 1; i >= 0; i--)
            {
                var       parameterInfo = parameterInfos[i];
                var       arg           = parameterInfo.ParameterType;
                ParamKind kind;

                if (arg == typeof(IReadOnlyList <ICommand>))
                {
                    kind = ParamKind.SpecialArguments;
                }
                else if (arg == typeof(ICommand))
                {
                    kind = ParamKind.NormalCommand;
                }
                else if (arg.IsArray)
                {
                    kind = ParamKind.NormalArray;
                }
                else if (arg.IsEnum ||
                         BasicTypes.Contains(arg) ||
                         BasicTypes.Contains(UnwrapParamType(arg)) ||
                         AdvancedTypes.Contains(arg) ||
                         AdvancedTypes.Contains(UnwrapParamType(arg)))
                {
                    kind = ParamKind.NormalParam;
                }
                // TODO How to distinguish between special type and dependency?
                else
                {
                    kind = ParamKind.Dependency;
                }

                TryFromFn?tryFrom = null;
                if (kind == ParamKind.NormalParam || kind == ParamKind.NormalArray)
                {
                    var finalType = arg;
                    if (kind == ParamKind.NormalArray)
                    {
                        finalType = finalType.GetElementType() ?? throw new InvalidOperationException("Not an array?");
                    }
                    finalType = UnwrapParamType(finalType);
                    var method = finalType.GetMethod("TryFrom", BindingFlags.Public | BindingFlags.Static);
                    if (method != null)
                    {
                        if (method.ReturnType == typeof(object))
                        {
                            // return directly: (object) -> object
                            tryFrom = (TryFromFn)method.CreateDelegate(typeof(TryFromFn));
                        }
                        else if (method.ReturnType.IsClass)
                        {
                            // have: [object]->class
                            // can be casted with covariance to [object]->object
                            tryFrom = (TryFromFn)method.CreateDelegate(typeof(Func <,>).MakeGenericType(typeof(object), method.ReturnType));
                        }
                        else if (method.ReturnType.IsValueType)
                        {