public override BoundNode VisitPatternSwitchStatement(BoundPatternSwitchStatement node) { _factory.Syntax = node.Syntax; var pslr = new PatternSwitchLocalRewriter(this, node); var expression = VisitExpression(node.Expression); // EnC: We need to insert a hidden sequence point to handle function remapping in case // the containing method is edited while methods invoked in the expression are being executed. if (!node.WasCompilerGenerated && this.Instrument) { expression = _instrumenter.InstrumentSwitchStatementExpression(node, expression, _factory); } var result = ArrayBuilder <BoundStatement> .GetInstance(); // output the decision tree part pslr.LowerDecisionTree(expression, node.DecisionTree, result); // if the endpoint is reachable, we exit the switch if (!node.DecisionTree.MatchIsComplete) { result.Add(_factory.Goto(node.BreakLabel)); } // at this point the end of result is unreachable. // output the sections of code foreach (var section in node.SwitchSections) { // Start with the part of the decision tree that is in scope of the section variables. // Its endpoint is not reachable (it jumps back into the decision tree code). var sectionBuilder = pslr.SwitchSections[section]; // Add labels corresponding to the labels of the switch section. foreach (var label in section.SwitchLabels) { sectionBuilder.Add(_factory.Label(label.Label)); } // Add the translated body of the switch section sectionBuilder.AddRange(VisitList(section.Statements)); sectionBuilder.Add(_factory.Goto(node.BreakLabel)); result.Add(_factory.Block(section.Locals, sectionBuilder.ToImmutableAndFree())); // at this point the end of result is unreachable. } result.Add(_factory.Label(node.BreakLabel)); BoundStatement translatedSwitch = _factory.Block(pslr.DeclaredTemps.ToImmutableArray().Concat(node.InnerLocals), node.InnerLocalFunctions, result.ToImmutableAndFree()); // Only add instrumentation (such as a sequence point) if the node is not compiler-generated. if (!node.WasCompilerGenerated && this.Instrument) { translatedSwitch = _instrumenter.InstrumentPatternSwitchStatement(node, translatedSwitch); } return(translatedSwitch); }
public override BoundNode VisitPatternSwitchStatement(BoundPatternSwitchStatement node) { _factory.Syntax = node.Syntax; var pslr = new PatternSwitchLocalRewriter(this, node); var expression = VisitExpression(node.Expression); var result = ArrayBuilder<BoundStatement>.GetInstance(); // output the decision tree part pslr.LowerDecisionTree(expression, node.DecisionTree, result); // if the endpoint is reachable, we exit the switch if (!node.DecisionTree.MatchIsComplete) { result.Add(_factory.Goto(node.BreakLabel)); } // at this point the end of result is unreachable. // output the sections of code foreach (var section in node.SwitchSections) { // Start with the part of the decision tree that is in scope of the section variables. // Its endpoint is not reachable (it jumps back into the decision tree code). var sectionBuilder = pslr.SwitchSections[section]; // Add labels corresponding to the labels of the switch section. foreach (var label in section.SwitchLabels) { sectionBuilder.Add(_factory.Label(label.Label)); } // Add the translated body of the switch section sectionBuilder.AddRange(VisitList(section.Statements)); sectionBuilder.Add(_factory.Goto(node.BreakLabel)); result.Add(_factory.Block(section.Locals, sectionBuilder.ToImmutableAndFree())); // at this point the end of result is unreachable. } result.Add(_factory.Label(node.BreakLabel)); BoundStatement translatedSwitch = _factory.Block(pslr.DeclaredTemps.ToImmutableArray().Concat(node.InnerLocals), node.InnerLocalFunctions, result.ToImmutableAndFree()); // Create the sequence point if generating debug info and // node is not compiler generated if (this.Instrument && !node.WasCompilerGenerated) { translatedSwitch = _instrumenter.InstrumentBoundPatternSwitchStatement(node, translatedSwitch); } return translatedSwitch; }
public override BoundNode VisitPatternSwitchStatement(BoundPatternSwitchStatement node) { _factory.Syntax = node.Syntax; var pslr = new PatternSwitchLocalRewriter(this, node); var expression = VisitExpression(node.Expression); var result = ArrayBuilder <BoundStatement> .GetInstance(); // output the decision tree part pslr.LowerDecisionTree(expression, node.DecisionTree, result); // if the endpoint is reachable, we exit the switch if (!node.DecisionTree.MatchIsComplete) { result.Add(_factory.Goto(node.BreakLabel)); } // at this point the end of result is unreachable. // output the sections of code foreach (var section in node.SwitchSections) { // Start with the part of the decision tree that is in scope of the section variables. // Its endpoint is not reachable (it jumps back into the decision tree code). var sectionBuilder = pslr.SwitchSections[section]; // Add labels corresponding to the labels of the switch section. foreach (var label in section.SwitchLabels) { sectionBuilder.Add(_factory.Label(label.Label)); } // Add the translated body of the switch section sectionBuilder.AddRange(VisitList(section.Statements)); sectionBuilder.Add(_factory.Goto(node.BreakLabel)); result.Add(_factory.Block(section.Locals, sectionBuilder.ToImmutableAndFree())); // at this point the end of result is unreachable. } result.Add(_factory.Label(node.BreakLabel)); BoundStatement translatedSwitch = _factory.Block(pslr.DeclaredTemps.ToImmutableArray().Concat(node.InnerLocals), node.InnerLocalFunctions, result.ToImmutableAndFree()); // Create the sequence point if generating debug info and // node is not compiler generated if (this.Instrument && !node.WasCompilerGenerated) { translatedSwitch = _instrumenter.InstrumentBoundPatternSwitchStatement(node, translatedSwitch); } return(translatedSwitch); }