internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers)
        {
            Debug.Assert(le != null, "le != null");

            if (le.Body.NodeType == ExpressionType.Constant)
            {
                if (ClientType.CheckElementTypeIsEntity(le.Body.Type))
                {
                    throw new NotSupportedException(Strings.ALinq_CannotCreateConstantEntity);
                }

                re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List <string>());
                return(true);
            }

            if (le.Body.NodeType == ExpressionType.MemberInit || le.Body.NodeType == ExpressionType.New)
            {
                AnalyzeResourceExpression(le, re);
                return(true);
            }

            if (matchMembers)
            {
                Expression withoutConverts = SkipConverts(le.Body);
                if (withoutConverts.NodeType == ExpressionType.MemberAccess)
                {
                    AnalyzeResourceExpression(le, re);
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
            internal override Expression VisitConstant(ConstantExpression c)
            {
                if (ClientType.CheckElementTypeIsEntity(c.Type))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, c.ToString()));
                }

                return(base.VisitConstant(c));
            }
Пример #3
0
            internal override Expression VisitTypeIs(TypeBinaryExpression b)
            {
                if (ClientType.CheckElementTypeIsEntity(b.Expression.Type) || IsCollectionProducingExpression(b.Expression))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, b.ToString()));
                }

                return(base.VisitTypeIs(b));
            }
Пример #4
0
            internal override Expression VisitInvocation(InvocationExpression iv)
            {
                if (ClientType.CheckElementTypeIsEntity(iv.Expression.Type) || IsCollectionProducingExpression(iv.Expression) ||
                    iv.Arguments.Any(a => ClientType.CheckElementTypeIsEntity(a.Type) || IsCollectionProducingExpression(a)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, iv.ToString()));
                }

                return(base.VisitInvocation(iv));
            }
Пример #5
0
            internal override NewExpression VisitNew(NewExpression nex)
            {
                if (ClientType.CheckElementTypeIsEntity(nex.Type) &&
                    !ResourceBinder.PatternRules.MatchNewDataServiceCollectionOfT(nex))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, nex.ToString()));
                }

                return(base.VisitNew(nex));
            }
Пример #6
0
            internal static void Analyze(MemberInitExpression mie, PathBox pb)
            {
                Debug.Assert(mie != null, "mie != null");

                var epa = new EntityProjectionAnalyzer(pb, mie.Type);

                MemberAssignmentAnalysis targetEntityPath = null;

                foreach (MemberBinding mb in mie.Bindings)
                {
                    MemberAssignment ma = mb as MemberAssignment;
                    epa.Visit(ma.Expression);
                    if (ma != null)
                    {
                        var analysis = MemberAssignmentAnalysis.Analyze(pb.ParamExpressionInScope, ma.Expression);
                        if (analysis.IncompatibleAssignmentsException != null)
                        {
                            throw analysis.IncompatibleAssignmentsException;
                        }

                        Type         targetType      = GetMemberType(ma.Member);
                        Expression[] lastExpressions = analysis.GetExpressionsBeyondTargetEntity();
                        if (lastExpressions.Length == 0)
                        {
                            throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(targetType, ma.Expression));
                        }

                        MemberExpression lastExpression = lastExpressions[lastExpressions.Length - 1] as MemberExpression;
                        Debug.Assert(
                            !analysis.MultiplePathsFound,
                            "!analysis.MultiplePathsFound -- the initilizer has been visited, and cannot be empty, and expressions that can combine paths should have thrown exception during initializer analysis");
                        Debug.Assert(
                            lastExpression != null,
                            "lastExpression != null -- the initilizer has been visited, and cannot be empty, and the only expressions that are allowed can be formed off the parameter, so this is always correlatd");
                        if (lastExpression != null && (lastExpression.Member.Name != ma.Member.Name))
                        {
                            throw new NotSupportedException(Strings.ALinq_PropertyNamesMustMatchInProjections(lastExpression.Member.Name, ma.Member.Name));
                        }

                        analysis.CheckCompatibleAssignments(mie.Type, ref targetEntityPath);

                        bool targetIsEntity = ClientType.CheckElementTypeIsEntity(targetType);
                        bool sourceIsEntity = ClientType.CheckElementTypeIsEntity(lastExpression.Type);
                        if (sourceIsEntity && !targetIsEntity)
                        {
                            throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(targetType, ma.Expression));
                        }
                    }
                }
            }
