提交 817593d9 编写于 作者: A AlekseyTs

VB CLSComplianceChecker: Visit declaration in each module separately to avoid...

VB CLSComplianceChecker: Visit declaration in each module separately to avoid dealing with merged namespaces. Merged namespaces do not have containing module, which was causing a NullReferenceException.
***NO_CI***
 (changeset 1389009)
上级 1713b54a
......@@ -3529,5 +3529,50 @@ public void Test()
// [CLSCompliant(new { field = false }.field)]
Diagnostic(ErrorCode.ERR_AnonymousTypeNotAvailable, "new"));
}
[Fact, WorkItem(1026453, "DevDiv")]
public void Bug1026453()
{
var source1 = @"
namespace N1
{
public class A { }
}
";
var comp1 = CreateCompilationWithMscorlib(source1, options: TestOptions.ReleaseModule);
var source2 = @"
using System;
[assembly: CLSCompliant(true)]
[module: CLSCompliant(true)]
namespace N1
{
public class B { }
}
";
var comp2 = CreateCompilationWithMscorlib(source2, new[] { comp1.EmitToImageReference() }, TestOptions.ReleaseDll.WithConcurrentBuild(false));
comp2.VerifyDiagnostics(
// warning CS3013: Added modules must be marked with the CLSCompliant attribute to match the assembly
Diagnostic(ErrorCode.WRN_CLS_ModuleMissingCLS).WithLocation(1, 1)
);
comp2.WithOptions(TestOptions.ReleaseDll.WithConcurrentBuild(true)).VerifyDiagnostics(
// warning CS3013: Added modules must be marked with the CLSCompliant attribute to match the assembly
Diagnostic(ErrorCode.WRN_CLS_ModuleMissingCLS).WithLocation(1, 1)
);
var comp3 = comp2.WithOptions(TestOptions.ReleaseModule.WithConcurrentBuild(false));
comp3.VerifyDiagnostics(
// warning CS3013: Added modules must be marked with the CLSCompliant attribute to match the assembly
Diagnostic(ErrorCode.WRN_CLS_ModuleMissingCLS).WithLocation(1, 1)
);
comp3.WithOptions(TestOptions.ReleaseModule.WithConcurrentBuild(true)).VerifyDiagnostics(
// warning CS3013: Added modules must be marked with the CLSCompliant attribute to match the assembly
Diagnostic(ErrorCode.WRN_CLS_ModuleMissingCLS).WithLocation(1, 1)
);
}
}
}
\ No newline at end of file
......@@ -67,6 +67,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' The regular attribute code handles conflicting attributes from included netmodules.
If symbol.Modules.Length > 1 AndAlso _compilation.Options.ConcurrentBuild Then
Dim options = If(Me._cancellationToken.CanBeCanceled, New ParallelOptions() With {.CancellationToken = Me._cancellationToken}, _defaultParallelOptions)
Parallel.ForEach(symbol.Modules, options, AddressOf VisitModule)
Else
For Each m In symbol.Modules
VisitModule(m)
Next
End If
End Sub
Public Overrides Sub VisitModule(symbol As ModuleSymbol)
Visit(symbol.GlobalNamespace)
End Sub
......@@ -594,17 +606,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private Function GetDeclaredOrInheritedCompliance(symbol As Symbol) As Compliance
Debug.Assert(symbol.Kind = SymbolKind.NamedType OrElse Not (TypeOf symbol Is TypeSymbol), "Type kinds without declarations are handled elsewhere.")
Debug.Assert(symbol.Kind <> If(Me._compilation.Options.OutputKind = OutputKind.NetModule, SymbolKind.Assembly, SymbolKind.NetModule),
Debug.Assert(symbol.Kind <> If(Me._compilation.Options.OutputKind = OutputKind.NetModule, SymbolKind.Assembly, SymbolKind.NetModule) OrElse
(symbol.Kind = SymbolKind.Assembly AndAlso Me._compilation.Assembly IsNot symbol),
"Don't care about assembly when building netmodule and vice versa")
If symbol.Kind = SymbolKind.Namespace Then
' Don't bother storing entries for namespaces - just go straight to the assembly.
If DirectCast(symbol, NamespaceSymbol).IsGlobalNamespace AndAlso
Me._compilation.Options.OutputKind = OutputKind.NetModule Then
' Special case: if we're building a net module, then we need the namespace's
' containing module (vs assembly) and there isn't one for the global namespace.
Return GetDeclaredOrInheritedCompliance(Me._compilation.Assembly.Modules(0))
End If
Return GetDeclaredOrInheritedCompliance(GetContainingModuleOrAssembly(symbol))
ElseIf symbol.Kind = SymbolKind.Method Then
Dim method As MethodSymbol = DirectCast(symbol, MethodSymbol)
......@@ -738,8 +745,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' Return the containing module if the output kind is module and the containing assembly otherwise.
''' </summary>
Private Function GetContainingModuleOrAssembly(symbol As Symbol) As Symbol
Dim containingAssembly = symbol.ContainingAssembly
If containingAssembly IsNot Me._compilation.Assembly Then
Return containingAssembly
End If
Dim producingNetModule = Me._compilation.Options.OutputKind = OutputKind.NetModule
Return If(producingNetModule, DirectCast(symbol.ContainingModule, Symbol), symbol.ContainingAssembly)
Return If(producingNetModule, DirectCast(symbol.ContainingModule, Symbol), containingAssembly)
End Function
Private Shared Function IsAccessibleOutsideAssembly(symbol As Symbol) As Boolean
......
......@@ -1979,6 +1979,38 @@ Imports System
CreateCompilationWithMscorlib(source2, options:=TestOptions.ReleaseDll.WithRootNamespace("_A")).AssertTheseDiagnostics(<errors><![CDATA[
BC40038: Root namespace '_A' is not CLS-compliant.
]]></errors>)
Dim source3 =
<compilation>
<file name="a.vb">
<![CDATA[
Public Class Test
End Class
]]>
</file>
</compilation>
Dim moduleRef = CreateCompilationWithMscorlib(source3, options:=TestOptions.ReleaseModule).EmitToImageReference()
CreateCompilationWithMscorlibAndReferences(source2, {moduleRef}, options:=TestOptions.ReleaseDll.WithRootNamespace("_A").WithConcurrentBuild(False)).AssertTheseDiagnostics(<errors><![CDATA[
BC40038: Root namespace '_A' is not CLS-compliant.
]]></errors>)
Dim source4 =
<compilation>
<file name="a.vb">
<![CDATA[
Imports System
<Module: CLSCompliant(True)>
]]>
</file>
</compilation>
CreateCompilationWithMscorlibAndReferences(source4, {moduleRef}, options:=TestOptions.ReleaseModule.WithRootNamespace("_A").WithConcurrentBuild(True)).AssertTheseDiagnostics(<errors><![CDATA[
BC40038: Root namespace '_A' is not CLS-compliant.
]]></errors>)
CreateCompilationWithMscorlibAndReferences(source2, {moduleRef}, options:=TestOptions.ReleaseModule.WithRootNamespace("_A")).AssertTheseDiagnostics()
End Sub
<Fact>
......@@ -1991,7 +2023,7 @@ Imports System
<Assembly: CLSCompliant(True)>
]]>
</file>
</file>
</compilation>
CreateCompilationWithMscorlib(source, options:=TestOptions.ReleaseDll.WithRootNamespace("_A.B.C")).AssertTheseDiagnostics(<errors><![CDATA[
......@@ -3616,5 +3648,48 @@ BC40030: event 'Public Event Scen6(x As Integer)' cannot be marked CLS-compliant
~~~~~
]]></errors>)
End Sub
<Fact, WorkItem(1026453, "DevDiv")>
Public Sub Bug1026453()
Dim source1 =
<compilation>
<file name="a.vb">
<![CDATA[
Namespace N1
Public Class A
End Class
End Namespace
]]>
</file>
</compilation>
Dim comp1 = CreateCompilationWithMscorlib(source1, TestOptions.ReleaseModule)
Dim source2 =
<compilation>
<file name="a.vb">
<![CDATA[
Imports System
<Assembly: CLSCompliant(True)>
<Module: CLSCompliant(True)>
Namespace N1
Public Class B
End Class
End Namespace
]]>
</file>
</compilation>
Dim comp2 = CreateCompilationWithMscorlibAndReferences(source2, {comp1.EmitToImageReference()}, TestOptions.ReleaseDll.WithConcurrentBuild(False))
comp2.AssertNoDiagnostics()
comp2.WithOptions(TestOptions.ReleaseDll.WithConcurrentBuild(True)).AssertNoDiagnostics()
Dim comp3 = comp2.WithOptions(TestOptions.ReleaseModule.WithConcurrentBuild(False))
comp3.AssertNoDiagnostics()
comp3.WithOptions(TestOptions.ReleaseModule.WithConcurrentBuild(True)).AssertNoDiagnostics()
End Sub
End Class
End Namespace
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册