Code:
                         / 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ProjectionPathBuilder.cs / 1305376 / ProjectionPathBuilder.cs
                        
                        
                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
//  
//  
// Provides a class that can materialize ATOM entries into typed
// objects, while maintaining a log of changes done. 
//   
//---------------------------------------------------------------------
 
namespace System.Data.Services.Client
{
    #region Namespaces.
 
    using System;
    using System.Collections.Generic; 
    using System.Diagnostics; 
    using System.Linq;
    using System.Linq.Expressions; 
    #endregion Namespaces.
    ///  
    /// Use this class to help keep track of projection paths built
    /// while compiling a projection-based materialization plan. 
    ///   
    internal class ProjectionPathBuilder
    { 
        #region Private fields.
        /// Stack of whether entities are in scope. 
        private readonly Stack entityInScope; 
        /// Registers rewrites for member initialization blocks.  
        private readonly List rewrites; 
        /// Stack of lambda expressions in scope.  
        private readonly Stack parameterExpressions;
        /// 
        /// Stack of expected type expression for  
        private readonly Stack parameterExpressionTypes; 
 
        /// Stack of 'entry' parameter expressions. 
        private readonly Stack parameterEntries; 
        /// Stack of projection (target-tree) types for parameters. 
        private readonly Stack parameterProjectionTypes;
 
        #endregion Private fields.
 
        #region Constructors. 
        /// Initializes a new   
        internal ProjectionPathBuilder()
        {
            this.entityInScope = new Stack();
            this.rewrites = new List(); 
            this.parameterExpressions = new Stack();
            this.parameterExpressionTypes = new Stack(); 
            this.parameterEntries = new Stack(); 
            this.parameterProjectionTypes = new Stack();
        } 
        #endregion Constructors.
        #region Internal properties. 
        /// Whether the current scope is acting on an entity.  
        internal bool CurrentIsEntity 
        {
            get { return this.entityInScope.Peek(); } 
        }
        /// Expression for the expected type parameter. 
        internal Expression ExpectedParamTypeInScope 
        {
            get 
            { 
                Debug.Assert(this.parameterExpressionTypes.Count > 0, "this.parameterExpressionTypes.Count > 0");
                return this.parameterExpressionTypes.Peek(); 
            }
        }
        /// Whether any rewrites have been registered.  
        internal bool HasRewrites
        { 
            get { return this.rewrites.Count > 0; } 
        }
 
        /// Expression for the entity parameter in the source tree lambda. 
        internal Expression LambdaParameterInScope
        {
            get 
            {
                return this.parameterExpressions.Peek(); 
            } 
        }
 
        /// Expression for the entry parameter in the target tree. 
        internal Expression ParameterEntryInScope
        {
            get 
            {
                return this.parameterEntries.Peek(); 
            } 
        }
 
        #endregion Internal properties.
        #region Methods.
 
        /// Provides a string representation of this object. 
        /// String representation of this object.  
        public override string ToString() 
        {
            string result = "ProjectionPathBuilder: "; 
            if (this.parameterExpressions.Count == 0)
            {
                result += "(empty)";
            } 
            else
            { 
                result += 
                    "entity:" + this.CurrentIsEntity +
                    " param:" + this.ParameterEntryInScope; 
            }
            return result;
        } 
        /// Records that a lambda scope has been entered when visiting a projection.  
        /// Lambda being visited. 
        /// Expression to the entry parameter from the target tree.
        /// Expression to the entry-expected-type from the target tree. 
        internal void EnterLambdaScope(LambdaExpression lambda, Expression entry, Expression expectedType)
        {
            Debug.Assert(lambda != null, "lambda != null");
            Debug.Assert(lambda.Parameters.Count == 1, "lambda.Parameters.Count == 1"); 
            ParameterExpression param = lambda.Parameters[0]; 
            Type projectionType = lambda.Body.Type; 
            bool isEntityType = ClientType.CheckElementTypeIsEntity(projectionType);
 
            this.entityInScope.Push(isEntityType);
            this.parameterExpressions.Push(param);
            this.parameterExpressionTypes.Push(expectedType);
            this.parameterEntries.Push(entry); 
            this.parameterProjectionTypes.Push(projectionType);
        } 
 
