Пример #1
0
		static TypeSpec Parse (string name, ref int p, bool is_recurse, bool allow_aqn)
		{
			int pos = p;
			int name_start;
			bool in_modifiers = false;
			TypeSpec data = new TypeSpec ();

			SkipSpace (name, ref pos);

			name_start = pos;

			for (; pos < name.Length; ++pos) {
				switch (name [pos]) {
				case '+':
					data.AddName (name.Substring (name_start, pos - name_start));
					name_start = pos + 1;
					break;
				case ',':
				case ']':
					data.AddName (name.Substring (name_start, pos - name_start));
					name_start = pos + 1;
					in_modifiers = true;
					if (is_recurse && !allow_aqn) {
						p = pos;
						return data;
					}
					break;
				case '&':
				case '*':
				case '[':
					if (name [pos] != '[' && is_recurse)
						throw new ArgumentException ("Generic argument can't be byref or pointer type", "typeName");
					data.AddName (name.Substring (name_start, pos - name_start));
					name_start = pos + 1;
					in_modifiers = true;
					break;
				}
				if (in_modifiers)
					break;
			}

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

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

					switch (name [pos]) {
					case '&':
						if (data.is_byref)
							throw new ArgumentException ("Can't have a byref of a byref", "typeName");

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

						if (name [pos] != ',' && name [pos] != '*' && name [pos]  != ']') {//generic args
							List<TypeSpec> args = new List <TypeSpec> ();
							if (data.IsArray)
								throw new 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
								args.Add (Parse (name, ref pos, true, aqn));
								if (pos >= name.Length)
									throw new ArgumentException ("Invalid generic arguments spec", "typeName");

								if (name [pos] == ']')
										break;
								if (name [pos] == ',')
									++pos; // skip ',' to the start of the next arg
								else
									throw new ArgumentException ("Invalid generic arguments separator " + name [pos], "typeName");
			
							}
							if (pos >= name.Length || name [pos] != ']')
								throw new ArgumentException ("Error parsing generic params spec", "typeName");
							data.generic_params = args;
						} else { //array spec
							int dimensions = 1;
							bool bound = false;
							while (pos < name.Length && name [pos] != ']') {
								if (name [pos] == '*') {
									if (bound)
										throw new ArgumentException ("Array spec cannot have 2 bound dimensions", "typeName");
									bound = true;
								}
								else if (name [pos] != ',')
									throw new ArgumentException ("Invalid character in array spec " + name [pos], "typeName");
								else
									++dimensions;

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

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

			p = pos;
			return data;
		}
Пример #2
0
        static TypeSpec Parse(string name, ref int p, bool is_recurse, bool allow_aqn)
        {
            int      pos = p;
            int      name_start;
            bool     in_modifiers = false;
            TypeSpec data         = new TypeSpec();

            SkipSpace(name, ref pos);

            name_start = pos;

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

                case ',':
                case ']':
                    data.AddName(name.Substring(name_start, pos - name_start));
                    name_start   = pos + 1;
                    in_modifiers = true;
                    if (is_recurse && !allow_aqn)
                    {
                        p = pos;
                        return(data);
                    }
                    break;

                case '&':
                case '*':
                case '[':
                    if (name [pos] != '[' && is_recurse)
                    {
                        throw new ArgumentException("Generic argument can't be byref or pointer type", "typeName");
                    }
                    data.AddName(name.Substring(name_start, pos - name_start));
                    name_start   = pos + 1;
                    in_modifiers = true;
                    break;
                }
                if (in_modifiers)
                {
                    break;
                }
            }

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

            if (in_modifiers)
            {
                for (; pos < name.Length; ++pos)
                {
                    switch (name [pos])
                    {
                    case '&':
                        if (data.is_byref)
                        {
                            throw new ArgumentException("Can't have a byref of a byref", "typeName");
                        }

                        data.is_byref = true;
                        break;

                    case '*':
                        if (data.is_byref)
                        {
                            throw new ArgumentException("Can't have a pointer to a byref type", "typeName");
                        }
                        ++data.pointer_level;
                        break;

                    case ',':
                        if (is_recurse)
                        {
                            int end = pos;
                            while (end < name.Length && name [end] != ']')
                            {
                                ++end;
                            }
                            if (end >= name.Length)
                            {
                                throw new ArgumentException("Unmatched ']' while parsing generic argument assembly name");
                            }
                            data.assembly_name = name.Substring(pos + 1, end - pos - 1).Trim();
                            p = end + 1;
                            return(data);
                        }
                        data.assembly_name = name.Substring(pos + 1).Trim();
                        pos = name.Length;
                        break;

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

                        if (name [pos] != ',' && name [pos] != '*' && name [pos] != ']')                           //generic args
                        {
                            List <TypeSpec> args = new List <TypeSpec> ();
                            if (data.IsArray)
                            {
                                throw new 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
                                }
                                args.Add(Parse(name, ref pos, true, aqn));
                                if (pos >= name.Length)
                                {
                                    throw new ArgumentException("Invalid generic arguments spec", "typeName");
                                }

                                if (name [pos] == ']')
                                {
                                    break;
                                }
                                if (name [pos] == ',')
                                {
                                    ++pos;                                     // skip ',' to the start of the next arg
                                }
                                else
                                {
                                    throw new ArgumentException("Invalid generic arguments separator " + name [pos], "typeName");
                                }
                            }
                            if (pos >= name.Length || name [pos] != ']')
                            {
                                throw new ArgumentException("Error parsing generic params spec", "typeName");
                            }
                            data.generic_params = args;
                        }
                        else                             //array spec
                        {
                            int  dimensions = 1;
                            bool bound      = false;
                            while (pos < name.Length && name [pos] != ']')
                            {
                                if (name [pos] == '*')
                                {
                                    if (bound)
                                    {
                                        throw new ArgumentException("Array spec cannot have 2 bound dimensions", "typeName");
                                    }
                                    bound = true;
                                }
                                else if (name [pos] != ',')
                                {
                                    throw new ArgumentException("Invalid character in array spec " + name [pos], "typeName");
                                }
                                else
                                {
                                    ++dimensions;
                                }

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

                        break;

                    case ']':
                        if (is_recurse)
                        {
                            p = pos + 1;
                            return(data);
                        }
                        throw new ArgumentException("Unmatched ']'", "typeName");

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

            p = pos;
            return(data);
        }
Пример #3
0
        private static TypeSpec Parse(string name, ref int p, bool is_recurse, bool allow_aqn)
        {
            // Invariants:
            //  - On exit p, is updated to pos the current unconsumed character.
            //
            //  - The callee peeks at but does not consume delimiters following
            //    recurisve parse (so for a recursive call like the args of "Foo[P,Q]"
            //    we'll return with p either on ',' or on ']'.  If the name was aqn'd
            //    "Foo[[P,assmblystuff],Q]" on return p with be on the ']' just
            //    after the "assmblystuff")
            //
            //  - If allow_aqn is True, assembly qualification is optional.
            //    If allow_aqn is False, assembly qualification is prohibited.
            int      pos = p;
            int      name_start;
            bool     in_modifiers = false;
            TypeSpec data         = new TypeSpec();

            SkipSpace(name, ref pos);

            name_start = pos;

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

                case ',':
                case ']':
                    data.AddName(name.Substring(name_start, pos - name_start));
                    name_start   = pos + 1;
                    in_modifiers = true;
                    if (is_recurse && !allow_aqn)
                    {
                        p = pos;
                        return(data);
                    }
                    break;

                case '&':
                case '*':
                case '[':
                    if (name[pos] != '[' && is_recurse)
                    {
                        throw new ArgumentException("Generic argument can't be byref or pointer type", "typeName");
                    }
                    data.AddName(name.Substring(name_start, pos - name_start));
                    name_start   = pos + 1;
                    in_modifiers = true;
                    break;

                case '\\':
                    pos++;
                    break;
                }
                if (in_modifiers)
                {
                    break;
                }
            }

            if (name_start < pos)
            {
                data.AddName(name.Substring(name_start, pos - name_start));
            }
            else if (name_start == pos)
            {
                data.AddName(string.Empty);
            }

            if (in_modifiers)
            {
                for (; pos < name.Length; ++pos)
                {
                    switch (name[pos])
                    {
                    case '&':
                        if (data.is_byref)
                        {
                            throw new ArgumentException("Can't have a byref of a byref", "typeName");
                        }

                        data.is_byref = true;
                        break;

                    case '*':
                        if (data.is_byref)
                        {
                            throw new ArgumentException("Can't have a pointer to a byref type", "typeName");
                        }
                        // take subsequent '*'s too
                        int pointer_level = 1;
                        while (pos + 1 < name.Length && name[pos + 1] == '*')
                        {
                            ++pos;
                            ++pointer_level;
                        }
                        data.AddModifier(new PointerSpec(pointer_level));
                        break;

                    case ',':
                        if (is_recurse && allow_aqn)
                        {
                            int end = pos;
                            while (end < name.Length && name[end] != ']')
                            {
                                ++end;
                            }
                            if (end >= name.Length)
                            {
                                throw new ArgumentException("Unmatched ']' while parsing generic argument assembly name");
                            }
                            data.assembly_name = name.Substring(pos + 1, end - pos - 1).Trim();
                            p = end;
                            return(data);
                        }
                        if (is_recurse)
                        {
                            p = pos;
                            return(data);
                        }
                        if (allow_aqn)
                        {
                            data.assembly_name = name.Substring(pos + 1).Trim();
                            pos = name.Length;
                        }
                        break;

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

                        if (name[pos] != ',' && name[pos] != '*' && name[pos] != ']')
                        {    //generic args
                            List <TypeSpec> args = new List <TypeSpec>();
                            if (data.HasModifiers)
                            {
                                throw new ArgumentException("generic args after array spec or pointer type", "typeName");
                            }

                            while (pos < name.Length)
                            {
                                SkipSpace(name, ref pos);
                                bool aqn = name[pos] == '[';
                                if (aqn)
                                {
                                    ++pos;     //skip '[' to the start of the type
                                }
                                args.Add(Parse(name, ref pos, true, aqn));
                                BoundCheck(pos, name);
                                if (aqn)
                                {
                                    if (name[pos] == ']')
                                    {
                                        ++pos;
                                    }
                                    else
                                    {
                                        throw new ArgumentException("Unclosed assembly-qualified type name at " + name[pos], "typeName");
                                    }
                                    BoundCheck(pos, name);
                                }

                                if (name[pos] == ']')
                                {
                                    break;
                                }
                                if (name[pos] == ',')
                                {
                                    ++pos;     // skip ',' to the start of the next arg
                                }
                                else
                                {
                                    throw new ArgumentException("Invalid generic arguments separator " + name[pos], "typeName");
                                }
                            }
                            if (pos >= name.Length || name[pos] != ']')
                            {
                                throw new ArgumentException("Error parsing generic params spec", "typeName");
                            }
                            data.generic_params = args;
                        }
                        else
                        {     //array spec
                            int  dimensions = 1;
                            bool bound      = false;
                            while (pos < name.Length && name[pos] != ']')
                            {
                                if (name[pos] == '*')
                                {
                                    if (bound)
                                    {
                                        throw new ArgumentException("Array spec cannot have 2 bound dimensions", "typeName");
                                    }
                                    bound = true;
                                }
                                else if (name[pos] != ',')
                                {
                                    throw new ArgumentException("Invalid character in array spec " + name[pos], "typeName");
                                }
                                else
                                {
                                    ++dimensions;
                                }

                                ++pos;
                                SkipSpace(name, ref pos);
                            }
                            if (pos >= name.Length || name[pos] != ']')
                            {
                                throw new ArgumentException("Error parsing array spec", "typeName");
                            }
                            if (dimensions > 1 && bound)
                            {
                                throw new ArgumentException("Invalid array spec, multi-dimensional array cannot be bound", "typeName");
                            }
                            data.AddModifier(new IArraySpec(dimensions, bound));
                        }

                        break;

                    case ']':
                        if (is_recurse)
                        {
                            p = pos;
                            return(data);
                        }
                        throw new ArgumentException("Unmatched ']'", "typeName");

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

            p = pos;
            return(data);
        }
Пример #4
0
		static TypeSpec Parse (string name, ref int p, bool is_recurse, bool allow_aqn)
		{
			// Invariants:
			//  - On exit p, is updated to pos the current unconsumed character.
			//
			//  - The callee peeks at but does not consume delimiters following
			//    recurisve parse (so for a recursive call like the args of "Foo[P,Q]"
			//    we'll return with p either on ',' or on ']'.  If the name was aqn'd
			//    "Foo[[P,assmblystuff],Q]" on return p with be on the ']' just
			//    after the "assmblystuff")
			//
			//  - If allow_aqn is True, assembly qualification is optional.
			//    If allow_aqn is False, assembly qualification is prohibited.
			int pos = p;
			int name_start;
			bool in_modifiers = false;
			TypeSpec data = new TypeSpec ();

			SkipSpace (name, ref pos);

			name_start = pos;

			for (; pos < name.Length; ++pos) {
				switch (name [pos]) {
				case '+':
					data.AddName (name.Substring (name_start, pos - name_start));
					name_start = pos + 1;
					break;
				case ',':
				case ']':
					data.AddName (name.Substring (name_start, pos - name_start));
					name_start = pos + 1;
					in_modifiers = true;
					if (is_recurse && !allow_aqn) {
						p = pos;
						return data;
					}
					break;
				case '&':
				case '*':
				case '[':
					if (name [pos] != '[' && is_recurse)
						throw new ArgumentException ("Generic argument can't be byref or pointer type", "typeName");
					data.AddName (name.Substring (name_start, pos - name_start));
					name_start = pos + 1;
					in_modifiers = true;
					break;
				case '\\':
					pos++;
					break;
				}
				if (in_modifiers)
					break;
			}

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

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

					switch (name [pos]) {
					case '&':
						if (data.is_byref)
							throw new ArgumentException ("Can't have a byref of a byref", "typeName");

						data.is_byref = true;
						break;
					case '*':
						if (data.is_byref)
							throw new ArgumentException ("Can't have a pointer to a byref type", "typeName");
						// take subsequent '*'s too
						int pointer_level = 1;
						while (pos+1 < name.Length && name[pos+1] == '*') {
							++pos;
							++pointer_level;
						}
						data.AddModifier (new PointerSpec(pointer_level));
						break;
					case ',':
						if (is_recurse && allow_aqn) {
							int end = pos;
							while (end < name.Length && name [end] != ']')
								++end;
							if (end >= name.Length)
								throw new ArgumentException ("Unmatched ']' while parsing generic argument assembly name");
							data.assembly_name = name.Substring (pos + 1, end - pos - 1).Trim ();
							p = end;
							return data;						
						}
						if (is_recurse) {
							p = pos;
							return data;
						}
						if (allow_aqn) {
							data.assembly_name = name.Substring (pos + 1).Trim ();
							pos = name.Length;
						}
						break;
					case '[':
						if (data.is_byref)
							throw new ArgumentException ("Byref qualifier must be the last one of a type", "typeName");
						++pos;
						if (pos >= name.Length)
								throw new ArgumentException ("Invalid array/generic spec", "typeName");
						SkipSpace (name, ref pos);

						if (name [pos] != ',' && name [pos] != '*' && name [pos]  != ']') {//generic args
							List<TypeSpec> args = new List <TypeSpec> ();
							if (data.HasModifiers)
								throw new ArgumentException ("generic args after array spec or pointer type", "typeName");

							while (pos < name.Length) {
								SkipSpace (name, ref pos);
								bool aqn = name [pos] == '[';
								if (aqn)
									++pos; //skip '[' to the start of the type
								args.Add (Parse (name, ref pos, true, aqn));
								BoundCheck (pos, name);
								if (aqn) {
									if (name [pos] == ']')
										++pos;
									else
										throw new ArgumentException ("Unclosed assembly-qualified type name at " + name[pos], "typeName");
									BoundCheck (pos, name);
}

								if (name [pos] == ']')
									break;
								if (name [pos] == ',')
									++pos; // skip ',' to the start of the next arg
								else
									throw new ArgumentException ("Invalid generic arguments separator " + name [pos], "typeName");
			
							}
							if (pos >= name.Length || name [pos] != ']')
								throw new ArgumentException ("Error parsing generic params spec", "typeName");
							data.generic_params = args;
						} else { //array spec
							int dimensions = 1;
							bool bound = false;
							while (pos < name.Length && name [pos] != ']') {
								if (name [pos] == '*') {
									if (bound)
										throw new ArgumentException ("Array spec cannot have 2 bound dimensions", "typeName");
									bound = true;
								}
								else if (name [pos] != ',')
									throw new ArgumentException ("Invalid character in array spec " + name [pos], "typeName");
								else
									++dimensions;

								++pos;
								SkipSpace (name, ref pos);
							}
							if (pos >= name.Length || name [pos] != ']')
								throw new ArgumentException ("Error parsing array spec", "typeName");
							if (dimensions > 1 && bound)
								throw new ArgumentException ("Invalid array spec, multi-dimensional array cannot be bound", "typeName");
							data.AddModifier (new ArraySpec (dimensions, bound));
						}

						break;
					case ']':
						if (is_recurse) {
							p = pos;
							return data;
						}
						throw new ArgumentException ("Unmatched ']'", "typeName");
					default:
						throw new ArgumentException ("Bad type def, can't handle '" + name [pos]+"'" + " at " + pos, "typeName");
					}
				}
			}

			p = pos;
			return data;
		}