public bool MoveNext()
        {
            InitlializeTokenBufferIfEmpty();
            if (CurrentSymbol == LexiconSymbol.SkipMaterial ||
                CurrentSymbol == LexiconSymbol.NA)
            {
                CurrentTokenBuffer.Clear();
            }

            while (!TokenStreamReader.EndOfStream)
            {
                var rawCharacter       = TokenStreamReader.Read();
                var convertedCharacter = Convert.ToChar(rawCharacter);
                var singleToken        = LanguageTokens.FindLexiconSymbol(convertedCharacter);

                CurrentTokenBuffer.Add(convertedCharacter);

                var validTokenBuffer = LanguageTokens.FindLexiconSymbol(CurrentTokenBuffer);

                var tempValidTokenBuffer = validTokenBuffer;
                var rulesToApply         = validTokenBuffer;
                rulesToApply = Rules.Select(appliedRule => rulesToApply = appliedRule(singleToken, rulesToApply, CurrentSymbol))
                               .Where(ls => ls != LexiconSymbol.NA)
                               .LastOrDefault();
                if (rulesToApply != tempValidTokenBuffer)
                {
                    validTokenBuffer = rulesToApply;
                }



                if (CurrentTokenBuffer.Count > 0 && validTokenBuffer == LexiconSymbol.Assign)
                {
                    CurrentTokenBuffer.RemoveAt(CurrentTokenBuffer.Count - 1);
                }



                CurrentSymbol = validTokenBuffer;

                var mayStopSymbol = LanguageTokens.FindLexiconSymbol(new List <char>()
                {
                    convertedCharacter
                });
                if (mayStopSymbol == LexiconSymbol.SkipMaterial)
                {
                    CurrentSymbol = mayStopSymbol;
                }

                if (CurrentSymbol != LexiconSymbol.NA)
                {
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 2
0
        internal static IEnumerable <IVbAttribute> GetAttributes(TokenStreamReader reader)
        {
            bool didEncounterAttributes = false;

            while (!reader.IsEOF)
            {
                IToken token = reader.Read();

                switch (token.Type)
                {
                case TokenType.Word:
                {
                    if (token.EqualsStringInvariant(AnalyzerConstants.Attribute_TokenName))
                    {
                        didEncounterAttributes = true;

                        List <IToken> lineTokens = new List <IToken>();
                        lineTokens.Add(token);
                        lineTokens.AddRange(reader.GetUntilEOL());

                        if (lineTokens.Count == 4)
                        {
                            yield return(new VbAttribute()
                                {
                                    Location = lineTokens[0].Location,
                                    Name = lineTokens[1].Content,
                                    Value = lineTokens[3].Content.Replace("\"", ""),
                                });
                        }
                    }
                    else
                    {
                        /* If we had attributes previously, it is now valid to break execution here.
                         * VB Classic files always end their "preamble" or "header" with an "Attribute" block.
                         * After that block, the user code is starting.
                         */
                        if (didEncounterAttributes)
                        {
                            yield break;
                        }
                    }
                }
                break;

                default:
                case TokenType.EOL:
                case TokenType.EOF:
                    continue;
                }
            }
        }
Esempio n. 3
0
        internal static IEnumerable <IVbMethod> GetMethods(TokenStreamReader reader)
        {
            bool         isInMethod = false;
            VbMethodType methodType = VbMethodType.Sub;

            // Remembers the complete signature for easier construction later.
            List <IToken> signatureTokens = new List <IToken>();

            IToken   previous = null;
            VbMethod method   = null;

            while (!reader.IsEOF)
            {
                if (!reader.IsBOF)
                {
                    previous = reader.GetPrevious();
                }

                IToken token = reader.Read();

                if (token.Type == TokenType.Word)
                {
                    if (token.EqualsStringInvariant(AnalyzerConstants.Method_Sub) ||
                        token.EqualsStringInvariant(AnalyzerConstants.Method_Function) ||
                        token.EqualsStringInvariant(AnalyzerConstants.Method_Property))
                    {
                        if (isInMethod)
                        {
                            if (previous.EqualsStringInvariant(AnalyzerConstants.End))
                            {
                                method.EndStatementLocation = token.Location;
                                isInMethod = false;
                            }

                            continue;
                        }

                        isInMethod = true;

                        methodType = (VbMethodType)Enum.Parse(typeof(VbMethodType), token.Content, true);

                        method = new VbMethod();

                        // Properties have Let/Get/Set next... eat that and store it.
                        if (methodType == VbMethodType.Property)
                        {
                            IToken propertyAcc = reader.Read();

                            method = new VbProperty()
                            {
                                Accessor = (VbPropertyAccessor)Enum.Parse(typeof(VbPropertyAccessor), propertyAcc.Content, true),
                            };
                        }

                        method.Visibility = MemberVisibility.Default;
                        method.Location   = token.Location;
                        method.MethodKind = methodType;

                        /* Check if there was a visibility-modifier preceeding this method. If so, add it to our signature and correct source location to point to that token.
                         */
                        MemberVisibility visibility = MemberVisibility.Default;
                        if (TryGetMemberVisibility(previous, out visibility))
                        {
                            // Set method location to the previous token (start of line).
                            method.Location = previous.Location;
                        }

                        method.Visibility = visibility;
                        method.Name       = reader.GetUntil(false, null, TokenType.Symbol).GetString();

                        signatureTokens.AddRange(reader.GetUntilEOL());

                        bool success = false;
                        try
                        {
                            ParseSignatureIntoMethod(method, signatureTokens);
                            success = true;
                        }
                        catch (Exception)
                        {
                            // FIXME: The parser may peek() too far beyond EOF. Need to handle that!
                        }

                        if (success)
                        {
                            yield return(method);
                        }

                        signatureTokens.Clear();
                    }
                }
            }
        }
Esempio n. 4
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
                        };
                    }
                }
            }
        }