        /// 
        /// Records that a member initialization expression has been entered 
        /// when visting a projection.
        ///  
        /// Expression for initialization.
        internal void EnterMemberInit(MemberInitExpression init) 
        {
            bool isEntityType = ClientType.CheckElementTypeIsEntity(init.Type); 
            this.entityInScope.Push(isEntityType); 
        }
 
        /// Gets a rewrite for the specified expression; null if none is found. 
        /// Expression to match.
        /// A rewrite for the expression; possibly null. 
        internal Expression GetRewrite(Expression expression) 
        {
            Debug.Assert(expression != null, "expression != null"); 
 
            List names = new List();
            while (expression.NodeType == ExpressionType.MemberAccess) 
            {
                MemberExpression member = (MemberExpression)expression;
                names.Add(member.Member.Name);
                expression = member.Expression; 
            }
 
            Expression result = null; 
            foreach (var rewrite in this.rewrites)
            { 
                if (rewrite.Root != expression)
                {
                    continue;
                } 
                if (names.Count != rewrite.MemberNames.Length) 
                { 
                    continue;
                } 
                bool match = true;
                for (int i = 0; i < names.Count && i < rewrite.MemberNames.Length; i++)
                { 
                    if (names[names.Count - i - 1] != rewrite.MemberNames[i])
                    { 
                        match = false; 
                        break;
                    } 
                }
                if (match)
                { 
                    result = rewrite.RewriteExpression;
                    break; 
                } 
            }
 
            return result;
        }
        /// Records that a lambda scope has been left when visting a projection.  
        internal void LeaveLambdaScope()
        { 
            this.entityInScope.Pop(); 
            this.parameterExpressions.Pop();
            this.parameterExpressionTypes.Pop(); 
            this.parameterEntries.Pop();
            this.parameterProjectionTypes.Pop();
        }
 
        /// 
        /// Records that a member initialization expression has been left when 
        /// visting a projection. 
        ///  
        internal void LeaveMemberInit() 
        {
            this.entityInScope.Pop();
        }
 
        /// Registers a member initialization rewrite. 
        /// Root of member access path, typically a source tree parameter of entity type. 
        /// Sequence of names to match. 
        /// Rewrite expression for names.
        internal void RegisterRewrite(Expression root, string[] names, Expression rewriteExpression) 
        {
            Debug.Assert(root != null, "root != null");
            Debug.Assert(names != null, "names != null");
            Debug.Assert(rewriteExpression != null, "rewriteExpression != null"); 
            this.rewrites.Add(new MemberInitRewrite() { Root = root, MemberNames = names, RewriteExpression = rewriteExpression }); 
            this.parameterEntries.Push(rewriteExpression); 
        }
 
        /// Revokes the latest rewrite registered on the specified  
        /// Root of rewrites to revoke.
        /// Names to revoke.
        internal void RevokeRewrite(Expression root, string[] names) 
        {
            Debug.Assert(root != null, "root != null"); 
 
            for (int i = 0; i < this.rewrites.Count; i++)
            { 
                if (this.rewrites[i].Root != root)
                {
                    continue;
                } 
                if (names.Length != this.rewrites[i].MemberNames.Length) 
                { 
                    continue;
                } 
                bool match = true;
                for (int j = 0; j < names.Length; j++)
                { 
                    if (names[j] != this.rewrites[i].MemberNames[j])
                    { 
                        match = false; 
                        break;
                    } 
                }
                if (match)
                { 
                    this.rewrites.RemoveAt(i);
                    this.parameterEntries.Pop(); 
                    return; 
                }
            } 
        }
        #endregion Methods.
 
        #region Inner types.
 
