Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ALinq / Evaluator.cs / 1305376 / Evaluator.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides funcletization of expression tree prior to resource binding.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Client
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
#if ASTORIA_LIGHT // Hashset not available
/// workaround until silver light client is updated
internal class HashSet : Dictionary, IEnumerable where T : class
{
/// workaround until silver light client is updated
public HashSet() { }
/// workaround until silver light client is updated
public HashSet(IEqualityComparer comparer) : base(comparer) { }
/// workaround until silver light client is updated
public HashSet(IEnumerable collection, IEqualityComparer comparer) : base(comparer)
{
this.UnionWith(collection);
}
/// workaround until silver light client is updated
public bool Add(T value) { if (!base.ContainsKey(value)) { base.Add(value, value); return true; } return false; }
/// workaround until silver light client is updated
public bool Contains(T value) { return base.ContainsKey(value); }
/// workaround until silver light client is updated
new public bool Remove(T value) { return base.Remove(value); }
/// workaround until silver light client is updated
new public IEnumerator GetEnumerator() { return base.Keys.GetEnumerator(); }
/// Modifies the current HashSet object to contain all elements that are present in both itself and in the specified collection.
/// The collection to compare to the current HashSet object.
public void UnionWith(IEnumerable other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
foreach (T local in other)
{
////this.AddIfNotPresent(local);
this.Add(local);
}
}
}
#endif
///
/// performs funcletization on an expression tree
///
internal static class Evaluator
{
///
/// Performs evaluation and replacement of independent sub-trees
///
/// The root of the expression tree.
/// A function that decides whether a given expression node can be part of the local function.
/// A new tree with sub-trees evaluated and replaced.
internal static Expression PartialEval(Expression expression, Func canBeEvaluated)
{
Nominator nominator = new Nominator(canBeEvaluated);
HashSet candidates = nominator.Nominate(expression);
return new SubtreeEvaluator(candidates).Eval(expression);
}
///
/// Performs evaluation and replacement of independent sub-trees
///
/// The root of the expression tree.
/// A new tree with sub-trees evaluated and replaced.
internal static Expression PartialEval(Expression expression)
{
return PartialEval(expression, Evaluator.CanBeEvaluatedLocally);
}
///
/// Evaluates if an expression can be evaluated locally.
///
/// the expression.
/// true/ false if can be evaluated locally
private static bool CanBeEvaluatedLocally(Expression expression)
{
return expression.NodeType != ExpressionType.Parameter &&
expression.NodeType != ExpressionType.Lambda &&
expression.NodeType != (ExpressionType) ResourceExpressionType.RootResourceSet;
}
///
/// Evaluates and replaces sub-trees when first candidate is reached (top-down)
///
internal class SubtreeEvaluator : DataServiceALinqExpressionVisitor
{
/// list of candidates
private HashSet candidates;
///
/// constructs an expression evaluator with a list of candidates
///
/// List of expressions to evaluate
internal SubtreeEvaluator(HashSet candidates)
{
this.candidates = candidates;
}
///
/// Evaluates an expression sub-tree
///
/// The expression to evaluate.
/// The evaluated expression.
internal Expression Eval(Expression exp)
{
return this.Visit(exp);
}
///
/// Visit method for visitor
///
/// the expression to visit
/// visited expression
internal override Expression Visit(Expression exp)
{
if (exp == null)
{
return null;
}
if (this.candidates.Contains(exp))
{
return Evaluate(exp);
}
return base.Visit(exp);
}
///
/// Evaluates expression
///
/// the expression to evaluate
/// constant expression with return value of evaluation
private static Expression Evaluate(Expression e)
{
if (e.NodeType == ExpressionType.Constant)
{
return e;
}
#if ASTORIA_LIGHT
LambdaExpression lambda = ExpressionHelpers.CreateLambda(e, new ParameterExpression[0]);
#else
LambdaExpression lambda = Expression.Lambda(e);
#endif
Delegate fn = lambda.Compile();
object constantValue = fn.DynamicInvoke(null);
Debug.Assert(!(constantValue is Expression), "!(constantValue is Expression)");
// Use the expression type unless it's an array type,
// where the actual type may be a vector array rather
// than an array with a dynamic lower bound.
Type constantType = e.Type;
if (constantValue != null && constantType.IsArray && constantType.GetElementType() == constantValue.GetType().GetElementType())
{
constantType = constantValue.GetType();
}
return Expression.Constant(constantValue, constantType);
}
}
///
/// Performs bottom-up analysis to determine which nodes can possibly
/// be part of an evaluated sub-tree.
///
internal class Nominator : DataServiceALinqExpressionVisitor
{
/// func to determine whether expression can be evaluated
private Func functionCanBeEvaluated;
/// candidate expressions for evaluation
private HashSet candidates;
/// flag for when sub tree cannot be evaluated
private bool cannotBeEvaluated;
///
/// Creates the Nominator based on the function passed.
///
///
/// A Func speficying whether an expression can be evaluated or not.
///
/// visited expression
internal Nominator(Func functionCanBeEvaluated)
{
this.functionCanBeEvaluated = functionCanBeEvaluated;
}
///
/// Nominates an expression to see if it can be evaluated
///
///
/// Expression to check
///
/// a list of expression sub trees that can be evaluated
internal HashSet Nominate(Expression expression)
{
this.candidates = new HashSet(EqualityComparer.Default);
this.Visit(expression);
return this.candidates;
}
///
/// Visit method for walking expression tree bottom up.
///
///
/// root expression to visit
///
/// visited expression
internal override Expression Visit(Expression expression)
{
if (expression != null)
{
bool saveCannotBeEvaluated = this.cannotBeEvaluated;
this.cannotBeEvaluated = false;
base.Visit(expression);
if (!this.cannotBeEvaluated)
{
if (this.functionCanBeEvaluated(expression))
{
this.candidates.Add(expression);
}
else
{
this.cannotBeEvaluated = true;
}
}
this.cannotBeEvaluated |= saveCannotBeEvaluated;
}
return expression;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides funcletization of expression tree prior to resource binding.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Client
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
#if ASTORIA_LIGHT // Hashset not available
/// workaround until silver light client is updated
internal class HashSet : Dictionary, IEnumerable where T : class
{
/// workaround until silver light client is updated
public HashSet() { }
/// workaround until silver light client is updated
public HashSet(IEqualityComparer comparer) : base(comparer) { }
/// workaround until silver light client is updated
public HashSet(IEnumerable collection, IEqualityComparer comparer) : base(comparer)
{
this.UnionWith(collection);
}
/// workaround until silver light client is updated
public bool Add(T value) { if (!base.ContainsKey(value)) { base.Add(value, value); return true; } return false; }
/// workaround until silver light client is updated
public bool Contains(T value) { return base.ContainsKey(value); }
/// workaround until silver light client is updated
new public bool Remove(T value) { return base.Remove(value); }
/// workaround until silver light client is updated
new public IEnumerator GetEnumerator() { return base.Keys.GetEnumerator(); }
/// Modifies the current HashSet object to contain all elements that are present in both itself and in the specified collection.
/// The collection to compare to the current HashSet object.
public void UnionWith(IEnumerable other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
foreach (T local in other)
{
////this.AddIfNotPresent(local);
this.Add(local);
}
}
}
#endif
///
/// performs funcletization on an expression tree
///
internal static class Evaluator
{
///
/// Performs evaluation and replacement of independent sub-trees
///
/// The root of the expression tree.
/// A function that decides whether a given expression node can be part of the local function.
/// A new tree with sub-trees evaluated and replaced.
internal static Expression PartialEval(Expression expression, Func canBeEvaluated)
{
Nominator nominator = new Nominator(canBeEvaluated);
HashSet candidates = nominator.Nominate(expression);
return new SubtreeEvaluator(candidates).Eval(expression);
}
///
/// Performs evaluation and replacement of independent sub-trees
///
/// The root of the expression tree.
/// A new tree with sub-trees evaluated and replaced.
internal static Expression PartialEval(Expression expression)
{
return PartialEval(expression, Evaluator.CanBeEvaluatedLocally);
}
///
/// Evaluates if an expression can be evaluated locally.
///
/// the expression.
/// true/ false if can be evaluated locally
private static bool CanBeEvaluatedLocally(Expression expression)
{
return expression.NodeType != ExpressionType.Parameter &&
expression.NodeType != ExpressionType.Lambda &&
expression.NodeType != (ExpressionType) ResourceExpressionType.RootResourceSet;
}
///
/// Evaluates and replaces sub-trees when first candidate is reached (top-down)
///
internal class SubtreeEvaluator : DataServiceALinqExpressionVisitor
{
/// list of candidates
private HashSet candidates;
///
/// constructs an expression evaluator with a list of candidates
///
/// List of expressions to evaluate
internal SubtreeEvaluator(HashSet candidates)
{
this.candidates = candidates;
}
///
/// Evaluates an expression sub-tree
///
/// The expression to evaluate.
/// The evaluated expression.
internal Expression Eval(Expression exp)
{
return this.Visit(exp);
}
///
/// Visit method for visitor
///
/// the expression to visit
/// visited expression
internal override Expression Visit(Expression exp)
{
if (exp == null)
{
return null;
}
if (this.candidates.Contains(exp))
{
return Evaluate(exp);
}
return base.Visit(exp);
}
///
/// Evaluates expression
///
/// the expression to evaluate
/// constant expression with return value of evaluation
private static Expression Evaluate(Expression e)
{
if (e.NodeType == ExpressionType.Constant)
{
return e;
}
#if ASTORIA_LIGHT
LambdaExpression lambda = ExpressionHelpers.CreateLambda(e, new ParameterExpression[0]);
#else
LambdaExpression lambda = Expression.Lambda(e);
#endif
Delegate fn = lambda.Compile();
object constantValue = fn.DynamicInvoke(null);
Debug.Assert(!(constantValue is Expression), "!(constantValue is Expression)");
// Use the expression type unless it's an array type,
// where the actual type may be a vector array rather
// than an array with a dynamic lower bound.
Type constantType = e.Type;
if (constantValue != null && constantType.IsArray && constantType.GetElementType() == constantValue.GetType().GetElementType())
{
constantType = constantValue.GetType();
}
return Expression.Constant(constantValue, constantType);
}
}
///
/// Performs bottom-up analysis to determine which nodes can possibly
/// be part of an evaluated sub-tree.
///
internal class Nominator : DataServiceALinqExpressionVisitor
{
/// func to determine whether expression can be evaluated
private Func functionCanBeEvaluated;
/// candidate expressions for evaluation
private HashSet candidates;
/// flag for when sub tree cannot be evaluated
private bool cannotBeEvaluated;
///
/// Creates the Nominator based on the function passed.
///
///
/// A Func speficying whether an expression can be evaluated or not.
///
/// visited expression
internal Nominator(Func functionCanBeEvaluated)
{
this.functionCanBeEvaluated = functionCanBeEvaluated;
}
///
/// Nominates an expression to see if it can be evaluated
///
///
/// Expression to check
///
/// a list of expression sub trees that can be evaluated
internal HashSet Nominate(Expression expression)
{
this.candidates = new HashSet(EqualityComparer.Default);
this.Visit(expression);
return this.candidates;
}
///
/// Visit method for walking expression tree bottom up.
///
///
/// root expression to visit
///
/// visited expression
internal override Expression Visit(Expression expression)
{
if (expression != null)
{
bool saveCannotBeEvaluated = this.cannotBeEvaluated;
this.cannotBeEvaluated = false;
base.Visit(expression);
if (!this.cannotBeEvaluated)
{
if (this.functionCanBeEvaluated(expression))
{
this.candidates.Add(expression);
}
else
{
this.cannotBeEvaluated = true;
}
}
this.cannotBeEvaluated |= saveCannotBeEvaluated;
}
return expression;
}
}
}
}
// 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
- CallContext.cs
- SQLMembershipProvider.cs
- TypeLoader.cs
- SystemInformation.cs
- ScriptModule.cs
- TrackBarRenderer.cs
- SoundPlayer.cs
- TraceEventCache.cs
- DtrList.cs
- ResXResourceReader.cs
- ZipIOFileItemStream.cs
- RoutedCommand.cs
- ZipIOLocalFileHeader.cs
- WebControl.cs
- NetworkInformationException.cs
- JsonFormatGeneratorStatics.cs
- FormViewUpdateEventArgs.cs
- Attributes.cs
- InputDevice.cs
- MultiSelectRootGridEntry.cs
- ResourceDescriptionAttribute.cs
- XmlNotation.cs
- ISessionStateStore.cs
- OdbcConnectionHandle.cs
- Lasso.cs
- DayRenderEvent.cs
- ImageSource.cs
- GuidelineSet.cs
- TypeToken.cs
- CodeAccessSecurityEngine.cs
- GeneralTransform3DTo2D.cs
- SettingsAttributes.cs
- Label.cs
- Stream.cs
- PointKeyFrameCollection.cs
- RuleInfoComparer.cs
- CompilerWrapper.cs
- EventsTab.cs
- ConfigurationStrings.cs
- AppDomainProtocolHandler.cs
- FtpCachePolicyElement.cs
- LongValidatorAttribute.cs
- StorageMappingItemCollection.cs
- DataGridAutoGeneratingColumnEventArgs.cs
- LingerOption.cs
- ProvidePropertyAttribute.cs
- InlineObject.cs
- SslSecurityTokenParameters.cs
- JavaScriptObjectDeserializer.cs
- CodeRemoveEventStatement.cs
- UpWmlMobileTextWriter.cs
- XPathNavigatorReader.cs
- ThreadInterruptedException.cs
- CodeNamespaceImportCollection.cs
- processwaithandle.cs
- GridViewPageEventArgs.cs
- MenuBindingsEditor.cs
- SchemaDeclBase.cs
- DrawingContextWalker.cs
- EntityAdapter.cs
- RoutedUICommand.cs
- CachedPathData.cs
- PrivacyNoticeBindingElement.cs
- PerfCounters.cs
- ClientScriptManagerWrapper.cs
- LinkLabelLinkClickedEvent.cs
- DrawingAttributesDefaultValueFactory.cs
- WpfWebRequestHelper.cs
- RawStylusSystemGestureInputReport.cs
- SoapHttpTransportImporter.cs
- BitmapDecoder.cs
- Codec.cs
- UniqueIdentifierService.cs
- IconConverter.cs
- DmlSqlGenerator.cs
- CompensationToken.cs
- SafeHandle.cs
- StackSpiller.cs
- AuthenticationModuleElement.cs
- ErrorWebPart.cs
- PenLineJoinValidation.cs
- CellConstant.cs
- OleDbPermission.cs
- WebEventTraceProvider.cs
- UpWmlMobileTextWriter.cs
- CustomUserNameSecurityTokenAuthenticator.cs
- ScriptHandlerFactory.cs
- MimeTypePropertyAttribute.cs
- DateTimeOffsetStorage.cs
- FieldDescriptor.cs
- Interlocked.cs
- OdbcConnectionStringbuilder.cs
- HtmlSelect.cs
- AutomationTextAttribute.cs
- ButtonChrome.cs
- InteropAutomationProvider.cs
- RSAOAEPKeyExchangeFormatter.cs
- FontFamily.cs
- EventSourceCreationData.cs
- HtmlTableCell.cs