Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Compiler / VariableBinder.cs / 1305376 / VariableBinder.cs
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Microsoft Public License. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Microsoft Public License, please send an email to
* dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Microsoft Public License.
*
* You must not remove this notice, or any other, from this software.
*
*
* ***************************************************************************/
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Dynamic.Utils;
#if SILVERLIGHT
using System.Core;
#endif
namespace System.Linq.Expressions.Compiler {
///
/// Determines if variables are closed over in nested lambdas and need to
/// be hoisted.
///
internal sealed class VariableBinder : ExpressionVisitor {
private readonly AnalyzedTree _tree = new AnalyzedTree();
private readonly Stack _scopes = new Stack();
private readonly Stack _constants = new Stack();
private bool _inQuote;
internal static AnalyzedTree Bind(LambdaExpression lambda) {
var binder = new VariableBinder();
binder.Visit(lambda);
return binder._tree;
}
private VariableBinder() {
}
protected internal override Expression VisitConstant(ConstantExpression node) {
// If we're in Quote, we can ignore constants completely
if (_inQuote) {
return node;
}
// Constants that can be emitted into IL don't need to be stored on
// the delegate
if (ILGen.CanEmitConstant(node.Value, node.Type)) {
return node;
}
_constants.Peek().AddReference(node.Value, node.Type);
return node;
}
protected internal override Expression VisitUnary(UnaryExpression node) {
if (node.NodeType == ExpressionType.Quote) {
bool savedInQuote = _inQuote;
_inQuote = true;
Visit(node.Operand);
_inQuote = savedInQuote;
} else {
Visit(node.Operand);
}
return node;
}
protected internal override Expression VisitLambda(Expression node) {
_scopes.Push(_tree.Scopes[node] = new CompilerScope(node, true));
_constants.Push(_tree.Constants[node] = new BoundConstants());
Visit(MergeScopes(node));
_constants.Pop();
_scopes.Pop();
return node;
}
protected internal override Expression VisitInvocation(InvocationExpression node) {
LambdaExpression lambda = node.LambdaOperand;
// optimization: inline code for literal lambda's directly
if (lambda != null) {
// visit the lambda, but treat it more like a scope
_scopes.Push(_tree.Scopes[lambda] = new CompilerScope(lambda, false));
Visit(MergeScopes(lambda));
_scopes.Pop();
// visit the invoke's arguments
Visit(node.Arguments);
return node;
}
return base.VisitInvocation(node);
}
protected internal override Expression VisitBlock(BlockExpression node) {
if (node.Variables.Count == 0) {
Visit(node.Expressions);
return node;
}
_scopes.Push(_tree.Scopes[node] = new CompilerScope(node, false));
Visit(MergeScopes(node));
_scopes.Pop();
return node;
}
protected override CatchBlock VisitCatchBlock(CatchBlock node) {
if (node.Variable == null) {
Visit(node.Body);
return node;
}
_scopes.Push(_tree.Scopes[node] = new CompilerScope(node, false));
Visit(node.Body);
_scopes.Pop();
return node;
}
// If the immediate child is another scope, merge it into this one
// This is an optimization to save environment allocations and
// array accesses.
private ReadOnlyCollection MergeScopes(Expression node) {
ReadOnlyCollection body;
var lambda = node as LambdaExpression;
if (lambda != null) {
body = new ReadOnlyCollection(new[] { lambda.Body });
} else {
body = ((BlockExpression)node).Expressions;
}
var currentScope = _scopes.Peek();
// A block body is mergeable if the body only contains one single block node containing variables,
// and the child block has the same type as the parent block.
while (body.Count == 1 && body[0].NodeType == ExpressionType.Block) {
var block = (BlockExpression)body[0];
if (block.Variables.Count > 0) {
// Make sure none of the variables are shadowed. If any
// are, we can't merge it.
foreach (var v in block.Variables) {
if (currentScope.Definitions.ContainsKey(v)) {
return body;
}
}
// Otherwise, merge it
if (currentScope.MergedScopes == null) {
currentScope.MergedScopes = new Set
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ECDiffieHellmanPublicKey.cs
- TypeConverterHelper.cs
- WebRequest.cs
- securitycriticaldataClass.cs
- MobileControlsSection.cs
- TypeLoadException.cs
- Matrix3DConverter.cs
- ListBoxChrome.cs
- ServicePointManagerElement.cs
- base64Transforms.cs
- BaseParser.cs
- SchemaReference.cs
- TableProviderWrapper.cs
- CodeFieldReferenceExpression.cs
- CommandField.cs
- SelfIssuedTokenFactoryCredential.cs
- AssemblyBuilderData.cs
- IgnoreDataMemberAttribute.cs
- DesignerCatalogPartChrome.cs
- RouteParametersHelper.cs
- DocumentApplication.cs
- XPathDocumentNavigator.cs
- TreeWalkHelper.cs
- ReaderWriterLock.cs
- precedingsibling.cs
- HotSpot.cs
- DesignUtil.cs
- RegexRunnerFactory.cs
- AQNBuilder.cs
- BindingsCollection.cs
- TemplateComponentConnector.cs
- Internal.cs
- BindingBase.cs
- InternalDuplexChannelListener.cs
- HttpContextWrapper.cs
- DbSetClause.cs
- IndentedTextWriter.cs
- SelectedDatesCollection.cs
- AnnotationComponentManager.cs
- TraceSwitch.cs
- KeyTimeConverter.cs
- ZipIOCentralDirectoryFileHeader.cs
- MouseGestureValueSerializer.cs
- DataTrigger.cs
- MobileUITypeEditor.cs
- FastEncoderStatics.cs
- ManagedCodeMarkers.cs
- TypedReference.cs
- CompositeActivityTypeDescriptor.cs
- TdsParserStaticMethods.cs
- CoreSwitches.cs
- AssemblyCacheEntry.cs
- MissingManifestResourceException.cs
- MeshGeometry3D.cs
- TextDecorationCollection.cs
- BitmapEncoder.cs
- NavigateEvent.cs
- RectValueSerializer.cs
- TimeoutException.cs
- ValidatorUtils.cs
- InkCollectionBehavior.cs
- SettingsPropertyWrongTypeException.cs
- StrokeNodeEnumerator.cs
- RangeExpression.cs
- ApplicationServicesHostFactory.cs
- RSAPKCS1SignatureFormatter.cs
- PanelDesigner.cs
- EntityContainerEmitter.cs
- SqlDataSourceView.cs
- ElementsClipboardData.cs
- FlowDocumentScrollViewerAutomationPeer.cs
- dsa.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- TempEnvironment.cs
- ApplicationHost.cs
- MetadataSection.cs
- IndexExpression.cs
- DataGridViewAdvancedBorderStyle.cs
- DataRow.cs
- HelpProvider.cs
- DataConnectionHelper.cs
- smtppermission.cs
- Hex.cs
- DataGridViewTextBoxCell.cs
- SaveLedgerEntryRequest.cs
- ResourcePool.cs
- ColorAnimation.cs
- OneToOneMappingSerializer.cs
- DataServiceQueryContinuation.cs
- ToolStripItemBehavior.cs
- PrinterSettings.cs
- TemplatePropertyEntry.cs
- ValidatorAttribute.cs
- DataDocumentXPathNavigator.cs
- TableLayoutPanelDesigner.cs
- WpfKnownType.cs
- ToolStripDropDownButton.cs
- BrowserDefinitionCollection.cs
- DelegateTypeInfo.cs
- TcpProcessProtocolHandler.cs