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

Avoid calling GetDiagnostics on compilation during EnC analysis #19167

Merged
merged 2 commits into from
May 8, 2017
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 @@ -92,6 +92,131 @@ public void Delta_AssemblyDefTable()
Assert.False(diff1.GetMetadata().Reader.IsAssembly);
}

[Fact]
public void SemanticErrors_MethodBody()
{
var source0 = MarkedSource(@"
class C
{
static void E()
{
int x = 1;
System.Console.WriteLine(x);
}

static void G()
{
System.Console.WriteLine(1);
}
}");
var source1 = MarkedSource(@"
class C
{
static void E()
{
int x = Unknown(2);
System.Console.WriteLine(x);
}

static void G()
{
System.Console.WriteLine(2);
}
}");

var compilation0 = CreateStandardCompilation(source0.Tree, options: ComSafeDebugDll);
var compilation1 = compilation0.WithSource(source1.Tree);

var e0 = compilation0.GetMember<MethodSymbol>("C.E");
var e1 = compilation1.GetMember<MethodSymbol>("C.E");
var g0 = compilation0.GetMember<MethodSymbol>("C.G");
var g1 = compilation1.GetMember<MethodSymbol>("C.G");

var v0 = CompileAndVerify(compilation0);
var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo);

// Semantic errors are reported only for the bodies of members being emitted.

var diffError = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(
new SemanticEdit(SemanticEditKind.Update, e0, e1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true)));

diffError.EmitResult.Diagnostics.Verify(
// (6,17): error CS0103: The name 'Unknown' does not exist in the current context
// int x = Unknown(2);
Diagnostic(ErrorCode.ERR_NameNotInContext, "Unknown").WithArguments("Unknown").WithLocation(6, 17));

var diffGood = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(
new SemanticEdit(SemanticEditKind.Update, g0, g1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true)));

diffGood.EmitResult.Diagnostics.Verify();

diffGood.VerifyIL(@"C.G", @"
{
// Code size 9 (0x9)
.maxstack 1
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: call ""void System.Console.WriteLine(int)""
IL_0007: nop
IL_0008: ret
}
");
}

[Fact]
public void SemanticErrors_Declaration()
{
var source0 = MarkedSource(@"
class C
{
static void G()
{
System.Console.WriteLine(1);
}
}
");
var source1 = MarkedSource(@"
class C
{
static void G()
{
System.Console.WriteLine(2);
}
}

class Bad : Bad
{
}
");

var compilation0 = CreateStandardCompilation(source0.Tree, options: ComSafeDebugDll);
var compilation1 = compilation0.WithSource(source1.Tree);

var g0 = compilation0.GetMember<MethodSymbol>("C.G");
var g1 = compilation1.GetMember<MethodSymbol>("C.G");

var v0 = CompileAndVerify(compilation0);
var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo);

var diff = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(
new SemanticEdit(SemanticEditKind.Update, g0, g1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true)));

// All declaration errors are reported regardless of what member do we emit.

diff.EmitResult.Diagnostics.Verify(
// (10,7): error CS0146: Circular base class dependency involving 'Bad' and 'Bad'
// class Bad : Bad
Diagnostic(ErrorCode.ERR_CircularBase, "Bad").WithArguments("Bad", "Bad").WithLocation(10, 7));
}

[Fact]
public void ModifyMethod()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5766,6 +5766,51 @@ partial void MyPartialMethod(MyUndefinedMethod m)
Assert.Equal(2, errs.Count());
}

[Fact]
public void PartialTypeDiagnostics_Constructors()
{
var file1 = @"
partial class C
{
C() {}
}
";

var file2 = @"
partial class C
{
C() {}
}
";
var file3 = @"
partial class C
{
C() {}
}
";

var tree1 = Parse(file1);
var tree2 = Parse(file2);
var tree3 = Parse(file3);
var comp = CreateStandardCompilation(new[] { tree1, tree2, tree3 });
var model1 = comp.GetSemanticModel(tree1);
var model2 = comp.GetSemanticModel(tree2);
var model3 = comp.GetSemanticModel(tree3);

model1.GetDeclarationDiagnostics().Verify();

model2.GetDeclarationDiagnostics().Verify(
// (4,5): error CS0111: Type 'C' already defines a member called '.ctor' with the same parameter types
Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "C").WithArguments(".ctor", "C").WithLocation(4, 5));

model3.GetDeclarationDiagnostics().Verify(
// (4,5): error CS0111: Type 'C' already defines a member called '.ctor' with the same parameter types
Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "C").WithArguments(".ctor", "C").WithLocation(4, 5));

Assert.Equal(3, comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C").InstanceConstructors.Length);
}


