internal virtual Expression VisitInputReferenceExpression(InputReferenceExpression ire) { // Debug.Assert(ire != null, "ire != null -- otherwise caller never should have visited here"); ResourceExpression re = (ResourceExpression)this.Visit(ire.Target); return(re.CreateReference()); }
internal InputReferenceExpression CreateReference() { if (this.inputRef == null) { this.inputRef = new InputReferenceExpression(this); } return(this.inputRef); }
internal override Expression VisitInputReferenceExpression(InputReferenceExpression ire) { Debug.Assert(ire != null, "ire != null"); if (this.parent == null || this.parent.NodeType != ExpressionType.MemberAccess) { string expressionText = (this.parent != null) ? this.parent.ToString() : ire.ToString(); throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqCantTranslateExpression, expressionText)); } return(ire); }
internal void OverrideInputReference(ResourceSetExpression newInput) { Debug.Assert(newInput != null, "Original resource set cannot be null"); Debug.Assert(this.inputRef == null, "OverrideInputReference cannot be called if the target has already been referenced"); InputReferenceExpression inputRef = newInput.inputRef; if (inputRef != null) { this.inputRef = inputRef; inputRef.OverrideTarget(this); } }
internal override Expression VisitMemberAccess(MemberExpression m) { if (this.inputSet == null || !this.inputSet.HasTransparentScope) { return(base.VisitMemberAccess(m)); } ParameterExpression innerParamRef = null; Stack <PropertyInfo> nestedAccesses = new Stack <PropertyInfo>(); MemberExpression memberRef = m; while (memberRef != null && memberRef.Member.MemberType == MemberTypes.Property && memberRef.Expression != null) { nestedAccesses.Push((PropertyInfo)memberRef.Member); if (memberRef.Expression.NodeType == ExpressionType.Parameter) { innerParamRef = (ParameterExpression)memberRef.Expression; } memberRef = memberRef.Expression as MemberExpression; } if (innerParamRef != this.inputParameter || nestedAccesses.Count == 0) { return(m); } ResourceExpression target = this.input; ResourceSetExpression targetSet = this.inputSet; bool transparentScopeTraversed = false; while (nestedAccesses.Count > 0) { if (targetSet == null || !targetSet.HasTransparentScope) { break; } PropertyInfo currentProp = nestedAccesses.Peek(); if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal)) { target = targetSet; nestedAccesses.Pop(); transparentScopeTraversed = true; continue; } Expression source; if (!targetSet.TransparentScope.SourceAccessors.TryGetValue(currentProp.Name, out source)) { break; } transparentScopeTraversed = true; nestedAccesses.Pop(); Debug.Assert(source != null, "source != null -- otherwise ResourceBinder created an accessor to nowhere"); InputReferenceExpression sourceReference = source as InputReferenceExpression; if (sourceReference == null) { targetSet = source as ResourceSetExpression; if (targetSet == null || !targetSet.HasTransparentScope) { target = (ResourceExpression)source; } } else { targetSet = sourceReference.Target as ResourceSetExpression; target = targetSet; } } if (!transparentScopeTraversed) { return(m); } Expression result = this.CreateReference(target); while (nestedAccesses.Count > 0) { result = Expression.Property(result, nestedAccesses.Pop()); } return(result); }