Пример #7
0
            internal override Expression VisitUnary(UnaryExpression u)
            {
                Debug.Assert(u != null, "u != null");

                if (!ResourceBinder.PatternRules.MatchConvertToAssignable(u))
                {
                    if (ClientType.CheckElementTypeIsEntity(u.Operand.Type))
                    {
                        throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, u.ToString()));
                    }
                }

                return(base.VisitUnary(u));
            }
Пример #8
0
        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);
        }
Пример #9
0
        private static void Analyze(MemberInitExpression mie, PathBox pb)
        {
            Debug.Assert(mie != null, "mie != null");
            Debug.Assert(pb != null, "pb != null");

            bool knownEntityType = ClientType.CheckElementTypeIsEntity(mie.Type);

            if (knownEntityType)
            {
                EntityProjectionAnalyzer.Analyze(mie, pb);
            }
            else
            {
                NonEntityProjectionAnalyzer.Analyze(mie, pb);
            }
        }
Пример #10
0
        internal override Expression VisitLambda(LambdaExpression lambda)
        {
            Debug.Assert(lambda != null, "lambda != null");

            Expression result;

            if (!this.topLevelProjectionFound || lambda.Parameters.Count == 1 && ClientType.CheckElementTypeIsEntity(lambda.Parameters[0].Type))
            {
                this.topLevelProjectionFound = true;

                ParameterExpression expectedTypeParameter = Expression.Parameter(typeof(Type), "type" + this.identifierId);
                ParameterExpression entryParameter        = Expression.Parameter(typeof(object), "entry" + this.identifierId);
                this.identifierId++;

                this.pathBuilder.EnterLambdaScope(lambda, entryParameter, expectedTypeParameter);
                ProjectionPath        parameterPath    = new ProjectionPath(lambda.Parameters[0], expectedTypeParameter, entryParameter);
                ProjectionPathSegment parameterSegment = new ProjectionPathSegment(parameterPath, null, null);
                parameterPath.Add(parameterSegment);
                this.annotations[lambda.Parameters[0]] = new ExpressionAnnotation()
                {
                    Segment = parameterSegment
                };

                Expression body = this.Visit(lambda.Body);

                if (body.Type.IsValueType)
                {
                    body = Expression.Convert(body, typeof(object));
                }

                result = Expression.Lambda <Func <object, object, Type, object> >(
                    body,
                    this.materializerExpression,
                    entryParameter,
                    expectedTypeParameter);

                this.pathBuilder.LeaveLambdaScope();
            }
            else
            {
                result = base.VisitLambda(lambda);
            }

            return(result);
        }
Пример #11
0
        internal static LambdaExpression TryToRewrite(LambdaExpression le, Type proposedParameterType)
        {
            LambdaExpression result;

            if (!ResourceBinder.PatternRules.MatchSingleArgumentLambda(le, out le) ||
                ClientType.CheckElementTypeIsEntity(le.Parameters[0].Type) ||
                !(le.Parameters[0].Type.GetProperties().Any(p => p.PropertyType == proposedParameterType)))
            {
                result = le;
            }
            else
            {
                ProjectionRewriter rewriter = new ProjectionRewriter(proposedParameterType);
                result = rewriter.Rebind(le);
            }

            return(result);
        }
Пример #12
0
        internal static LambdaExpression TryToRewrite(LambdaExpression le, Type proposedParameterType)
        {
            LambdaExpression result;

            if (!ResourceBinder.PatternRules.MatchSingleArgumentLambda(le, out le) ||                       // can only rewrite single parameter Lambdas.
                ClientType.CheckElementTypeIsEntity(le.Parameters[0].Type) ||                               // only attempt to rewrite if lambda parameter is not an entity type
                !(le.Parameters[0].Type.GetProperties().Any(p => p.PropertyType == proposedParameterType))) // lambda parameter must have public property that is same as proposed type.
            {
                result = le;
            }
            else
            {
                ProjectionRewriter rewriter = new ProjectionRewriter(proposedParameterType);
                result = rewriter.Rebind(le);
            }

            return(result);
        }
