Beispiel #1
0
        /// <summary>
        /// シリアライズされた型名を<see cref="Type"/>オブジェクトに変換します。
        /// </summary>
        public static Type Deserialize(string serializedTypeName)
        {
            if (string.IsNullOrEmpty(serializedTypeName))
            {
                throw new ArgumentNullException("serializedTypeName");
            }

            // レキサからトークンを取り出しながら構文解析を行います。
            var lexer = new TypeLexer(serializedTypeName);

            // 最初のトークンを取得します。
            return(ParseType(lexer));
        }
Beispiel #2
0
        /// <summary>
        /// ジェネリック型の引数部分を解析します。
        /// </summary>
        private static Type[] ParseGenericArguments(TypeLexer lexer)
        {
            // '['が無いということは、つまり引数が無いということです。
            if (lexer.Token != LexicalToken.OpenBlanket)
            {
                return(null);
            }
            lexer.NextToken();

            // ']'があると言うことは引数無しでフィニッシュです。
            if (lexer.Token == LexicalToken.CloseBlanket)
            {
                lexer.NextToken();
                return(null);
            }

            var result = new List <Type>();

            while (true)
            {
                // 次の型をパースします。
                var type = ParseType(lexer);
                if ((object)type == null)
                {
                    throw new TypeLoadException(
                              "ジェネリック型の引数が正しくありません。");
                }
                result.Add(type);

                if (lexer.Token == LexicalToken.CloseBlanket)
                {
                    lexer.NextToken();
                    return(result.ToArray());
                }
                else if (lexer.Token == LexicalToken.Comma)
                {
                    // もう一回パース
                    lexer.NextToken();
                }
                else
                {
                    throw new TypeLoadException(
                              "ジェネリック型の引数が正しくありません。");
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// ジェネリック型の引数部分を解析します。
        /// </summary>
        private static Type[] ParseGenericArguments(TypeLexer lexer)
        {
            // '['が無いということは、つまり引数が無いということです。
            if (lexer.Token != LexicalToken.OpenBlanket)
            {
                return null;
            }
            lexer.NextToken();

            // ']'があると言うことは引数無しでフィニッシュです。
            if (lexer.Token == LexicalToken.CloseBlanket)
            {
                lexer.NextToken();
                return null;
            }

            var result = new List<Type>();
            while (true)
            {
                // 次の型をパースします。
                var type = ParseType(lexer);
                if ((object)type == null)
                {
                    throw new TypeLoadException(
                        "ジェネリック型の引数が正しくありません。");
                }
                result.Add(type);

                if (lexer.Token == LexicalToken.CloseBlanket)
                {
                    lexer.NextToken();
                    return result.ToArray();
                }
                else if (lexer.Token == LexicalToken.Comma)
                {
                    // もう一回パース
                    lexer.NextToken();
                }
                else
                {
                    throw new TypeLoadException(
                        "ジェネリック型の引数が正しくありません。");
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// 通常orジェネリック型をパースします。
        /// </summary>
        private static Type ParseType(TypeLexer lexer)
        {
            var hasBlanket = false;
            
            if (lexer.Token == LexicalToken.OpenBlanket)
            {
                hasBlanket = true;
                lexer.NextToken();
            }

            if (lexer.Token != LexicalToken.GenericTypeName &&
                lexer.Token != LexicalToken.TypeName &&
                lexer.Token != LexicalToken.CloseBlanket)
            {
                throw new TypeLoadException(
                    "型名がありませんでした。");
            }

            // 型無しでフィニッシュです。
            if (lexer.Token == LexicalToken.CloseBlanket)
            {
                lexer.NextToken();
                return null;
            }

            // とりあえず型名から、その型を取り出します。
            var type = Util.FindTypeFromCurrentDomain(lexer.Name);
            if ((object)type == null)
            {
                throw new TypeLoadException(
                    string.Format(
                        "型'{0}'が現在のドメインで見つかりませんでした。",
                        lexer.Name));
            }

            if (lexer.Token == LexicalToken.GenericTypeName)
            {
                lexer.NextToken();

                var args = ParseGenericArguments(lexer);
                if (args != null)
                {
                    // 引数部分を置き換えた型にします。
                    type = type.MakeGenericType(args);
                }
            }
            else
            {
                // LexicalToken.TypeName の場合
                lexer.NextToken();
            }

            // 最後の']'があるかもしれないので。
            if (hasBlanket)
            {
                if (lexer.Token != LexicalToken.CloseBlanket)
                {
                    throw new TypeLoadException(
                        "対応する']'がありません。");
                }

                lexer.NextToken();
            }

            return type;
        }
Beispiel #5
0
        /// <summary>
        /// シリアライズされた型名を<see cref="Type"/>オブジェクトに変換します。
        /// </summary>
        public static Type Deserialize(string serializedTypeName)
        {
            if (string.IsNullOrEmpty(serializedTypeName))
            {
                throw new ArgumentNullException("serializedTypeName");
            }
            
            // レキサからトークンを取り出しながら構文解析を行います。
            var lexer = new TypeLexer(serializedTypeName);

            // 最初のトークンを取得します。
            return ParseType(lexer);
        }
Beispiel #6
0
        /// <summary>
        /// 通常orジェネリック型をパースします。
        /// </summary>
        private static Type ParseType(TypeLexer lexer)
        {
            var hasBlanket = false;

            if (lexer.Token == LexicalToken.OpenBlanket)
            {
                hasBlanket = true;
                lexer.NextToken();
            }

            if (lexer.Token != LexicalToken.GenericTypeName &&
                lexer.Token != LexicalToken.TypeName &&
                lexer.Token != LexicalToken.CloseBlanket)
            {
                throw new TypeLoadException(
                          "型名がありませんでした。");
            }

            // 型無しでフィニッシュです。
            if (lexer.Token == LexicalToken.CloseBlanket)
            {
                lexer.NextToken();
                return(null);
            }

            // とりあえず型名から、その型を取り出します。
            var type = Util.FindTypeFromCurrentDomain(lexer.Name);

            if ((object)type == null)
            {
                throw new TypeLoadException(
                          string.Format(
                              "型'{0}'が現在のドメインで見つかりませんでした。",
                              lexer.Name));
            }

            if (lexer.Token == LexicalToken.GenericTypeName)
            {
                lexer.NextToken();

                var args = ParseGenericArguments(lexer);
                if (args != null)
                {
                    // 引数部分を置き換えた型にします。
                    type = type.MakeGenericType(args);
                }
            }
            else
            {
                // LexicalToken.TypeName の場合
                lexer.NextToken();
            }

            // 最後の']'があるかもしれないので。
            if (hasBlanket)
            {
                if (lexer.Token != LexicalToken.CloseBlanket)
                {
                    throw new TypeLoadException(
                              "対応する']'がありません。");
                }

                lexer.NextToken();
            }

            return(type);
        }