/// <summary>
        /// Creates a SemanticModel for an ArrowExpressionClause, which includes
        /// an ExecutableCodeBinder and a ScopedExpressionBinder.
        /// </summary>
        internal static MethodBodySemanticModel Create(CSharpCompilation compilation, MethodSymbol owner, Binder rootBinder, ArrowExpressionClauseSyntax syntax)
        {
            Binder binder = new ExecutableCodeBinder(syntax, owner, rootBinder);

            binder = new ScopedExpressionBinder(binder, syntax.Expression);
            return(new MethodBodySemanticModel(compilation, owner, binder, syntax));
        }
예제 #2
0
 public QueryUnboundLambdaState(UnboundLambda unbound, Binder binder, RangeVariableMap rangeVariableMap, ImmutableArray <RangeVariableSymbol> parameters, ExpressionSyntax body)
     : this(unbound, binder, rangeVariableMap, parameters, (LambdaSymbol lambdaSymbol, ref Binder lambdaBodyBinder, DiagnosticBag diagnostics) =>
 {
     lambdaBodyBinder = new ScopedExpressionBinder(lambdaBodyBinder, body);
     return(lambdaBodyBinder.BindLambdaExpressionAsBlock(body, diagnostics));
 })
 { }
 public QueryUnboundLambdaState(UnboundLambda unbound, Binder binder, RangeVariableMap rangeVariableMap, ImmutableArray<RangeVariableSymbol> parameters, ExpressionSyntax body)
     : this(unbound, binder, rangeVariableMap, parameters, (LambdaSymbol lambdaSymbol, ref Binder lambdaBodyBinder, DiagnosticBag diagnostics) =>
 {
     lambdaBodyBinder = new ScopedExpressionBinder(lambdaBodyBinder, body);
     return lambdaBodyBinder.BindLambdaExpressionAsBlock(body, diagnostics);
 })
 { }
예제 #4
0
 public QueryUnboundLambdaState(UnboundLambda unbound, Binder binder, RangeVariableMap rangeVariableMap, ImmutableArray <RangeVariableSymbol> parameters, ExpressionSyntax body, TypeSyntax castTypeSyntax, TypeSymbol castType)
     : this(unbound, binder, rangeVariableMap, parameters, (LambdaSymbol lambdaSymbol, ref Binder lambdaBodyBinder, DiagnosticBag diagnostics) =>
 {
     lambdaBodyBinder = new ScopedExpressionBinder(lambdaBodyBinder, body);
     BoundExpression expression = lambdaBodyBinder.BindValue(body, diagnostics, BindValueKind.RValue);
     Debug.Assert((object)castType != null);
     Debug.Assert(castTypeSyntax != null);
     // We transform the expression from "expr" to "expr.Cast<castTypeOpt>()".
     expression = lambdaBodyBinder.MakeQueryInvocation(body, expression, "Cast", castTypeSyntax, castType, diagnostics);
     return(lambdaBodyBinder.CreateBlockFromExpression(lambdaBodyBinder.Locals, expression, body, diagnostics));
 })
 { }
 public QueryUnboundLambdaState(UnboundLambda unbound, Binder binder, RangeVariableMap rangeVariableMap, ImmutableArray<RangeVariableSymbol> parameters, ExpressionSyntax body, TypeSyntax castTypeSyntax, TypeSymbol castType)
     : this(unbound, binder, rangeVariableMap, parameters, (LambdaSymbol lambdaSymbol, ref Binder lambdaBodyBinder, DiagnosticBag diagnostics) =>
 {
     lambdaBodyBinder = new ScopedExpressionBinder(lambdaBodyBinder, body);
     BoundExpression expression = lambdaBodyBinder.BindValue(body, diagnostics, BindValueKind.RValue);
     Debug.Assert((object)castType != null);
     Debug.Assert(castTypeSyntax != null);
     // We transform the expression from "expr" to "expr.Cast<castTypeOpt>()".
     expression = lambdaBodyBinder.MakeQueryInvocation(body, expression, "Cast", castTypeSyntax, castType, diagnostics);
     return lambdaBodyBinder.CreateBlockFromExpression(lambdaBodyBinder.Locals, expression, body, diagnostics);
 })
 { }
예제 #6
0
 protected override BoundBlock BindLambdaBody(LambdaSymbol lambdaSymbol, ref Binder lambdaBodyBinder, DiagnosticBag diagnostics)
 {
     if (this.IsExpressionLambda)
     {
         var body = (ExpressionSyntax)this.Body;
         lambdaBodyBinder = new ScopedExpressionBinder(lambdaBodyBinder, body);
         return(lambdaBodyBinder.BindLambdaExpressionAsBlock(body, diagnostics));
     }
     else
     {
         return(lambdaBodyBinder.BindBlock((BlockSyntax)this.Body, diagnostics));
     }
 }
