ExpressionLambdaRewriter.cs 49.5 KB
Newer Older
1
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2 3 4 5 6 7 8 9 10 11 12 13

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp
{
    internal class ExpressionLambdaRewriter // this is like a bound tree rewriter, but only handles a small subset of node kinds
    {
14 15 16
        private readonly SyntheticBoundNodeFactory _bound;
        private readonly TypeMap _typeMap;
        private readonly Dictionary<ParameterSymbol, BoundExpression> _parameterMap = new Dictionary<ParameterSymbol, BoundExpression>();
17
        private readonly bool _ignoreAccessibility;
18
        private int _recursionDepth;
P
Pilchie 已提交
19 20 21 22 23 24

        private NamedTypeSymbol _ExpressionType;
        private NamedTypeSymbol ExpressionType
        {
            get
            {
25 26
                if ((object)_ExpressionType == null)
                {
27
                    _ExpressionType = _bound.WellKnownType(WellKnownType.System_Linq_Expressions_Expression);
28
                }
P
Pilchie 已提交
29 30 31 32 33 34 35 36 37
                return _ExpressionType;
            }
        }

        private NamedTypeSymbol _ParameterExpressionType;
        private NamedTypeSymbol ParameterExpressionType
        {
            get
            {
38 39
                if ((object)_ParameterExpressionType == null)
                {
40
                    _ParameterExpressionType = _bound.WellKnownType(WellKnownType.System_Linq_Expressions_ParameterExpression);
41
                }
P
Pilchie 已提交
42 43 44 45 46 47 48 49 50
                return _ParameterExpressionType;
            }
        }

        private NamedTypeSymbol _ElementInitType;
        private NamedTypeSymbol ElementInitType
        {
            get
            {
51 52
                if ((object)_ElementInitType == null)
                {
53
                    _ElementInitType = _bound.WellKnownType(WellKnownType.System_Linq_Expressions_ElementInit);
54
                }
P
Pilchie 已提交
55 56 57 58 59 60 61 62 63 64
                return _ElementInitType;
            }
        }

        private NamedTypeSymbol _MemberBindingType;

        public NamedTypeSymbol MemberBindingType
        {
            get
            {
65 66
                if ((object)_MemberBindingType == null)
                {
67
                    _MemberBindingType = _bound.WellKnownType(WellKnownType.System_Linq_Expressions_MemberBinding);
68
                }
P
Pilchie 已提交
69 70 71 72
                return _MemberBindingType;
            }
        }

73
        private readonly NamedTypeSymbol _int32Type;
P
Pilchie 已提交
74

75
        private readonly NamedTypeSymbol _objectType;
P
Pilchie 已提交
76

77
        private readonly NamedTypeSymbol _nullableType;
P
Pilchie 已提交
78 79 80 81 82 83

        private NamedTypeSymbol _MemberInfoType;
        private NamedTypeSymbol MemberInfoType
        {
            get
            {
84 85
                if ((object)_MemberInfoType == null)
                {
86
                    _MemberInfoType = _bound.WellKnownType(WellKnownType.System_Reflection_MemberInfo);
87
                }
P
Pilchie 已提交
88 89 90 91
                return _MemberInfoType;
            }
        }

92
        private readonly NamedTypeSymbol _IEnumerableType;
P
Pilchie 已提交
93

94
        private DiagnosticBag Diagnostics { get { return _bound.Diagnostics; } }
P
Pilchie 已提交
95

96
        private ExpressionLambdaRewriter(TypeCompilationState compilationState, TypeMap typeMap, CSharpSyntaxNode node, int recursionDepth, DiagnosticBag diagnostics)
P
Pilchie 已提交
97
        {
98
            _bound = new SyntheticBoundNodeFactory(null, compilationState.Type, node, compilationState, diagnostics);
99
            _ignoreAccessibility = compilationState.ModuleBuilderOpt.IgnoreAccessibility;
100 101 102 103
            _int32Type = _bound.SpecialType(SpecialType.System_Int32);
            _objectType = _bound.SpecialType(SpecialType.System_Object);
            _nullableType = _bound.SpecialType(SpecialType.System_Nullable_T);
            _IEnumerableType = _bound.SpecialType(SpecialType.System_Collections_Generic_IEnumerable_T);
104

105
            _typeMap = typeMap;
106
            _recursionDepth = recursionDepth;
P
Pilchie 已提交
107 108
        }

109
        internal static BoundNode RewriteLambda(BoundLambda node, TypeCompilationState compilationState, TypeMap typeMap, int recursionDepth, DiagnosticBag diagnostics)
P
Pilchie 已提交
110 111 112
        {
            try
            {
113
                var r = new ExpressionLambdaRewriter(compilationState, typeMap, node.Syntax, recursionDepth, diagnostics);
P
Pilchie 已提交
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
                var result = r.VisitLambdaInternal(node);
                if (node.Type != result.Type)
                {
                    diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, node.Syntax.Location, r.ExpressionType, "Lambda");
                }
                return result;
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                return node;
            }
        }

        private BoundExpression TranslateLambdaBody(BoundBlock block)
        {
130
            Debug.Assert(block.Locals.IsEmpty);
P
Pilchie 已提交
131 132 133 134 135 136 137 138
            foreach (var s in block.Statements)
            {
                for (var stmt = s; stmt != null;)
                {
                    switch (stmt.Kind)
                    {
                        case BoundKind.ReturnStatement:
                            var result = Visit(((BoundReturnStatement)stmt).ExpressionOpt);
139 140 141 142
                            if (result != null)
                            {
                                return result;
                            }
P
Pilchie 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
                            stmt = null;
                            break;
                        case BoundKind.ExpressionStatement:
                            return Visit(((BoundExpressionStatement)stmt).Expression);
                        case BoundKind.SequencePoint:
                            stmt = ((BoundSequencePoint)stmt).StatementOpt;
                            break;
                        case BoundKind.SequencePointWithSpan:
                            stmt = ((BoundSequencePointWithSpan)stmt).StatementOpt;
                            break;
                        default:
                            throw ExceptionUtilities.UnexpectedValue(stmt.Kind);
                    }
                }
            }

            return null;
        }

        private BoundExpression Visit(BoundExpression node)
        {
164 165 166 167 168
            if (node == null)
            {
                return null;
            }

169 170
            CSharpSyntaxNode old = _bound.Syntax;
            _bound.Syntax = node.Syntax;
P
Pilchie 已提交
171
            var result = VisitInternal(node);
172 173
            _bound.Syntax = old;
            return _bound.Convert(ExpressionType, result);
P
Pilchie 已提交
174 175
        }

176
        private BoundExpression VisitExpressionWithoutStackGuard(BoundExpression node)
P
Pilchie 已提交
177 178 179 180 181 182 183 184 185 186 187 188 189 190
        {
            switch (node.Kind)
            {
                case BoundKind.ArrayAccess:
                    return VisitArrayAccess((BoundArrayAccess)node);
                case BoundKind.ArrayCreation:
                    return VisitArrayCreation((BoundArrayCreation)node);
                case BoundKind.ArrayLength:
                    return VisitArrayLength((BoundArrayLength)node);
                case BoundKind.AsOperator:
                    return VisitAsOperator((BoundAsOperator)node);
                case BoundKind.BaseReference:
                    return VisitBaseReference((BoundBaseReference)node);
                case BoundKind.BinaryOperator:
191 192 193 194 195
                    var binOp = (BoundBinaryOperator)node;
                    return VisitBinaryOperator(binOp.OperatorKind, binOp.MethodOpt, binOp.Type, binOp.Left, binOp.Right);
                case BoundKind.UserDefinedConditionalLogicalOperator:
                    var userDefCondLogOp = (BoundUserDefinedConditionalLogicalOperator)node;
                    return VisitBinaryOperator(userDefCondLogOp.OperatorKind, userDefCondLogOp.LogicalOperator, userDefCondLogOp.Type, userDefCondLogOp.Left, userDefCondLogOp.Right);
P
Pilchie 已提交
196 197 198 199 200 201 202 203 204
                case BoundKind.Call:
                    return VisitCall((BoundCall)node);
                case BoundKind.ConditionalOperator:
                    return VisitConditionalOperator((BoundConditionalOperator)node);
                case BoundKind.Conversion:
                    return VisitConversion((BoundConversion)node);
                case BoundKind.DelegateCreationExpression:
                    return VisitDelegateCreationExpression((BoundDelegateCreationExpression)node);
                case BoundKind.FieldAccess:
205 206 207 208 209 210
                    var fieldAccess = (BoundFieldAccess)node;
                    if (fieldAccess.FieldSymbol.IsCapturedFrame)
                    {
                        return Constant(fieldAccess);
                    }
                    return VisitFieldAccess(fieldAccess);
P
Pilchie 已提交
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
                case BoundKind.IsOperator:
                    return VisitIsOperator((BoundIsOperator)node);
                case BoundKind.Lambda:
                    return VisitLambda((BoundLambda)node);
                case BoundKind.NewT:
                    return VisitNewT((BoundNewT)node);
                case BoundKind.NullCoalescingOperator:
                    return VisitNullCoalescingOperator((BoundNullCoalescingOperator)node);
                case BoundKind.ObjectCreationExpression:
                    return VisitObjectCreationExpression((BoundObjectCreationExpression)node);
                case BoundKind.Parameter:
                    return VisitParameter((BoundParameter)node);
                case BoundKind.PointerIndirectionOperator:
                    return VisitPointerIndirectionOperator((BoundPointerIndirectionOperator)node);
                case BoundKind.PointerElementAccess:
                    return VisitPointerElementAccess((BoundPointerElementAccess)node);
                case BoundKind.PropertyAccess:
                    return VisitPropertyAccess((BoundPropertyAccess)node);
                case BoundKind.SizeOfOperator:
                    return VisitSizeOfOperator((BoundSizeOfOperator)node);
                case BoundKind.UnaryOperator:
                    return VisitUnaryOperator((BoundUnaryOperator)node);

                case BoundKind.DefaultOperator:
                case BoundKind.HostObjectMemberReference:
                case BoundKind.Literal:
                case BoundKind.Local:
                case BoundKind.MethodInfo:
                case BoundKind.PreviousSubmissionReference:
                case BoundKind.ThisReference:
                case BoundKind.TypeOfOperator:
                    return Constant(node);
                default:
                    throw ExceptionUtilities.UnexpectedValue(node.Kind);
            }
        }

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
        private BoundExpression VisitInternal(BoundExpression node)
        {
            BoundExpression result;
            _recursionDepth++;
#if DEBUG
            int saveRecursionDepth = _recursionDepth;
#endif

            if (_recursionDepth > 1)
            {
                StackGuard.EnsureSufficientExecutionStack(_recursionDepth);

                result = VisitExpressionWithoutStackGuard(node);
            }
            else
            {
                result = VisitExpressionWithStackGuard(node);
            }

#if DEBUG
            Debug.Assert(saveRecursionDepth == _recursionDepth);
#endif
            _recursionDepth--;
            return result;
        }

        private BoundExpression VisitExpressionWithStackGuard(BoundExpression node)
        {
            try
            {
                return VisitExpressionWithoutStackGuard(node);
            }
            catch (Exception ex) when (StackGuard.IsInsufficientExecutionStackException(ex))
            {
                throw new BoundTreeVisitor.CancelledByStackGuardException(ex, node);
            }
        }

P
Pilchie 已提交
286 287 288 289 290 291 292
        private BoundExpression VisitArrayAccess(BoundArrayAccess node)
        {
            var array = Visit(node.Expression);
            if (node.Indices.Length == 1)
            {
                var arg = node.Indices[0];
                var index = Visit(arg);
V
vsadov 已提交
293
                if (index.Type != _int32Type)
294
                {
295
                    index = ConvertIndex(index, arg.Type, _int32Type);
296
                }
P
Pilchie 已提交
297 298 299 300 301 302 303 304
                return ExprFactory("ArrayIndex", array, index);
            }
            else
            {
                return ExprFactory("ArrayIndex", array, Indices(node.Indices));
            }
        }

305
        private BoundExpression Indices(ImmutableArray<BoundExpression> expressions)
P
Pilchie 已提交
306 307 308 309 310
        {
            var builder = ArrayBuilder<BoundExpression>.GetInstance();
            foreach (var arg in expressions)
            {
                var index = Visit(arg);
V
vsadov 已提交
311
                if (index.Type != _int32Type)
312
                {
313
                    index = ConvertIndex(index, arg.Type, _int32Type);
314
                }
P
Pilchie 已提交
315 316 317
                builder.Add(index);
            }

318
            return _bound.ArrayOrEmpty(ExpressionType, builder.ToImmutableAndFree());
P
Pilchie 已提交
319 320
        }

321
        private BoundExpression Expressions(ImmutableArray<BoundExpression> expressions)
P
Pilchie 已提交
322 323 324 325 326 327 328
        {
            var builder = ArrayBuilder<BoundExpression>.GetInstance();
            foreach (var arg in expressions)
            {
                builder.Add(Visit(arg));
            }

329
            return _bound.ArrayOrEmpty(ExpressionType, builder.ToImmutableAndFree());
P
Pilchie 已提交
330 331 332 333 334
        }

        private BoundExpression VisitArrayCreation(BoundArrayCreation node)
        {
            var arrayType = (ArrayTypeSymbol)node.Type;
335
            var boundType = _bound.Typeof(arrayType.ElementType);
P
Pilchie 已提交
336 337
            if (node.InitializerOpt != null)
            {
338
                if (arrayType.IsSZArray)
P
Pilchie 已提交
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
                {
                    return ExprFactory("NewArrayInit", boundType, Expressions(node.InitializerOpt.Initializers));
                }
                else
                {
                    // error should have been reported earlier
                    // Bound.Diagnostics.Add(ErrorCode.ERR_ExpressionTreeContainsMultiDimensionalArrayInitializer, node.Syntax.Location);
                    return new BoundBadExpression(node.Syntax, default(LookupResultKind), ImmutableArray<Symbol>.Empty, ImmutableArray.Create<BoundNode>(node), ExpressionType);
                }
            }
            else
            {
                return ExprFactory("NewArrayBounds", boundType, Expressions(node.Bounds));
            }
        }

        private BoundExpression VisitArrayLength(BoundArrayLength node)
        {
            return ExprFactory("ArrayLength", Visit(node.Expression));
        }

        private BoundExpression VisitAsOperator(BoundAsOperator node)
        {
            if (node.Operand.IsLiteralNull() && (object)node.Operand.Type == null)
            {
364
                var operand = _bound.Null(_bound.SpecialType(SpecialType.System_Object));
P
Pilchie 已提交
365 366 367
                node = node.Update(operand, node.TargetType, node.Conversion, node.Type);
            }

368
            return ExprFactory("TypeAs", Visit(node.Operand), _bound.Typeof(node.Type));
P
Pilchie 已提交
369 370 371 372 373 374 375 376 377
        }

        private BoundExpression VisitBaseReference(BoundBaseReference node)
        {
            // should have been reported earlier.
            // Diagnostics.Add(ErrorCode.ERR_ExpressionTreeContainsBaseAccess, node.Syntax.Location);
            return new BoundBadExpression(node.Syntax, 0, ImmutableArray<Symbol>.Empty, ImmutableArray.Create<BoundNode>(node), ExpressionType);
        }

378
        private string GetBinaryOperatorName(BinaryOperatorKind opKind, out bool isChecked, out bool isLifted, out bool requiresLifted)
P
Pilchie 已提交
379
        {
380 381 382 383 384
            isChecked = opKind.IsChecked();
            isLifted = opKind.IsLifted();
            requiresLifted = opKind.IsComparison();

            switch (opKind.Operator())
P
Pilchie 已提交
385
            {
386 387 388 389 390 391 392 393 394 395
                case BinaryOperatorKind.Addition: return isChecked ? "AddChecked" : "Add";
                case BinaryOperatorKind.Multiplication: return isChecked ? "MultiplyChecked" : "Multiply";
                case BinaryOperatorKind.Subtraction: return isChecked ? "SubtractChecked" : "Subtract";
                case BinaryOperatorKind.Division: return "Divide";
                case BinaryOperatorKind.Remainder: return "Modulo";
                case BinaryOperatorKind.And: return opKind.IsLogical() ? "AndAlso" : "And";
                case BinaryOperatorKind.Xor: return "ExclusiveOr";
                case BinaryOperatorKind.Or: return opKind.IsLogical() ? "OrElse" : "Or";
                case BinaryOperatorKind.LeftShift: return "LeftShift";
                case BinaryOperatorKind.RightShift: return "RightShift";
396 397 398 399 400 401
                case BinaryOperatorKind.Equal: return "Equal";
                case BinaryOperatorKind.NotEqual: return "NotEqual";
                case BinaryOperatorKind.LessThan: return "LessThan";
                case BinaryOperatorKind.LessThanOrEqual: return "LessThanOrEqual";
                case BinaryOperatorKind.GreaterThan: return "GreaterThan";
                case BinaryOperatorKind.GreaterThanOrEqual: return "GreaterThanOrEqual";
P
Pilchie 已提交
402
                default:
403
                    throw ExceptionUtilities.UnexpectedValue(opKind.Operator());
P
Pilchie 已提交
404
            }
405
        }
P
Pilchie 已提交
406

407 408 409 410
        private BoundExpression VisitBinaryOperator(BinaryOperatorKind opKind, MethodSymbol methodOpt, TypeSymbol type, BoundExpression left, BoundExpression right)
        {
            bool isChecked, isLifted, requiresLifted;
            string opName = GetBinaryOperatorName(opKind, out isChecked, out isLifted, out requiresLifted);
P
Pilchie 已提交
411 412

            // Fix up the null value for a nullable comparison vs null
413 414
            if ((object)left.Type == null && left.IsLiteralNull())
            {
415
                left = _bound.Default(right.Type);
416 417 418
            }
            if ((object)right.Type == null && right.IsLiteralNull())
            {
419
                right = _bound.Default(left.Type);
420
            }
P
Pilchie 已提交
421 422 423


            // Enums are handled as per their promoted underlying type
424
            switch (opKind.OperandTypes())
P
Pilchie 已提交
425 426 427
            {
                case BinaryOperatorKind.EnumAndUnderlying:
                case BinaryOperatorKind.UnderlyingAndEnum:
428
                case BinaryOperatorKind.Enum:
P
Pilchie 已提交
429
                    {
430
                        var enumOperand = (opKind.OperandTypes() == BinaryOperatorKind.UnderlyingAndEnum) ? right : left;
P
Pilchie 已提交
431
                        var promotedType = PromotedType(enumOperand.Type.StrippedType().GetEnumUnderlyingType());
432 433
                        if (opKind.IsLifted())
                        {
434
                            promotedType = _nullableType.Construct(promotedType);
435 436
                        }

437 438
                        var loweredLeft = VisitAndPromoteEnumOperand(left, promotedType, isChecked);
                        var loweredRight = VisitAndPromoteEnumOperand(right, promotedType, isChecked);
439 440 441

                        var result = MakeBinary(methodOpt, type, isLifted, requiresLifted, opName, loweredLeft, loweredRight);
                        return Demote(result, type, isChecked);
P
Pilchie 已提交
442 443
                    }
                default:
444 445 446 447 448 449 450 451
                    {
                        var loweredLeft = Visit(left);
                        var loweredRight = Visit(right);
                        return MakeBinary(methodOpt, type, isLifted, requiresLifted, opName, loweredLeft, loweredRight);
                    }
            }
        }

V
vsadov 已提交
452
        private static BoundExpression DemoteEnumOperand(BoundExpression operand)
453
        {
V
vsadov 已提交
454
            if (operand.Kind == BoundKind.Conversion)
455
            {
V
vsadov 已提交
456
                var conversion = (BoundConversion)operand;
457
                if (!conversion.ConversionKind.IsUserDefinedConversion() &&
458 459
                    conversion.ConversionKind.IsImplicitConversion() &&
                    conversion.ConversionKind != ConversionKind.NullLiteral &&
460 461
                    conversion.Type.StrippedType().IsEnumType())
                {
V
vsadov 已提交
462
                    operand = conversion.Operand;
463
                }
P
Pilchie 已提交
464
            }
465

V
vsadov 已提交
466
            return operand;
P
Pilchie 已提交
467 468
        }

469
        private BoundExpression VisitAndPromoteEnumOperand(BoundExpression operand, TypeSymbol promotedType, bool isChecked)
470 471 472 473 474
        {
            var literal = operand as BoundLiteral;
            if (literal != null)
            {
                // for compat reasons enum literals are directly promoted into underlying values
V
vsadov 已提交
475
                return Constant(literal.Update(literal.ConstantValue, promotedType));
476 477 478
            }
            else
            {
479 480 481 482 483
                // COMPAT: if we have an operand converted to enum, we should unconvert it first
                //         Otherwise we will have an extra conversion in the tree: op -> enum -> underlying
                //         where native compiler would just directly convert to underlying
                var demotedOperand = DemoteEnumOperand(operand);
                var loweredOperand = Visit(demotedOperand);
484 485 486 487
                return Convert(loweredOperand, operand.Type, promotedType, isChecked, false);
            }
        }

488
        private BoundExpression MakeBinary(MethodSymbol methodOpt, TypeSymbol type, bool isLifted, bool requiresLifted, string opName, BoundExpression loweredLeft, BoundExpression loweredRight)
P
Pilchie 已提交
489 490
        {
            return
491
                ((object)methodOpt == null) ? ExprFactory(opName, loweredLeft, loweredRight) :
492 493
                    requiresLifted ? ExprFactory(opName, loweredLeft, loweredRight, _bound.Literal(isLifted && methodOpt.ReturnType != type), _bound.MethodInfo(methodOpt)) :
                        ExprFactory(opName, loweredLeft, loweredRight, _bound.MethodInfo(methodOpt));
P
Pilchie 已提交
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
        }

        private TypeSymbol PromotedType(TypeSymbol underlying)
        {
            if (underlying.SpecialType == SpecialType.System_Boolean)
            {
                return underlying;
            }

            var possiblePromote = Binder.GetEnumPromotedType(underlying.SpecialType);

            if (possiblePromote == underlying.SpecialType)
            {
                return underlying;
            }
            else
            {
511
                return _bound.SpecialType(possiblePromote);
P
Pilchie 已提交
512 513 514 515 516 517 518 519 520 521 522 523 524
            }
        }

        private BoundExpression Demote(BoundExpression node, TypeSymbol type, bool isChecked)
        {
            var e = type as NamedTypeSymbol;
            if ((object)e != null)
            {
                if (e.TypeKind == TypeKind.Enum || e.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T && e.TypeArgumentsNoUseSiteDiagnostics[0].TypeKind == TypeKind.Enum)
                {
                    return Convert(node, type, isChecked);
                }

525
                var promotedType = e.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T ? _nullableType.Construct(PromotedType((NamedTypeSymbol)e.TypeArgumentsNoUseSiteDiagnostics[0])) : PromotedType(e);
P
Pilchie 已提交
526 527 528 529 530 531 532 533 534 535 536 537
                if (promotedType != type)
                {
                    return Convert(node, type, isChecked);
                }
            }

            return node;
        }

        private BoundExpression ConvertIndex(BoundExpression expr, TypeSymbol oldType, TypeSymbol newType)
        {
            HashSet<DiagnosticInfo> useSiteDiagnostics = null;
538
            var kind = _bound.Compilation.Conversions.ClassifyConversion(oldType, newType, ref useSiteDiagnostics).Kind;
P
Pilchie 已提交
539 540 541 542 543 544 545 546
            Debug.Assert(useSiteDiagnostics.IsNullOrEmpty());
            switch (kind)
            {
                case ConversionKind.Identity:
                    return expr;
                case ConversionKind.ExplicitNumeric:
                    return Convert(expr, newType, true);
                default:
547
                    return Convert(expr, _int32Type, false);
P
Pilchie 已提交
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
            }
        }

        private BoundExpression VisitCall(BoundCall node)
        {
            if (node.IsDelegateCall)
            {
                // Generate Expression.Invoke(Receiver, arguments)
                return ExprFactory(WellKnownMemberNames.DelegateInvokeName, Visit(node.ReceiverOpt), Expressions(node.Arguments));
            }
            else
            {
                // Generate Expression.Call(Receiver, Method, [typeArguments,] arguments)
                var method = node.Method;
                return ExprFactory(
                    "Call",
564 565
                    method.IsStatic ? _bound.Null(ExpressionType) : Visit(node.ReceiverOpt),
                    _bound.MethodInfo(method),
P
Pilchie 已提交
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
                    Expressions(node.Arguments));
            }
        }

        private BoundExpression VisitConditionalOperator(BoundConditionalOperator node)
        {
            var condition = Visit(node.Condition);
            var consequence = VisitExactType(node.Consequence);
            var alternative = VisitExactType(node.Alternative);
            return ExprFactory("Condition", condition, consequence, alternative);
        }

        /// <summary>
        /// Visit the expression, but do so in a way that ensures that its type is precise.  That means that any
        /// sometimes-unnecessary conversions (such as an implicit reference conversion) are retained.
        /// </summary>
        private BoundExpression VisitExactType(BoundExpression e)
        {
            var conversion = e as BoundConversion;
            if (conversion != null && !conversion.ExplicitCastInCode)
            {
587 588 589 590 591 592 593 594 595 596 597 598
                e = conversion.Update(
                    conversion.Operand,
                    conversion.ConversionKind,
                    conversion.ResultKind,
                    isBaseConversion: conversion.IsBaseConversion,
                    symbolOpt: conversion.SymbolOpt,
                    @checked: conversion.Checked,
                    explicitCastInCode: true,
                    isExtensionMethod: conversion.IsExtensionMethod,
                    isArrayIndex: conversion.IsArrayIndex,
                    constantValueOpt: conversion.ConstantValueOpt,
                    type: conversion.Type);
P
Pilchie 已提交
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
            }

            return Visit(e);
        }

        private BoundExpression VisitConversion(BoundConversion node)
        {
            switch (node.ConversionKind)
            {
                case ConversionKind.MethodGroup:
                    {
                        var mg = (BoundMethodGroup)node.Operand;
                        return DelegateCreation(mg.ReceiverOpt, node.SymbolOpt, node.Type, node.SymbolOpt.IsStatic && !node.IsExtensionMethod);
                    }
                case ConversionKind.ExplicitUserDefined:
                case ConversionKind.ImplicitUserDefined:
                case ConversionKind.IntPtr:
                    {
                        var method = node.SymbolOpt;
                        var operandType = node.Operand.Type;
                        var strippedOperandType = operandType.StrippedType();
                        var conversionInputType = method.Parameters[0].Type;
                        var isLifted = operandType != conversionInputType && strippedOperandType == conversionInputType;
                        bool requireAdditionalCast =
                            strippedOperandType != ((node.ConversionKind == ConversionKind.ExplicitUserDefined) ? conversionInputType : conversionInputType.StrippedType());
624
                        var resultType = (isLifted && method.ReturnType.IsNonNullableValueType() && node.Type.IsNullableType()) ? _nullableType.Construct(method.ReturnType) : method.ReturnType;
P
Pilchie 已提交
625 626 627
                        var e1 = requireAdditionalCast
                            ? Convert(Visit(node.Operand), node.Operand.Type, method.Parameters[0].Type, node.Checked, false)
                            : Visit(node.Operand);
628
                        var e2 = ExprFactory("Convert", e1, _bound.Typeof(resultType), _bound.MethodInfo(method));
P
Pilchie 已提交
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
                        return Convert(e2, resultType, node.Type, node.Checked, false);
                    }
                case ConversionKind.ImplicitReference:
                case ConversionKind.Identity:
                    {
                        var operand = Visit(node.Operand);
                        return node.ExplicitCastInCode ? Convert(operand, node.Type, false) : operand;
                    }
                case ConversionKind.ImplicitNullable:
                    if (node.Operand.Type.IsNullableType())
                    {
                        return Convert(Visit(node.Operand), node.Operand.Type, node.Type, node.Checked, node.ExplicitCastInCode);
                    }
                    else
                    {
                        // the native compiler performs this conversion in two steps, so we follow suit
                        var nullable = (NamedTypeSymbol)node.Type;
                        var intermediate = nullable.TypeArgumentsNoUseSiteDiagnostics[0];
                        var e1 = Convert(Visit(node.Operand), node.Operand.Type, intermediate, node.Checked, false);
                        return Convert(e1, intermediate, node.Type, node.Checked, false);
                    }
                case ConversionKind.NullLiteral:
651
                    return Convert(Constant(_bound.Null(_objectType)), _objectType, node.Type, false, node.ExplicitCastInCode);
P
Pilchie 已提交
652 653 654 655 656 657 658 659 660 661 662 663
                default:
                    return Convert(Visit(node.Operand), node.Operand.Type, node.Type, node.Checked, node.ExplicitCastInCode);
            }
        }

        private BoundExpression Convert(BoundExpression operand, TypeSymbol oldType, TypeSymbol newType, bool isChecked, bool isExplicit)
        {
            return (oldType == newType && !isExplicit) ? operand : Convert(operand, newType, isChecked);
        }

        private BoundExpression Convert(BoundExpression expr, TypeSymbol type, bool isChecked)
        {
664
            return ExprFactory(isChecked ? "ConvertChecked" : "Convert", expr, _bound.Typeof(type));
P
Pilchie 已提交
665 666 667 668
        }

        private BoundExpression DelegateCreation(BoundExpression receiver, MethodSymbol method, TypeSymbol delegateType, bool staticMember)
        {
669 670
            var nullObject = _bound.Null(_objectType);
            receiver = staticMember ? nullObject : receiver.Type.IsReferenceType ? receiver : _bound.Convert(_objectType, receiver);
P
Pilchie 已提交
671

672
            var createDelegate = _bound.WellKnownMethod(WellKnownMember.System_Reflection_MethodInfo__CreateDelegate, isOptional: true);
P
Pilchie 已提交
673 674 675 676
            BoundExpression unquoted;
            if ((object)createDelegate != null)
            {
                // beginning in 4.5, we do it this way
677
                unquoted = _bound.Call(_bound.MethodInfo(method), createDelegate, _bound.Typeof(delegateType), receiver);
P
Pilchie 已提交
678 679 680 681 682 683
            }
            else
            {
                // 4.0 and earlier we do it this way
                //createDelegate = (MethodSymbol)Bound.WellKnownMember(WellKnownMember.System_Delegate__CreateDelegate);
                //operand = Bound.Call(nullObject, createDelegate, Bound.Typeof(node.Type), receiver, Bound.MethodInfo(method));
684
                unquoted = _bound.StaticCall(_bound.SpecialType(SpecialType.System_Delegate), "CreateDelegate", _bound.Typeof(delegateType), receiver, _bound.MethodInfo(method));
P
Pilchie 已提交
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
            }

            // NOTE: we visit the just-built node, which has not yet been visited.  This is not the usual order
            // of operations.  The above code represents Dev10's pre-expression-tree lowering, and producing
            // the expanded lowering by hand is very cumbersome.
            return Convert(Visit(unquoted), delegateType, false);
        }

        private BoundExpression VisitDelegateCreationExpression(BoundDelegateCreationExpression node)
        {
            var mg = node.Argument as BoundMethodGroup;
            if (mg != null)
            {
                return DelegateCreation(mg.ReceiverOpt, node.MethodOpt, node.Type, node.MethodOpt.IsStatic && !mg.SearchExtensionMethods);
            }

            var d = node.Argument.Type as NamedTypeSymbol;
            if ((object)d != null && d.TypeKind == TypeKind.Delegate)
            {
                return DelegateCreation(node.Argument, d.DelegateInvokeMethod, node.Type, false);
            }

            // there should be no other cases.  Have we missed one?
            throw ExceptionUtilities.UnexpectedValue(node.Argument);
        }

        private BoundExpression VisitFieldAccess(BoundFieldAccess node)
        {
713
            var receiver = node.FieldSymbol.IsStatic ? _bound.Null(ExpressionType) : Visit(node.ReceiverOpt);
P
Pilchie 已提交
714 715
            return ExprFactory(
                "Field",
716
                receiver, _bound.FieldInfo(node.FieldSymbol));
P
Pilchie 已提交
717 718 719 720 721 722 723
        }

        private BoundExpression VisitIsOperator(BoundIsOperator node)
        {
            var operand = node.Operand;
            if ((object)operand.Type == null && operand.ConstantValue != null && operand.ConstantValue.IsNull)
            {
724
                operand = _bound.Null(_objectType);
P
Pilchie 已提交
725 726
            }

727
            return ExprFactory("TypeIs", Visit(operand), _bound.Typeof(node.TargetType.Type));
P
Pilchie 已提交
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
        }

        private BoundExpression VisitLambda(BoundLambda node)
        {
            var result = VisitLambdaInternal(node);
            return node.Type.IsExpressionTree() ? ExprFactory("Quote", result) : result;
        }

        private BoundExpression VisitLambdaInternal(BoundLambda node)
        {
            // prepare parameters so that they can be seen later
            var locals = ArrayBuilder<LocalSymbol>.GetInstance();
            var initializers = ArrayBuilder<BoundExpression>.GetInstance();
            var parameters = ArrayBuilder<BoundExpression>.GetInstance();
            foreach (var p in node.Symbol.Parameters)
            {
744
                var param = _bound.SynthesizedLocal(ParameterExpressionType);
P
Pilchie 已提交
745
                locals.Add(param);
746
                var parameterReference = _bound.Local(param);
P
Pilchie 已提交
747 748 749
                parameters.Add(parameterReference);
                var parameter = ExprFactory(
                    "Parameter",
750
                    _bound.Typeof(_typeMap.SubstituteType(p.Type).Type), _bound.Literal(p.Name));
751 752
                initializers.Add(_bound.AssignmentExpression(parameterReference, parameter));
                _parameterMap[p] = parameterReference;
P
Pilchie 已提交
753 754 755
            }

            var underlyingDelegateType = node.Type.GetDelegateType();
756
            var result = _bound.Sequence(locals.ToImmutableAndFree(), initializers.ToImmutableAndFree(),
P
Pilchie 已提交
757 758 759 760
                ExprFactory(
                    "Lambda",
                    ImmutableArray.Create<TypeSymbol>(underlyingDelegateType),
                    TranslateLambdaBody(node.Body),
761
                    _bound.ArrayOrEmpty(ParameterExpressionType, parameters.ToImmutableAndFree())));
P
Pilchie 已提交
762 763 764

            foreach (var p in node.Symbol.Parameters)
            {
765
                _parameterMap.Remove(p);
P
Pilchie 已提交
766 767 768 769 770 771 772
            }

            return result;
        }

        private BoundExpression VisitNewT(BoundNewT node)
        {
773
            return VisitObjectCreationContinued(ExprFactory("New", _bound.Typeof(node.Type)), node.InitializerExpressionOpt);
P
Pilchie 已提交
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
        }

        private BoundExpression VisitNullCoalescingOperator(BoundNullCoalescingOperator node)
        {
            var left = Visit(node.LeftOperand);
            var right = Visit(node.RightOperand);
            if (node.LeftConversion.IsUserDefined)
            {
                TypeSymbol lambdaParamType = node.LeftOperand.Type.StrippedType();
                return ExprFactory("Coalesce", left, right, MakeConversionLambda(node.LeftConversion, lambdaParamType, node.Type));
            }
            else
            {
                return ExprFactory("Coalesce", left, right);
            }
        }

        private BoundExpression MakeConversionLambda(Conversion conversion, TypeSymbol fromType, TypeSymbol toType)
        {
            string parameterName = "p";
794 795 796 797 798 799 800 801
            ParameterSymbol lambdaParameter = _bound.SynthesizedParameter(fromType, parameterName);
            var param = _bound.SynthesizedLocal(ParameterExpressionType);
            var parameterReference = _bound.Local(param);
            var parameter = ExprFactory("Parameter", _bound.Typeof(fromType), _bound.Literal(parameterName));
            _parameterMap[lambdaParameter] = parameterReference;
            var convertedValue = Visit(_bound.Convert(toType, _bound.Parameter(lambdaParameter), conversion));
            _parameterMap.Remove(lambdaParameter);
            var result = _bound.Sequence(
802
                ImmutableArray.Create(param),
803
                ImmutableArray.Create<BoundExpression>(_bound.AssignmentExpression(parameterReference, parameter)),
P
Pilchie 已提交
804 805 806
                ExprFactory(
                    "Lambda",
                    convertedValue,
807
                    _bound.ArrayOrEmpty(ParameterExpressionType, ImmutableArray.Create<BoundExpression>(parameterReference))));
P
Pilchie 已提交
808 809 810 811 812 813 814 815
            return result;
        }

        private BoundExpression InitializerMemberSetter(Symbol symbol)
        {
            switch (symbol.Kind)
            {
                case SymbolKind.Field:
816
                    return _bound.Convert(MemberInfoType, _bound.FieldInfo((FieldSymbol)symbol));
P
Pilchie 已提交
817
                case SymbolKind.Property:
818
                    return _bound.MethodInfo(((PropertySymbol)symbol).GetOwnOrInheritedSetMethod());
P
Pilchie 已提交
819
                case SymbolKind.Event:
820
                    return _bound.Convert(MemberInfoType, _bound.FieldInfo(((EventSymbol)symbol).AssociatedField));
P
Pilchie 已提交
821 822 823 824 825 826 827 828 829 830
                default:
                    throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
            }
        }

        private BoundExpression InitializerMemberGetter(Symbol symbol)
        {
            switch (symbol.Kind)
            {
                case SymbolKind.Field:
831
                    return _bound.Convert(MemberInfoType, _bound.FieldInfo((FieldSymbol)symbol));
P
Pilchie 已提交
832
                case SymbolKind.Property:
833
                    return _bound.MethodInfo(((PropertySymbol)symbol).GetOwnOrInheritedGetMethod());
P
Pilchie 已提交
834
                case SymbolKind.Event:
835
                    return _bound.Convert(MemberInfoType, _bound.FieldInfo(((EventSymbol)symbol).AssociatedField));
P
Pilchie 已提交
836 837 838 839 840
                default:
                    throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
            }
        }

841
        private enum InitializerKind { Expression, MemberInitializer, CollectionInitializer };
P
Pilchie 已提交
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885

        private BoundExpression VisitInitializer(BoundExpression node, out InitializerKind kind)
        {
            switch (node.Kind)
            {
                case BoundKind.ObjectInitializerExpression:
                    {
                        var oi = (BoundObjectInitializerExpression)node;
                        var builder = ArrayBuilder<BoundExpression>.GetInstance();
                        foreach (BoundAssignmentOperator a in oi.Initializers)
                        {
                            var sym = ((BoundObjectInitializerMember)a.Left).MemberSymbol;

                            // An error is reported in diagnostics pass when a dynamic object initializer is encountered in an ET:
                            Debug.Assert((object)sym != null);

                            InitializerKind elementKind;
                            var value = VisitInitializer(a.Right, out elementKind);
                            switch (elementKind)
                            {
                                case InitializerKind.CollectionInitializer:
                                    {
                                        var left = InitializerMemberGetter(sym);
                                        builder.Add(ExprFactory("ListBind", left, value));
                                        break;
                                    }
                                case InitializerKind.Expression:
                                    {
                                        var left = InitializerMemberSetter(sym);
                                        builder.Add(ExprFactory("Bind", left, value));
                                        break;
                                    }
                                case InitializerKind.MemberInitializer:
                                    {
                                        var left = InitializerMemberGetter(sym);
                                        builder.Add(ExprFactory("MemberBind", left, value));
                                        break;
                                    }
                                default:
                                    throw ExceptionUtilities.UnexpectedValue(elementKind);
                            }
                        }

                        kind = InitializerKind.MemberInitializer;
886
                        return _bound.ArrayOrEmpty(MemberBindingType, builder.ToImmutableAndFree());
P
Pilchie 已提交
887 888 889 890 891 892 893 894 895 896 897 898 899 900
                    }

                case BoundKind.CollectionInitializerExpression:
                    {
                        var ci = (BoundCollectionInitializerExpression)node;
                        Debug.Assert(ci.Initializers.Length != 0);
                        kind = InitializerKind.CollectionInitializer;

                        var builder = ArrayBuilder<BoundExpression>.GetInstance();

                        // The method invocation must be a static call. 
                        // Dynamic calls are not allowed in ETs, an error is reported in diagnostics pass.
                        foreach (BoundCollectionElementInitializer i in ci.Initializers)
                        {
901
                            BoundExpression elementInit = ExprFactory("ElementInit", _bound.MethodInfo(i.AddMethod), Expressions(i.Arguments));
P
Pilchie 已提交
902 903 904
                            builder.Add(elementInit);
                        }

905
                        return _bound.ArrayOrEmpty(ElementInitType, builder.ToImmutableAndFree());
P
Pilchie 已提交
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945
                    }

                default:
                    {
                        kind = InitializerKind.Expression;
                        return Visit(node);
                    }
            }
        }

        private BoundExpression VisitObjectCreationExpression(BoundObjectCreationExpression node)
        {
            return VisitObjectCreationContinued(VisitObjectCreationExpressionInternal(node), node.InitializerExpressionOpt);
        }

        private BoundExpression VisitObjectCreationContinued(BoundExpression creation, BoundExpression initializerExpressionOpt)
        {
            var result = creation;
            if (initializerExpressionOpt == null) return result;
            InitializerKind initializerKind;
            var init = VisitInitializer(initializerExpressionOpt, out initializerKind);
            switch (initializerKind)
            {
                case InitializerKind.CollectionInitializer:
                    return ExprFactory("ListInit", result, init);
                case InitializerKind.MemberInitializer:
                    return ExprFactory("MemberInit", result, init);
                default:
                    throw ExceptionUtilities.UnexpectedValue(initializerKind); // no other options at the top level of an initializer
            }
        }

        private BoundExpression VisitObjectCreationExpressionInternal(BoundObjectCreationExpression node)
        {
            if (node.ConstantValue != null)
            {
                // typically a decimal constant.
                return Constant(node);
            }

946 947
            if ((object)node.Constructor == null ||
                (node.Arguments.Length == 0 && !node.Type.IsStructType()) ||
948
                node.Constructor.IsDefaultValueTypeConstructor())
P
Pilchie 已提交
949
            {
950
                return ExprFactory("New", _bound.Typeof(node.Type));
P
Pilchie 已提交
951 952
            }

953 954
            var ctor = _bound.ConstructorInfo(node.Constructor);
            var args = _bound.Convert(_IEnumerableType.Construct(ExpressionType), Expressions(node.Arguments));
P
Pilchie 已提交
955 956 957 958 959 960
            if (node.Type.IsAnonymousType && node.Arguments.Length != 0)
            {
                var anonType = (NamedTypeSymbol)node.Type;
                var membersBuilder = ArrayBuilder<BoundExpression>.GetInstance();
                for (int i = 0; i < node.Arguments.Length; i++)
                {
961
                    membersBuilder.Add(_bound.MethodInfo(AnonymousTypeManager.GetAnonymousTypeProperty(anonType, i).GetMethod));
P
Pilchie 已提交
962 963
                }

964
                return ExprFactory("New", ctor, args, _bound.ArrayOrEmpty(MemberInfoType, membersBuilder.ToImmutableAndFree()));
P
Pilchie 已提交
965 966 967 968 969 970 971 972 973
            }
            else
            {
                return ExprFactory("New", ctor, args);
            }
        }

        private BoundExpression VisitParameter(BoundParameter node)
        {
974
            return _parameterMap[node.ParameterSymbol];
P
Pilchie 已提交
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992
        }

        private static BoundExpression VisitPointerIndirectionOperator(BoundPointerIndirectionOperator node)
        {
            // error should have been reported earlier
            // Diagnostics.Add(ErrorCode.ERR_ExpressionTreeContainsPointerOp, node.Syntax.Location);
            return new BoundBadExpression(node.Syntax, default(LookupResultKind), ImmutableArray<Symbol>.Empty, ImmutableArray.Create<BoundNode>(node), node.Type);
        }

        private static BoundExpression VisitPointerElementAccess(BoundPointerElementAccess node)
        {
            // error should have been reported earlier
            // Diagnostics.Add(ErrorCode.ERR_ExpressionTreeContainsPointerOp, node.Syntax.Location);
            return new BoundBadExpression(node.Syntax, default(LookupResultKind), ImmutableArray<Symbol>.Empty, ImmutableArray.Create<BoundNode>(node), node.Type);
        }

        private BoundExpression VisitPropertyAccess(BoundPropertyAccess node)
        {
993
            var receiver = node.PropertySymbol.IsStatic ? _bound.Null(ExpressionType) : Visit(node.ReceiverOpt);
P
Pilchie 已提交
994
            var getMethod = node.PropertySymbol.GetOwnOrInheritedGetMethod();
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006

            // COMPAT: see https://github.com/dotnet/roslyn/issues/4471
            //         old compiler used to insert casts like this and 
            //         there are known dependencies on this kind of tree shape.
            //
            //         While the casts are semantically incorrect, the conditions
            //         under which they are observable are extremely narrow:
            //         We would have to deal with a generic T receiver which is actually a struct
            //         that implements a property form an interface and 
            //         the implementation of the getter must make observable mutations to the instance.
            //
            //         At this point it seems more appropriate to continue adding these casts.
V
vsadov 已提交
1007 1008
            if (node.ReceiverOpt?.Type.IsTypeParameter() == true &&
                !node.ReceiverOpt.Type.IsReferenceType)
1009 1010 1011 1012
            {
                receiver = this.Convert(receiver, getMethod.ReceiverType, isChecked: false);
            }

1013
            return ExprFactory("Property", receiver, _bound.MethodInfo(getMethod));
P
Pilchie 已提交
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
        }

        private static BoundExpression VisitSizeOfOperator(BoundSizeOfOperator node)
        {
            // error should have been reported earlier
            // Diagnostics.Add(ErrorCode.ERR_ExpressionTreeContainsPointerOp, node.Syntax.Location);
            return new BoundBadExpression(node.Syntax, default(LookupResultKind), ImmutableArray<Symbol>.Empty, ImmutableArray.Create<BoundNode>(node), node.Type);
        }

        private BoundExpression VisitUnaryOperator(BoundUnaryOperator node)
        {
            var arg = node.Operand;
            var loweredArg = Visit(arg);
            var opKind = node.OperatorKind;
            var op = opKind & UnaryOperatorKind.OpMask;
            var isChecked = (opKind & UnaryOperatorKind.Checked) != 0;

            string opname;
            switch (op)
            {
                case UnaryOperatorKind.UnaryPlus:
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
                    if ((object)node.MethodOpt == null)
                    {
                        return loweredArg;
                    }
                    opname = "UnaryPlus";
                    break;
                case UnaryOperatorKind.UnaryMinus:
                    opname = isChecked ? "NegateChecked" : "Negate";
                    break;
                case UnaryOperatorKind.BitwiseComplement:
                case UnaryOperatorKind.LogicalNegation:
                    opname = "Not";
                    break;
P
Pilchie 已提交
1048 1049 1050 1051 1052 1053 1054 1055
                default:
                    throw ExceptionUtilities.UnexpectedValue(op);
            }

            if (node.OperatorKind.OperandTypes() == UnaryOperatorKind.Enum && (opKind & UnaryOperatorKind.Lifted) != 0)
            {
                Debug.Assert((object)node.MethodOpt == null);
                var promotedType = PromotedType(arg.Type.StrippedType().GetEnumUnderlyingType());
1056
                promotedType = _nullableType.Construct(promotedType);
P
Pilchie 已提交
1057 1058 1059 1060 1061 1062 1063
                loweredArg = Convert(loweredArg, arg.Type, promotedType, isChecked, false);
                var result = ExprFactory(opname, loweredArg);
                return Demote(result, node.Type, isChecked);
            }

            return ((object)node.MethodOpt == null)
                ? ExprFactory(opname, loweredArg)
1064
                : ExprFactory(opname, loweredArg, _bound.MethodInfo(node.MethodOpt));
P
Pilchie 已提交
1065 1066 1067 1068 1069 1070
        }

        // ======================================================

        private BoundExpression ExprFactory(string name, params BoundExpression[] arguments)
        {
1071
            return _bound.StaticCall(ExpressionType, name, arguments);
P
Pilchie 已提交
1072 1073 1074 1075
        }

        private BoundExpression ExprFactory(string name, ImmutableArray<TypeSymbol> typeArgs, params BoundExpression[] arguments)
        {
1076
            return _bound.StaticCall(_ignoreAccessibility ? BinderFlags.IgnoreAccessibility : BinderFlags.None, ExpressionType, name, typeArgs, arguments);
P
Pilchie 已提交
1077 1078 1079 1080
        }

        private BoundExpression ExprFactory(WellKnownMember method, ImmutableArray<TypeSymbol> typeArgs, params BoundExpression[] arguments)
        {
1081
            var m0 = _bound.WellKnownMethod(method);
P
Pilchie 已提交
1082 1083 1084
            Debug.Assert((object)m0 != null);
            Debug.Assert(m0.ParameterCount == arguments.Length);
            var m1 = m0.Construct(typeArgs);
1085
            return _bound.Call(null, m1, arguments);
P
Pilchie 已提交
1086 1087 1088 1089 1090 1091
        }

        private BoundExpression Constant(BoundExpression node)
        {
            return ExprFactory(
                "Constant",
1092 1093
                _bound.Convert(_objectType, node),
                _bound.Typeof(node.Type));
P
Pilchie 已提交
1094 1095 1096
        }
    }
}