コード例 #1
0
        /// <summary>
        /// Lower a block of code by performing local rewritings.
        /// </summary>
        public static BoundStatement Rewrite(
            CSharpCompilation compilation,
            MethodSymbol method,
            int methodOrdinal,
            NamedTypeSymbol containingType,
            BoundStatement statement,
            TypeCompilationState compilationState,
            SynthesizedSubmissionFields previousSubmissionFields,
            bool allowOmissionOfConditionalCalls,
            DiagnosticBag diagnostics,
            out bool sawLambdas,
            out bool sawAwaitInExceptionHandler)
        {
            Debug.Assert(statement != null);
            Debug.Assert(compilationState != null);

            try
            {
                var factory          = new SyntheticBoundNodeFactory(method, statement.Syntax, compilationState, diagnostics);
                var localRewriter    = new LocalRewriter(compilation, method, methodOrdinal, containingType, factory, previousSubmissionFields, allowOmissionOfConditionalCalls, diagnostics);
                var loweredStatement = (BoundStatement)localRewriter.Visit(statement);
                sawLambdas = localRewriter.sawLambdas;
                sawAwaitInExceptionHandler = localRewriter.sawAwaitInExceptionHandler;
                var block  = loweredStatement as BoundBlock;
                var result = (block == null) ? loweredStatement : InsertPrologueSequencePoint(block, method);
                return(result);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                sawLambdas = sawAwaitInExceptionHandler = false;
                return(new BoundBadStatement(statement.Syntax, ImmutableArray.Create <BoundNode>(statement), hasErrors: true));
            }
        }
コード例 #2
0
        /// <summary>
        /// Lower a block of code by performing local rewritings.
        /// </summary>
        public static BoundStatement Rewrite(
            bool generateDebugInfo,
            MethodSymbol containingSymbol,
            NamedTypeSymbol containingType,
            BoundStatement statement,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            SynthesizedSubmissionFields previousSubmissionFields,
            out bool sawLambdas,
            out bool sawDynamicOperations,
            out bool sawAwaitInExceptionHandler)
        {
            Debug.Assert(statement != null);
            Debug.Assert(compilationState != null);

            try
            {
                var compilation      = containingType.DeclaringCompilation;
                var factory          = new SyntheticBoundNodeFactory(containingSymbol, statement.Syntax, compilationState, diagnostics);
                var localRewriter    = new LocalRewriter(generateDebugInfo, containingSymbol, containingType, factory, previousSubmissionFields, compilation, diagnostics);
                var loweredStatement = (BoundStatement)localRewriter.Visit(statement);
                sawLambdas = localRewriter.sawLambdas;
                sawAwaitInExceptionHandler = localRewriter.sawAwaitInExceptionHandler;
                sawDynamicOperations       = localRewriter.dynamicFactory.GeneratedDynamicOperations;
                var block  = loweredStatement as BoundBlock;
                var result = (block == null) ? loweredStatement : InsertPrologueSequencePoint(block, containingSymbol);
                return(result);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                sawLambdas = sawDynamicOperations = sawAwaitInExceptionHandler = false;
                return(new BoundBadStatement(statement.Syntax, ImmutableArray.Create <BoundNode>(statement), hasErrors: true));
            }
        }
コード例 #3
0
        private static BoundStatement RewriteFieldInitializer(BoundFieldEqualsValue fieldInit)
        {
            SyntaxNode syntax = fieldInit.Syntax;

            syntax = (syntax as EqualsValueClauseSyntax)?.Value ?? syntax; //we want the attached sequence point to indicate the value node
            var boundReceiver = fieldInit.Field.IsStatic ? null :
                                new BoundThisReference(syntax, fieldInit.Field.ContainingType);

            BoundStatement boundStatement =
                new BoundExpressionStatement(syntax,
                                             new BoundAssignmentOperator(syntax,
                                                                         new BoundFieldAccess(syntax,
                                                                                              boundReceiver,
                                                                                              fieldInit.Field,
                                                                                              constantValueOpt: null),
                                                                         fieldInit.Value,
                                                                         fieldInit.Field.Type.TypeSymbol)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = !fieldInit.Locals.IsEmpty || fieldInit.WasCompilerGenerated
            };

            if (!fieldInit.Locals.IsEmpty)
            {
                boundStatement = new BoundBlock(syntax, fieldInit.Locals, ImmutableArray.Create(boundStatement))
                {
                    WasCompilerGenerated = fieldInit.WasCompilerGenerated
                };
            }

            Debug.Assert(LocalRewriter.IsFieldOrPropertyInitializer(boundStatement));
            return(boundStatement);
        }
