internal static ExtractedClassName GetFirstClassNameFullyQualified(Stream binaryStream)
 {
     try
     {
         CSharpTokenizer tokens = new CSharpTokenizer(binaryStream, false);
         return Extract(tokens);
     }
     catch (DecoderFallbackException)
     {
         CSharpTokenizer tokenizer2 = new CSharpTokenizer(binaryStream, true);
         return Extract(tokenizer2);
     }
 }
 /// <summary>
 /// Parse a C# file and get the first class name, fully qualified with namespace.
 /// </summary>
 /// <param name="binaryStream"></param>
 /// <returns></returns>
 static internal ExtractedClassName GetFirstClassNameFullyQualified(Stream binaryStream)
 {
     try
     {
         CSharpTokenizer tokens = new CSharpTokenizer(binaryStream, /* forceANSI */ false);
         return Extract(tokens);
     }
     catch (DecoderFallbackException)
     {
         // There was no BOM and there are non UTF8 sequences. Fall back to ANSI.
         CSharpTokenizer tokens = new CSharpTokenizer(binaryStream, /* forceANSI */ true);
         return Extract(tokens);
     }
 }
        /*
         * Method:  AssertTokenizeStream
         * 
         * Tokenize a string ('source') and compare it to the expected set of tokens.
         * Also compare the source that is regenerated by concatenating all of the tokens
         * to 'expectedSource'.
         */
        static private void AssertTokenizeStream
        (
           Stream source,
           string expectedSource,
           string expectedTokenKey,
           int expectedLastLineNumber
        )
        {
            CSharpTokenizer tokens = new CSharpTokenizer
            (
                source,
                false
            );
            string results = "";
            string tokenKey = "";
            int lastLine = 0;
            bool syntaxError = false;
            foreach (Token t in tokens)
            {
                results += t.InnerText;
                lastLine = t.Line;

                if (!syntaxError)
                {
                    // Its not really a file name, but GetExtension serves the purpose of getting the class name without
                    // the namespace prepended.
                    string tokenClass = t.ToString();
                    int pos = tokenClass.LastIndexOfAny(new char[] { '+', '.' });

                    tokenKey += ".";
                    tokenKey += tokenClass.Substring(pos + 1);
                }

                if (t is SyntaxErrorToken)
                {
                    // Stop processing after the first syntax error because
                    // the order of tokens after this is an implementation detail and
                    // shouldn't be encoded into the unit tests.
                    syntaxError = true;
                }
            }
            tokenKey = tokenKey.Replace("Token", "");
            Console.WriteLine(tokenKey);

            Assert.AreEqual(expectedSource, results);
            Assert.AreEqual(expectedTokenKey, tokenKey);
            Assert.AreEqual(expectedLastLineNumber, lastLine);
        }
 private static ExtractedClassName Extract(CSharpTokenizer tokens)
 {
     ParseState state = new ParseState();
     ExtractedClassName name = new ExtractedClassName();
     foreach (Token token in tokens)
     {
         if (token is KeywordToken)
         {
             state.Reset();
             if (token.InnerText == "namespace")
             {
                 state.ResolvingNamespace = true;
                 if (state.InsideConditionalDirective)
                 {
                     name.IsInsideConditionalBlock = true;
                 }
             }
             else if (token.InnerText == "class")
             {
                 state.ResolvingClass = true;
                 if (state.InsideConditionalDirective)
                 {
                     name.IsInsideConditionalBlock = true;
                 }
             }
         }
         else if (token is CSharpTokenizer.OpenScopeToken)
         {
             state.PushNamespacePart(state.Namespace);
             state.Reset();
         }
         else if (token is CSharpTokenizer.CloseScopeToken)
         {
             state.Reset();
             state.PopNamespacePart();
         }
         else if (token is OperatorOrPunctuatorToken)
         {
             if (state.ResolvingNamespace && (token.InnerText == "."))
             {
                 state.Namespace = state.Namespace + ".";
             }
         }
         else if (token is IdentifierToken)
         {
             if (!state.ResolvingNamespace)
             {
                 if (state.ResolvingClass)
                 {
                     name.Name = state.ComposeQualifiedClassName(token.InnerText);
                     return name;
                 }
             }
             else
             {
                 state.Namespace = state.Namespace + token.InnerText;
             }
         }
         else if (token is OpenConditionalDirectiveToken)
         {
             state.OpenConditionalDirective();
         }
         else if (token is CloseConditionalDirectiveToken)
         {
             state.CloseConditionalDirective();
         }
     }
     return name;
 }
        /// <summary>
        /// Extract the class name.
        /// </summary>
        /// <param name="tokens"></param>
        /// <returns></returns>
        private static ExtractedClassName Extract(CSharpTokenizer tokens)
        {
            ParseState state = new ParseState();
            ExtractedClassName result = new ExtractedClassName();

            foreach (Token t in tokens)
            {
                // Search first for the namespace keyword
                if (t is KeywordToken)
                {
                    state.Reset();

                    if (t.InnerText == "namespace")
                    {
                        state.ResolvingNamespace = true;
                        if (state.InsideConditionalDirective)
                        {
                            result.IsInsideConditionalBlock = true;
                        }
                    }
                    else if (t.InnerText == "class")
                    {
                        state.ResolvingClass = true;
                        if (state.InsideConditionalDirective)
                        {
                            result.IsInsideConditionalBlock = true;
                        }
                    }
                }
                else if (t is CSharpTokenizer.OpenScopeToken)
                {
                    state.PushNamespacePart(state.Namespace);
                    state.Reset();
                }
                else if (t is CSharpTokenizer.CloseScopeToken)
                {
                    state.Reset();
                    state.PopNamespacePart();
                }
                else if (t is OperatorOrPunctuatorToken)
                {
                    if (state.ResolvingNamespace)
                    {
                        if (t.InnerText == ".")
                        {
                            state.Namespace += ".";
                        }
                    }
                }
                else if (t is IdentifierToken)
                {
                    // If we're resolving a namespace, then this is part of the namespace.
                    if (state.ResolvingNamespace)
                    {
                        state.Namespace += t.InnerText;
                    }
                    // If we're resolving a class, then we're done. We found the class name.
                    else if (state.ResolvingClass)
                    {
                        // We're done.
                        result.Name = state.ComposeQualifiedClassName(t.InnerText);
                        return result;
                    }
                }
                else if (t is OpenConditionalDirectiveToken)
                {
                    state.OpenConditionalDirective();
                }
                else if (t is CloseConditionalDirectiveToken)
                {
                    state.CloseConditionalDirective();
                }
            }

            return result;
        }