Exemplo n.º 1
0
        public static Type GetTypeFromName(string name)
        {
            ClrTypeSpec spec = Parse(name);

            if (spec == null)
            {
                return(null);
            }
            return(spec.Resolve(
                       assyName => Assembly.Load(assyName),
                       //(assy, typeName) => assy == null ? RT.classForName(typeName) : assy.GetType(typeName));  <--- this goes into an infinite loop on a non-existent typename
                       (assy, typeName) => assy == null ? (name.Equals(typeName) ? null : RT.classForName(typeName)) : assy.GetType(typeName)));
        }
Exemplo n.º 2
0
        static ClrTypeSpec Parse(string name)
        {
            int         pos  = 0;
            ClrTypeSpec spec = Parse(name, ref pos, false, false);

            if (spec == null)
            {
                return(null);                                           // bad parse
            }
            if (pos < name.Length)
            {
                return(null);                                           // ArgumentException ("Count not parse the whole type name", "typeName");
            }
            return(spec);
        }
Exemplo n.º 3
0
        static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAssyQualName)
        {
            int pos = p;
            int name_start;
            bool hasModifiers = false;
            ClrTypeSpec spec = new ClrTypeSpec();

            SkipSpace(name, ref pos);

            name_start = pos;

            for (; pos < name.Length; ++pos)
            {
                switch (name[pos])
                {
                    case '+':
                        spec.AddName(name.Substring(name_start, pos - name_start));
                        name_start = pos + 1;
                        break;
                    case ',':
                    case ']':
                        spec.AddName(name.Substring(name_start, pos - name_start));
                        name_start = pos + 1;
                        if (isRecursive && !allowAssyQualName)
                        {
                            p = pos;
                            return spec;
                        }
                    hasModifiers = true;
                        break;
                    case '&':
                    case '*':
                    case '[':
                        if (name[pos] != '[' && isRecursive)
                            return null;                                              // ArgumentException ("Generic argument can't be byref or pointer type", "typeName");
                        spec.AddName(name.Substring(name_start, pos - name_start));
                        name_start = pos + 1;
                        hasModifiers = true;
                        break;
                }
                if (hasModifiers)
                    break;
            }

            if (name_start < pos)
                spec.AddName(name.Substring(name_start, pos - name_start));

            if (hasModifiers)
            {
                for (; pos < name.Length; ++pos)
                {

                    switch (name[pos])
                    {
                        case '&':
                            if (spec._isByRef)
                                return null;                                           // ArgumentException ("Can't have a byref of a byref", "typeName")

                            spec._isByRef = true;
                            break;
                        case '*':
                            if (spec._isByRef)
                                return null;                                           // ArgumentException ("Can't have a pointer to a byref type", "typeName");
                            ++spec._pointerLevel;
                            break;
                        case ',':
                            if (isRecursive)
                            {
                                int end = pos;
                                while (end < name.Length && name[end] != ']')
                                    ++end;
                                if (end >= name.Length)
                                    return null;                                        // ArgumentException ("Unmatched ']' while parsing generic argument assembly name");
                                spec._assemblyName = name.Substring(pos + 1, end - pos - 1).Trim();
                                p = end + 1;
                                return spec;
                            }
                            spec._assemblyName = name.Substring(pos + 1).Trim();
                            pos = name.Length;
                            break;
                        case '[':
                            if (spec._isByRef)
                                return null;                                             // ArgumentException ("Byref qualifier must be the last one of a type", "typeName");
                            ++pos;
                            if (pos >= name.Length)
                                return null;                                             // ArgumentException ("Invalid array/generic spec", "typeName");
                            SkipSpace(name, ref pos);

                            if (name[pos] != ',' && name[pos] != '*' && name[pos] != ']')
                            {//generic args
                                List<ClrTypeSpec> args = new List<ClrTypeSpec>();
                                if (spec.IsArray)
                                    return null;                                          // ArgumentException ("generic args after array spec", "typeName");

                                while (pos < name.Length)
                                {
                                    SkipSpace(name, ref pos);
                                    bool aqn = name[pos] == '[';
                                    if (aqn)
                                        ++pos; //skip '[' to the start of the type
                                    {
                                        ClrTypeSpec arg = Parse(name, ref pos, true, aqn);
                                        if (arg == null)
                                            return null;                                   // bad generic arg
                                        args.Add(arg);
                                    }
                                    if (pos >= name.Length)
                                        return null;                                       // ArgumentException ("Invalid generic arguments spec", "typeName");

                                    if (name[pos] == ']')
                                        break;
                                    if (name[pos] == ',')
                                        ++pos; // skip ',' to the start of the next arg
                                    else
                                        return null;                                       // ArgumentException ("Invalid generic arguments separator " + name [pos], "typeName")

                                }
                                if (pos >= name.Length || name[pos] != ']')
                                    return null;                                           // ArgumentException ("Error parsing generic params spec", "typeName");
                                spec._genericParams = args;
                            }
                            else
                            { //array spec
                                int dimensions = 1;
                                bool bound = false;
                                while (pos < name.Length && name[pos] != ']')
                                {
                                    if (name[pos] == '*')
                                    {
                                        if (bound)
                                            return null;                                    // ArgumentException ("Array spec cannot have 2 bound dimensions", "typeName");
                                        bound = true;
                                    }
                                    else if (name[pos] != ',')
                                        return null;                                        // ArgumentException ("Invalid character in array spec " + name [pos], "typeName");
                                    else
                                        ++dimensions;

                                    ++pos;
                                    SkipSpace(name, ref pos);
                                }
                                if (name[pos] != ']')
                                    return null;                                            // ArgumentException ("Error parsing array spec", "typeName");
                                if (dimensions > 1 && bound)
                                    return null;                                            // ArgumentException ("Invalid array spec, multi-dimensional array cannot be bound", "typeName")
                                spec.AddArray(new ClrArraySpec(dimensions, bound));
                            }

                            break;
                        case ']':
                            if (isRecursive)
                            {
                                p = pos + 1;
                                return spec;
                            }
                            return null;                                                    // ArgumentException ("Unmatched ']'", "typeName");
                        default:
                            return null;                                                    // ArgumentException ("Bad type def, can't handle '" + name [pos]+"'" + " at " + pos, "typeName");
                    }
                }
            }

            p = pos;
            return spec;
        }
