crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/SourceParser/Parsers/ParserSrcMethod.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/SourceParser/Parsers/ParserSrcMethod.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,234 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+* 
+* Description:
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SymbianUtils.SourceParser.Objects;
+using SymbianUtils.SourceParser.Parsers;
+
+namespace SymbianUtils.SourceParser.Parsers
+{
+    public class ParserSrcMethod
+    {
+        #region Constructors
+        public ParserSrcMethod()
+        {
+        }
+        #endregion
+
+        #region API
+        public SrcMethod Parse( ref string aText )
+        {
+            SrcMethod ret = null;
+            //
+            if ( aText.Length > 0 )
+            {
+                string parameters = string.Empty;
+                //
+                if ( ContainsParameters( aText ) )
+                {
+                    // This leaves modifiers intact
+                    parameters = ExtractParameters( ref aText );
+                }
+
+                // Look for the class separator. If we find that, then everything after
+                // it is the method name.
+                //
+                // If no class separator exists, then we treat the whole thing as the method
+                // name.
+                int pos = aText.IndexOf( SrcClass.KClassSeparator );
+
+                // By default, treat the whole text as the class name
+                string methodText = aText;
+                if ( pos >= 0 )
+                {
+                    methodText = aText.Substring( pos + SrcClass.KClassSeparator.Length );
+                    aText = aText.Substring( 0, pos + SrcClass.KClassSeparator.Length );
+                }
+                else
+                {
+                    // Everything was consumed...
+                    aText = string.Empty;
+                }
+
+                // Make a new method. Work out if the method text
+                // actually has any parameters
+                ret = new SrcMethod();
+
+                // Try to parse the modifiers. We extract that first
+                // to leave us with just the method name and the parameters.
+                bool hasModifier = ContainsModifier( methodText );
+                if ( hasModifier )
+                {
+                    ParserSrcMethodModifier parser = new ParserSrcMethodModifier();
+                    SrcMethodModifier modifier = parser.Parse( ref methodText );
+                    if ( modifier != null )
+                    {
+                        ret.Modifier = modifier;
+                    }
+                }
+
+                // Try to parse the parameters. We can also use this
+                // to calculate the exact method name.
+                if ( parameters.Length > 0 )
+                {
+                    ParserSrcMethodParameter parser = new ParserSrcMethodParameter();
+                    parser.Parse( ref parameters, ret );
+                }
+
+                // What's left should be the method name followed by "()" if the
+                // 'method' wasn't a label.
+                if ( ContainsParameters( methodText ) )
+                {
+                    // Discard "()";
+                    pos = methodText.LastIndexOf( "(" );
+                    methodText = methodText.Substring( 0, pos );
+                }
+
+                ret.Name = methodText;
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+        #region Properties
+        #endregion
+
+        #region Internal methods
+        private static bool ContainsParameters( string aText )
+        {
+            // Search initiall for '(' - if that is found, then
+            // we should also find a closing bracket.
+            bool parameters = false;
+            int openingBracketPos = aText.IndexOf( "(" );
+            //
+            if ( openingBracketPos > 0 )
+            {
+                // Should also be a closing bracket and it should
+                // appear after the opening bracket
+                int closingBracketPos = aText.LastIndexOf( ")" );
+                parameters = ( closingBracketPos > openingBracketPos );
+            }
+            //
+            return parameters;
+        }
+
+        private static bool ContainsModifier( string aText )
+        {
+            bool modifiers = false;
+
+            int openingBracketPos = aText.IndexOf( "(" );
+            if ( openingBracketPos >= 0 )
+            {
+                int closingBracketPos = openingBracketPos;
+                SymbianUtils.Strings.StringParsingUtils.SkipToEndOfSection( ref aText, ref closingBracketPos, '(', ')' );
+
+                if ( closingBracketPos > openingBracketPos )
+                {
+                    // everything here on is the modifier text;
+                    string modifierText = aText.Substring( closingBracketPos + 1 );
+                    modifiers = ( modifierText.Trim().Length > 0 );
+                }
+            }
+            //
+            return modifiers;
+        }
+
+        private static string ExtractParameters( ref string aText )
+        {
+            const string KOperatorChevronText = "operator <<";
+
+            // DoAppendFormatList<TDes16, (int)2>(T1&, const T3&, std::__va_list, T2*)
+            // DoAppendFormatList<TDes16, (int)2>(T1&, TBuf<(int)256>, std::__va_list, T2*)
+            // Method<TDes16>::Wibble( something )
+            // Method::Wibble( RPointerArray<HBufC> )
+            // RTest::operator ()(int, int, const unsigned short*)
+            // TDesC16::Left(int) const
+            // CObjectCon::AtL(int) const
+            // User::Panic(const TDesC16&, int)
+            // operator <<(RWriteStream&, const unsigned char&)
+
+            // Handle special case of "operator <<" confusing matters
+            string workingText = aText;
+            int operatorOpeningChevronPos = aText.IndexOf( KOperatorChevronText );
+            if ( operatorOpeningChevronPos >= 0 )
+            {
+                aText = aText.Substring( 0, operatorOpeningChevronPos + KOperatorChevronText.Length );
+                workingText = workingText.Substring( operatorOpeningChevronPos + KOperatorChevronText.Length );
+            }
+            else
+            {
+                aText = string.Empty;
+            }
+
+            string ret = string.Empty;
+            //
+            int closingPos = 0;
+            int openingPos = 0;
+            int templatePos = 0;
+            //
+            while ( openingPos >= 0 )
+            {
+                if ( templatePos >= 0 )
+                    templatePos = workingText.IndexOf( "<", templatePos );
+                openingPos = workingText.IndexOf( "(", openingPos );
+
+                if ( templatePos >= 0 && templatePos < openingPos )
+                {
+                    // Template region appears before the next bracket. Skip
+                    // over all characters until we hit the end of the template
+                    // section
+                    int endingPos = templatePos;
+                    SymbianUtils.Strings.StringParsingUtils.SkipToEndOfSection( ref workingText, ref endingPos, '<', '>' );
+
+                    if ( endingPos < 0 )
+                    {
+                        // Matching closing brace was never found - dealing with operator << ?
+                        templatePos = -1;
+                    }
+                    else
+                    {
+                        // Something like DoAppendFormatList<TDes16, (int)2>(T1&, const T3&, std::__va_list, T2*) ???
+                        templatePos = endingPos;
+                        openingPos = endingPos;
+                    }
+                }
+                else if ( openingPos >= 0 )
+                {
+                    // Skipped over any template nonsense. Work backward from the end 
+                    // in order to locate start of parameters.
+                    closingPos = workingText.LastIndexOf( ')' );
+                    openingPos = closingPos;
+                    SymbianUtils.Strings.StringParsingUtils.SkipToBeginningOfSection( ref workingText, ref openingPos, '(', ')' );
+
+                    string parameters = workingText.Substring( openingPos + 1, ( closingPos - openingPos ) - 1 ).Trim();
+                    ret = parameters;
+                    workingText = workingText.Substring( 0, openingPos + 1 ) + workingText.Substring( closingPos );
+                    aText = aText + workingText;
+                    break;
+                }
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+        #region Data members
+        #endregion
+    }
+}