コード例 #4
0
        protected BoundStatement GenerateParameterStorage(LocalSymbol stateMachineVariable, IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> proxies)
        {
            var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

            // starting with the "this" proxy
            if (!method.IsStatic)
            {
                Debug.Assert((object)method.ThisParameter != null);

                CapturedSymbolReplacement proxy;
                if (proxies.TryGetValue(method.ThisParameter, out proxy))
                {
                    bodyBuilder.Add(F.Assignment(proxy.Replacement(F.Syntax, frameType1 => F.Local(stateMachineVariable)), F.This()));
                }
            }

            foreach (var parameter in method.Parameters)
            {
                CapturedSymbolReplacement proxy;
                if (proxies.TryGetValue(parameter, out proxy))
                {
                    bodyBuilder.Add(F.Assignment(proxy.Replacement(F.Syntax, frameType1 => F.Local(stateMachineVariable)),
                                                 F.Parameter(parameter)));
                }
            }

            var builtBody = bodyBuilder.ToImmutableAndFree();
            ImmutableArray <BoundStatement> newBody = LocalRewriter.TryConstructNullCheckedStatementList(method.Parameters, builtBody, F);

            return(newBody.IsDefault ? F.Block(builtBody) : F.Block(ImmutableArray.Create(stateMachineVariable), newBody));
        }
コード例 #5
0
 public PatternLocalRewriter(SyntaxNode node, LocalRewriter localRewriter, bool generateInstrumentation)
 {
     _localRewriter          = localRewriter;
     _factory                = localRewriter._factory;
     GenerateInstrumentation = generateInstrumentation;
     _tempAllocator          = new DagTempAllocator(_factory, node, generateInstrumentation);
 }
コード例 #6
0
        internal static BoundStatement RewriteXSharpMethod(MethodSymbol method,
                                                           BoundStatement body,
                                                           int methodOrdinal,
                                                           TypeCompilationState compilationState,
                                                           DiagnosticBag diagnostics)
        {
            switch (method.Name)
            {
            case XSharpSpecialNames.AppInit:
                body = LocalRewriter.RewriteAppInit(method, body, diagnostics);
                break;

            case XSharpSpecialNames.AppExit:
                body = LocalRewriter.RewriteAppExit(method, body, diagnostics);
                break;

            case XSharpSpecialNames.ExitProc:
                body = LocalRewriter.RewriteExit(method, body, diagnostics);
                break;

            case ReservedNames.RunInitProcs:
                body = LocalRewriter.RewriteRunInitProc(method, body, diagnostics);
                break;
            }
            switch (method.MethodKind)
            {
            case MethodKind.PropertyGet:
            case MethodKind.PropertySet:
                var node = method.GetNonNullSyntaxNode();
                if (node.XGenerated)
                {
                    if (body is BoundBlock oldbody)
                    {
                        var newbody = new BoundBlock(oldbody.Syntax, oldbody.Locals, oldbody.Statements, oldbody.HasErrors)
                        {
                            WasCompilerGenerated = true
                        };
                        body = newbody;
                    }
                }
                break;
            }

            var xnode = method.GetNonNullSyntaxNode().XNode as XSharpParserRuleContext;

            if (xnode is XSharpParser.ClsmethodContext cmc)
            {
                xnode = cmc.Member;
            }
            else if (xnode is XSharpParser.FoxclsmethodContext fmc)
            {
                xnode = fmc.Member;
            }
            if (xnode is XSharpParser.IEntityContext iec)
            {
                body = LocalRewriter.RemoveUnusedVars(iec.Data, body, diagnostics);
            }

            return(body);
        }