Exemplo n.º 4
0
        static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAssyQualName)
        {
            int         pos = p;
            int         name_start;
            bool        hasModifiers = false;
            ClrTypeSpec spec         = new ClrTypeSpec();

            SkipSpace(name, ref pos);

            name_start = pos;

            for (; pos < name.Length; ++pos)
            {
                switch (name[pos])
                {
                case '+':
                    spec.AddName(name.Substring(name_start, pos - name_start));
                    name_start = pos + 1;
                    break;

                case ',':
                case ']':
                    spec.AddName(name.Substring(name_start, pos - name_start));
                    name_start = pos + 1;
                    if (isRecursive && !allowAssyQualName)
                    {
                        p = pos;
                        return(spec);
                    }
                    hasModifiers = true;
                    break;

                case '&':
                case '*':
                case '[':
                    if (name[pos] != '[' && isRecursive)
                    {
                        return(null);                                                 // ArgumentException ("Generic argument can't be byref or pointer type", "typeName");
                    }
                    spec.AddName(name.Substring(name_start, pos - name_start));
                    name_start   = pos + 1;
                    hasModifiers = true;
                    break;
                }
                if (hasModifiers)
                {
                    break;
                }
            }

            if (name_start < pos)
            {
                spec.AddName(name.Substring(name_start, pos - name_start));
            }

            if (hasModifiers)
            {
                for (; pos < name.Length; ++pos)
                {
                    switch (name[pos])
                    {
                    case '&':
                        if (spec._isByRef)
                        {
                            return(null);                                              // ArgumentException ("Can't have a byref of a byref", "typeName")
                        }
                        spec._isByRef = true;
                        break;

                    case '*':
                        if (spec._isByRef)
                        {
                            return(null);                                              // ArgumentException ("Can't have a pointer to a byref type", "typeName");
                        }
                        ++spec._pointerLevel;
                        break;

                    case ',':
                        if (isRecursive)
                        {
                            int end = pos;
                            while (end < name.Length && name[end] != ']')
                            {
                                ++end;
                            }
                            if (end >= name.Length)
                            {
                                return(null);                                           // ArgumentException ("Unmatched ']' while parsing generic argument assembly name");
                            }
                            spec._assemblyName = name.Substring(pos + 1, end - pos - 1).Trim();
                            p = end + 1;
                            return(spec);
                        }
                        spec._assemblyName = name.Substring(pos + 1).Trim();
                        pos = name.Length;
                        break;

                    case '[':
                        if (spec._isByRef)
                        {
                            return(null);                                                // ArgumentException ("Byref qualifier must be the last one of a type", "typeName");
                        }
                        ++pos;
                        if (pos >= name.Length)
                        {
                            return(null);                                                // ArgumentException ("Invalid array/generic spec", "typeName");
                        }
                        SkipSpace(name, ref pos);

                        if (name[pos] != ',' && name[pos] != '*' && name[pos] != ']')
                        {    //generic args
                            List <ClrTypeSpec> args = new List <ClrTypeSpec>();
                            if (spec.IsArray)
                            {
                                return(null);                                             // ArgumentException ("generic args after array spec", "typeName");
                            }
                            while (pos < name.Length)
                            {
                                SkipSpace(name, ref pos);
                                bool aqn = name[pos] == '[';
                                if (aqn)
                                {
                                    ++pos;     //skip '[' to the start of the type
                                }
                                {
                                    ClrTypeSpec arg = Parse(name, ref pos, true, aqn);
                                    if (arg == null)
                                    {
                                        return(null);                                      // bad generic arg
                                    }
                                    args.Add(arg);
                                }
                                if (pos >= name.Length)
                                {
                                    return(null);                                          // ArgumentException ("Invalid generic arguments spec", "typeName");
                                }
                                if (name[pos] == ']')
                                {
                                    break;
                                }
                                if (name[pos] == ',')
                                {
                                    ++pos;     // skip ',' to the start of the next arg
                                }
                                else
                                {
                                    return(null);                                          // ArgumentException ("Invalid generic arguments separator " + name [pos], "typeName")
                                }
                            }
                            if (pos >= name.Length || name[pos] != ']')
                            {
                                return(null);                                              // ArgumentException ("Error parsing generic params spec", "typeName");
                            }
                            spec._genericParams = args;
                        }
                        else
                        {     //array spec
                            int  dimensions = 1;
                            bool bound      = false;
                            while (pos < name.Length && name[pos] != ']')
                            {
                                if (name[pos] == '*')
                                {
                                    if (bound)
                                    {
                                        return(null);                                       // ArgumentException ("Array spec cannot have 2 bound dimensions", "typeName");
                                    }
                                    bound = true;
                                }
                                else if (name[pos] != ',')
                                {
                                    return(null);                                           // ArgumentException ("Invalid character in array spec " + name [pos], "typeName");
                                }
                                else
                                {
                                    ++dimensions;
                                }

                                ++pos;
                                SkipSpace(name, ref pos);
                            }
                            if (name[pos] != ']')
                            {
                                return(null);                                               // ArgumentException ("Error parsing array spec", "typeName");
                            }
                            if (dimensions > 1 && bound)
                            {
                                return(null);                                               // ArgumentException ("Invalid array spec, multi-dimensional array cannot be bound", "typeName")
                            }
                            spec.AddArray(new ClrArraySpec(dimensions, bound));
                        }

                        break;

                    case ']':
                        if (isRecursive)
                        {
                            p = pos + 1;
                            return(spec);
                        }
                        return(null);                                                       // ArgumentException ("Unmatched ']'", "typeName");

                    default:
                        return(null);                                                       // ArgumentException ("Bad type def, can't handle '" + name [pos]+"'" + " at " + pos, "typeName");
                    }
                }
            }

            p = pos;
            return(spec);
        }