Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ protected BoundTreeRewriterWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperat

if (child.Kind != BoundKind.BinaryOperator)
{
return base.VisitBinaryOperator(node);
return node.Update(node.OperatorKind, VisitBinaryOperatorData(node), node.ResultKind, (BoundExpression)this.Visit(node.Left), (BoundExpression)this.Visit(node.Right), this.VisitType(node.Type));
}

var stack = ArrayBuilder<BoundBinaryOperator>.GetInstance();
Expand Down Expand Up @@ -279,7 +279,7 @@ protected BoundTreeRewriterWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperat
var right = (BoundExpression?)this.Visit(binary.Right);
Debug.Assert(right is { });
var type = this.VisitType(binary.Type);
left = binary.Update(binary.OperatorKind, binary.Data, binary.ResultKind, left, right, type);
left = binary.Update(binary.OperatorKind, VisitBinaryOperatorData(binary), binary.ResultKind, left, right, type);
}
while (stack.Count > 0);

Expand All @@ -289,6 +289,11 @@ protected BoundTreeRewriterWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperat
return left;
}

protected virtual BoundBinaryOperator.UncommonData? VisitBinaryOperatorData(BoundBinaryOperator node)
{
return node.Data;
}

public sealed override BoundNode? VisitIfStatement(BoundIfStatement node)
{
if (node.AlternativeOpt is not BoundIfStatement ifStatement)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.CSharp
/// a bound node rewriter that rewrites types properly (which in some cases the automatically-generated
/// base class does not). This is used in the lambda rewriter, the iterator rewriter, and the async rewriter.
/// </summary>
internal abstract class BoundTreeToDifferentEnclosingContextRewriter : BoundTreeRewriterWithStackGuard
internal abstract class BoundTreeToDifferentEnclosingContextRewriter : BoundTreeRewriterWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator
{
// A mapping from every local variable to its replacement local variable. Local variables are replaced when
// their types change due to being inside of a generic method. Otherwise we reuse the original local (even
Expand Down Expand Up @@ -111,20 +111,12 @@ protected BoundBlock VisitBlock(BoundBlock node, bool removeInstrumentation)
return TypeMap.SubstituteType(type).Type;
}

public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
protected override BoundBinaryOperator.UncommonData? VisitBinaryOperatorData(BoundBinaryOperator node)
{
// Local rewriter should have already rewritten interpolated strings into their final form of calls and gotos
Debug.Assert(node.InterpolatedStringHandlerData is null);

return node.Update(
node.OperatorKind,
node.ConstantValueOpt,
VisitMethodSymbol(node.Method),
VisitType(node.ConstrainedToType),
node.ResultKind,
(BoundExpression)Visit(node.Left),
(BoundExpression)Visit(node.Right),
VisitType(node.Type));
return BoundBinaryOperator.UncommonData.CreateIfNeeded(node.ConstantValueOpt, VisitMethodSymbol(node.Method), VisitType(node.ConstrainedToType), node.OriginalUserDefinedOperatorsOpt);
}

public override BoundNode? VisitConversion(BoundConversion node)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,5 @@ public override BoundNode VisitFunctionPointerLoad(BoundFunctionPointerLoad node
{
return ExtensionMethodReferenceRewriter.VisitFunctionPointerLoad(this, node);
}

// PROTOTYPE: Handle deep recursion on long chain of binary operators, etc.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,13 @@ public static BoundNode VisitFunctionPointerLoad(BoundTreeRewriter rewriter, Bou
TypeSymbol? type = rewriter.VisitType(node.Type);
return node.Update(targetMethod, constrainedToTypeOpt, type);
}

protected override BoundBinaryOperator.UncommonData? VisitBinaryOperatorData(BoundBinaryOperator node)
{
Debug.Assert(node.Method is null ||
(!node.Method.IsExtensionMethod && !node.Method.GetIsNewExtensionMember())); // Expression tree context. At the moment an operator cannot be an extension method

return base.VisitBinaryOperatorData(node);
}
}
}