public BoundConditionalExpression(ConditionalExpressionSyntax syntax, BoundExpression condition, BoundExpression consequence, BoundExpression alternative) : base(BoundNodeKind.ConditionalExpression, syntax) { Condition = condition; Consequence = consequence; Alternative = alternative; Type = consequence.Type; }
public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { var token = CreateConditionalBlock(node.Condition.ToString()); _tokenList.Add(token); VisitChildren(token.FalseStatements, node.WhenFalse); VisitChildren(token.TrueStatements, node.WhenTrue); }
public static void Go(OutputWriter writer, ConditionalExpressionSyntax expression) { writer.Write("("); Core.Write(writer, expression.Condition); writer.Write(") ? ("); Core.Write(writer, expression.WhenTrue); writer.Write(") : ("); Core.Write(writer, expression.WhenFalse); writer.Write(")"); }
private static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, YieldStatementSyntax yieldStatement, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); IfStatementSyntax ifStatement = ReplaceWithIfElseWithYieldReturn(conditionalExpression, yieldStatement) .WithFormatterAnnotation(); SyntaxNode newRoot = root.ReplaceNode(yieldStatement, ifStatement); return(document.WithSyntaxRoot(newRoot)); }
public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { if (!PreVisit(node)) { return; } node.Condition?.Accept(this); node.WhenTrue?.Accept(this); node.WhenFalse?.Accept(this); base.VisitConditionalExpression(node); PostVisit(node); }
public override Ust VisitConditionalExpression(ConditionalExpressionSyntax node) { var condition = (Expression)base.Visit(node.Condition); var trueExpression = (Expression)base.Visit(node.WhenTrue); var falseExpression = (Expression)base.Visit(node.WhenFalse); var result = new ConditionalExpression( condition, trueExpression, falseExpression, node.GetTextSpan() ); return(result); }
private static ExpressionSyntax CreateNewNode( ConditionalExpressionSyntax conditionalExpression, ExpressionSyntax newNode) { SyntaxTriviaList trailingTrivia = conditionalExpression .DescendantTrivia(TextSpan.FromBounds(conditionalExpression.Condition.Span.End, conditionalExpression.Span.End)) .ToSyntaxTriviaList() .EmptyIfWhitespace() .AddRange(conditionalExpression.GetTrailingTrivia()); return(newNode .WithLeadingTrivia(conditionalExpression.GetLeadingTrivia()) .WithTrailingTrivia(trailingTrivia) .WithSimplifierAnnotation()); }
private Doc PrintConditionalExpressionSyntax( ConditionalExpressionSyntax node) { return(Group( Indent( this.Print(node.Condition), Line, this.PrintSyntaxToken(node.QuestionToken, " "), this.Print(node.WhenTrue), Line, this.PrintSyntaxToken(node.ColonToken, " "), this.Print(node.WhenFalse) ) )); }
private void BuildConditionalExpression(ConditionalExpressionSyntax conditional) { var successor = currentBlock; currentBlock = CreateBlock(successor); BuildExpression(conditional.WhenFalse); var falseBlock = currentBlock; currentBlock = CreateBlock(successor); BuildExpression(conditional.WhenTrue); var trueBlock = currentBlock; currentBlock = CreateBinaryBranchBlock(conditional, trueBlock, falseBlock); BuildExpression(conditional.Condition); }
private static void AddConditionalExpressionTerms(ConditionalExpressionSyntax conditionalExpression, IList <string> terms, ref ExpressionType expressionType) { ExpressionType conditionFlags = ExpressionType.Invalid, trueFlags = ExpressionType.Invalid, falseFlags = ExpressionType.Invalid; AddSubExpressionTerms(conditionalExpression.Condition, terms, ref conditionFlags); AddSubExpressionTerms(conditionalExpression.WhenTrue, terms, ref trueFlags); AddSubExpressionTerms(conditionalExpression.WhenFalse, terms, ref falseFlags); AddIfValidTerm(conditionalExpression.Condition, conditionFlags, terms); AddIfValidTerm(conditionalExpression.WhenTrue, trueFlags, terms); AddIfValidTerm(conditionalExpression.WhenFalse, falseFlags, terms); // We're valid if all children are... expressionType = (conditionFlags & trueFlags & falseFlags) & ExpressionType.ValidExpression; }
private static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, YieldStatementSyntax yieldStatement, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); IfStatementSyntax ifStatement = ConvertToIfElseWithYieldReturn(conditionalExpression, yieldStatement) .WithAdditionalAnnotations(Formatter.Annotation); SyntaxNode newRoot = oldRoot.ReplaceNode(yieldStatement, ifStatement); return(document.WithSyntaxRoot(newRoot)); }
private static Task <Document> IfElseToAssignmentWithConditionalExpressionAsync( Document document, IfElseToAssignmentWithConditionalExpressionAnalysis analysis, CancellationToken cancellationToken = default) { IfStatementSyntax ifStatement = analysis.IfStatement; ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(ifStatement.Condition, analysis.WhenTrue, analysis.WhenFalse); ExpressionStatementSyntax newNode = SimpleAssignmentStatement(analysis.Left, conditionalExpression) .WithTriviaFrom(ifStatement) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken)); }
private static Task <Document> IfElseToReturnWithConditionalExpressionAsync( Document document, IfElseToReturnWithConditionalExpressionAnalysis analysis, CancellationToken cancellationToken = default) { IfStatementSyntax ifStatement = analysis.IfStatement; ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(ifStatement.Condition, analysis.Expression1, analysis.Expression2); StatementSyntax newNode = ReturnStatement(conditionalExpression) .WithTriviaFrom(ifStatement) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken)); }
private static void ConditionalExpressionCheck(ConditionalExpressionSyntax conditionalExpression, SemanticModel semanticModel, Action <Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken) { var trueExp = conditionalExpression.WhenTrue; var falseExp = conditionalExpression.WhenFalse; if (trueExp != null) { CheckTypeConversion(semanticModel.GetConversion(trueExp, cancellationToken), reportDiagnostic, trueExp.GetLocation(), filePath); } if (falseExp != null) { CheckTypeConversion(semanticModel.GetConversion(falseExp, cancellationToken), reportDiagnostic, falseExp.GetLocation(), filePath); } }
private static Document RemoveConditional(Document document, SyntaxNode root, ConditionalExpressionSyntax conditional) { if (EquivalenceChecker.AreEquivalent(conditional.WhenTrue, SyntaxHelper.TrueLiteralExpression)) { var newRoot = root.ReplaceNode(conditional, conditional.Condition.WithAdditionalAnnotations(Formatter.Annotation)); return(document.WithSyntaxRoot(newRoot)); } else { var newRoot = root.ReplaceNode(conditional, GetNegatedExpression(conditional.Condition).WithAdditionalAnnotations(Formatter.Annotation)); return(document.WithSyntaxRoot(newRoot)); } }
private static bool IsFixable(ConditionalExpressionSyntax conditionalExpression, SemanticModel semanticModel, CancellationToken cancellationToken) { ExpressionSyntax condition = conditionalExpression.Condition.WalkDownParentheses(); switch (condition.Kind()) { case SyntaxKind.EqualsExpression: return(IsFixable((BinaryExpressionSyntax)condition, conditionalExpression.WhenFalse, semanticModel, cancellationToken)); case SyntaxKind.NotEqualsExpression: return(IsFixable((BinaryExpressionSyntax)condition, conditionalExpression.WhenTrue, semanticModel, cancellationToken)); default: return(false); } }
public static Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken = default(CancellationToken)) { ConditionalExpressionSyntax newNode = conditionalExpression.Update( condition: Negator.LogicallyNegate(conditionalExpression.Condition), questionToken: conditionalExpression.QuestionToken, whenTrue: conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue), colonToken: conditionalExpression.ColonToken, whenFalse: conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse)); newNode = newNode.WithFormatterAnnotation(); return(document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken)); }
public static void Analyze(SyntaxNodeAnalysisContext context, ConditionalExpressionSyntax conditionalExpression) { ExpressionSyntax condition = conditionalExpression.Condition; if (condition?.IsMissing == false && !condition.IsKind(SyntaxKind.ParenthesizedExpression) && !conditionalExpression.QuestionToken.IsMissing && !conditionalExpression.ColonToken.IsMissing && conditionalExpression.WhenTrue?.IsMissing == false && conditionalExpression.WhenFalse?.IsMissing == false) { context.ReportDiagnostic( DiagnosticDescriptors.ParenthesizeConditionInConditionalExpression, condition); } }
public static Doc Print(ConditionalExpressionSyntax node) { return(Doc.Concat( Node.Print(node.Condition), Doc.Group( Doc.Indent( Doc.Line, Token.Print(node.QuestionToken, " "), Doc.Indent(Node.Print(node.WhenTrue)), Doc.Line, Token.Print(node.ColonToken, " "), Doc.Indent(Node.Print(node.WhenFalse)) ) ) )); }
public override SyntaxNode VisitConditionalExpression(ConditionalExpressionSyntax node) { if (node.Condition is BinaryExpressionSyntax binaryExpression && binaryExpression.IsKind(SyntaxKind.NotEqualsExpression)) { return(base.VisitConditionalExpression(InvertConditionalExpression(node, InvertBinaryExpression(binaryExpression)))); } if (node.Condition is PrefixUnaryExpressionSyntax prefixUnaryExpression && prefixUnaryExpression.IsKind(SyntaxKind.LogicalNotExpression)) { return(base.VisitConditionalExpression(InvertConditionalExpression(node, InvertPrefixUnaryExpression(prefixUnaryExpression)))); } return(base.VisitConditionalExpression(node)); }
protected override IValue VisitConditionalExpression(ConditionalExpressionSyntax node) { var aaaa = ModelExtensions.GetTypeInfo(state.Context.RoslynModel, node); var resultType = state.Context.Roslyn_ResolveType(aaaa.Type); var condition = Visit(node.Condition); var whenTrue = Visit(node.WhenTrue); var whenFalse = Visit(node.WhenFalse); //Type resultType; //if (whenTrue.ValueType == whenFalse.ValueType) // resultType = whenTrue.ValueType; //else // throw new NotSupportedException(); var res = new ConditionalExpression(condition, whenTrue, whenFalse, resultType); return(Simplify(res)); }
public static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); ConditionalExpressionSyntax newConditionalExpression = conditionalExpression .WithCondition(conditionalExpression.Condition.Negate()) .WithWhenTrue(conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue)) .WithWhenFalse(conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse)) .WithFormatterAnnotation(); SyntaxNode newRoot = oldRoot.ReplaceNode(conditionalExpression, newConditionalExpression); return(document.WithSyntaxRoot(newRoot)); }
private static async Task <Document> SwapStatementsAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); ConditionalExpressionSyntax newConditionalExpression = conditionalExpression .WithCondition(conditionalExpression.Condition.Negate()) .WithWhenTrue(conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue)) .WithWhenFalse(conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse)) .WithAdditionalAnnotations(Formatter.Annotation); SyntaxNode newRoot = oldRoot.ReplaceNode(conditionalExpression, newConditionalExpression); return(document.WithSyntaxRoot(newRoot)); }
private async Task <Document> RefactorWithConditionalExpressionAsync( Document document, IfStatementSyntax ifStatement, ExpressionSyntax whenTrue, ExpressionSyntax whenFalse, CancellationToken cancellationToken) { ConditionalExpressionSyntax conditionalExpression = ReplaceIfWithStatementRefactoring.CreateConditionalExpression(ifStatement.Condition, whenTrue, whenFalse); TStatement newNode = CreateStatement(conditionalExpression); newNode = newNode .WithTriviaFrom(ifStatement) .WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(ifStatement, newNode, cancellationToken).ConfigureAwait(false)); }
private static IfStatementSyntax ConvertToIfElseWithAssignment(ConditionalExpressionSyntax conditionalExpression, ExpressionSyntax left) { if (conditionalExpression == null) { throw new ArgumentNullException(nameof(conditionalExpression)); } ExpressionSyntax whenTrue = conditionalExpression.WhenTrue.WithoutTrivia(); ExpressionSyntax whenFalse = conditionalExpression.WhenFalse.WithoutTrivia(); bool addBlock = whenTrue.IsMultiline() || whenFalse.IsMultiline(); return(IfStatement( GetCondition(conditionalExpression), GetIfContent(whenTrue, addBlock, left), ElseClause(GetElseContent(whenFalse, addBlock, left)))); }
public override TempComputeResult VisitConditionalExpression(ConditionalExpressionSyntax node) { var tuple = GetOrCreateVariableReference(node, ""); tuple.Top.Type = VariableTypes.Value; bool conditionValue; var conditionResult = Visit(node.Condition); if (conditionResult.Value is bool) { conditionValue = (bool)conditionResult.Value; } else { // true运算符重载 var overloadTrueMethod = DebugService.GetMethod(conditionResult.Type, "op_True", BindingFlags.Public | BindingFlags.Static, methodInfo => CheckConditionalOperatorUnaryMethodParameters(conditionResult.Type, methodInfo)); if (overloadTrueMethod != null) { conditionValue = (bool)overloadTrueMethod.Invoke(null, new object[1] { conditionResult.Value }); } else { throw new InvalidOperationException(string.Format("\"{0}\" is not conditional expression", node.Condition.ToString())); } } TempComputeResult result; if (conditionValue) { result = Visit(node.WhenTrue); } else { result = Visit(node.WhenFalse); } tuple.Top.Value = result.Value; tuple.Top.ValueType = result.Type; return(ResolveVariable(tuple.Bottom)); }
private static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, ExpressionStatementSyntax expressionStatement, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken); var assignmentExpression = (AssignmentExpressionSyntax)conditionalExpression.Parent; IfStatementSyntax ifStatement = ConvertToIfElseWithAssignment(conditionalExpression, assignmentExpression.Left.WithoutTrivia()) .WithTriviaFrom(expressionStatement) .WithAdditionalAnnotations(Formatter.Annotation); SyntaxNode newRoot = oldRoot.ReplaceNode(expressionStatement, ifStatement); return(document.WithSyntaxRoot(newRoot)); }
private static async Task <Document> AddParenthesesToConditionAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); ConditionalExpressionSyntax newNode = conditionalExpression .WithCondition( SyntaxFactory.ParenthesizedExpression( conditionalExpression.Condition.WithoutTrivia() ).WithTriviaFrom(conditionalExpression.Condition) ).WithFormatterAnnotation(); SyntaxNode newRoot = oldRoot.ReplaceNode(conditionalExpression, newNode); return(document.WithSyntaxRoot(newRoot)); }
private static IfStatementSyntax ReplaceWithIfElseWithYieldReturn( ConditionalExpressionSyntax conditionalExpression, YieldStatementSyntax yieldStatement) { ExpressionSyntax condition = conditionalExpression.Condition.WithoutTrivia(); if (condition.IsKind(SyntaxKind.ParenthesizedExpression)) { condition = ((ParenthesizedExpressionSyntax)condition).Expression; } IfStatementSyntax ifStatement = CreateIfStatement( condition, YieldReturnStatement(conditionalExpression.WhenTrue.WithoutTrivia()), YieldReturnStatement(conditionalExpression.WhenFalse.WithoutTrivia())); return(ifStatement.WithTriviaFrom(yieldStatement)); }
public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { if (debug) { Console.WriteLine(node.ToFullString()); } // Todo("ConditionalExpression"); var nl = OurLine.NewLine(LineKind.Decl, "ConditionalExpression"); OurLine.AddEssentialInfo(ref nl, "condition:" + node.Condition.ToString()); OurLine.AddEssentialInfo(ref nl, "whentrue:" + node.WhenTrue.ToString()); OurLine.AddEssentialInfo(ref nl, "whenfalse:" + node.WhenFalse.ToString()); nl.Source = node.ToFullString(); nl.ParentKind = node.Parent.RawKind; nl.RawKind = node.RawKind; LogCommand(nl); base.VisitConditionalExpression(node); }
private static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, ExpressionStatementSyntax expressionStatement, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var assignmentExpression = (AssignmentExpressionSyntax)conditionalExpression.Parent; IfStatementSyntax ifStatement = ReplaceWithIfElseWithAssignment(conditionalExpression, assignmentExpression.Left.WithoutTrivia()) .WithTriviaFrom(expressionStatement) .WithFormatterAnnotation(); SyntaxNode newRoot = root.ReplaceNode(expressionStatement, ifStatement); return(document.WithSyntaxRoot(newRoot)); }
public static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken = default(CancellationToken)) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ConditionalExpressionSyntax newNode = conditionalExpression.Update( condition: CSharpUtility.LogicallyNegate(conditionalExpression.Condition, semanticModel, cancellationToken), questionToken: conditionalExpression.QuestionToken, whenTrue: conditionalExpression.WhenFalse.WithTriviaFrom(conditionalExpression.WhenTrue), colonToken: conditionalExpression.ColonToken, whenFalse: conditionalExpression.WhenTrue.WithTriviaFrom(conditionalExpression.WhenFalse)); newNode = newNode.WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false)); }
public static async Task ComputeRefactoringAsync(RefactoringContext context, ConditionalExpressionSyntax conditionalExpression) { ExpressionSyntax expression = conditionalExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; if (parent.IsKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement)) { context.RegisterRefactoring( Title, cancellationToken => RefactorAsync(context.Document, (StatementSyntax)parent, conditionalExpression, cancellationToken)); } else if (parent is AssignmentExpressionSyntax assignment) { if (assignment.Parent is ExpressionStatementSyntax expressionStatement) { context.RegisterRefactoring( Title, cancellationToken => RefactorAsync(context.Document, expressionStatement, conditionalExpression, cancellationToken)); } } else { SingleLocalDeclarationStatementInfo localDeclarationInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(expression); if (localDeclarationInfo.Success) { TypeSyntax type = localDeclarationInfo.Type; if (type != null) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!type.IsVar || semanticModel.GetTypeSymbol(type, context.CancellationToken)?.SupportsExplicitDeclaration() == true) { context.RegisterRefactoring( Title, cancellationToken => RefactorAsync(context.Document, localDeclarationInfo.Statement, conditionalExpression, semanticModel, cancellationToken)); } } } } }
public static IEnumerable<ReplaceAction> GetSimplifications(ConditionalExpressionSyntax ternaryNode, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken)) { if (!ternaryNode.DefinitelyHasBooleanType(model)) yield break; var whenTrueFalseCmp = ternaryNode.WhenTrue.TryEvalAlternativeComparison(ternaryNode.WhenFalse, model, assume); if (whenTrueFalseCmp == true) { // (c ? b : b) --> b yield return new ReplaceAction( "Simplify", ternaryNode, ternaryNode.WhenTrue); // if condition has side effects we may need to keep it // (c ? b : b) --> ((c && false) || b) if (ternaryNode.Condition.HasSideEffects(model, assume) != false) { var replacement = ternaryNode.Condition .BracketedOrProtected() .BOpLogicalAnd(false.AsLiteral()) .Bracketed() .BOpLogicalOr(ternaryNode.WhenTrue); yield return new ReplaceAction( "Simplify (keeping condition evaluation)", ternaryNode, replacement); } } if (whenTrueFalseCmp == false) { // (c ? b : !b) --> (c == b) var replacement = ternaryNode.Condition .BracketedOrProtected() .BOpEquals(ternaryNode.WhenTrue); yield return new ReplaceAction( "Simplify", ternaryNode, replacement); } }
private IEnumerable<ITypeSymbol> InferTypeInConditionalExpression(ConditionalExpressionSyntax conditional, ExpressionSyntax expressionOpt = null, SyntaxToken? previousToken = null) { if (expressionOpt != null && conditional.Condition == expressionOpt) { // Foo() ? a : b return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Boolean)); } // a ? Foo() : b // // a ? b : Foo() var inTrueClause = (conditional.WhenTrue == expressionOpt) || (previousToken == conditional.QuestionToken); var inFalseClause = (conditional.WhenFalse == expressionOpt) || (previousToken == conditional.ColonToken); var otherTypes = inTrueClause ? GetTypes(conditional.WhenFalse) : inFalseClause ? GetTypes(conditional.WhenTrue) : SpecializedCollections.EmptyEnumerable<ITypeSymbol>(); return otherTypes.IsEmpty() ? InferTypes(conditional) : otherTypes; }
public override SyntaxNode VisitConditionalExpression(ConditionalExpressionSyntax node) { this.VisitExpression(node.Condition); _output.TrivialWrite(" ? "); this.VisitExpression(node.WhenTrue); _output.TrivialWrite(" : "); this.VisitExpression(node.WhenFalse); return node; }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitConditionalExpression(ConditionalExpressionSyntax node) { this.OnNodeVisited(node); if (!this.traverseRootOnly) base.VisitConditionalExpression(node); }
private static void RegisterConditionalExpressionRewrite(CodeFixContext context, SyntaxNode root, LiteralExpressionSyntax literal, ConditionalExpressionSyntax conditionalParent) { context.RegisterCodeFix( CodeAction.Create( Title, c => RewriteConditional(context.Document, root, literal, conditionalParent)), context.Diagnostics); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitConditionalExpression(ConditionalExpressionSyntax node) { this.OnNodeVisited(node, this.type.IsInstanceOfType(node)); base.VisitConditionalExpression(node); }
private static Document RewriteConditional(Document document, SyntaxNode root, SyntaxNode syntaxNode, ConditionalExpressionSyntax conditional) { if (conditional.WhenTrue.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.TrueExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalOrExpression, conditional.Condition, conditional.WhenFalse); return document.WithSyntaxRoot(newRoot); } if (conditional.WhenTrue.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.FalseExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalAndExpression, GetNegatedExpression(conditional.Condition), conditional.WhenFalse); return document.WithSyntaxRoot(newRoot); } if (conditional.WhenFalse.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.TrueExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalOrExpression, GetNegatedExpression(conditional.Condition), conditional.WhenTrue); return document.WithSyntaxRoot(newRoot); } if (conditional.WhenFalse.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.FalseExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalAndExpression, conditional.Condition, conditional.WhenTrue); return document.WithSyntaxRoot(newRoot); } return document; }
private static Document RemoveConditional(Document document, SyntaxNode root, ConditionalExpressionSyntax conditional) { if (EquivalenceChecker.AreEquivalent(conditional.WhenTrue, SyntaxHelper.TrueLiteralExpression)) { var newRoot = root.ReplaceNode(conditional, conditional.Condition.WithAdditionalAnnotations(Formatter.Annotation)); return document.WithSyntaxRoot(newRoot); } else { var newRoot = root.ReplaceNode(conditional, GetNegatedExpression(conditional.Condition).WithAdditionalAnnotations(Formatter.Annotation)); return document.WithSyntaxRoot(newRoot); } }
public ConditionalExpressionTranslation(ConditionalExpressionSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { Condition = syntax.Condition.Get<ExpressionTranslation>(this); WhenFalse = syntax.WhenFalse.Get<ExpressionTranslation>(this); WhenTrue = syntax.WhenTrue.Get<ExpressionTranslation>(this); }
private static Document RewriteConditional(Document document, SyntaxNode root, SyntaxNode syntaxNode, ConditionalExpressionSyntax conditional) { var whenTrue = conditional.WhenTrue.RemoveParentheses(); if (whenTrue.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, SyntaxHelper.TrueLiteralExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalOrExpression, conditional.Condition, conditional.WhenFalse); return document.WithSyntaxRoot(newRoot); } if (whenTrue.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, SyntaxHelper.FalseLiteralExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalAndExpression, GetNegatedExpression(conditional.Condition), conditional.WhenFalse); return document.WithSyntaxRoot(newRoot); } var whenFalse = conditional.WhenFalse.RemoveParentheses(); if (whenFalse.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, SyntaxHelper.TrueLiteralExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalOrExpression, GetNegatedExpression(conditional.Condition), conditional.WhenTrue); return document.WithSyntaxRoot(newRoot); } if (whenFalse.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, SyntaxHelper.FalseLiteralExpression)) { var newRoot = ReplaceExpressionWithBinary(conditional, root, SyntaxKind.LogicalAndExpression, conditional.Condition, conditional.WhenTrue); return document.WithSyntaxRoot(newRoot); } return document; }
private static Task<Document> RewriteConditional(Document document, SyntaxNode root, SyntaxNode syntaxNode, ConditionalExpressionSyntax conditional) { if (conditional.WhenTrue.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.TrueExpression)) { var newRoot = root.ReplaceNode(conditional, SyntaxFactory.BinaryExpression( SyntaxKind.LogicalOrExpression, conditional.Condition, conditional.WhenFalse)) .WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } if (conditional.WhenTrue.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.FalseExpression)) { var newRoot = root.ReplaceNode(conditional, SyntaxFactory.BinaryExpression( SyntaxKind.LogicalAndExpression, SyntaxFactory.PrefixUnaryExpression( SyntaxKind.LogicalNotExpression, conditional.Condition), conditional.WhenFalse)) .WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } if (conditional.WhenFalse.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.TrueExpression)) { var newRoot = root.ReplaceNode(conditional, SyntaxFactory.BinaryExpression( SyntaxKind.LogicalOrExpression, SyntaxFactory.PrefixUnaryExpression( SyntaxKind.LogicalNotExpression, conditional.Condition), conditional.WhenTrue)) .WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } if (conditional.WhenFalse.Equals(syntaxNode) && EquivalenceChecker.AreEquivalent(syntaxNode, BooleanLiteralUnnecessary.FalseExpression)) { var newRoot = root.ReplaceNode(conditional, SyntaxFactory.BinaryExpression( SyntaxKind.LogicalAndExpression, conditional.Condition, conditional.WhenTrue)) .WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } return Task.FromResult(document); }
private static Task<Document> RemoveConditional(Document document, SyntaxNode root, ConditionalExpressionSyntax conditional) { if (EquivalenceChecker.AreEquivalent(conditional.WhenTrue, BooleanLiteralUnnecessary.TrueExpression)) { var newRoot = root.ReplaceNode(conditional, conditional.Condition) .WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } else { var newRoot = root.ReplaceNode(conditional, SyntaxFactory.PrefixUnaryExpression( SyntaxKind.LogicalNotExpression, conditional.Condition)) .WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } }
private static void RegisterConditionalExpressionRemoval(CodeFixContext context, SyntaxNode root, ConditionalExpressionSyntax conditional) { context.RegisterCodeFix( CodeAction.Create( Title, c => RemoveConditional(context.Document, root, conditional)), context.Diagnostics); }
private ExpressionSyntax ParseSubExpression(uint precedence) { if (Current.Kind == SyntaxKind.CompileKeyword) { var compile = Match(SyntaxKind.CompileKeyword); var shaderTarget = Match(SyntaxKind.IdentifierToken); var shaderFunctionName = ParseIdentifier(); var shaderFunction = new InvocationExpressionSyntax(shaderFunctionName, ParseParenthesizedArgumentList(false)); return new CompileExpressionSyntax(compile, shaderTarget, shaderFunction); } ExpressionSyntax leftOperand; SyntaxKind opKind; // No left operand, so we need to parse one -- possibly preceded by a // unary operator. var tk = Current.Kind; if (SyntaxFacts.IsPrefixUnaryExpression(tk)) { opKind = SyntaxFacts.GetPrefixUnaryExpression(tk); leftOperand = ParsePrefixUnaryExpression(opKind); } else { // Not a unary operator - get a primary expression. leftOperand = ParseTerm(); } while (true) { // We either have a binary or assignment operator here, or we're finished. tk = Current.Kind; var isAssignmentOperator = false; if (SyntaxFacts.IsBinaryExpression(tk) && (!_greaterThanTokenIsNotOperator || tk != SyntaxKind.GreaterThanToken) && ((tk != SyntaxKind.GreaterThanToken || !_allowGreaterThanTokenAroundRhsExpression) && Lookahead.Kind != SyntaxKind.SemiToken)) { opKind = SyntaxFacts.GetBinaryExpression(tk); } else if (SyntaxFacts.IsAssignmentExpression(tk)) { opKind = SyntaxFacts.GetAssignmentExpression(tk); isAssignmentOperator = true; } else { break; } var newPrecedence = SyntaxFacts.GetOperatorPrecedence(opKind); Debug.Assert(newPrecedence > 0); // All binary operators must have precedence > 0! // Check the precedence to see if we should "take" this operator if (newPrecedence < precedence) break; // Same precedence, but not right-associative -- deal with this "later" if (newPrecedence == precedence && !SyntaxFacts.IsRightAssociative(opKind)) break; // Precedence is okay, so we'll "take" this operator. var opToken = NextToken(); SyntaxToken lessThanToken = null; if (isAssignmentOperator && _allowGreaterThanTokenAroundRhsExpression) lessThanToken = NextTokenIf(SyntaxKind.LessThanToken); var rightOperand = ParseSubExpression(newPrecedence); SyntaxToken greaterThanToken = null; if (lessThanToken != null) greaterThanToken = NextTokenIf(SyntaxKind.GreaterThanToken); if (isAssignmentOperator) leftOperand = new AssignmentExpressionSyntax(opKind, leftOperand, opToken, lessThanToken, rightOperand, greaterThanToken); else leftOperand = new BinaryExpressionSyntax(opKind, leftOperand, opToken, rightOperand); } var conditionalPrecedence = SyntaxFacts.GetOperatorPrecedence(SyntaxKind.ConditionalExpression); if (tk == SyntaxKind.QuestionToken && precedence <= conditionalPrecedence) { var questionToken = NextToken(); var colonLeft = ParseSubExpression(conditionalPrecedence); var colon = Match(SyntaxKind.ColonToken); var colonRight = ParseSubExpression(conditionalPrecedence); leftOperand = new ConditionalExpressionSyntax(leftOperand, questionToken, colonLeft, colon, colonRight); } return leftOperand; }
public void VisitConditionalExpression(ConditionalExpressionSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); ExpressionStart(node); node.Condition.Accept(this); if (_writer.Configuration.Spaces.TernaryOperator.BeforeQuestionMark) _writer.WriteSpace(); var wrap = _writer.Configuration.LineBreaksAndWrapping.LineWrapping.WrapTernaryExpression; if (wrap != Configuration.WrapStyle.SimpleWrap) _writer.Break(wrap == Configuration.WrapStyle.ChopAlways); _writer.WriteSyntax(Syntax.Question); if (_writer.Configuration.Spaces.TernaryOperator.AfterQuestionMark) _writer.WriteSpace(); node.WhenTrue.Accept(this); if (_writer.Configuration.Spaces.TernaryOperator.BeforeColon) _writer.WriteSpace(); if (wrap != Configuration.WrapStyle.SimpleWrap) _writer.Break(wrap == Configuration.WrapStyle.ChopAlways); _writer.WriteSyntax(Syntax.Colon); if (_writer.Configuration.Spaces.TernaryOperator.AfterColon) _writer.WriteSpace(); node.WhenFalse.Accept(this); ExpressionEnd(node); }
protected abstract void CompileConditionalExpression(ConditionalExpressionSyntax conditional);
public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { var getConditionMembers = new GetMembersVisitor(this); getConditionMembers.Visit(node.Condition); AddProperties(getConditionMembers._properties); var getWhenTrueMembers = new GetMembersVisitor(this); getWhenTrueMembers.Visit(node.WhenTrue); AddProperties(getWhenTrueMembers._properties); var getWhenFalseMembers = new GetMembersVisitor(this); getWhenFalseMembers.Visit(node.WhenFalse); AddProperties(getWhenFalseMembers._properties); var last = new PropertyDependence(); AddProperties(getWhenFalseMembers._properties.Last, last); AddProperties(getWhenTrueMembers._properties.Last, last); _properties.Last = last; _proceed = true; }
public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { Visit(node.Condition); var cond = expression; Visit(node.WhenTrue); var wt = expression; Visit(node.WhenFalse); var wf = expression; expression = Expression.Condition(cond, wt, wf); }
private static bool IsOnNullableBoolean(ConditionalExpressionSyntax conditionalExpression, SemanticModel semanticModel) { var typeLeft = semanticModel.GetTypeInfo(conditionalExpression.WhenTrue).Type; var typeRight = semanticModel.GetTypeInfo(conditionalExpression.WhenFalse).Type; return IsOnNullableBoolean(typeLeft, typeRight); }
static IfStatementSyntax CreateForConditionalExpression(AssignmentExpressionSyntax expr, ConditionalExpressionSyntax conditional) { return SyntaxFactory.IfStatement( conditional.Condition, SyntaxFactory.ExpressionStatement( SyntaxFactory.AssignmentExpression(expr.Kind(), expr.Left, conditional.WhenTrue) ), SyntaxFactory.ElseClause( SyntaxFactory.ExpressionStatement( SyntaxFactory.AssignmentExpression(expr.Kind(), expr.Left, conditional.WhenFalse) ) ) ); }
private static void AddConditionalExpressionTerms(ConditionalExpressionSyntax conditionalExpression, IList<string> terms, ref ExpressionType expressionType) { ExpressionType conditionFlags = ExpressionType.Invalid, trueFlags = ExpressionType.Invalid, falseFlags = ExpressionType.Invalid; AddSubExpressionTerms(conditionalExpression.Condition, terms, ref conditionFlags); AddSubExpressionTerms(conditionalExpression.WhenTrue, terms, ref trueFlags); AddSubExpressionTerms(conditionalExpression.WhenFalse, terms, ref falseFlags); AddIfValidTerm(conditionalExpression.Condition, conditionFlags, terms); AddIfValidTerm(conditionalExpression.WhenTrue, trueFlags, terms); AddIfValidTerm(conditionalExpression.WhenFalse, falseFlags, terms); // We're valid if all children are... expressionType = (conditionFlags & trueFlags & falseFlags) & ExpressionType.ValidExpression; }
/// <remarks> /// From ExpressionBinder::EnsureQMarkTypesCompatible: /// /// The v2.0 specification states that the types of the second and third operands T and S of a ternary operator /// must be TT and TS such that either (a) TT==TS, or (b), TT->TS or TS->TT but not both. /// /// Unfortunately that is not what we implemented in v2.0. Instead, we implemented /// that either (a) TT=TS or (b) T->TS or S->TT but not both. That is, we looked at the /// convertibility of the expressions, not the types. /// /// /// Changing that to the algorithm in the standard would be a breaking change. /// /// b ? (Func<int>)(delegate(){return 1;}) : (delegate(){return 2;}) /// /// and /// /// b ? 0 : myenum /// /// would suddenly stop working. (The first because o2 has no type, the second because 0 goes to /// any enum but enum doesn't go to int.) /// /// It gets worse. We would like the 3.0 language features which require type inference to use /// a consistent algorithm, and that furthermore, the algorithm be smart about choosing the best /// of a set of types. However, the language committee has decided that this algorithm will NOT /// consume information about the convertibility of expressions. Rather, it will gather up all /// the possible types and then pick the "largest" of them. /// /// To maintain backwards compatibility while still participating in the spirit of consistency, /// we implement an algorithm here which picks the type based on expression convertibility, but /// if there is a conflict, then it chooses the larger type rather than producing a type error. /// This means that b?0:myshort will have type int rather than producing an error (because 0->short, /// myshort->int). /// </remarks> private BoundExpression BindConditionalOperator(ConditionalExpressionSyntax node, DiagnosticBag diagnostics) { BoundExpression condition = BindBooleanExpression(node.Condition, diagnostics); BoundExpression trueExpr = BindValue(node.WhenTrue, diagnostics, BindValueKind.RValue); BoundExpression falseExpr = BindValue(node.WhenFalse, diagnostics, BindValueKind.RValue); TypeSymbol trueType = trueExpr.Type; TypeSymbol falseType = falseExpr.Type; TypeSymbol type; bool hasErrors = false; if (trueType == falseType) { // NOTE: Dev10 lets the type inferrer handle this case (presumably, for maximum consistency), // but it seems like a worthwhile short-circuit for a common case. if ((object)trueType == null) { // If trueExpr and falseExpr both have type null, then we don't have any symbols // to pass to a SymbolDistinguisher (which ERR_InvalidQM would usually require). diagnostics.Add(ErrorCode.ERR_InvalidQM, node.Location, trueExpr.Display, falseExpr.Display); type = CreateErrorType(); hasErrors = true; } else { // <expr> ? T : T type = trueType; } } else { bool hadMultipleCandidates; HashSet<DiagnosticInfo> useSiteDiagnostics = null; TypeSymbol bestType = BestTypeInferrer.InferBestTypeForConditionalOperator(trueExpr, falseExpr, this.Conversions, out hadMultipleCandidates, ref useSiteDiagnostics); diagnostics.Add(node, useSiteDiagnostics); if ((object)bestType == null) { // CONSIDER: Dev10 suppresses ERR_InvalidQM unless the following is true for both trueType and falseType // (!T->type->IsErrorType() || T->type->AsErrorType()->HasTypeParent() || T->type->AsErrorType()->HasNSParent()) if (hadMultipleCandidates) { diagnostics.Add(ErrorCode.ERR_AmbigQM, node.Location, trueExpr.Display, falseExpr.Display); } else { object trueArg = trueExpr.Display; object falseArg = falseExpr.Display; Symbol trueSymbol = trueArg as Symbol; Symbol falseSymbol = falseArg as Symbol; if ((object)trueSymbol != null && (object)falseSymbol != null) { SymbolDistinguisher distinguisher = new SymbolDistinguisher(this.Compilation, trueSymbol, falseSymbol); trueArg = distinguisher.First; falseArg = distinguisher.Second; } diagnostics.Add(ErrorCode.ERR_InvalidQM, node.Location, trueArg, falseArg); } type = CreateErrorType(); hasErrors = true; } else if (bestType.IsErrorType()) { type = bestType; hasErrors = true; } else { trueExpr = GenerateConversionForAssignment(bestType, trueExpr, diagnostics); falseExpr = GenerateConversionForAssignment(bestType, falseExpr, diagnostics); if (trueExpr.HasAnyErrors || falseExpr.HasAnyErrors) { // If one of the conversions went wrong (e.g. return type of method group being converted // didn't match), then we don't want to use bestType because it's not accurate. type = CreateErrorType(); hasErrors = true; } else { type = bestType; } } } ConstantValue constantValue = null; if (!hasErrors) { constantValue = FoldConditionalOperator(condition, trueExpr, falseExpr); hasErrors = constantValue != null && constantValue.IsBad; } return new BoundConditionalOperator(node, condition, trueExpr, falseExpr, constantValue, type, hasErrors); }
public virtual void VisitConditionalExpression(ConditionalExpressionSyntax node) { DefaultVisit(node); }
private ExpressionSyntax ParseDirectiveSubExpression(uint precedence) { ExpressionSyntax leftOperand; SyntaxKind opKind; // No left operand, so we need to parse one -- possibly preceded by a // unary operator. var tk = Current.Kind; if (SyntaxFacts.IsPrefixUnaryExpression(tk, true)) { opKind = SyntaxFacts.GetPrefixUnaryExpression(tk); leftOperand = ParseDirectivePrefixUnaryExpression(opKind); } else { // Not a unary operator - get a primary expression. leftOperand = ParseDirectiveTerm(); } while (true) { // We either have a binary operator here, or we're finished. tk = Current.Kind; if (SyntaxFacts.IsBinaryExpression(tk)) opKind = SyntaxFacts.GetBinaryExpression(tk); else break; var newPrecedence = SyntaxFacts.GetOperatorPrecedence(opKind); Debug.Assert(newPrecedence > 0); // All binary operators must have precedence > 0! // Check the precedence to see if we should "take" this operator if (newPrecedence < precedence) break; // Same precedence, but not right-associative -- deal with this "later" if (newPrecedence == precedence && !SyntaxFacts.IsRightAssociative(opKind)) break; // Precedence is okay, so we'll "take" this operator. var opToken = NextToken(); var rightOperand = ParseDirectiveSubExpression(newPrecedence); leftOperand = new BinaryExpressionSyntax(opKind, leftOperand, opToken, rightOperand); } var conditionalPrecedence = SyntaxFacts.GetOperatorPrecedence(SyntaxKind.ConditionalExpression); if (tk == SyntaxKind.QuestionToken && precedence <= conditionalPrecedence) { var questionToken = NextToken(); var colonLeft = ParseDirectiveSubExpression(conditionalPrecedence); var colon = Match(SyntaxKind.ColonToken); var colonRight = ParseDirectiveSubExpression(conditionalPrecedence); leftOperand = new ConditionalExpressionSyntax(leftOperand, questionToken, colonLeft, colon, colonRight); } return leftOperand; }
public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { this.Logic.Add(this.nodeFactory.CreateConditional(node)); }