예제 #7
0
        void ReduceLet(LetClauseSyntax let, QueryTranslationState state, DiagnosticBag diagnostics)
        {
            // A query expression with a let clause
            //     from x in e
            //     let y = f
            //     ...
            // is translated into
            //     from * in ( e ) . Select ( x => new { x , y = f } )
            //     ...
            var x = state.rangeVariable;

            // We use a slightly different translation strategy.  We produce
            //     from * in ( e ) . Select ( x => new Pair<X,Y>(x, f) )
            // Where X is the type of x, and Y is the type of the expression f.
            // Subsequently, x (or members of x, if it is a transparent identifier)
            // are accessed as TRID.Item1 (or members of that), and y is accessed
            // as TRID.Item2, where TRID is the compiler-generated identifier used
            // to represent the transparent identifier in the result.
            LambdaBodyResolver resolver = (LambdaSymbol lambdaSymbol, ref Binder lambdaBodyBinder, DiagnosticBag d) =>
            {
                var xExpression = new BoundParameter(let, lambdaSymbol.Parameters[0])
                {
                    WasCompilerGenerated = true
                };

                lambdaBodyBinder = new ScopedExpressionBinder(lambdaBodyBinder, let.Expression);
                var            yExpression   = lambdaBodyBinder.BindValue(let.Expression, d, BindValueKind.RValue);
                SourceLocation errorLocation = new SourceLocation(let.SyntaxTree, new TextSpan(let.Identifier.SpanStart, let.Expression.Span.End - let.Identifier.SpanStart));
                if (!yExpression.HasAnyErrors && !yExpression.HasExpressionType())
                {
                    MessageID id = MessageID.IDS_NULL;
                    if (yExpression.Kind == BoundKind.UnboundLambda)
                    {
                        id = ((UnboundLambda)yExpression).MessageID;
                    }
                    else if (yExpression.Kind == BoundKind.MethodGroup)
                    {
                        id = MessageID.IDS_MethodGroup;
                    }
                    else
                    {
                        Debug.Assert(yExpression.IsLiteralNull(), "How did we successfully bind an expression without a type?");
                    }

                    Error(d, ErrorCode.ERR_QueryRangeVariableAssignedBadValue, errorLocation, id.Localize());
                    yExpression = new BoundBadExpression(yExpression.Syntax, LookupResultKind.Empty, ImmutableArray <Symbol> .Empty, ImmutableArray.Create <BoundNode>(yExpression), CreateErrorType());
                }
                else if (!yExpression.HasAnyErrors && yExpression.Type.SpecialType == SpecialType.System_Void)
                {
                    Error(d, ErrorCode.ERR_QueryRangeVariableAssignedBadValue, errorLocation, yExpression.Type);
                    yExpression = new BoundBadExpression(yExpression.Syntax, LookupResultKind.Empty, ImmutableArray <Symbol> .Empty, ImmutableArray.Create <BoundNode>(yExpression), yExpression.Type);
                }

                var construction = MakePair(let, x.Name, xExpression, let.Identifier.ValueText, yExpression, state, d);
                return(lambdaBodyBinder.CreateBlockFromExpression(lambdaBodyBinder.Locals, construction, let, d));
            };
            var lambda = MakeQueryUnboundLambda(state.RangeVariableMap(), x, let.Expression, resolver);

            state.rangeVariable = state.TransparentRangeVariable(this);
            state.AddTransparentIdentifier(x.Name);
            var y = state.AddRangeVariable(this, let.Identifier, diagnostics);

            state.allRangeVariables[y].Add(let.Identifier.ValueText);
            var invocation = MakeQueryInvocation(let, state.fromExpression, "Select", lambda, diagnostics);

            state.fromExpression = MakeQueryClause(let, invocation, y, invocation);
        }
 protected override BoundBlock BindLambdaBody(LambdaSymbol lambdaSymbol, ref Binder lambdaBodyBinder, DiagnosticBag diagnostics)
 {
     if (this.IsExpressionLambda)
     {
         var body = (ExpressionSyntax)this.Body;
         lambdaBodyBinder = new ScopedExpressionBinder(lambdaBodyBinder, body);
         return lambdaBodyBinder.BindLambdaExpressionAsBlock(body, diagnostics);
     }
     else
     {
         return lambdaBodyBinder.BindBlock((BlockSyntax)this.Body, diagnostics);
     }
 }
 /// <summary>
 /// Creates a SemanticModel for an ArrowExpressionClause, which includes
 /// an ExecutableCodeBinder and a ScopedExpressionBinder.
 /// </summary>
 internal static MethodBodySemanticModel Create(CSharpCompilation compilation, MethodSymbol owner, Binder rootBinder, ArrowExpressionClauseSyntax syntax)
 {
     Binder binder = new ExecutableCodeBinder(syntax, owner, rootBinder);
     binder = new ScopedExpressionBinder(binder, syntax.Expression);
     return new MethodBodySemanticModel(compilation, owner, binder, syntax);
 }
