public static bool TryMatchPattern( ISyntaxFactsService syntaxFacts, IConditionalOperation ifOperation, out ISimpleAssignmentOperation trueAssignment, out ISimpleAssignmentOperation falseAssignment) { trueAssignment = null; falseAssignment = null; var trueStatement = ifOperation.WhenTrue; var falseStatement = ifOperation.WhenFalse; trueStatement = UseConditionalExpressionHelpers.UnwrapSingleStatementBlock(trueStatement); falseStatement = UseConditionalExpressionHelpers.UnwrapSingleStatementBlock(falseStatement); if (!TryGetAssignment(trueStatement, out trueAssignment) || !TryGetAssignment(falseStatement, out falseAssignment)) { return(false); } // The left side of both assignment statements has to be syntactically identical (modulo // trivia differences). if (!syntaxFacts.AreEquivalent(trueAssignment.Target.Syntax, falseAssignment.Target.Syntax)) { return(false); } return(UseConditionalExpressionHelpers.CanConvert( syntaxFacts, ifOperation, trueAssignment, falseAssignment)); }
public static bool TryMatchPattern( ISyntaxFactsService syntaxFacts, IConditionalOperation ifOperation, out IReturnOperation trueReturn, out IReturnOperation falseReturn) { trueReturn = null; falseReturn = null; var trueStatement = ifOperation.WhenTrue; var falseStatement = ifOperation.WhenFalse; // we support: // // if (expr) // return a; // else // return b; // // and // // if (expr) // return a; // // return b; if (falseStatement == null) { var parentBlock = ifOperation.Parent as IBlockOperation; if (parentBlock == null) { return(false); } var ifIndex = parentBlock.Operations.IndexOf(ifOperation); if (ifIndex < 0) { return(false); } if (ifIndex + 1 < parentBlock.Operations.Length) { falseStatement = parentBlock.Operations[ifIndex + 1]; if (falseStatement.IsImplicit) { return(false); } } } trueStatement = UseConditionalExpressionHelpers.UnwrapSingleStatementBlock(trueStatement); falseStatement = UseConditionalExpressionHelpers.UnwrapSingleStatementBlock(falseStatement); // Both return-statements must be of the form "return value" if (!(trueStatement is IReturnOperation trueReturnOp) || !(falseStatement is IReturnOperation falseReturnOp) || trueReturnOp.ReturnedValue == null || falseReturnOp.ReturnedValue == null) { return(false); } if (trueReturnOp.Kind != falseReturnOp.Kind) { // Not allowed if these are different types of returns. i.e. // "yield return ..." and "return ...". return(false); } if (trueReturnOp.Kind == OperationKind.YieldBreak) { // This check is just paranoia. We likely shouldn't get here since we already // checked if .ReturnedValue was null above. return(false); } if (trueReturnOp.Kind == OperationKind.YieldReturn && ifOperation.WhenFalse == null) { // we have the following: // // if (...) { // yield return ... // } // // yield return ... // // It is *not* correct to replace this with: // // yield return ... ? ... ? ... // // as both yields need to be hit. return(false); } trueReturn = trueReturnOp; falseReturn = falseReturnOp; return(UseConditionalExpressionHelpers.CanConvert( syntaxFacts, ifOperation, trueReturn, falseReturn)); }