提交 5a259513 编写于 作者: J Julien Couvreur 提交者: GitHub

Filter "missing method body" error when emitting metadata-only (#18542)

上级 8e6cfc0f
......@@ -2311,7 +2311,14 @@ internal override StrongNameKeys StrongNameKeys
{
// The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that the emitter
// does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...)
bool hasDeclarationErrors = !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken));
PooledHashSet<int> excludeDiagnostics = null;
if (emitMetadataOnly)
{
excludeDiagnostics = PooledHashSet<int>.GetInstance();
excludeDiagnostics.Add((int)ErrorCode.ERR_ConcreteMissingBody);
}
bool hasDeclarationErrors = !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken), excludeDiagnostics);
excludeDiagnostics?.Free();
// TODO (tomat): NoPIA:
// EmbeddedSymbolManager.MarkAllDeferredSymbolsAsReferenced(this)
......
......@@ -321,7 +321,6 @@ public void RefAssembly_ReferenceAssemblyAttributeAlsoInSource()
[InlineData("public struct S { private int i; }", "public struct S { }", Match.Different)]
[InlineData("private int i;", "", Match.RefOut)]
[InlineData("public C() { }", "", Match.BothMetadataAndRefOut)]
//[InlineData("public int NoBody();", "public int NoBody() { }", Match.BothMetadataAndRefOut)] // PROTOTYPE(refout) Further refinement https://github.com/dotnet/roslyn/issues/17612
public void RefAssembly_InvariantToSomeChanges(string left, string right, Match expectedMatch)
{
string sourceTemplate = @"
......@@ -569,26 +568,40 @@ private static void VerifyRefAssemblyClient(string lib_cs, string source, Action
[Theory]
[InlineData("public int M() { error(); }", true)]
[InlineData("public int M() { error() }", false)] // Should be true. See follow-up issue https://github.com/dotnet/roslyn/issues/17612
[InlineData("public int M() { error() }", false)] // This may get relaxed. See follow-up issue https://github.com/dotnet/roslyn/issues/17612
[InlineData("public int M();", true)]
[InlineData("public int M() { int Local(); }", true)]
[InlineData("public C();", true)]
[InlineData("~ C();", true)]
[InlineData("public Error M() { return null; }", false)] // This may get relaxed. See follow-up issue https://github.com/dotnet/roslyn/issues/17612
[InlineData("public static explicit operator C(int i);", true)]
[InlineData("public async Task M();", false)]
[InlineData("partial void M(); partial void M();", false)] // This may get relaxed. See follow-up issue https://github.com/dotnet/roslyn/issues/17612
public void RefAssembly_IgnoresSomeDiagnostics(string change, bool expectSuccess)
{
string sourceTemplate = @"
public class C
using System.Threading.Tasks;
public partial class C
{
CHANGE
}
";
string source = sourceTemplate.Replace("CHANGE", change);
string name = GetUniqueName();
CSharpCompilation comp1 = CreateCompilationWithMscorlib(Parse(source),
options: TestOptions.DebugDll.WithDeterministic(true), assemblyName: name);
VerifyIgnoresDiagnostics(EmitOptions.Default.WithEmitMetadataOnly(false).WithTolerateErrors(false), success: false);
VerifyIgnoresDiagnostics(EmitOptions.Default.WithEmitMetadataOnly(true).WithTolerateErrors(false), success: expectSuccess);
using (var output = new MemoryStream())
void VerifyIgnoresDiagnostics(EmitOptions emitOptions, bool success)
{
var emitResult = comp1.Emit(output, options: EmitOptions.Default.WithEmitMetadataOnly(true));
Assert.Equal(expectSuccess, emitResult.Success);
Assert.Equal(!expectSuccess, emitResult.Diagnostics.Any());
string source = sourceTemplate.Replace("CHANGE", change);
string name = GetUniqueName();
CSharpCompilation comp = CreateCompilationWithMscorlib(Parse(source),
options: TestOptions.DebugDll.WithDeterministic(true), assemblyName: name);
using (var output = new MemoryStream())
{
var emitResult = comp.Emit(output, options: emitOptions);
Assert.Equal(!success, emitResult.Diagnostics.HasAnyErrors());
Assert.Equal(success, emitResult.Success);
}
}
}
......
......@@ -1151,7 +1151,7 @@ internal void CompleteCompilationEventQueue_NoLock()
/// <returns>True if there were no errors or warnings-as-errors.</returns>
internal bool FilterAndAppendAndFreeDiagnostics(DiagnosticBag accumulator, ref DiagnosticBag incoming)
{
bool result = FilterAndAppendDiagnostics(accumulator, incoming.AsEnumerableWithoutResolution());
bool result = FilterAndAppendDiagnostics(accumulator, incoming.AsEnumerableWithoutResolution(), exclude: null);
incoming.Free();
incoming = null;
return result;
......@@ -1161,13 +1161,18 @@ internal bool FilterAndAppendAndFreeDiagnostics(DiagnosticBag accumulator, ref D
/// Filter out warnings based on the compiler options (/nowarn, /warn and /warnaserror) and the pragma warning directives.
/// </summary>
/// <returns>True when there is no error.</returns>
internal bool FilterAndAppendDiagnostics(DiagnosticBag accumulator, IEnumerable<Diagnostic> incoming)
internal bool FilterAndAppendDiagnostics(DiagnosticBag accumulator, IEnumerable<Diagnostic> incoming, HashSet<int> exclude)
{
bool hasError = false;
bool reportSuppressedDiagnostics = Options.ReportSuppressedDiagnostics;
foreach (Diagnostic d in incoming)
{
if (exclude?.Contains(d.Code) == true)
{
continue;
}
var filtered = Options.FilterDiagnostic(d);
if (filtered == null ||
(!reportSuppressedDiagnostics && filtered.IsSuppressed))
......
......@@ -2221,7 +2221,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that we don't emit
' metadata if there are declaration errors or method body errors (but we do insert all errors from method body binding...)
Dim hasDeclarationErrors = Not FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, True, cancellationToken))
Dim hasDeclarationErrors = Not FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, True, cancellationToken), exclude:=Nothing)
Dim moduleBeingBuilt = DirectCast(moduleBuilder, PEModuleBuilder)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册