예제 #10
0
        /// <summary>
        /// In regular C#, all field initializers are assignments to fields and the assigned expressions
        /// may not reference instance members.
        /// </summary>
        private static void BindRegularCSharpFieldInitializers(
            CSharpCompilation compilation,
            ImmutableArray <FieldInitializers> initializers,
            ArrayBuilder <BoundInitializer> boundInitializers,
            DiagnosticBag diagnostics,
            bool generateDebugInfo,
            out ConsList <Imports> firstDebugImports)
        {
            firstDebugImports = null;

            foreach (FieldInitializers siblingInitializers in initializers)
            {
                // All sibling initializers share the same parent node and tree so we can reuse the binder
                // factory across siblings.  Unfortunately, we cannot reuse the binder itself, because
                // individual fields might have their own binders (e.g. because of being declared unsafe).
                BinderFactory binderFactory = null;

                var infos = ArrayBuilder <FieldInitializerInfo> .GetInstance(); // Exact size is not known up front.

                foreach (FieldInitializer initializer in siblingInitializers.Initializers)
                {
                    FieldSymbol fieldSymbol = initializer.Field;
                    Debug.Assert((object)fieldSymbol != null);

                    // A constant field of type decimal needs a field initializer, so
                    // check if it is a metadata constant, not just a constant to exclude
                    // decimals. Other constants do not need field initializers.
                    if (!fieldSymbol.IsMetadataConstant)
                    {
                        //Can't assert that this is a regular C# compilation, because we could be in a nested type of a script class.
                        SyntaxReference syntaxRef       = initializer.Syntax;
                        var             initializerNode = (EqualsValueClauseSyntax)syntaxRef.GetSyntax();

                        if (binderFactory == null)
                        {
                            binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree);
                        }

                        Binder parentBinder = binderFactory.GetBinder(initializerNode);
                        Debug.Assert(parentBinder.ContainingMemberOrLambda == fieldSymbol.ContainingType || //should be the binder for the type
                                     fieldSymbol.ContainingType.IsImplicitClass);                           //however, we also allow fields in namespaces to help support script scenarios

                        if (generateDebugInfo && firstDebugImports == null)
                        {
                            firstDebugImports = parentBinder.ImportsList;
                        }

                        parentBinder = new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(parentBinder.Flags | BinderFlags.FieldInitializer, fieldSymbol);

                        if (!fieldSymbol.IsConst && !fieldSymbol.IsStatic)
                        {
                            parentBinder = parentBinder.WithPrimaryConstructorParametersIfNecessary(fieldSymbol.ContainingType);
                        }

                        infos.Add(new FieldInitializerInfo(initializer, parentBinder, initializerNode));
                    }
                }

                // See if there are locals that we need to bring into the scope.
                var locals = default(ImmutableArray <LocalSymbol>);
                if (siblingInitializers.TypeDeclarationSyntax != null)
                {
                    locals = GetInitializationScopeLocals(infos);
                }

                ArrayBuilder <BoundInitializer> initializersBuilder = locals.IsDefaultOrEmpty ? boundInitializers : ArrayBuilder <BoundInitializer> .GetInstance(infos.Count);

                foreach (var info in infos)
                {
                    Binder binder = info.Binder;
                    ScopedExpressionBinder scopedExpressionBinder = null;

                    // Constant initializers is not part of the initialization scope.
                    if (info.Initializer.Field.IsConst || locals.IsDefault)
                    {
                        binder = scopedExpressionBinder = new ScopedExpressionBinder(binder, info.EqualsValue.Value);
                    }
                    else if (!locals.IsEmpty)
                    {
                        binder = new SimpleLocalScopeBinder(locals, binder);
                    }

                    BoundFieldInitializer boundInitializer = BindFieldInitializer(binder, info.Initializer.Field, info.EqualsValue, diagnostics);

                    if (scopedExpressionBinder != null && !scopedExpressionBinder.Locals.IsDefaultOrEmpty)
                    {
                        boundInitializer = boundInitializer.Update(boundInitializer.Field, scopedExpressionBinder.AddLocalScopeToExpression(boundInitializer.InitialValue));
                    }

                    initializersBuilder.Add(boundInitializer);
                }

                Debug.Assert(locals.IsDefaultOrEmpty == (initializersBuilder == boundInitializers));
                if (!locals.IsDefaultOrEmpty)
                {
                    boundInitializers.Add(new BoundInitializationScope((CSharpSyntaxNode)siblingInitializers.TypeDeclarationSyntax.GetSyntax(),
                                                                       locals, initializersBuilder.ToImmutableAndFree()));
                }
            }
        }