Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert more lambda rude edits to runtime rude edits #75285

Merged
merged 3 commits into from
Oct 4, 2024
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 @@ -9850,5 +9850,103 @@ .maxstack 8
})
.Verify();
}

/// <summary>
/// Some lambda rude edits are simpler to detect in the IDE. They are specified via <see cref="RuntimeRudeEdit"/>.
/// The IDE tests cover the specific cases.
/// </summary>
[Fact]
public void IdeDetectedRuntimeRudeEdit()
{
using var _ = new EditAndContinueTest()
.AddBaseline(
source: """
using System;
class C
{
public void F()
<N:0>{
_ = new Func<int>(<N:1>() => 1</N:1>);
}</N:0>
}
""",
validator: g =>
{
g.VerifySynthesizedMembers(displayTypeKind: true,
[
"class C: {<>c}",
"class C.<>c: {<>9__0_0, <F>b__0_0}"
]);
})

.AddGeneration(
source: """
using System;
class C
{
public void F()
<N:0>{
_ = new Func<double>(<N:1>() => 1.0</N:1>);
}</N:0>
}
""",
edits:
[
Edit(SemanticEditKind.Update, c => c.GetMember("C.F"), preserveLocalVariables: true, rudeEdits: _ => new RuntimeRudeEdit("Return type changed", 0x123)),
],
validator: g =>
{
g.VerifySynthesizedMembers(
"System.Runtime.CompilerServices.HotReloadException",
"C: {<>c}",
"C.<>c: {<>9__0_0#1, <F>b__0_0#1}");

g.VerifyMethodDefNames(
"F", "<F>b__0_0", ".ctor", "<F>b__0_0#1");

g.VerifyIL(
"""
{
// Code size 30 (0x1e)
.maxstack 8
IL_0000: nop
IL_0001: ldsfld 0x04000004
IL_0006: brtrue.s IL_001d
IL_0008: ldsfld 0x04000001
IL_000d: ldftn 0x06000007
IL_0013: newobj 0x0A000008
IL_0018: stsfld 0x04000004
IL_001d: ret
}
{
// Code size 16 (0x10)
.maxstack 8
IL_0000: ldstr 0x70000005
IL_0005: ldc.i4 0x123
IL_000a: newobj 0x06000006
IL_000f: throw
}
{
// Code size 16 (0x10)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call 0x0A000009
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.2
IL_000a: stfld 0x04000003
IL_000f: ret
}
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldc.r8 1
IL_0009: ret
}
""");
})
.Verify();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ Imports System.Collections.Immutable
Imports System.Reflection.Metadata.Ecma335
Imports Microsoft.CodeAnalysis.EditAndContinue.UnitTests
Imports Microsoft.CodeAnalysis.Emit
Imports Microsoft.CodeAnalysis.Operations
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.EditAndContinue.UnitTests
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Roslyn.Test.Utilities
Expand Down Expand Up @@ -3947,6 +3949,100 @@ End Class
IL_0011: ldloc.0
IL_0012: ret
}
")
End Sub).
Verify()
End Using
End Sub

