Example #1
0
        private static void ParseSignatureIntoMethod(VbMethod method, IReadOnlyList<IToken> signatureTokens)
        {
            TokenStreamReader tokenReader = new TokenStreamReader(signatureTokens);
            if (tokenReader.Peek().Type == TokenType.Symbol)
            {
                tokenReader.Read();
            }

            VbParameter parameter = new VbParameter();

            while (!tokenReader.IsEOF)
            {
                // If it's already the end of the signature, leave the loop.
                if (tokenReader.Peek().EqualsStringInvariant(")"))
                {
                    tokenReader.Read();
                    break;
                }

                IToken token = tokenReader.Read();

                if (IsParameterOptional(token))
                {
                    parameter.IsOptional = true;
                    continue;
                }

                VbParameterAccess access = VbParameterAccess.Default;
                if (IsParamaterAccessToken(token, out access))
                {
                    parameter.Access = access;
                    continue;
                }

                /* Assume that if the next parameter is "As", then this is a parameter name.
                 * Also watch out for implicit parameters, which are parameters that don't declare a type (variant).
                 */
                IToken peek = tokenReader.Peek();
                if (peek == null)
                {
                    break;
                }

                if (peek.EqualsStringInvariant("As") ||
                    peek.Type == TokenType.Symbol)
                {
                    parameter.Name = token.Content;
                    parameter.Location = token.Location;

                    if (peek.Type == TokenType.Symbol)
                    {
                        parameter.Type = VbTypes.Variant;

                        // Eat token.
                        tokenReader.Read();
                    }
                    else
                    {
                        // Eat token.
                        tokenReader.Read();

                        parameter.Type = new VbType()
                        {
                            TypeName = ReadUntilEOLIntoString(tokenReader, Delimiters)
                        };
                    }

                    /* Look ahead for an optional value declaration if this parameter is optional.
                     */
                    if (parameter.IsOptional)
                    {
                        if (tokenReader.GetPrevious().Content == "=")
                        {
                            parameter.OptionalDefaultValue = ReadUntilEOLIntoString(tokenReader, Delimiters);
                        }
                    }

                    /* Add parameter and reset instance.
                     */
                    method.AddParameter(parameter);

                    parameter = new VbParameter();

                    continue;
                }
            }

            /* Specify "void" return "type" in advance; may be overridden.
             */
            method.ReturnType = VbTypes.Void;

            bool canHaveReturnType = false;
            if (method.MethodKind == VbMethodType.Function)
            {
                canHaveReturnType = true;
            }
            else if (method.MethodKind == VbMethodType.Property)
            {
                IVbProperty property = (IVbProperty)method;
                if (property.Accessor == VbPropertyAccessor.Get)
                {
                    canHaveReturnType = true;
                }
            }

            /* Look for a return type.
             */
            if (canHaveReturnType)
            {
                method.ReturnType = VbTypes.Variant;

                if (!tokenReader.IsEOF)
                {
                    var returnTokens = tokenReader.GetUntilEOL().ToArray();
                    if (returnTokens[0].EqualsStringInvariant("As"))
                    {
                        string typeName = string.Concat(returnTokens.Skip(1).Select(_ => _.Content));
                        method.ReturnType = new VbType() { TypeName = typeName };
                    }
                }
            }
        }