コード例 #7
0
        private static BoundStatement RewriteFieldInitializer(BoundFieldInitializer fieldInit)
        {
            var syntax        = fieldInit.Syntax;
            var boundReceiver = fieldInit.Field.IsStatic ? null :
                                new BoundThisReference(syntax, fieldInit.Field.ContainingType);

            BoundStatement boundStatement =
                new BoundExpressionStatement(syntax,
                                             new BoundAssignmentOperator(syntax,
                                                                         new BoundFieldAccess(syntax,
                                                                                              boundReceiver,
                                                                                              fieldInit.Field,
                                                                                              constantValueOpt: null),
                                                                         fieldInit.InitialValue,
                                                                         fieldInit.Field.Type)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = fieldInit.WasCompilerGenerated
            };

            Debug.Assert(LocalRewriter.IsFieldOrPropertyInitializer(boundStatement));
            return(boundStatement);
        }
コード例 #8
0
            public IsPatternExpressionLocalRewriter(SyntaxNode node, LocalRewriter localRewriter)
                : base(node, localRewriter)
            {
                this._conjunctBuilder = ArrayBuilder <BoundExpression> .GetInstance();

                this._sideEffectBuilder = ArrayBuilder <BoundExpression> .GetInstance();
            }
コード例 #9
0
 protected DecisionDagRewriter(
     SyntaxNode node,
     LocalRewriter localRewriter,
     bool generateInstrumentation)
     : base(node, localRewriter, generateInstrumentation)
 {
 }
コード例 #10
0
ファイル: Instrumenter.cs プロジェクト: belav/roslyn
 public virtual BoundStatement InstrumentFieldOrPropertyInitializer(
     BoundStatement original,
     BoundStatement rewritten
     )
 {
     Debug.Assert(LocalRewriter.IsFieldOrPropertyInitializer(original));
     return(InstrumentStatement(original, rewritten));
 }
コード例 #11
0
            public static BoundStatement Rewrite(LocalRewriter localRewriter, BoundSwitchStatement node)
            {
                var            rewriter = new SwitchStatementLocalRewriter(node, localRewriter);
                BoundStatement result   = rewriter.LowerSwitchStatement(node);

                rewriter.Free();
                return(result);
            }
コード例 #12
0
            public static BoundExpression Rewrite(LocalRewriter localRewriter, BoundConvertedSwitchExpression node)
            {
                var             rewriter = new SwitchExpressionLocalRewriter(node, localRewriter);
                BoundExpression result   = rewriter.LowerSwitchExpression(node);

                rewriter.Free();
                return(result);
            }
コード例 #13
0
ファイル: LocalRewriter.cs プロジェクト: gtkatakura/roslyn
        /// <summary>
        /// Lower a block of code by performing local rewritings.
        /// </summary>
        public static BoundStatement Rewrite(
            CSharpCompilation compilation,
            MethodSymbol method,
            int methodOrdinal,
            NamedTypeSymbol containingType,
            BoundStatement statement,
            TypeCompilationState compilationState,
            SynthesizedSubmissionFields previousSubmissionFields,
            bool allowOmissionOfConditionalCalls,
            bool instrumentForDynamicAnalysis,
            ref ImmutableArray <SourceSpan> dynamicAnalysisSpans,
            DebugDocumentProvider debugDocumentProvider,
            DiagnosticBag diagnostics,
            out bool sawLambdas,
            out bool sawLocalFunctions,
            out bool sawAwaitInExceptionHandler,
            // @MattWindsor91 (Concept-C# 2017)
            //
            // Sending concept witnesses to hoist to method compiler.
            // TODO: need to work out better way to do this
            out SmallDictionary <TypeSymbol, LocalSymbol> conceptWitnessesToHoist)
        {
            Debug.Assert(statement != null);
            Debug.Assert(compilationState != null);

            try
            {
                var factory = new SyntheticBoundNodeFactory(method, statement.Syntax, compilationState, diagnostics);
                DynamicAnalysisInjector dynamicInstrumenter = instrumentForDynamicAnalysis ? DynamicAnalysisInjector.TryCreate(method, statement, factory, diagnostics, debugDocumentProvider, Instrumenter.NoOp) : null;

                // We don’t want IL to differ based upon whether we write the PDB to a file/stream or not.
                // Presence of sequence points in the tree affects final IL, therefore, we always generate them.
                var localRewriter = new LocalRewriter(compilation, method, methodOrdinal, statement, containingType, factory, previousSubmissionFields, allowOmissionOfConditionalCalls, diagnostics,
                                                      dynamicInstrumenter != null ? new DebugInfoInjector(dynamicInstrumenter) : DebugInfoInjector.Singleton);

                var loweredStatement = (BoundStatement)localRewriter.Visit(statement);
                sawLambdas                 = localRewriter._sawLambdas;
                sawLocalFunctions          = localRewriter._sawLocalFunctions;
                sawAwaitInExceptionHandler = localRewriter._sawAwaitInExceptionHandler;
                if (dynamicInstrumenter != null)
                {
                    dynamicAnalysisSpans = dynamicInstrumenter.DynamicAnalysisSpans;
                }

                conceptWitnessesToHoist = localRewriter._conceptWitnessesToHoist;  // @MattWindsor91 (Concept-C# 2017)

                return(loweredStatement);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                sawLambdas = sawLocalFunctions = sawAwaitInExceptionHandler = false;

                conceptWitnessesToHoist = null;  // @MattWindsor91 (Concept-C# 2017)

                return(new BoundBadStatement(statement.Syntax, ImmutableArray.Create <BoundNode>(statement), hasErrors: true));
            }
        }