        /// Use this class to record how rewrites should occur under nested member initializations.  
        internal class MemberInitRewrite
        { 
            /// Sequence of member names to match. 
            internal string[] MemberNames
            {
                get; 
                set;
            } 
 
            /// Root of member access path, typically a source tree parameter of entity type. 
            internal Expression Root 
            {
                get;
                set;
            } 
            /// Rewrite expressions for the last member path.  
            internal Expression RewriteExpression 
            {
                get; 
                set;
            }
        }
 
        #endregion Inner types.
    } 
} 
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                                      
                        
                        
                        
                    Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CompositeActivityMarkupSerializer.cs
- ConstraintManager.cs
- RoutedUICommand.cs
- PeerContact.cs
- _MultipleConnectAsync.cs
- ZipIOFileItemStream.cs
- ItemsPanelTemplate.cs
- ExpressionPrefixAttribute.cs
- DataSourceCache.cs
- WindowsFormsLinkLabel.cs
- XmlUTF8TextReader.cs
- CompilerTypeWithParams.cs
- GacUtil.cs
- UIElementAutomationPeer.cs
- SafeMILHandleMemoryPressure.cs
- ArcSegment.cs
- GeneralTransform3DTo2DTo3D.cs
- ExtensibleClassFactory.cs
- BaseDataListComponentEditor.cs
- DesignSurfaceServiceContainer.cs
- ImportStoreException.cs
- Base64Stream.cs
- UrlPropertyAttribute.cs
- OciHandle.cs
- EncodingInfo.cs
- SetterBaseCollection.cs
- VariableBinder.cs
- EntityConnection.cs
- BackStopAuthenticationModule.cs
- CoTaskMemSafeHandle.cs
- CultureInfoConverter.cs
- DocumentPage.cs
- DataGridViewMethods.cs
- WindowsSolidBrush.cs
- UpdateExpressionVisitor.cs
- NetCodeGroup.cs
- DesignerDataTable.cs
- HttpStreamMessageEncoderFactory.cs
- XmlDictionary.cs
- ResourceReferenceKeyNotFoundException.cs
- TraceHandler.cs
- InputLanguageManager.cs
- ListViewInsertEventArgs.cs
- EncoderParameters.cs
- ProfileSettingsCollection.cs
- SafeProcessHandle.cs
- StructuredType.cs
- Renderer.cs
- XPathEmptyIterator.cs
- ObjectAssociationEndMapping.cs
- LinkArea.cs
- AssertFilter.cs
- Stack.cs
- CodeBlockBuilder.cs
- Timer.cs
- BaseTreeIterator.cs
- SslStreamSecurityBindingElement.cs
- EntityObject.cs
- HtmlInputImage.cs
- LOSFormatter.cs
- WindowsEditBoxRange.cs
- FocusWithinProperty.cs
- CorrelationKeyCalculator.cs
- Transform.cs
- Comparer.cs
- Comparer.cs
- ClientCultureInfo.cs
- ProxyFragment.cs
- xdrvalidator.cs
- ServiceNameElementCollection.cs
- EventHandlerList.cs
- MetricEntry.cs
- XmlBoundElement.cs
- UniqueConstraint.cs
- GridViewAutomationPeer.cs
- D3DImage.cs
- ClientConvert.cs
- AttributeEmitter.cs
- CqlWriter.cs
- BitmapEffectOutputConnector.cs
- SecurityTokenValidationException.cs
- UIElement3D.cs
- PermissionSet.cs
- WebPartRestoreVerb.cs
- ObjectQuery.cs
- DataPagerFieldCollection.cs
- TypeExtensionConverter.cs
- XhtmlConformanceSection.cs
- ObjectMaterializedEventArgs.cs
- SiteMapHierarchicalDataSourceView.cs
- Statements.cs
- TreeIterator.cs
- TextPointer.cs
- QilDataSource.cs
- ObjectDataSourceMethodEventArgs.cs
- URL.cs
- EntityTemplateUserControl.cs
- LockedBorderGlyph.cs
- StyleHelper.cs
- ContentTextAutomationPeer.cs