提交 516db69f 编写于 作者: A Andrew Casey

Report diagnostics when short-circuiting emit

As an optimization, submissions not containing declarations are not
emitted.  However, when we short-circuit emission, we also skip diagnostic
reporting (e.g. in usings) that can trigger an assert in the next
submission (which assumes that all errors have been reported).

Fixes #3795
上级 aaf608f5
...@@ -2250,12 +2250,7 @@ internal override StrongNameKeys StrongNameKeys ...@@ -2250,12 +2250,7 @@ internal override StrongNameKeys StrongNameKeys
DiagnosticBag diagnostics, DiagnosticBag diagnostics,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// Do not waste a slot in the submission chain for submissions that contain no executable code Debug.Assert(!IsSubmission || HasCodeToEmit());
// (they may only contain #r directives, usings, etc.)
if (IsSubmission && !HasCodeToEmit())
{
return null;
}
string runtimeMDVersion = GetRuntimeMetadataVersion(emitOptions, diagnostics); string runtimeMDVersion = GetRuntimeMetadataVersion(emitOptions, diagnostics);
if (runtimeMDVersion == null) if (runtimeMDVersion == null)
......
...@@ -1579,6 +1579,15 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken) ...@@ -1579,6 +1579,15 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
return ToEmitResultAndFree(diagnostics, success: false, entryPointOpt: null); return ToEmitResultAndFree(diagnostics, success: false, entryPointOpt: null);
} }
// Do not waste a slot in the submission chain for submissions that contain no executable code
// (they may only contain #r directives, usings, etc.)
if (IsSubmission && !HasCodeToEmit())
{
// Still report diagnostics since downstream submissions will assume there are no errors.
diagnostics.AddRange(this.GetDiagnostics());
return ToEmitResultAndFree(diagnostics, success: false, entryPointOpt: null);
}
var moduleBeingBuilt = this.CreateModuleBuilder( var moduleBeingBuilt = this.CreateModuleBuilder(
options, options,
manifestResources, manifestResources,
......
...@@ -2147,12 +2147,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -2147,12 +2147,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
cancellationToken As CancellationToken) As CommonPEModuleBuilder cancellationToken As CancellationToken) As CommonPEModuleBuilder
Debug.Assert(diagnostics.IsEmptyWithoutResolution) ' True, but not required. Debug.Assert(diagnostics.IsEmptyWithoutResolution) ' True, but not required.
Debug.Assert(Not IsSubmission OrElse HasCodeToEmit())
' Do not waste a slot in the submission chain for submissions that contain no executable code
' (they may only contain #r directives, usings, etc.)
If IsSubmission AndAlso Not HasCodeToEmit() Then
Return Nothing
End If
' Get the runtime metadata version from the cor library. If this fails we have no reasonable value to give. ' Get the runtime metadata version from the cor library. If this fails we have no reasonable value to give.
Dim runtimeMetadataVersion = GetRuntimeMetadataVersion() Dim runtimeMetadataVersion = GetRuntimeMetadataVersion()
......
...@@ -1996,6 +1996,33 @@ public void SubmissionCompilation_Errors() ...@@ -1996,6 +1996,33 @@ public void SubmissionCompilation_Errors()
Assert.Throws<ArgumentException>(() => CSharpCompilation.CreateSubmission("a", options: TestOptions.ReleaseDll.WithDelaySign(false))); Assert.Throws<ArgumentException>(() => CSharpCompilation.CreateSubmission("a", options: TestOptions.ReleaseDll.WithDelaySign(false)));
} }
[WorkItem(3795, "https://github.com/dotnet/roslyn/issues/3795")]
[Fact]
public void ErrorInUsing()
{
var submission = CSharpCompilation.CreateSubmission("sub1", Parse("using Unknown;", options: TestOptions.Script), new[] { MscorlibRef });
var expectedDiagnostics = new[]
{
// (1,7): error CS0246: The type or namespace name 'Unknown' could not be found (are you missing a using directive or an assembly reference?)
// using Unknown;
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unknown").WithArguments("Unknown").WithLocation(1, 7),
// (1,1): hidden CS8019: Unnecessary using directive.
// using Unknown;
Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using Unknown;").WithLocation(1, 1),
};
// Emit produces the same diagnostics as GetDiagnostics (below).
using (var stream = new MemoryStream())
{
var emitResult = submission.Emit(stream);
Assert.False(emitResult.Success);
emitResult.Diagnostics.Verify(expectedDiagnostics);
}
submission.GetDiagnostics().Verify(expectedDiagnostics);
}
private CSharpCompilation CreateSubmission(string code, CSharpParseOptions options, int expectedErrorCount = 0) private CSharpCompilation CreateSubmission(string code, CSharpParseOptions options, int expectedErrorCount = 0)
{ {
var submission = CSharpCompilation.CreateSubmission("sub", var submission = CSharpCompilation.CreateSubmission("sub",
......
...@@ -402,6 +402,27 @@ End Function") ...@@ -402,6 +402,27 @@ End Function")
'Assert.False(symbols.Any(Function(s) s.Name = "Roslyn")) 'Assert.False(symbols.Any(Function(s) s.Name = "Roslyn"))
End Sub End Sub
<WorkItem(3795, "https:'github.com/dotnet/roslyn/issues/3795")>
<Fact>
Public Sub ErrorInUsing()
Dim submission = VisualBasicCompilation.CreateSubmission("sub1", Parse("Imports Unknown", options:=TestOptions.Script), {MscorlibRef})
Dim expectedErrors = <errors><![CDATA[
BC40056: Namespace or type specified in the Imports 'Unknown' doesn't contain any public member or cannot be found. Make sure the namespace or the type is defined and contains at least one public member. Make sure the imported element name doesn't use any aliases.
Imports Unknown
~~~~~~~
]]></errors>
' Emit produces the same diagnostics as GetDiagnostics (below).
Using stream As New MemoryStream()
Dim emitResult = submission.Emit(stream)
Assert.False(emitResult.Success)
emitResult.Diagnostics.AssertTheseDiagnostics(expectedErrors)
End Using
submission.GetDiagnostics().AssertTheseDiagnostics(expectedErrors)
End Sub
#End Region #End Region
#Region "Anonymous types" #Region "Anonymous types"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册