Пример #13
0
            internal override Expression VisitConditional(ConditionalExpression c)
            {
                var nullCheck = ResourceBinder.PatternRules.MatchNullCheck(this.box.ParamExpressionInScope, c);

                if (nullCheck.Match)
                {
                    this.Visit(nullCheck.AssignExpression);
                    return(c);
                }

                if (ClientType.CheckElementTypeIsEntity(c.Test.Type) || ClientType.CheckElementTypeIsEntity(c.IfTrue.Type) || ClientType.CheckElementTypeIsEntity(c.IfFalse.Type) ||
                    IsCollectionProducingExpression(c.Test) || IsCollectionProducingExpression(c.IfTrue) || IsCollectionProducingExpression(c.IfFalse))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, c.ToString()));
                }

                return(base.VisitConditional(c));
            }
Пример #14
0
        internal override Expression VisitConditional(ConditionalExpression conditional)
        {
            Debug.Assert(conditional != null, "conditional != null");
            Expression original = this.GetExpressionBeforeNormalization(conditional);

            if (original != conditional)
            {
                return(this.Visit(original));
            }

            var nullCheck = ResourceBinder.PatternRules.MatchNullCheck(this.pathBuilder.LambdaParameterInScope, conditional);

            if (!nullCheck.Match || !ClientType.CheckElementTypeIsEntity(nullCheck.AssignExpression.Type))
            {
                return(base.VisitConditional(conditional));
            }

            return(this.RebindConditionalNullCheck(conditional, nullCheck));
        }
Пример #15
0
        internal override Expression VisitUnary(UnaryExpression u)
        {
            UnaryExpression visited = (UnaryExpression)base.VisitUnary(u);
            Expression      result  = visited;

            this.RecordRewrite(u, result);

            if ((visited.NodeType == ExpressionType.Convert || visited.NodeType == ExpressionType.TypeAs) && visited.Type.IsAssignableFrom(visited.Operand.Type))
            {
                if (!ClientConvert.IsKnownNullableType(visited.Operand.Type) && !ClientConvert.IsKnownNullableType(visited.Type) || visited.Operand.Type == visited.Type)
                {
                    if (!(ClientType.CheckElementTypeIsEntity(visited.Operand.Type) && ProjectionAnalyzer.IsCollectionProducingExpression(visited.Operand)))
                    {
                        result = visited.Operand;
                    }
                }
            }

            return(result);
        }
Пример #16
0
            internal override NewExpression VisitNew(NewExpression nex)
            {
                if (ResourceBinder.PatternRules.MatchNewDataServiceCollectionOfT(nex))
                {
                    if (ClientType.CheckElementTypeIsEntity(nex.Type))
                    {
                        foreach (Expression e in nex.Arguments)
                        {
                            if (e.NodeType != ExpressionType.Constant)
                            {
                                base.Visit(e);
                            }
                        }

                        return(nex);
                    }
                }

                throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, nex.ToString()));
            }
Пример #17
0
            internal override Expression VisitMemberAccess(MemberExpression m)
            {
                Debug.Assert(m != null, "m != null");

                if (!ClientType.CheckElementTypeIsEntity(m.Expression.Type) || IsCollectionProducingExpression(m.Expression))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, m.ToString()));
                }

                PropertyInfo pi = null;

                if (ResourceBinder.PatternRules.MatchNonPrivateReadableProperty(m, out pi))
                {
                    Expression e = base.VisitMemberAccess(m);
                    box.AppendToPath(pi);
                    return(e);
                }

                throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, m.ToString()));
            }
Пример #18
0
            internal override Expression VisitMethodCall(MethodCallExpression m)
            {
                if ((m.Object != null && IsDisallowedExpressionForMethodCall(m.Object)) ||
                    m.Arguments.Any(a => IsDisallowedExpressionForMethodCall(a)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }

                if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m))
                {
                    CheckChainedSequence(m, this.type);

                    return(base.VisitMethodCall(m));
                }

                if ((m.Object != null ? ClientType.CheckElementTypeIsEntity(m.Object.Type) : false) ||
                    m.Arguments.Any(a => ClientType.CheckElementTypeIsEntity(a.Type)))
                {
                    throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, m.ToString()));
                }

                return(base.VisitMethodCall(m));
            }