''' <summary>
''' Some lambda rude edits are simpler to detect in the IDE. They are specified via <see cref="RuntimeRudeEdit"/>.
''' The IDE tests cover the specific cases.
''' </summary>
<Fact>
Public Sub IdeDetectedRuntimeRudeEdit()
Using test = New EditAndContinueTest()
test.AddBaseline(
source:="
Imports System
Class C
Sub F()
Dim f1 = New Func(Of Integer)(<N:0>Function() 1</N:0>)
End Sub
End Class
",
validator:=
Sub(g)
g.VerifySynthesizedMembers(
"C._Closure$__: {$I1-0, _Lambda$__1-0}",
"C: {_Closure$__}")
End Sub).
AddGeneration(
source:="
Imports System
Class C
Sub F()
Dim f1 = New Func(Of Double)(<N:0>Function() 1.0</N:0>)
End Sub
End Class
",
edits:={Edit(SemanticEditKind.Update, Function(c) c.GetMember("C.F"), preserveLocalVariables:=True,
rudeEdits:=Function(node) New RuntimeRudeEdit("Return type changed", &H123))},
validator:=
Sub(g)
g.VerifySynthesizedMembers(
"System.Runtime.CompilerServices.HotReloadException",
"C: {_Closure$__}",
"C._Closure$__: {$I1-0#1, _Lambda$__1-0#1}")

g.VerifyMethodDefNames("F", "_Lambda$__1-0", ".ctor", "_Lambda$__1-0#1")

g.VerifyIL("
{
// Code size 39 (0x27)
.maxstack 2
IL_0000: nop
IL_0001: ldsfld 0x04000004
IL_0006: brfalse.s IL_000f
IL_0008: ldsfld 0x04000004
IL_000d: br.s IL_0025
IL_000f: ldsfld 0x04000001
IL_0014: ldftn 0x06000007
IL_001a: newobj 0x0A000008
IL_001f: dup
IL_0020: stsfld 0x04000004
IL_0025: stloc.1
IL_0026: ret
}
{
// Code size 12 (0xc)
.maxstack 8
IL_0000: ldstr 0x70000005
IL_0005: ldc.i4.m1
IL_0006: newobj 0x06000006
IL_000b: throw
}
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call 0x0A000009
IL_0007: ldarg.0
IL_0008: ldarg.2
IL_0009: stfld 0x04000003
IL_000e: ret
}
{
// Code size 15 (0xf)
.maxstack 1
IL_0000: nop
IL_0001: ldc.r8 1
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
}
")
End Sub).
Verify()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,8 @@ private static bool GroupBySignatureEquivalent(IMethodSymbol? oldMethod, IMethod
return ((AnonymousObjectCreationExpressionSyntax)node).NewKeyword.Span;

case SyntaxKind.ParenthesizedLambdaExpression:
return ((ParenthesizedLambdaExpressionSyntax)node).ParameterList.Span;
var parenthesizedLambda = (ParenthesizedLambdaExpressionSyntax)node;
return CombineSpans(parenthesizedLambda.ReturnType?.Span ?? default, parenthesizedLambda.ParameterList.Span, defaultSpan: default);

case SyntaxKind.SimpleLambdaExpression:
return ((SimpleLambdaExpressionSyntax)node).Parameter.Span;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10203,7 +10203,6 @@ static void Main(string[] args)
var active = GetActiveStatements(src1, src2);

edits.VerifySemanticDiagnostics(active,
Diagnostic(RudeEditKind.ChangingLambdaReturnType, "b", GetResource("lambda")),
Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "F(b);", GetResource("lambda")));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests;
internal static class EditAndContinueValidation
{
internal static void VerifyLineEdits(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
SourceLineUpdate[] lineEdits,
SemanticEditDescription[]? semanticEdits = null,
RudeEditDiagnosticDescription[]? diagnostics = null,
Expand All @@ -31,7 +31,7 @@ internal static void VerifyLineEdits(
}

internal static void VerifyLineEdits(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
SequencePointUpdates[] lineEdits,
SemanticEditDescription[]? semanticEdits = null,
RudeEditDiagnosticDescription[]? diagnostics = null,
Expand All @@ -46,30 +46,30 @@ internal static void VerifyLineEdits(
}

internal static void VerifySemanticDiagnostics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
params RudeEditDiagnosticDescription[] diagnostics)
{
VerifySemanticDiagnostics(editScript, activeStatements: null, targetFrameworks: null, capabilities: null, diagnostics);
}

internal static void VerifySemanticDiagnostics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
ActiveStatementsDescription activeStatements,
params RudeEditDiagnosticDescription[] diagnostics)
{
VerifySemanticDiagnostics(editScript, activeStatements, targetFrameworks: null, capabilities: null, diagnostics);
}

internal static void VerifySemanticDiagnostics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
RudeEditDiagnosticDescription[] diagnostics,
EditAndContinueCapabilities? capabilities)
{
VerifySemanticDiagnostics(editScript, activeStatements: null, targetFrameworks: null, capabilities, diagnostics);
}

internal static void VerifySemanticDiagnostics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
ActiveStatementsDescription? activeStatements = null,
TargetFramework[]? targetFrameworks = null,
EditAndContinueCapabilities? capabilities = null,
Expand All @@ -83,7 +83,7 @@ [new DocumentAnalysisResultsDescription(activeStatements: activeStatements, diag
}

internal static void VerifySemantics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
ActiveStatementsDescription activeStatements,
SemanticEditDescription[] semanticEdits,
EditAndContinueCapabilities? capabilities = null)
Expand All @@ -95,22 +95,22 @@ [new DocumentAnalysisResultsDescription(activeStatements, semanticEdits: semanti
}

internal static void VerifySemantics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
SemanticEditDescription[] semanticEdits,
EditAndContinueCapabilities capabilities)
{
VerifySemantics(editScript, ActiveStatementsDescription.Empty, semanticEdits, capabilities);
}

internal static void VerifySemantics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
params SemanticEditDescription[] semanticEdits)
{
VerifySemantics(editScript, ActiveStatementsDescription.Empty, semanticEdits, capabilities: null);
}

internal static void VerifySemantics(
this EditScript<SyntaxNode> editScript,
this EditScriptDescription editScript,
SemanticEditDescription[] semanticEdits,
RudeEditDiagnosticDescription[] warnings,
EditAndContinueCapabilities? capabilities = null)
Expand All @@ -122,7 +122,7 @@ [new DocumentAnalysisResultsDescription(ActiveStatementsDescription.Empty, seman
}

internal static void VerifySemantics(
EditScript<SyntaxNode>[] editScripts,
EditScriptDescription[] editScripts,
DocumentAnalysisResultsDescription[] results,
TargetFramework[]? targetFrameworks = null,
EditAndContinueCapabilities? capabilities = null)
Expand Down
Loading
Loading