diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Parser/Framework/Workers/SymParserWorkerCondition.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymBuildParsingLib/Parser/Framework/Workers/SymParserWorkerCondition.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2004-2008 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 SymBuildParsingLib.Tree; +using SymBuildParsingLib.Token; +using SymBuildParsingLib.Parser.Framework.Nodes; +using SymBuildParsingLib.Utils; +using SymbianTree; + +namespace SymBuildParsingLib.Parser.Framework.Workers +{ + public class SymParserWorkerCondition : SymParserWorkerConsumer + { + #region Constructors & destructor + public SymParserWorkerCondition( SymParserWorkerContext aContext ) + : this( aContext, new SymNodeCondition( aContext.CurrentToken.Value ) ) + { + } + + public SymParserWorkerCondition( SymParserWorkerContext aContext, SymNodeCondition aNodeCondition ) + : base( aContext, SymToken.TClass.EClassNewLine ) + { + System.Diagnostics.Debug.Assert( aContext.Document.CurrentNode is SymNodeConditionalExpression ); + + // Make a new child node for the conditions. + iConditionNode = aNodeCondition; + aContext.Document.CurrentNode.Add( iConditionNode ); + aContext.Document.CurrentNode = iConditionNode; + + // Set up the token balancer event handler + iTokenBalancer.EventLevelFinished += new SymBuildParsingLib.Token.SymTokenBalancer.LevelChangeEventHandler( TokenBalancer_EventLevelFinished ); + iTokenBalancer.EventLevelsImbalanced += new SymBuildParsingLib.Token.SymTokenBalancer.LevelsImbalancedEventHandler( TokenBalancer_EventLevelsImbalanced ); + + // If we're handling an ifdef or ifndef expression, we can tell + // the token balancer to discard all brackets, irrespective of their level. + // For normal if statements, we want the brackets. + bool emitLevelZeroBrackets = !( iConditionNode.Type == SymNodeCondition.TType.ETypeIfdef || iConditionNode.Type == SymNodeCondition.TType.ETypeIfndef ); + iTokenBalancer.RegisterBalancerTokens( emitLevelZeroBrackets ); + } + #endregion + + #region From SymParserWorker + public override SymParserWorker.TTokenConsumptionType OfferToken( SymToken aToken ) + { + System.Diagnostics.Debug.Assert( WorkerContext.Document.CurrentNode is SymNodeCondition ); + // + TTokenConsumptionType ret = TTokenConsumptionType.ETokenNotConsumed; + if ( aToken.Class != SymToken.TClass.EClassNewLine ) + { + if ( iTokenBalancer.OfferToken( aToken ) ) + { + ret = TTokenConsumptionType.ETokenConsumed; + } + } + + // Try offering to base class.... + // Base class will dequeue us once we reach the new line + if ( ret != TTokenConsumptionType.ETokenConsumed ) + { + ret = base.OfferToken( aToken ); + } + + return ret; + } + #endregion + + #region From SymParserWorkerConsumer + protected override void HandleTerminatingConditionMatch( SymToken aToken ) + { + // Give the condition node ownership of the raw parsed tokens + iConditionNode.AssignArgumentTokens( iTokenBalancer.DocumentTree ); + + // We only need to evaluate the conditional arguments if we have not yet + // found a positive branch. + SymNodeConditionalExpression condExpNode = (SymNodeConditionalExpression) iConditionNode.Parent; + if ( condExpNode.HasPositiveBranch == false ) + { + iConditionNode.Evaluate( WorkerContext ); + } + + // We remain as the current node, even after we die. This allows + // the body of the condition to be added as our child. + } + #endregion + + #region Properties + public SymNodeCondition ConditionNode + { + get { return iConditionNode; } + } + #endregion + + #region Token balancer event handlers + private void TokenBalancer_EventLevelFinished( int aLevelCount, SymNode aOldLevel, SymNode aNewLevel ) + { + } + + private void TokenBalancer_EventLevelsImbalanced() + { + throw new Exception( "Levels not balanced during condition parsing" ); + } + #endregion + + #region Data members + private SymTokenBalancer iTokenBalancer = new SymTokenBalancer(); + private readonly SymNodeCondition iConditionNode; + #endregion + } +}