Пример #19
0
        internal void AppendToPath(PropertyInfo pi)
        {
            Debug.Assert(pi != null, "pi != null");

            StringBuilder sb;
            Type          t = TypeSystem.GetElementType(pi.PropertyType);

            if (ClientType.CheckElementTypeIsEntity(t))
            {
                // an entity, so need to append to expand path also
                sb = expandPaths.Last();
                Debug.Assert(sb != null);  // there should always be an expand path because must call StartNewPath first.
                if (sb.Length > 0)
                {
                    sb.Append(UriHelper.FORWARDSLASH);
                }

                sb.Append(pi.Name);
            }

            sb = projectionPaths.Last();
            Debug.Assert(sb != null, "sb != null -- we are always building paths in the context of a parameter");

            RemoveEntireEntityMarkerIfPresent(sb);

            if (sb.Length > 0)
            {
                sb.Append(UriHelper.FORWARDSLASH);
            }

            sb.Append(pi.Name);

            if (ClientType.CheckElementTypeIsEntity(t))
            {
                AddEntireEntityMarker(sb);
            }
        }
        internal void AppendToPath(PropertyInfo pi)
        {
            Debug.Assert(pi != null, "pi != null");

            StringBuilder sb;
            Type          t = TypeSystem.GetElementType(pi.PropertyType);

            if (ClientType.CheckElementTypeIsEntity(t))
            {
                sb = expandPaths.Last();
                Debug.Assert(sb != null);
                if (sb.Length > 0)
                {
                    sb.Append(UriHelper.FORWARDSLASH);
                }

                sb.Append(pi.Name);
            }

            sb = projectionPaths.Last();
            Debug.Assert(sb != null, "sb != null -- we are always building paths in the context of a parameter");

            RemoveEntireEntityMarkerIfPresent(sb);

            if (sb.Length > 0)
            {
                sb.Append(UriHelper.FORWARDSLASH);
            }

            sb.Append(pi.Name);

            if (ClientType.CheckElementTypeIsEntity(t))
            {
                AddEntireEntityMarker(sb);
            }
        }