コード例 #14
0
 public PatternSwitchLocalRewriter(LocalRewriter localRewriter, BoundPatternSwitchStatement node)
 {
     this.LocalRewriter = localRewriter;
     this._factory      = localRewriter._factory;
     foreach (var section in node.SwitchSections)
     {
         SwitchSections.Add(section, ArrayBuilder <BoundStatement> .GetInstance());
     }
 }
コード例 #15
0
 public PatternSwitchLocalRewriter(LocalRewriter localRewriter, BoundPatternSwitchStatement node)
 {
     this.LocalRewriter = localRewriter;
     this._factory = localRewriter._factory;
     foreach (var section in node.SwitchSections)
     {
         SwitchSections.Add(section, ArrayBuilder<BoundStatement>.GetInstance());
     }
 }
コード例 #16
0
        /// <summary>
        /// Lower a block of code by performing local rewritings.
        /// </summary>
        public static BoundStatement Rewrite(
            CSharpCompilation compilation,
            MethodSymbol method,
            int methodOrdinal,
            NamedTypeSymbol containingType,
            BoundStatement statement,
            TypeCompilationState compilationState,
            SynthesizedSubmissionFields previousSubmissionFields,
            bool allowOmissionOfConditionalCalls,
            bool instrumentForDynamicAnalysis,
            ref ImmutableArray <SourceSpan> dynamicAnalysisSpans,
            DebugDocumentProvider debugDocumentProvider,
            BindingDiagnosticBag diagnostics,
            out bool sawLambdas,
            out bool sawLocalFunctions,
            out bool sawAwaitInExceptionHandler)
        {
            Debug.Assert(statement != null);
            Debug.Assert(compilationState != null);

            try
            {
                var factory = new SyntheticBoundNodeFactory(method, statement.Syntax, compilationState, diagnostics);
                DynamicAnalysisInjector?dynamicInstrumenter = instrumentForDynamicAnalysis ? DynamicAnalysisInjector.TryCreate(method, statement, factory, diagnostics, debugDocumentProvider, Instrumenter.NoOp) : null;

                // We don’t want IL to differ based upon whether we write the PDB to a file/stream or not.
                // Presence of sequence points in the tree affects final IL, therefore, we always generate them.
                var localRewriter = new LocalRewriter(compilation, method, methodOrdinal, statement, containingType, factory, previousSubmissionFields, allowOmissionOfConditionalCalls, diagnostics,
                                                      dynamicInstrumenter != null ? new DebugInfoInjector(dynamicInstrumenter) : DebugInfoInjector.Singleton);

                statement.CheckLocalsDefined();
                var loweredStatement = localRewriter.VisitStatement(statement);
                Debug.Assert(loweredStatement is { });
                loweredStatement.CheckLocalsDefined();
                sawLambdas                 = localRewriter._sawLambdas;
                sawLocalFunctions          = localRewriter._availableLocalFunctionOrdinal != 0;
                sawAwaitInExceptionHandler = localRewriter._sawAwaitInExceptionHandler;

                if (localRewriter._needsSpilling && !loweredStatement.HasErrors)
                {
                    // Move spill sequences to a top-level statement. This handles "lifting" await and the switch expression.
                    var spilledStatement = SpillSequenceSpiller.Rewrite(loweredStatement, method, compilationState, diagnostics);
                    spilledStatement.CheckLocalsDefined();
                    loweredStatement = spilledStatement;
                }

                if (dynamicInstrumenter != null)
                {
                    dynamicAnalysisSpans = dynamicInstrumenter.DynamicAnalysisSpans;
                }
#if DEBUG
                LocalRewritingValidator.Validate(loweredStatement);
                localRewriter.AssertNoPlaceholderReplacements();
#endif
                return(loweredStatement);
            }
コード例 #17
0
 private PatternSwitchLocalRewriter(LocalRewriter localRewriter, BoundPatternSwitchStatement node)
     : base(localRewriter._factory.CurrentMethod, localRewriter._factory.Compilation.Conversions)
 {
     this._localRewriter = localRewriter;
     this._factory = localRewriter._factory;
     this._factory.Syntax = node.Syntax;
     foreach (var section in node.SwitchSections)
     {
         _switchSections.Add((SyntaxNode)section.Syntax, ArrayBuilder<BoundStatement>.GetInstance());
     }
 }
コード例 #18
0
 private PatternSwitchLocalRewriter(LocalRewriter localRewriter, BoundPatternSwitchStatement node)
     : base(localRewriter._factory.CurrentMethod, (SwitchStatementSyntax)node.Syntax, localRewriter._factory.Compilation.Conversions)
 {
     this._localRewriter  = localRewriter;
     this._factory        = localRewriter._factory;
     this._factory.Syntax = node.Syntax;
     foreach (var section in node.SwitchSections)
     {
         _switchSections.Add(section.Syntax, ArrayBuilder <BoundStatement> .GetInstance());
     }
 }
コード例 #19
0
        private static RefKind ReceiverSpillRefKind(BoundExpression receiver)
        {
            var result = RefKind.None;

            if (!receiver.Type.IsReferenceType && LocalRewriter.CanBePassedByReference(receiver))
            {
                result = receiver.Type.IsReadOnly ? RefKind.In : RefKind.Ref;
            }

            return(result);
        }
コード例 #20
0
 private SwitchExpressionLocalRewriter(
     BoundConvertedSwitchExpression node,
     LocalRewriter localRewriter
     )
     : base(
         node.Syntax,
         localRewriter,
         node.SwitchArms.SelectAsArray(arm => arm.Syntax),
         generateInstrumentation: !node.WasCompilerGenerated && localRewriter.Instrument
         )
 {
 }
コード例 #21
0
 private SwitchStatementLocalRewriter(
     BoundSwitchStatement node,
     LocalRewriter localRewriter
     )
     : base(
         node.Syntax,
         localRewriter,
         node.SwitchSections.SelectAsArray(section => section.Syntax),
         // Only add instrumentation (such as sequence points) if the node is not compiler-generated.
         generateInstrumentation: localRewriter.Instrument && !node.WasCompilerGenerated
         )
 {
 }
コード例 #22
0
            protected BaseSwitchLocalRewriter(
                SyntaxNode node,
                LocalRewriter localRewriter,
                ImmutableArray <SyntaxNode> arms,
                bool isSwitchStatement)
                : base(node, localRewriter)
            {
                this._isSwitchStatement = isSwitchStatement;
                foreach (var arm in arms)
                {
                    var armBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                    // We start each switch block with a hidden sequence point so that
                    // we do not appear to be in the previous switch block when we begin.
                    armBuilder.Add(_factory.HiddenSequencePoint());
                    _switchArms.Add(arm, armBuilder);
                }
            }
コード例 #23
0
        private static BoundStatement RewriteFieldInitializer(BoundFieldInitializer fieldInit)
        {
            var syntax        = fieldInit.Syntax;
            var boundReceiver = fieldInit.Field.IsStatic ? null :
                                new BoundThisReference(syntax, fieldInit.Field.ContainingType);

            // Mark this as CompilerGenerated so that the local rewriter doesn't add a sequence point.
            BoundStatement boundStatement =
                new BoundExpressionStatement(syntax,
                                             new BoundAssignmentOperator(syntax,
                                                                         new BoundFieldAccess(syntax,
                                                                                              boundReceiver,
                                                                                              fieldInit.Field,
                                                                                              constantValueOpt: null),
                                                                         fieldInit.InitialValue,
                                                                         fieldInit.Field.Type)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            Debug.Assert(syntax is ExpressionSyntax); // Should be the initial value.
            Debug.Assert(syntax.Parent.Kind == SyntaxKind.EqualsValueClause);
            switch (syntax.Parent.Parent.Kind)
            {
            case SyntaxKind.VariableDeclarator:
                var declaratorSyntax = (VariableDeclaratorSyntax)syntax.Parent.Parent;
                boundStatement = LocalRewriter.AddSequencePoint(declaratorSyntax, boundStatement);
                break;

            case SyntaxKind.PropertyDeclaration:
                var declaration = (PropertyDeclarationSyntax)syntax.Parent.Parent;
                boundStatement = LocalRewriter.AddSequencePoint(declaration, boundStatement);
                break;

            default:
                throw ExceptionUtilities.Unreachable;
            }

            return(boundStatement);
        }
コード例 #24
0
        public override BoundNode VisitLoweredConditionalAccess(BoundLoweredConditionalAccess node)
        {
            var receiverRefKind = ReceiverSpillRefKind(node.Receiver);

            BoundSpillSequenceBuilder receiverBuilder = null;
            var receiver = VisitExpression(ref receiverBuilder, node.Receiver);

            BoundSpillSequenceBuilder whenNotNullBuilder = null;
            var whenNotNull = VisitExpression(ref whenNotNullBuilder, node.WhenNotNull);

            BoundSpillSequenceBuilder whenNullBuilder = null;
            var whenNullOpt = VisitExpression(ref whenNullBuilder, node.WhenNullOpt);

            if (whenNotNullBuilder == null && whenNullBuilder == null)
            {
                return(UpdateExpression(receiverBuilder, node.Update(receiver, node.HasValueMethodOpt, whenNotNull, whenNullOpt, node.Id, node.Type)));
            }

            if (receiverBuilder == null)
            {
                receiverBuilder = new BoundSpillSequenceBuilder();
            }
            if (whenNotNullBuilder == null)
            {
                whenNotNullBuilder = new BoundSpillSequenceBuilder();
            }
            if (whenNullBuilder == null)
            {
                whenNullBuilder = new BoundSpillSequenceBuilder();
            }


            BoundExpression condition;

            if (receiver.Type.IsReferenceType || receiver.Type.IsValueType || receiverRefKind == RefKind.None)
            {
                // spill to a clone
                receiver = Spill(receiverBuilder, receiver, RefKind.None);
                var hasValueOpt = node.HasValueMethodOpt;

                if (hasValueOpt == null)
                {
                    condition = _F.ObjectNotEqual(
                        _F.Convert(_F.SpecialType(SpecialType.System_Object), receiver),
                        _F.Null(_F.SpecialType(SpecialType.System_Object)));
                }
                else
                {
                    condition = _F.Call(receiver, hasValueOpt);
                }
            }
            else
            {
                Debug.Assert(node.HasValueMethodOpt == null);
                receiver = Spill(receiverBuilder, receiver, RefKind.Ref);

                var clone = _F.SynthesizedLocal(receiver.Type, _F.Syntax, refKind: RefKind.None, kind: SynthesizedLocalKind.Spill);
                receiverBuilder.AddLocal(clone);

                //  (object)default(T) != null
                var isNotClass = _F.ObjectNotEqual(
                    _F.Convert(_F.SpecialType(SpecialType.System_Object), _F.Default(receiver.Type)),
                    _F.Null(_F.SpecialType(SpecialType.System_Object)));

                // isNotCalss || {clone = receiver; (object)clone != null}
                condition = _F.LogicalOr(
                    isNotClass,
                    _F.MakeSequence(
                        _F.AssignmentExpression(_F.Local(clone), receiver),
                        _F.ObjectNotEqual(
                            _F.Convert(_F.SpecialType(SpecialType.System_Object), _F.Local(clone)),
                            _F.Null(_F.SpecialType(SpecialType.System_Object))))
                    );

                receiver = _F.ComplexConditionalReceiver(receiver, _F.Local(clone));
            }

            if (node.Type.IsVoidType())
            {
                var whenNotNullStatement = UpdateStatement(whenNotNullBuilder, _F.ExpressionStatement(whenNotNull));
                whenNotNullStatement = ConditionalReceiverReplacer.Replace(whenNotNullStatement, receiver, node.Id, RecursionDepth);

                Debug.Assert(whenNullOpt == null || !LocalRewriter.ReadIsSideeffecting(whenNullOpt));

                receiverBuilder.AddStatement(_F.If(condition, whenNotNullStatement));

                return(receiverBuilder.Update(_F.Default(node.Type)));
            }
            else
            {
                var tmp = _F.SynthesizedLocal(node.Type, kind: SynthesizedLocalKind.Spill, syntax: _F.Syntax);
                var whenNotNullStatement = UpdateStatement(whenNotNullBuilder, _F.Assignment(_F.Local(tmp), whenNotNull));
                whenNotNullStatement = ConditionalReceiverReplacer.Replace(whenNotNullStatement, receiver, node.Id, RecursionDepth);

                whenNullOpt = whenNullOpt ?? _F.Default(node.Type);

                receiverBuilder.AddLocal(tmp);
                receiverBuilder.AddStatement(
                    _F.If(condition,
                          whenNotNullStatement,
                          UpdateStatement(whenNullBuilder, _F.Assignment(_F.Local(tmp), whenNullOpt))));

                return(receiverBuilder.Update(_F.Local(tmp)));
            }
        }
コード例 #25
0
 private SwitchExpressionLocalRewriter(BoundSwitchExpression node, LocalRewriter localRewriter)
     : base(node.Syntax, localRewriter, node.SwitchArms.SelectAsArray(arm => arm.Syntax), isSwitchStatement: false)
 {
 }
コード例 #26
0
 private static RefKind ReceiverSpillRefKind(BoundExpression receiver)
 {
     return(LocalRewriter.WouldBeAssignableIfUsedAsMethodReceiver(receiver) ?
            RefKind.Ref :
            RefKind.None);
 }
コード例 #27
0
 private SwitchExpressionLocalRewriter(BoundConvertedSwitchExpression node, LocalRewriter localRewriter)
     : base(node.Syntax, localRewriter, node.SwitchArms.SelectAsArray(arm => arm.Syntax))
 {
 }
コード例 #28
0
 public PatternLocalRewriter(SyntaxNode node, LocalRewriter localRewriter)
 {
     _localRewriter = localRewriter;
     _factory       = localRewriter._factory;
     _tempAllocator = new DagTempAllocator(_factory, node, IsSwitchStatement);
 }
コード例 #29
0
 internal static BoundStatement MakeLoweredForm(LocalRewriter localRewriter, BoundPatternSwitchStatement node)
 {
     return(new PatternSwitchLocalRewriter(localRewriter, node).MakeLoweredForm(node));
 }
コード例 #30
0
 internal static BoundStatement MakeLoweredForm(LocalRewriter localRewriter, BoundPatternSwitchStatement node)
 {
     return new PatternSwitchLocalRewriter(localRewriter, node).MakeLoweredForm(node);
 }
コード例 #31
0
 private SwitchStatementLocalRewriter(BoundSwitchStatement node, LocalRewriter localRewriter)
     : base(node.Syntax, localRewriter, node.SwitchSections.SelectAsArray(section => section.Syntax))
 {
 }
コード例 #32
0
 public IsPatternExpressionGeneralLocalRewriter(
     SyntaxNode node,
     LocalRewriter localRewriter) : base(node, localRewriter, generateInstrumentation: false)
 {
 }
コード例 #33
0
 public PatternLocalRewriter(SyntaxNode node, LocalRewriter localRewriter)
 {
     this._localRewriter = localRewriter;
     this._factory       = localRewriter._factory;
     this._tempAllocator = new DagTempAllocator(_factory, node);
 }