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); }
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; } }
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) {