diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs index 91a2c3008c9c5..535215aa96485 100644 --- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs +++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs @@ -760,8 +760,7 @@ private bool AreNamespacesEqual(NamespaceSymbol @namespace, NamespaceSymbol othe private bool AreParametersEqual(ParameterSymbol parameter, ParameterSymbol other) { Debug.Assert(parameter.Ordinal == other.Ordinal); - return StringOrdinalComparer.Equals(parameter.MetadataName, other.MetadataName) && - (parameter.RefKind == other.RefKind) && + return (parameter.RefKind == other.RefKind) && _comparer.Equals(parameter.Type, other.Type); } diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs index fe4f8001f5fb7..61d2beaed442d 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs @@ -294,6 +294,97 @@ static void Main() { } Handle(2, TableIndex.AssemblyRef)); } + [Fact] + public void ModifyMethod_RenameParameter() + { + var source0 = +@"class C +{ + static string F(int a) { return a.ToString(); } +}"; + var source1 = +@"class C +{ + static string F(int x) { return x.ToString(); } +}"; + var source2 = +@"class C +{ + static string F(int b) { return b.ToString(); } +}"; + + var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll); + var compilation1 = compilation0.WithSource(source1); + var compilation2 = compilation1.WithSource(source2); + + var method0 = compilation0.GetMember("C.F"); + + // Verify full metadata contains expected rows. + var bytes0 = compilation0.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb)); + using var md0 = ModuleMetadata.CreateFromImage(bytes0); + var reader0 = md0.MetadataReader; + + CheckNames(reader0, reader0.GetTypeDefNames(), "", "C"); + CheckNames(reader0, reader0.GetMethodDefNames(), "F", ".ctor"); + CheckNames(reader0, reader0.GetParameterDefNames(), "a"); + + var generation0 = EmitBaseline.CreateInitialBaseline( + md0, + EmptyLocalsProvider); + var method1 = compilation1.GetMember("C.F"); + + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1))); + + // Verify delta metadata contains expected rows. + using var md1 = diff1.GetMetadata(); + var reader1 = md1.Reader; + var readers = new[] { reader0, reader1 }; + + EncValidation.VerifyModuleMvid(1, reader0, reader1); + + CheckNames(readers, reader1.GetTypeDefNames()); + CheckNames(readers, reader1.GetMethodDefNames(), "F"); + CheckNames(readers, reader1.GetParameterDefNames(), "x"); + + CheckEncLogDefinitions(reader1, + Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.Param, EditAndContinueOperation.Default)); + + CheckEncMapDefinitions(reader1, + Handle(1, TableIndex.MethodDef), + Handle(1, TableIndex.Param), + Handle(2, TableIndex.StandAloneSig)); + + var method2 = compilation2.GetMember("C.F"); + + var diff2 = compilation2.EmitDifference( + diff1.NextGeneration, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method1, method2))); + + // Verify delta metadata contains expected rows. + using var md2 = diff2.GetMetadata(); + var reader2 = md2.Reader; + readers = new[] { reader0, reader1, reader2 }; + + CheckNames(readers, reader2.GetTypeDefNames()); + CheckNames(readers, reader2.GetMethodDefNames(), "F"); + CheckNames(readers, reader2.GetMemberRefNames(), "ToString"); + CheckNames(readers, reader2.GetParameterDefNames(), "b"); + + CheckEncLogDefinitions(reader2, + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.Param, EditAndContinueOperation.Default)); + + CheckEncMapDefinitions(reader2, + Handle(1, TableIndex.MethodDef), + Handle(1, TableIndex.Param), + Handle(3, TableIndex.StandAloneSig)); + } + [CompilerTrait(CompilerFeature.Tuples)] [Fact] public void ModifyMethod_WithTuples() @@ -1404,6 +1495,10 @@ class C EncValidation.VerifyModuleMvid(2, reader1, reader2); CheckNames(readers, reader2.GetTypeDefNames()); + CheckNames(readers, reader2.GetMethodDefNames(), "F"); + CheckNames(readers, reader2.GetParameterDefNames(), "", "arg"); + CheckNames(readers, diff2.EmitResult.ChangedTypes, "C"); + CheckNames(readers, diff2.EmitResult.UpdatedMethods, "F"); CheckEncLogDefinitions(reader2, Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default), // C.F2 @@ -12043,5 +12138,89 @@ public void TopLevelStatement_Update() Handle(8, TableIndex.MemberRef), Handle(2, TableIndex.AssemblyRef)); } + + [Fact] + public void LambdaParameterToDiscard() + { + var source0 = MarkedSource(@" +using System; +class C +{ + void M() + { + var x = new Func((a, b) => a + b + 1); + Console.WriteLine(x(1, 2)); + } +}"); + var source1 = MarkedSource(@" +using System; +class C +{ + void M() + { + var x = new Func((_, _) => 10); + Console.WriteLine(x(1, 2)); + } +}"); + + var compilation0 = CreateCompilation(source0.Tree, options: ComSafeDebugDll); + var compilation1 = compilation0.WithSource(source1.Tree); + + var method0 = compilation0.GetMember("C.M"); + var method1 = compilation1.GetMember("C.M"); + + var v0 = CompileAndVerify(compilation0, verify: Verification.Skipped); + + using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); + + var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); + + var diff = compilation1.EmitDifference( + generation0, + ImmutableArray.Create( + SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); + + // There should be no diagnostics from rude edits + diff.EmitResult.Diagnostics.Verify(); + + diff.VerifySynthesizedMembers( + "C: {<>c}", + "C.<>c: {<>9__0_0, b__0_0}"); + + diff.VerifyIL("C.M", + @" + { + // Code size 48 (0x30) + .maxstack 3 + .locals init ([unchanged] V_0, + System.Func V_1) //x + IL_0000: nop + IL_0001: ldsfld ""System.Func C.<>c.<>9__0_0"" + IL_0006: dup + IL_0007: brtrue.s IL_0020 + IL_0009: pop + IL_000a: ldsfld ""C.<>c C.<>c.<>9"" + IL_000f: ldftn ""int C.<>c.b__0_0(int, int)"" + IL_0015: newobj ""System.Func..ctor(object, System.IntPtr)"" + IL_001a: dup + IL_001b: stsfld ""System.Func C.<>c.<>9__0_0"" + IL_0020: stloc.1 + IL_0021: ldloc.1 + IL_0022: ldc.i4.1 + IL_0023: ldc.i4.2 + IL_0024: callvirt ""int System.Func.Invoke(int, int)"" + IL_0029: call ""void System.Console.WriteLine(int)"" + IL_002e: nop + IL_002f: ret +}"); + + diff.VerifyIL("C.<>c.b__0_0(int, int)", @" +{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldc.i4.s 10 + IL_0002: ret +}"); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.cs index e3238e95c4e61..b2bb176e580eb 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.cs @@ -1112,6 +1112,68 @@ class C Assert.NotNull(other); } + [Fact] + public void Method_ParameterRename() + { + var source0 = @" +using System.Collections.Generic; +class C +{ + string M(string s) => s.ToString(); +}"; + var source1 = @" +using System.Collections.Generic; +class C +{ + string M(string m) => m.ToString(); +}"; + var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll); + var compilation1 = compilation0.WithSource(source1); + + var matcher = new CSharpSymbolMatcher( + null, + compilation1.SourceAssembly, + default, + compilation0.SourceAssembly, + default, + null); + + var member = compilation1.GetMember("C.M"); + var other = matcher.MapDefinition(member.GetCciAdapter()); + Assert.NotNull(other); + } + + [Fact] + public void Method_ParameterRenameToDiscard() + { + var source0 = @" +using System.Collections.Generic; +class C +{ + string M(string s) => s.ToString(); +}"; + var source1 = @" +using System.Collections.Generic; +class C +{ + string M(string _) => ""Hello""; +}"; + var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll); + var compilation1 = compilation0.WithSource(source1); + + var matcher = new CSharpSymbolMatcher( + null, + compilation1.SourceAssembly, + default, + compilation0.SourceAssembly, + default, + null); + + var member = compilation1.GetMember("C.M"); + var other = matcher.MapDefinition(member.GetCciAdapter()); + Assert.NotNull(other); + } + [Fact] public void Field_NullableChange() { diff --git a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb index 5ae48120979ef..739ecbf9b1fcc 100644 --- a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb +++ b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb @@ -597,7 +597,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit Private Function AreParametersEqual(parameter As ParameterSymbol, other As ParameterSymbol) As Boolean Debug.Assert(parameter.Ordinal = other.Ordinal) - Return s_nameComparer.Equals(parameter.Name, other.Name) AndAlso parameter.IsByRef = other.IsByRef AndAlso Me._comparer.Equals(parameter.Type, other.Type) + Return parameter.IsByRef = other.IsByRef AndAlso Me._comparer.Equals(parameter.Type, other.Type) End Function Private Function ArePropertiesEqual([property] As PropertySymbol, other As PropertySymbol) As Boolean diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTestBase.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTestBase.vb index f05b8ece272e4..8252f2f63d2b1 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTestBase.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTestBase.vb @@ -186,12 +186,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests End Sub Friend Shared Sub CheckEncLogDefinitions(reader As MetadataReader, ParamArray rows As EditAndContinueLogEntry()) - AssertEx.Equal(rows, reader.GetEditAndContinueLogEntries().Where(Function(entry) IsDefinition(entry)), itemInspector:=AddressOf EncLogRowToString) + AssertEx.Equal(rows, reader.GetEditAndContinueLogEntries().Where(Function(entry) IsDefinition(entry.Handle.Kind)), itemInspector:=AddressOf EncLogRowToString) End Sub - Friend Shared Function IsDefinition(entry As EditAndContinueLogEntry) As Boolean + Friend Shared Function IsDefinition(kind As HandleKind) As Boolean Dim index As TableIndex - Assert.True(MetadataTokens.TryGetTableIndex(entry.Handle.Kind, index)) + Assert.True(MetadataTokens.TryGetTableIndex(kind, index)) Select Case index Case TableIndex.MethodDef, @@ -232,6 +232,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests AssertEx.Equal([handles], reader.GetEditAndContinueMapEntries(), itemInspector:=AddressOf EncMapRowToString) End Sub + Friend Shared Sub CheckEncMapDefinitions(reader As MetadataReader, ParamArray [handles] As EntityHandle()) + AssertEx.Equal([handles], reader.GetEditAndContinueMapEntries().Where(Function(e) IsDefinition(e.Kind)), itemInspector:=AddressOf EncMapRowToString) + End Sub + Friend Shared Sub CheckNames(reader As MetadataReader, [handles] As StringHandle(), ParamArray expectedNames As String()) CheckNames({reader}, [handles], expectedNames) End Sub diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb index f13031ee6ca7a..cd3b9bea2632e 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb @@ -185,6 +185,60 @@ End Class End Using End Sub + + Public Sub ModifyMethod_RenameParameter() + Dim source0 = +" +Class C + Shared Function F(i As Integer) As Integer + Return i + End Function +End Class +" + Dim source1 = +" +Class C + Shared Function F(x As Integer) As Integer + Return x + End Function +End Class +" + Dim compilation0 = CreateCompilationWithMscorlib40({source0}, options:=TestOptions.DebugDll, references:={ValueTupleRef, SystemRuntimeFacadeRef}) + Dim compilation1 = compilation0.WithSource(source1) + + Dim bytes0 = compilation0.EmitToArray() + Using md0 = ModuleMetadata.CreateFromImage(bytes0) + Dim reader0 = md0.MetadataReader + Dim method0 = compilation0.GetMember(Of MethodSymbol)("C.F") + Dim generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider) + + CheckNames(reader0, reader0.GetParameterDefNames(), "i") + + Dim method1 = compilation1.GetMember(Of MethodSymbol)("C.F") + Dim diff1 = compilation1.EmitDifference(generation0, ImmutableArray.Create(New SemanticEdit(SemanticEditKind.Update, method0, method1))) + + ' Verify delta metadata contains expected rows. + Using md1 = diff1.GetMetadata() + Dim reader1 = md1.Reader + Dim readers = {reader0, reader1} + EncValidation.VerifyModuleMvid(1, reader0, reader1) + CheckNames(readers, reader1.GetTypeDefNames()) + CheckNames(readers, reader1.GetMethodDefNames(), "F") + CheckNames(readers, reader1.GetParameterDefNames(), "x") + + CheckEncLogDefinitions(reader1, + Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.Param, EditAndContinueOperation.Default)) + + CheckEncMapDefinitions(reader1, + Handle(2, TableIndex.MethodDef), + Handle(1, TableIndex.Param), + Handle(2, TableIndex.StandAloneSig)) + End Using + End Using + End Sub + Public Sub PartialMethod() diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb index 8cd4cdd848467..05b95fab174b9 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb @@ -515,6 +515,38 @@ End Class Assert.Null(mappedX2) End Sub + + Public Sub Method_RenameParameter() + Dim source0 = " +Class C + Public Function X(a As Integer) As Integer + Return a + End Function +End Class +" + Dim source1 = " +Class C + Public Function X(b As Integer) As Integer + Return b + End Function +End Class +" + Dim compilation0 = CreateCompilationWithMscorlib40(source0, options:=TestOptions.DebugDll, references:=ValueTupleRefs) + Dim compilation1 = compilation0.WithSource(source1) + + Dim matcher = New VisualBasicSymbolMatcher( + Nothing, + compilation1.SourceAssembly, + New EmitContext(), + compilation0.SourceAssembly, + New EmitContext(), + Nothing) + + Dim member = compilation1.GetMember(Of MethodSymbol)("C.X") + Dim other = matcher.MapDefinition(member.GetCciAdapter()) + Assert.NotNull(other) + End Sub + Public Sub TupleField_TypeChange() Dim source0 = " diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs index ebbb1ab30742a..252fce25a3da2 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs @@ -897,8 +897,13 @@ class Goo var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, - Diagnostic(RudeEditKind.Renamed, "int b", FeaturesResources.parameter)); + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("Goo..ctor")) + }, + capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); } [WorkItem(742334, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")] @@ -8724,6 +8729,36 @@ static void Main() edits.VerifyRudeDiagnostics(active); } + [Fact] + public void Lambdas_ActiveStatementUpdate() + { + var src1 = @" +using System; +class C +{ + static void Main(string[] args) + { + Func f = (int a, int b) => a + b + 1; + f(2); + } +}"; + var src2 = @" +using System; +class C +{ + static void Main(string[] args) + { + Func f = (_, _) => 10; + f(2); + } +} +"; + var edits = GetTopEdits(src1, src2); + var active = GetActiveStatements(src1, src2); + + edits.VerifySemanticDiagnostics(active, capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + } + [Fact] public void Lambdas_ActiveStatementRemoved1() { diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs index cece2fab3af28..466bf997ff5d8 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs @@ -4942,8 +4942,57 @@ static void Main(int X) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "int X", FeaturesResources.parameter)); + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("Program.Main"), preserveLocalVariables: true) + }, + capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + } + + [Fact] + public void Lambdas_Parameter_To_Discard1() + { + var src1 = "var x = new System.Func((a, b) => 1);"; + var src2 = "var x = new System.Func((a, _) => 1);"; + + var edits = GetMethodEdits(src1, src2); + + edits.VerifyEdits( + "Update [b]@45 -> [_]@45"); + + GetTopEdits(edits).VerifySemantics(SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"), preserveLocalVariables: true)); + } + + [Fact] + public void Lambdas_Parameter_To_Discard2() + { + var src1 = "var x = new System.Func((int a, int b) => 1);"; + var src2 = "var x = new System.Func((_, _) => 1);"; + + var edits = GetMethodEdits(src1, src2); + + edits.VerifyEdits( + "Update [int a]@42 -> [_]@42", + "Update [int b]@49 -> [_]@45"); + + GetTopEdits(edits).VerifySemantics(SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"), preserveLocalVariables: true)); + } + + [Fact] + public void Lambdas_Parameter_To_Discard3() + { + var src1 = "var x = new System.Func((a, b) => 1);"; + var src2 = "var x = new System.Func((_, _) => 1);"; + + var edits = GetMethodEdits(src1, src2); + + edits.VerifyEdits( + "Update [a]@42 -> [_]@42", + "Update [b]@45 -> [_]@45"); + + GetTopEdits(edits).VerifySemantics(SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"), preserveLocalVariables: true)); } #endregion @@ -6986,8 +7035,13 @@ static void Main(int X) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "int X", FeaturesResources.parameter)); + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("Program.Main"), preserveLocalVariables: true) + }, + capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); } [Fact] diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementMatchingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementMatchingTests.cs index 87040bbf65213..7a097a377a7c5 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementMatchingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementMatchingTests.cs @@ -938,6 +938,29 @@ public void LambdasInStackalloc_Initializer() expected.AssertEqual(actual); } + [Fact] + public void Lambdas_ParameterToDiscard() + { + var src1 = "var x = F((a, b) => 1);"; + var src2 = "var x = F((_, _) => 2);"; + + var match = GetMethodMatch(src1, src2); + var actual = ToMatchingPairs(match); + + var expected = new MatchingPairs + { + { "var x = F((a, b) => 1);", "var x = F((_, _) => 2);" }, + { "var x = F((a, b) => 1)", "var x = F((_, _) => 2)" }, + { "x = F((a, b) => 1)", "x = F((_, _) => 2)" }, + { "(a, b) => 1", "(_, _) => 2" }, + { "(a, b)", "(_, _)" }, + { "a", "_" }, + { "b", "_" } + }; + + expected.AssertEqual(actual); + } + #endregion #region Local Functions diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs index 31bb6050293a8..69257523a93b6 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs @@ -4052,7 +4052,16 @@ public void Delegates_Parameter_Rename() "Update [int a]@22 -> [int b]@22"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "int b", FeaturesResources.parameter)); + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.Invoke")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.BeginInvoke")) + }, + capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); } [Fact] @@ -6788,7 +6797,48 @@ static void Main(string[] b) "Update [string[] args]@35 -> [string[] b]@35"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "string[] b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "string[] b", FeaturesResources.parameter)); + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Main")) + }, + capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + } + + [Fact] + public void MethodUpdate_UpdateParameterAndBody() + { + var src1 = @" +class C +{ + static void Main(string[] args) + { + + } +}"; + var src2 = @" +class C +{ + static void Main(string[] b) + { + System.Console.Write(1); + } +}"; + var edits = GetTopEdits(src1, src2); + + edits.VerifyRudeDiagnostics( + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "string[] b", FeaturesResources.parameter)); + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Main")) + }, + capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); } [Fact] diff --git a/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs b/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs index a7f89cabeae84..1b612f36a90d7 100644 --- a/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs +++ b/src/EditorFeatures/TestUtilities/EditAndContinue/EditAndContinueTestHelpers.cs @@ -34,7 +34,8 @@ internal abstract class EditAndContinueTestHelpers public static readonly EditAndContinueCapabilities Net6RuntimeCapabilities = Net5RuntimeCapabilities | - EditAndContinueCapabilities.ChangeCustomAttributes; + EditAndContinueCapabilities.ChangeCustomAttributes | + EditAndContinueCapabilities.UpdateParameters; public abstract AbstractEditAndContinueAnalyzer Analyzer { get; } public abstract SyntaxNode FindNode(SyntaxNode root, TextSpan span); diff --git a/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb b/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb index ff30e3a7a95b0..10f75fe74ac0f 100644 --- a/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb +++ b/src/EditorFeatures/VisualBasicTest/EditAndContinue/TopLevelEditingTests.vb @@ -2217,7 +2217,16 @@ End Class "Update [a]@27 -> [b]@27") edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "Public Delegate Function D(b As Integer)", DeletedSymbolDisplay(FeaturesResources.parameter, "a As Integer"))) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "Public Delegate Function D(b As Integer)", DeletedSymbolDisplay(FeaturesResources.parameter, "a As Integer"))) + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + semanticEdits:= + { + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("D.Invoke")), + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("D.BeginInvoke")) + }, + capabilities:=EditAndContinueTestHelpers.Net6RuntimeCapabilities) End Sub @@ -9758,7 +9767,15 @@ End Class "Update [a]@24 -> [b]@24") edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "b", FeaturesResources.parameter)) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "b", FeaturesResources.parameter)) + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + semanticEdits:= + { + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.M")) + }, + capabilities:=EditAndContinueTestHelpers.Net6RuntimeCapabilities) End Sub @@ -9771,7 +9788,15 @@ End Class "Update [a]@26 -> [b]@26") edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "b", FeaturesResources.parameter)) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "b", FeaturesResources.parameter)) + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + semanticEdits:= + { + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").InstanceConstructors.Single()) + }, + capabilities:=EditAndContinueTestHelpers.Net6RuntimeCapabilities) End Sub @@ -9784,7 +9809,15 @@ End Class "Update [a]@40 -> [b]@40") edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "b", FeaturesResources.parameter)) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "b", FeaturesResources.parameter)) + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + semanticEdits:= + { + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").GetMember("op_Explicit")) + }, + capabilities:=EditAndContinueTestHelpers.Net6RuntimeCapabilities) End Sub @@ -9797,7 +9830,15 @@ End Class "Update [b]@44 -> [x]@44") edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "x", FeaturesResources.parameter)) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "x", FeaturesResources.parameter)) + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + semanticEdits:= + { + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember(Of NamedTypeSymbol)("C").GetMember("op_Addition")) + }, + capabilities:=EditAndContinueTestHelpers.Net6RuntimeCapabilities) End Sub @@ -9810,7 +9851,15 @@ End Class "Update [b]@52 -> [x]@52") edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "x", FeaturesResources.parameter)) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "x", FeaturesResources.parameter)) + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + semanticEdits:= + { + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.P")) + }, + capabilities:=EditAndContinueTestHelpers.Net6RuntimeCapabilities) End Sub @@ -9823,7 +9872,15 @@ End Class "Update [a]@24 -> [b]@24") edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Renamed, "b", FeaturesResources.parameter)) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "b", FeaturesResources.parameter)) + + edits.VerifySemantics( + ActiveStatementsDescription.Empty, + semanticEdits:= + { + SemanticEdit(SemanticEditKind.Update, Function(c) c.GetMember("C.M")) + }, + capabilities:=EditAndContinueTestHelpers.Net6RuntimeCapabilities) End Sub @@ -10015,7 +10072,7 @@ End Class edits.VerifyRudeDiagnostics( Diagnostic(RudeEditKind.Move, "b As Integer", FeaturesResources.parameter), - Diagnostic(RudeEditKind.Renamed, "c", FeaturesResources.parameter)) + Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "c", FeaturesResources.parameter)) End Sub diff --git a/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs b/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs index b17d5eea3a220..bc6a3043f0c28 100644 --- a/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs +++ b/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs @@ -708,7 +708,7 @@ internal virtual void ReportDeclarationInsertDeleteRudeEdits(ArrayBuilder s_exactSymbolEqualityComparer.Equals(oldSymbol, newSymbol); protected static bool SignaturesEquivalent(ImmutableArray oldParameters, ITypeSymbol oldReturnType, ImmutableArray newParameters, ITypeSymbol newReturnType) - => ParametersEquivalent(oldParameters, newParameters, exact: false) && + => ParameterTypesEquivalent(oldParameters, newParameters, exact: false) && s_runtimeSymbolEqualityComparer.Equals(oldReturnType, newReturnType); // TODO: should check ref, ref readonly, custom mods - protected static bool ParametersEquivalent(ImmutableArray oldParameters, ImmutableArray newParameters, bool exact) + protected static bool ParameterTypesEquivalent(ImmutableArray oldParameters, ImmutableArray newParameters, bool exact) => oldParameters.SequenceEqual(newParameters, exact, (oldParameter, newParameter, exact) => ParameterTypesEquivalent(oldParameter, newParameter, exact)); protected static bool CustomModifiersEquivalent(CustomModifier oldModifier, CustomModifier newModifier, bool exact) @@ -3278,14 +3278,17 @@ private void ReportUpdatedSymbolDeclarationRudeEdits( ISymbol newSymbol, SyntaxNode? newNode, Compilation newCompilation, + EditAndContinueCapabilities capabilities, out bool hasGeneratedAttributeChange, out bool hasGeneratedReturnTypeAttributeChange, + out bool hasParameterRename, CancellationToken cancellationToken) { var rudeEdit = RudeEditKind.None; hasGeneratedAttributeChange = false; hasGeneratedReturnTypeAttributeChange = false; + hasParameterRename = false; if (oldSymbol.Kind != newSymbol.Kind) { @@ -3293,7 +3296,21 @@ private void ReportUpdatedSymbolDeclarationRudeEdits( } else if (oldSymbol.Name != newSymbol.Name) { - rudeEdit = RudeEditKind.Renamed; + if (oldSymbol is IParameterSymbol && newSymbol is IParameterSymbol) + { + if (capabilities.HasFlag(EditAndContinueCapabilities.UpdateParameters)) + { + hasParameterRename = true; + } + else + { + rudeEdit = RudeEditKind.RenamingNotSupportedByRuntime; + } + } + else + { + rudeEdit = RudeEditKind.Renamed; + } // specialize rude edit for accessors and conversion operators: if (oldSymbol is IMethodSymbol oldMethod && newSymbol is IMethodSymbol newMethod) @@ -3647,11 +3664,16 @@ private void AnalyzeSymbolUpdate( ReportCustomAttributeRudeEdits(diagnostics, oldSymbol, newSymbol, newNode, newCompilation, capabilities, out var hasAttributeChange, out var hasReturnTypeAttributeChange, cancellationToken); - ReportUpdatedSymbolDeclarationRudeEdits(diagnostics, oldSymbol, newSymbol, newNode, newCompilation, out var hasGeneratedAttributeChange, out var hasGeneratedReturnTypeAttributeChange, cancellationToken); + ReportUpdatedSymbolDeclarationRudeEdits(diagnostics, oldSymbol, newSymbol, newNode, newCompilation, capabilities, out var hasGeneratedAttributeChange, out var hasGeneratedReturnTypeAttributeChange, out var hasParameterRename, cancellationToken); hasAttributeChange |= hasGeneratedAttributeChange; hasReturnTypeAttributeChange |= hasGeneratedReturnTypeAttributeChange; - if (hasAttributeChange || hasReturnTypeAttributeChange) + if (hasParameterRename) + { + Debug.Assert(newSymbol is IParameterSymbol); + AddParameterUpdateSemanticEdit(semanticEdits, (IParameterSymbol)newSymbol, syntaxMap, cancellationToken); + } + else if (hasAttributeChange || hasReturnTypeAttributeChange) { AddCustomAttributeSemanticEdits(semanticEdits, oldSymbol, newSymbol, topMatch, syntaxMap, hasAttributeChange, hasReturnTypeAttributeChange, cancellationToken); } @@ -3686,7 +3708,7 @@ private static void AddCustomAttributeSemanticEdits( { // attributes applied on return type of a delegate are applied to both Invoke and BeginInvoke methods semanticEdits.Add(new SemanticEditInfo(SemanticEditKind.Update, SymbolKey.Create(newDelegateInvokeMethod, cancellationToken), syntaxMap, syntaxMapTree: null, partialType: null)); - AddDelegateBeginInvokeEdit(newDelegateType); + AddDelegateBeginInvokeEdit(semanticEdits, newDelegateType, syntaxMap, cancellationToken); } } else if (newSymbol is INamedTypeSymbol) @@ -3705,28 +3727,32 @@ private static void AddCustomAttributeSemanticEdits( { semanticEdits.Add(new SemanticEditInfo(SemanticEditKind.Update, SymbolKey.Create(newSymbol, cancellationToken), syntaxMap, syntaxMapTree: null, partialType: null)); } - else if (newSymbol is IParameterSymbol) + else if (newSymbol is IParameterSymbol newParameterSymbol) { - var newContainingSymbol = newSymbol.ContainingSymbol; - semanticEdits.Add(new SemanticEditInfo(SemanticEditKind.Update, SymbolKey.Create(newContainingSymbol, cancellationToken), syntaxMap, syntaxMapTree: null, partialType: null)); - - // attributes applied on parameters of a delegate are applied to both Invoke and BeginInvoke methods - if (newContainingSymbol.ContainingSymbol is INamedTypeSymbol { TypeKind: TypeKind.Delegate } newContainingDelegateType) - { - AddDelegateBeginInvokeEdit(newContainingDelegateType); - } + AddParameterUpdateSemanticEdit(semanticEdits, newParameterSymbol, syntaxMap, cancellationToken); } + } - // attribute applied on parameters or return value of a delegate are applied to both Invoke and BeginInvoke methods - void AddDelegateBeginInvokeEdit(INamedTypeSymbol delegateType) + private static void AddParameterUpdateSemanticEdit(ArrayBuilder semanticEdits, IParameterSymbol newParameterSymbol, Func? syntaxMap, CancellationToken cancellationToken) + { + var newContainingSymbol = newParameterSymbol.ContainingSymbol; + semanticEdits.Add(new SemanticEditInfo(SemanticEditKind.Update, SymbolKey.Create(newContainingSymbol, cancellationToken), syntaxMap, syntaxMapTree: null, partialType: null)); + + // attributes applied on parameters of a delegate are applied to both Invoke and BeginInvoke methods + if (newContainingSymbol.ContainingSymbol is INamedTypeSymbol { TypeKind: TypeKind.Delegate } newContainingDelegateType) { - Debug.Assert(semanticEdits != null); + AddDelegateBeginInvokeEdit(semanticEdits, newContainingDelegateType, syntaxMap, cancellationToken); + } + } - var beginInvokeMethod = delegateType.GetMembers("BeginInvoke").FirstOrDefault(); - if (beginInvokeMethod != null) - { - semanticEdits.Add(new SemanticEditInfo(SemanticEditKind.Update, SymbolKey.Create(beginInvokeMethod, cancellationToken), syntaxMap, syntaxMapTree: null, partialType: null)); - } + private static void AddDelegateBeginInvokeEdit(ArrayBuilder semanticEdits, INamedTypeSymbol delegateType, Func? syntaxMap, CancellationToken cancellationToken) + { + Debug.Assert(semanticEdits != null); + + var beginInvokeMethod = delegateType.GetMembers("BeginInvoke").FirstOrDefault(); + if (beginInvokeMethod != null) + { + semanticEdits.Add(new SemanticEditInfo(SemanticEditKind.Update, SymbolKey.Create(beginInvokeMethod, cancellationToken), syntaxMap, syntaxMapTree: null, partialType: null)); } } @@ -5257,7 +5283,7 @@ private void ReportLambdaSignatureRudeEdits( var newLambdaSymbol = GetLambdaExpressionSymbol(newModel, newLambda, cancellationToken); // signature validation: - if (!ParametersEquivalent(oldLambdaSymbol.Parameters, newLambdaSymbol.Parameters, exact: false)) + if (!ParameterTypesEquivalent(oldLambdaSymbol.Parameters, newLambdaSymbol.Parameters, exact: false)) { ReportUpdateRudeEdit(diagnostics, RudeEditKind.ChangingLambdaParameters, newLambda); hasSignatureErrors = true; diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs index 2d6a527566aac..cdf44e071eb26 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs @@ -43,5 +43,10 @@ internal enum EditAndContinueCapabilities /// Adding, updating and deleting of custom attributes (as distinct from pseudo-custom attributes) /// ChangeCustomAttributes = 1 << 5, + + /// + /// Whether the runtime supports updating the Param table, and hence related edits (eg parameter renames) + /// + UpdateParameters = 1 << 6, } } diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs index fdccdf2e73822..ec65ce92bf5b3 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs @@ -150,7 +150,8 @@ void AddGeneralDiagnostic(EditAndContinueErrorCode code, string resourceName, Di AddRudeEdit(RudeEditKind.ChangingParameterTypes, nameof(FeaturesResources.Changing_parameter_types_of_0_requires_restarting_the_application)); AddRudeEdit(RudeEditKind.ChangingTypeParameters, nameof(FeaturesResources.Changing_type_parameters_of_0_requires_restarting_the_application)); AddRudeEdit(RudeEditKind.ChangingConstraints, nameof(FeaturesResources.Changing_constraints_of_0_requires_restarting_the_application)); - AddRudeEdit(RudeEditKind.ChangeImplicitMainReturnType, FeaturesResources.An_update_that_causes_the_return_type_of_implicit_main_to_change_requires_restarting_the_application); + AddRudeEdit(RudeEditKind.ChangeImplicitMainReturnType, nameof(FeaturesResources.An_update_that_causes_the_return_type_of_implicit_main_to_change_requires_restarting_the_application)); + AddRudeEdit(RudeEditKind.RenamingNotSupportedByRuntime, nameof(FeaturesResources.Renaming_0_requires_restarting_the_application_because_it_is_not_supported_by_the_runtime)); // VB specific AddRudeEdit(RudeEditKind.HandlesClauseUpdate, nameof(FeaturesResources.Updating_the_Handles_clause_of_0_requires_restarting_the_application)); diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueWorkspaceService.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueWorkspaceService.cs index 3430af562aaf1..34e478659cdaa 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueWorkspaceService.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueWorkspaceService.cs @@ -168,6 +168,7 @@ internal static EditAndContinueCapabilities ParseCapabilities(ImmutableArray EditAndContinueCapabilities.AddInstanceFieldToExistingType, "NewTypeDefinition" => EditAndContinueCapabilities.NewTypeDefinition, "ChangeCustomAttributes" => EditAndContinueCapabilities.ChangeCustomAttributes, + "UpdateParameters" => EditAndContinueCapabilities.UpdateParameters, // To make it eaiser for runtimes to specify more broad capabilities "AddDefinitionToExistingType" => EditAndContinueCapabilities.AddMethodToExistingType | EditAndContinueCapabilities.AddStaticFieldToExistingType | EditAndContinueCapabilities.AddInstanceFieldToExistingType, diff --git a/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs b/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs index 616d33c6aec30..2f0b9455e4593 100644 --- a/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs +++ b/src/Features/Core/Portable/EditAndContinue/RudeEditKind.cs @@ -133,5 +133,6 @@ internal enum RudeEditKind : ushort ChangingTypeParameters = 104, ChangingConstraints = 105, ChangingReloadableTypeNotSupportedByRuntime = 106, + RenamingNotSupportedByRuntime = 107, } } diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx index d87c3270a535e..2f6d976c6ee48 100644 --- a/src/Features/Core/Portable/FeaturesResources.resx +++ b/src/Features/Core/Portable/FeaturesResources.resx @@ -2914,4 +2914,7 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Selection not contained inside a type. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + \ No newline at end of file diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf index bb5b816afbc9d..2a6c917b44bad 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf @@ -2180,6 +2180,11 @@ Pozitivní kontrolní výrazy zpětného vyhledávání s nulovou délkou se obv Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf index 067de42276bf3..97a8117a67bd3 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf @@ -2180,6 +2180,11 @@ Positive Lookbehindassertionen mit Nullbreite werden normalerweise am Anfang reg Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf index 34461f733c450..40527a635c97a 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf @@ -2180,6 +2180,11 @@ Las aserciones de búsqueda retrasada (lookbehind) positivas de ancho cero se us Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf index a8a177af0c2ff..a4f4febcac2a1 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf @@ -2180,6 +2180,11 @@ Les assertions arrière positives de largeur nulle sont généralement utilisée Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf index 58080feda2ab2..2436cc3bf6e32 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf @@ -2180,6 +2180,11 @@ Le asserzioni lookbehind positive di larghezza zero vengono usate in genere all' Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf index be629234c23bc..31d92cede4ad6 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf @@ -2180,6 +2180,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf index 0209c50ff7bbd..f18c089a49935 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf @@ -2180,6 +2180,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf index 0a67e7239d193..4d07997f1a33a 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf @@ -2180,6 +2180,11 @@ Pozytywne asercje wsteczne o zerowej szerokości są zwykle używane na początk Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf index 6c8568fdd26f2..6ab62400db7f9 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf @@ -2180,6 +2180,11 @@ As declarações de lookbehind positivas de largura zero normalmente são usadas Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf index 293b945ecaf3c..ef5b1725bae8e 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf @@ -2180,6 +2180,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf index f65f419019066..a449b4d8a52c2 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf @@ -2180,6 +2180,11 @@ Sıfır genişlikli pozitif geri yönlü onaylamalar genellikle normal ifadeleri Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf index 489b56be5ad06..941c8971334c6 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf @@ -2180,6 +2180,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf index d1ef9cc3b207d..667955b790d09 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf @@ -2180,6 +2180,11 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Renaming {0} requires restarting the application. + + Renaming {0} requires restarting the application because it is not supported by the runtime. + Renaming {0} requires restarting the application because it is not supported by the runtime. + + Renaming a captured variable, from '{0}' to '{1}' requires restarting the application. Renaming a captured variable, from '{0}' to '{1}' requires restarting the application.