Пример #21
0
        private Expression RebindEntityMemberInit(MemberInitExpression init)
        {
            Debug.Assert(init != null, "init != null");
            Debug.Assert(init.Bindings.Count > 0, "init.Bindings.Count > 0 -- otherwise this is just empty construction");

            Expression[] expressions;
            if (!this.pathBuilder.HasRewrites)
            {
                MemberAssignmentAnalysis propertyAnalysis = MemberAssignmentAnalysis.Analyze(
                    this.pathBuilder.LambdaParameterInScope,
                    ((MemberAssignment)init.Bindings[0]).Expression);
                expressions = propertyAnalysis.GetExpressionsToTargetEntity();
                Debug.Assert(expressions.Length != 0, "expressions.Length != 0 -- otherwise there is no correlation to parameter in entity member init");
            }
            else
            {
                expressions = MemberAssignmentAnalysis.EmptyExpressionArray;
            }

            Expression    entryParameterAtMemberInit = this.pathBuilder.ParameterEntryInScope;
            List <string> propertyNames = new List <string>();
            List <Func <object, object, Type, object> > propertyFunctions = new List <Func <object, object, Type, object> >();
            Type       projectedType           = init.NewExpression.Type;
            Expression projectedTypeExpression = Expression.Constant(projectedType, typeof(Type));

            Expression entryToInitValue;            Expression expectedParamValue;            ParameterExpression entryParameterForMembers;            ParameterExpression expectedParameterForMembers;            string[] expressionNames = expressions.Skip(1).Select(e => ((MemberExpression)e).Member.Name).ToArray();

            if (expressions.Length <= 1)
            {
                entryToInitValue            = this.pathBuilder.ParameterEntryInScope;
                expectedParamValue          = this.pathBuilder.ExpectedParamTypeInScope;
                entryParameterForMembers    = (ParameterExpression)this.pathBuilder.ParameterEntryInScope;
                expectedParameterForMembers = (ParameterExpression)this.pathBuilder.ExpectedParamTypeInScope;
            }
            else
            {
                entryToInitValue            = this.GetDeepestEntry(expressions);
                expectedParamValue          = projectedTypeExpression;
                entryParameterForMembers    = Expression.Parameter(typeof(object), "subentry" + this.identifierId++);
                expectedParameterForMembers = (ParameterExpression)this.pathBuilder.ExpectedParamTypeInScope;

                ProjectionPath entryPath = new ProjectionPath(
                    (ParameterExpression)this.pathBuilder.LambdaParameterInScope,
                    this.pathBuilder.ExpectedParamTypeInScope,
                    this.pathBuilder.ParameterEntryInScope,
                    expressions.Skip(1));

                this.annotations.Add(entryToInitValue, new ExpressionAnnotation()
                {
                    Segment = entryPath[entryPath.Count - 1]
                });
                this.annotations.Add(entryParameterForMembers, new ExpressionAnnotation()
                {
                    Segment = entryPath[entryPath.Count - 1]
                });
                this.pathBuilder.RegisterRewrite(this.pathBuilder.LambdaParameterInScope, expressionNames, entryParameterForMembers);
            }

            for (int i = 0; i < init.Bindings.Count; i++)
            {
                MemberAssignment assignment = (MemberAssignment)init.Bindings[i];
                propertyNames.Add(assignment.Member.Name);

                LambdaExpression propertyLambda;

                if ((ClientType.CheckElementTypeIsEntity(assignment.Member.ReflectedType) &&
                     assignment.Expression.NodeType == ExpressionType.MemberInit))
                {
                    Expression nestedEntry = CallMaterializer(
                        "ProjectionGetEntry",
                        entryParameterAtMemberInit,
                        Expression.Constant(assignment.Member.Name, typeof(string)));
                    ParameterExpression nestedEntryParameter = Expression.Parameter(
                        typeof(object),
                        "subentry" + this.identifierId++);

                    ProjectionPath       entryPath;
                    ExpressionAnnotation entryAnnotation;
                    if (this.annotations.TryGetValue(this.pathBuilder.ParameterEntryInScope, out entryAnnotation))
                    {
                        entryPath = new ProjectionPath(
                            (ParameterExpression)this.pathBuilder.LambdaParameterInScope,
                            this.pathBuilder.ExpectedParamTypeInScope,
                            entryParameterAtMemberInit);
                        entryPath.AddRange(entryAnnotation.Segment.StartPath);
                    }
                    else
                    {
                        entryPath = new ProjectionPath(
                            (ParameterExpression)this.pathBuilder.LambdaParameterInScope,
                            this.pathBuilder.ExpectedParamTypeInScope,
                            entryParameterAtMemberInit,
                            expressions.Skip(1));
                    }

                    ProjectionPathSegment nestedSegment = new ProjectionPathSegment(
                        entryPath,
                        assignment.Member.Name,
                        assignment.Member.ReflectedType);

                    entryPath.Add(nestedSegment);

                    string[] names = (entryPath.Where(m => m.Member != null).Select(m => m.Member)).ToArray();

                    this.annotations.Add(nestedEntryParameter, new ExpressionAnnotation()
                    {
                        Segment = nestedSegment
                    });
                    this.pathBuilder.RegisterRewrite(this.pathBuilder.LambdaParameterInScope, names, nestedEntryParameter);
                    Expression e = this.Visit(assignment.Expression);
                    this.pathBuilder.RevokeRewrite(this.pathBuilder.LambdaParameterInScope, names);
                    this.annotations.Remove(nestedEntryParameter);

                    e = Expression.Convert(e, typeof(object));
                    ParameterExpression[] parameters =
                        new ParameterExpression[]
                    {
                        this.materializerExpression,
                        nestedEntryParameter,
                        expectedParameterForMembers,
                    };
                    propertyLambda = Expression.Lambda(e, parameters);

                    Expression[] nestedParams =
                        new Expression[]
                    {
                        this.materializerExpression,
                        nestedEntry,
                        expectedParameterForMembers,
                    };
                    var invokeParameters =
                        new ParameterExpression[]
                    {
                        this.materializerExpression,
                        (ParameterExpression)entryParameterAtMemberInit,
                        expectedParameterForMembers,
                    };
                    propertyLambda = Expression.Lambda(Expression.Invoke(propertyLambda, nestedParams), invokeParameters);
                }
                else
                {
                    Expression e = this.Visit(assignment.Expression);
                    e = Expression.Convert(e, typeof(object));
                    ParameterExpression[] parameters =
                        new ParameterExpression[]
                    {
                        this.materializerExpression,
                        entryParameterForMembers,
                        expectedParameterForMembers,
                    };
                    propertyLambda = Expression.Lambda(e, parameters);
                }

#if TRACE_CLIENT_PROJECTIONS
                Trace.WriteLine("Compiling lambda for " + assignment.Member.Name + ": " + propertyLambda);
#endif
                propertyFunctions.Add((Func <object, object, Type, object>)propertyLambda.Compile());
            }

            for (int i = 1; i < expressions.Length; i++)
            {
                this.pathBuilder.RevokeRewrite(this.pathBuilder.LambdaParameterInScope, expressionNames);
                this.annotations.Remove(entryToInitValue);
                this.annotations.Remove(entryParameterForMembers);
            }

            Expression reboundExpression = CallMaterializer(
                "ProjectionInitializeEntity",
                this.materializerExpression,
                entryToInitValue,
                expectedParamValue,
                projectedTypeExpression,
                Expression.Constant(propertyNames.ToArray()),
                Expression.Constant(propertyFunctions.ToArray()));

            return(Expression.Convert(reboundExpression, projectedType));
        }