[WorkItem(1076661, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1076661")]
[Fact]
public void Bug1076661()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,107 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Public Class EditAndContinueTests
Inherits EditAndContinueTestBase

<Fact>
Public Sub SemanticErrors_MethodBody()
Dim source0 = MarkedSource("
Class C
Shared Sub E()
Dim x As Integer = 1
System.Console.WriteLine(x)
End Sub

Shared Sub G()
System.Console.WriteLine(1)
End Sub
End Class
")
Dim source1 = MarkedSource("
Class C
Shared Sub E()
Dim x = Unknown(2)
System.Console.WriteLine(x)
End Sub

Shared Sub G()
System.Console.WriteLine(2)
End Sub
End Class
")
Dim compilation0 = CreateCompilationWithMscorlib(source0.Tree, options:=ComSafeDebugDll)
Dim compilation1 = compilation0.WithSource(source1.Tree)

Dim e0 = compilation0.GetMember(Of MethodSymbol)("C.E")
Dim e1 = compilation1.GetMember(Of MethodSymbol)("C.E")
Dim g0 = compilation0.GetMember(Of MethodSymbol)("C.G")
Dim g1 = compilation1.GetMember(Of MethodSymbol)("C.G")

Dim v0 = CompileAndVerify(compilation0)
Dim md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)
Dim generation0 = EmitBaseline.CreateInitialBaseline(md0, AddressOf v0.CreateSymReader().GetEncMethodDebugInfo)

' Semantic errors are reported only for the bodies of members being emitted.
Dim diffError = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(New SemanticEdit(SemanticEditKind.Update, e0, e1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables:=True)))

diffError.EmitResult.Diagnostics.Verify(
Diagnostic(ERRID.ERR_NameNotDeclared1, "Unknown").WithArguments("Unknown").WithLocation(4, 17))

Dim diffGood = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(New SemanticEdit(SemanticEditKind.Update, g0, g1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables:=True)))

diffGood.EmitResult.Diagnostics.Verify()
diffGood.VerifyIL("C.G", "
{
// Code size 9 (0x9)
.maxstack 1
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: call ""Sub System.Console.WriteLine(Integer)""
IL_0007: nop
IL_0008: ret
}")
End Sub

<Fact>
Public Sub SemanticErrors_Declaration()
Dim source0 = MarkedSource("
Class C
Sub G()
System.Console.WriteLine(1)
End Sub
End Class
")
Dim source1 = MarkedSource("
Class C
Sub G()
System.Console.WriteLine(1)
End Sub
End Class

Class Bad
Inherits Bad
End Class
")
Dim compilation0 = CreateCompilationWithMscorlib(source0.Tree, options:=ComSafeDebugDll)
Dim compilation1 = compilation0.WithSource(source1.Tree)

Dim g0 = compilation0.GetMember(Of MethodSymbol)("C.G")
Dim g1 = compilation1.GetMember(Of MethodSymbol)("C.G")

Dim v0 = CompileAndVerify(compilation0)
Dim md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)
Dim generation0 = EmitBaseline.CreateInitialBaseline(md0, AddressOf v0.CreateSymReader().GetEncMethodDebugInfo)

Dim diff = compilation1.EmitDifference(
generation0,
ImmutableArray.Create(New SemanticEdit(SemanticEditKind.Update, g0, g1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables:=True)))

diff.EmitResult.Diagnostics.Verify(
Diagnostic(ERRID.ERR_TypeInItsInheritsClause1, "Bad").WithArguments("Bad").WithLocation(9, 12))
End Sub

<Fact>
Public Sub ModifyMethod_WithTuples()
Dim source0 =
Expand Down Expand Up @@ -5183,5 +5284,8 @@ End Class")
}
")
End Sub



End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@ public static void Main()
}
}

[Fact]
public async Task AnalyzeDocumentAsync_SemanticError_Change()
[Fact, WorkItem(10683, "https://github.com/dotnet/roslyn/issues/10683")]
public async Task AnalyzeDocumentAsync_SemanticErrorInMethodBody_Change()
{
string source1 = @"
class C
Expand All @@ -521,6 +521,46 @@ public static void Main()
";
var analyzer = new CSharpEditAndContinueAnalyzer();

using (var workspace = TestWorkspace.CreateCSharp(source1))
{
var documentId = workspace.CurrentSolution.Projects.First().Documents.First().Id;
var oldSolution = workspace.CurrentSolution;
var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2));

var baseActiveStatements = ImmutableArray.Create<ActiveStatementSpan>();
var result = await analyzer.AnalyzeDocumentAsync(oldSolution, baseActiveStatements, newSolution.GetDocument(documentId), default(CancellationToken));

Assert.True(result.HasChanges);

// no declaration errors (error in method body is only reported when emitting):
Assert.False(result.HasChangesAndErrors);
Assert.False(result.HasChangesAndCompilationErrors);
}
}

[Fact, WorkItem(10683, "https://github.com/dotnet/roslyn/issues/10683")]
public async Task AnalyzeDocumentAsync_SemanticErrorInDeclaration_Change()
{
string source1 = @"
class C
{
public static void Main(Bar x)
{
System.Console.WriteLine(1);
}
}
";
string source2 = @"
class C
{
public static void Main(Bar x)
{
System.Console.WriteLine(2);
}
}
";
var analyzer = new CSharpEditAndContinueAnalyzer();

using (var workspace = TestWorkspace.CreateCSharp(source1))
{
var documentId = workspace.CurrentSolution.Projects.First().Documents.First().Id;
Expand Down
Loading