Exemplo n.º 1
0
        public bool Parse(string input)
        {
            string methodKeyword = ".method";

            if (!input.StartsWith(methodKeyword))
            {
                throw new EcmaILParserException(methodKeyword, "begin of method declaration", input);
            }

            content = methodKeyword;

            int  p = 7;
            char c;

            while (char.IsWhiteSpace(c = input[p]))
            {
                content += c;
                p++;
            }

            EcmaMethAttr methodAttr = new EcmaMethAttr();

            if (!methodAttr.Parse(input.Substring(p)))
            {
                return(false);
            }

            this.methodAttrs = methodAttr.MethodAttrs;

            p            += methodAttr.NextTokenPosition;
            this.content += methodAttr.Content;

            while (char.IsWhiteSpace(c = input[p]))
            {
                content += c;
                p++;
            }

            EcmaCallConv callConv = new EcmaCallConv();

            if (callConv.Parse(input.Substring(p)))
            {
                p            += callConv.NextTokenPosition;
                this.content += callConv.Content;
                if (callConv.Content.StartsWith("instance"))
                {
                    this.isInstance = true;
                }

                this.methodAttrs.AddRange(callConv.FoundKeywords);

                while (char.IsWhiteSpace(c = input[p]))
                {
                    content += c;
                    p++;
                }
            }

            EcmaType type = new EcmaType();

            if (!type.Parse(input.Substring(p)))
            {
                throw new EcmaILParserException("Type in MethodHeader", input.Substring(0, p), input);
            }

            this.content += type.Content;
            this.ilType   = type.Content;
            p            += type.NextTokenPosition;

            while (char.IsWhiteSpace(c = input[p]))
            {
                content += c;
                p++;
            }

            string s = input.Substring(p);

            if (s.StartsWith("marshal"))
            {
                int q = 7;
                while (char.IsWhiteSpace(s[q]))
                {
                    q++;
                }
                if (s[q] != '(')
                {
                    throw new EcmaILParserException("(", "marshal", input);
                }

                q++;

                int count = 1;
                while (count > 0 && q < s.Length)
                {
                    if (s[q] == ')')
                    {
                        count--;
                    }
                    if (s[q] == '(')
                    {
                        count++;
                    }
                    q++;
                }
                if (count > 0)
                {
                    throw new EcmaILParserException(")", s, input);
                }

                content += s.Substring(0, q);

                p += q;
                while (char.IsWhiteSpace(c = input[p]))
                {
                    content += c;
                    p++;
                }
            }

            EcmaMethodName emethodName = new EcmaMethodName();

            if (!emethodName.Parse(input.Substring(p)))
            {
                throw new EcmaILParserException("MethodName", input.Substring(0, p), input);
            }

            content        += emethodName.Content;
            p              += emethodName.NextTokenPosition;
            this.methodName = emethodName.Content;

            while (char.IsWhiteSpace(c = input[p]))
            {
                content += c;
                p++;
            }

            if (input[p] == '<')
            {
                EcmaGenericParameter genPar = new EcmaGenericParameter();
                genPar.Parse(input.Substring(p));
                content += genPar.Content;
                this.genericParameterList = genPar.Content;
                p += genPar.NextTokenPosition;
                while (char.IsWhiteSpace(c = input[p]))
                {
                    content += c;
                    p++;
                }
            }

            EcmaParameterList parList = new EcmaParameterList();

            if (!parList.Parse(input.Substring(p)))
            {
                throw new EcmaILParserException("ParameterList", input.Substring(0, p), input);
            }

            content           += parList.Content;
            p                 += parList.NextTokenPosition;
            this.parameterList = parList.Content;
            this.signature     = this.methodName + this.genericParameterList + this.parameterList;

            while (char.IsWhiteSpace(c = input[p]))
            {
                content += c;
                p++;
            }

            EcmaImplAttr implAttr = new EcmaImplAttr();

            if (!implAttr.Parse(input.Substring(p)))
            {
                throw new EcmaILParserException("at least one of the ImplAttrs like 'cil'", input.Substring(0, p), input);
            }

            this.implAttributes = implAttr.ImplAttributes;
            this.content       += implAttr.Content;
            p += implAttr.NextTokenPosition;

            this.nextTokenPosition = p;

            return(true);
        }