/// <summary>
        /// Returns the constructed form of the provided generic type.
        /// </summary>
        public static string GetConstructed(this TypeConverter formatter, string unconstructed, params Type[] typeArguments)
        {
            var typeString     = unconstructed;
            var indicatorIndex = typeString.IndexOf(GenericTypeIndicator);
            var argumentsIndex = typeString.IndexOf(StartArgument, indicatorIndex);

            if (argumentsIndex >= 0)
            {
                throw new InvalidOperationException("Cannot construct an already-constructed type");
            }

            var arityString = typeString.Substring(indicatorIndex + 1);
            var arity       = int.Parse(arityString);

            if (typeArguments.Length != arity)
            {
                throw new InvalidOperationException($"Insufficient number of type arguments, {typeArguments.Length}, provided while constructing type \"{unconstructed}\" of arity {arity}");
            }

            var typeSpecs = new TypeSpec[typeArguments.Length];

            for (var i = 0; i < typeArguments.Length; i++)
            {
                typeSpecs[i] = RuntimeTypeNameParser.Parse(formatter.Format(typeArguments[i]));
            }

            var constructed = new ConstructedGenericTypeSpec(new NamedTypeSpec(null, typeString, typeArguments.Length), typeSpecs).Format();

            return(constructed);
        }
        /// <summary>
        /// Returns the type arguments for the provided constructed generic type string.
        /// </summary>
        public static Type[] GetArguments(this TypeConverter formatter, string constructed)
        {
            var str   = constructed;
            var index = str.IndexOf(StartArgument);

            if (index <= 0)
            {
                return(Array.Empty <Type>());
            }

            var safeString = "safer" + str.Substring(str.IndexOf(GenericTypeIndicator));
            var parsed     = RuntimeTypeNameParser.Parse(safeString);

            if (parsed is not ConstructedGenericTypeSpec spec)
            {
                throw new InvalidOperationException($"Unable to correctly parse grain type {str}");
            }

            var result = new Type[spec.Arguments.Length];

            for (var i = 0; i < result.Length; i++)
            {
                var arg          = spec.Arguments[i];
                var formattedArg = arg.Format();
                result[i] = formatter.Parse(formattedArg);
                if (result[i] is null)
                {
                    throw new InvalidOperationException($"Unable to parse argument \"{formattedArg}\" as a type for grain type \"{str}\"");
                }
            }

            return(result);
        }
Beispiel #3
0
        private string FormatInternal(Type type, Func <TypeSpec, TypeSpec> rewriter = null)
        {
            string runtimeType = null;

            foreach (var converter in _converters)
            {
                if (converter.TryFormat(type, out var value))
                {
                    runtimeType = value;
                    break;
                }
            }

            if (string.IsNullOrWhiteSpace(runtimeType))
            {
                runtimeType = RuntimeTypeNameFormatter.Format(type);
            }

            var runtimeTypeSpec = RuntimeTypeNameParser.Parse(runtimeType);
            var displayTypeSpec = RuntimeTypeNameRewriter.Rewrite(runtimeTypeSpec, _convertToDisplayName);

            if (rewriter is object)
            {
                displayTypeSpec = rewriter(displayTypeSpec);
            }

            var formatted = displayTypeSpec.Format();

            return(formatted);
        }
Beispiel #4
0
        public TypeConverter(IEnumerable <ITypeConverter> formatters, IConfiguration <SerializerConfiguration> configuration)
        {
            _converters             = formatters.ToArray();
            _convertToDisplayName   = ConvertToDisplayName;
            _convertFromDisplayName = ConvertFromDisplayName;

            _wellKnownAliasToType = new Dictionary <QualifiedType, QualifiedType>();
            _wellKnownTypeToAlias = new Dictionary <QualifiedType, QualifiedType>();

            var aliases = configuration.Value.WellKnownTypeAliases;

            foreach (var item in aliases)
            {
                var    alias   = new QualifiedType(null, item.Key);
                var    spec    = RuntimeTypeNameParser.Parse(RuntimeTypeNameFormatter.Format(item.Value));
                string asmName = null;
                if (spec is AssemblyQualifiedTypeSpec asm)
                {
                    asmName = asm.Assembly;
                    spec    = asm.Type;
                }

                var originalQualifiedType = new QualifiedType(asmName, spec.Format());
                _wellKnownTypeToAlias[originalQualifiedType] = alias;
                if (asmName is { Length: > 0 })
Beispiel #5
0
        private bool ParseInternal(string formatted, out Type type)
        {
            var parsed          = RuntimeTypeNameParser.Parse(formatted);
            var runtimeTypeSpec = RuntimeTypeNameRewriter.Rewrite(parsed, _convertFromDisplayName);
            var runtimeType     = runtimeTypeSpec.Format();

            foreach (var converter in _converters)
            {
                if (converter.TryParse(runtimeType, out type))
                {
                    return(true);
                }
            }

            return(_resolver.TryResolveType(runtimeType, out type));
        }