Пример #22
0
        internal void EnterMemberInit(MemberInitExpression init)
        {
            bool isEntityType = ClientType.CheckElementTypeIsEntity(init.Type);

            this.entityInScope.Push(isEntityType);
        }
Пример #23
0
            /// <summary>Analyzes the specified member-init expression.</summary>
            /// <param name="mie">Expression to analyze.</param>
            /// <param name="pb">Path-tracking object to store analysis in.</param>
            internal static void Analyze(MemberInitExpression mie, PathBox pb)
            {
                Debug.Assert(mie != null, "mie != null");

                var epa = new EntityProjectionAnalyzer(pb, mie.Type);

                MemberAssignmentAnalysis targetEntityPath = null;

                foreach (MemberBinding mb in mie.Bindings)
                {
                    MemberAssignment ma = mb as MemberAssignment;
                    epa.Visit(ma.Expression);
                    if (ma != null)
                    {
                        var analysis = MemberAssignmentAnalysis.Analyze(pb.ParamExpressionInScope, ma.Expression);
                        if (analysis.IncompatibleAssignmentsException != null)
                        {
                            throw analysis.IncompatibleAssignmentsException;
                        }

                        // Note that an "empty" assignment on the binding is not checked/handled,
                        // because the funcletizer would have turned that into a constant
                        // in the tree, the visit earlier in this method would have thrown
                        // an exception at finding a constant in an entity projection.
                        //
                        // We do account however for failing to find a reference off the
                        // parameter entry to detect errors like this: new ET() { Ref = e }
                        // Here it looks like the new ET should be the parent of 'e', but
                        // there is nothing in scope that represents that.
                        //
                        // This also explains while error messages might be a bit misleading
                        // in this case (because they reference a constant when the user
                        // hasn't included any).
                        Type         targetType      = GetMemberType(ma.Member);
                        Expression[] lastExpressions = analysis.GetExpressionsBeyondTargetEntity();
                        if (lastExpressions.Length == 0)
                        {
                            throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(targetType, ma.Expression));
                        }

                        MemberExpression lastExpression = lastExpressions[lastExpressions.Length - 1] as MemberExpression;
                        Debug.Assert(
                            !analysis.MultiplePathsFound,
                            "!analysis.MultiplePathsFound -- the initilizer has been visited, and cannot be empty, and expressions that can combine paths should have thrown exception during initializer analysis");
                        Debug.Assert(
                            lastExpression != null,
                            "lastExpression != null -- the initilizer has been visited, and cannot be empty, and the only expressions that are allowed can be formed off the parameter, so this is always correlatd");
                        if (lastExpression != null && (lastExpression.Member.Name != ma.Member.Name))
                        {
                            throw new NotSupportedException(Strings.ALinq_PropertyNamesMustMatchInProjections(lastExpression.Member.Name, ma.Member.Name));
                        }

                        analysis.CheckCompatibleAssignments(mie.Type, ref targetEntityPath);

                        // Unless we're initializing an entity, we should not traverse into the parameter in scope.
                        bool targetIsEntity = ClientType.CheckElementTypeIsEntity(targetType);
                        bool sourceIsEntity = ClientType.CheckElementTypeIsEntity(lastExpression.Type);
                        if (sourceIsEntity && !targetIsEntity)
                        {
                            throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(targetType, ma.Expression));
                        }
                    }
                }
            }