提交 d94f503a 编写于 作者: T Tom Meschter

VB command line options should override rule sets

VB has the same problem where a rule turned on in a rule set file will
not be promoted to errors as you expect when using `/WarnAsError`. To
fix that, `/WarnAsError` now explicitly promotes warnings from rule set
files into errors. To accomplish this without breaking existing behavior
around `/WarnAsError` and `/NoWarn`, we implement the following
hierarchy of settings:

1. Specific `/NoWarn` arguments, in order
2. Specific `/WarnAsError` arguments, in order
3. General `/NoWarn` and `/WarnAsError` arguments, in order
4. Rule set file settings
上级 cf3594c2
......@@ -134,7 +134,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim generalDiagnosticOption As ReportDiagnostic = ReportDiagnostic.Default
' Diagnostic ids specified via /nowarn /warnaserror must be processed in case-insensitive fashion.
Dim specificDiagnosticOptions = New Dictionary(Of String, ReportDiagnostic)(CaseInsensitiveComparison.Comparer)
Dim specificDiagnosticOptionsFromRuleSet = New Dictionary(Of String, ReportDiagnostic)(CaseInsensitiveComparison.Comparer)
Dim specificDiagnosticOptionsFromGeneralArguments = New Dictionary(Of String, ReportDiagnostic)(CaseInsensitiveComparison.Comparer)
Dim specificDiagnosticOptionsFromSpecificArguments = New Dictionary(Of String, ReportDiagnostic)(CaseInsensitiveComparison.Comparer)
Dim specificDiagnosticOptionsFromNoWarnArguments = New Dictionary(Of String, ReportDiagnostic)(CaseInsensitiveComparison.Comparer)
Dim keyFileSetting As String = Nothing
Dim keyContainerSetting As String = Nothing
Dim delaySignSetting As Boolean? = Nothing
......@@ -157,7 +160,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Continue For
End If
generalDiagnosticOption = GetDiagnosticOptionsFromRulesetFile(specificDiagnosticOptions, diagnostics, unquoted, baseDirectory)
generalDiagnosticOption = GetDiagnosticOptionsFromRulesetFile(specificDiagnosticOptionsFromRuleSet, diagnostics, unquoted, baseDirectory)
End If
Next
End If
......@@ -627,10 +630,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Case "warnaserror", "warnaserror+"
If value Is Nothing Then
generalDiagnosticOption = ReportDiagnostic.Error
specificDiagnosticOptionsFromGeneralArguments.Clear()
For Each pair In specificDiagnosticOptionsFromRuleSet
If pair.Value = ReportDiagnostic.Warn Then
specificDiagnosticOptionsFromGeneralArguments.Add(pair.Key, ReportDiagnostic.Error)
End If
Next
Continue For
End If
AddWarnings(specificDiagnosticOptions, ReportDiagnostic.Error, ParseWarnings(value))
AddWarnings(specificDiagnosticOptionsFromSpecificArguments, ReportDiagnostic.Error, ParseWarnings(value))
Continue For
Case "warnaserror-"
......@@ -638,19 +649,38 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If generalDiagnosticOption <> ReportDiagnostic.Suppress Then
generalDiagnosticOption = ReportDiagnostic.Default
End If
specificDiagnosticOptionsFromGeneralArguments.Clear()
Continue For
End If
AddWarnings(specificDiagnosticOptions, ReportDiagnostic.Default, ParseWarnings(value))
For Each id In ParseWarnings(value)
Dim ruleSetValue As ReportDiagnostic
If specificDiagnosticOptionsFromRuleSet.TryGetValue(id, ruleSetValue) Then
specificDiagnosticOptionsFromSpecificArguments(id) = ruleSetValue
Else
specificDiagnosticOptionsFromSpecificArguments(id) = ReportDiagnostic.Default
End If
Next
Continue For
Case "nowarn"
If value Is Nothing Then
generalDiagnosticOption = ReportDiagnostic.Suppress
specificDiagnosticOptionsFromGeneralArguments.Clear()
For Each pair In specificDiagnosticOptionsFromRuleSet
If pair.Value <> ReportDiagnostic.Error Then
specificDiagnosticOptionsFromGeneralArguments.Add(pair.Key, ReportDiagnostic.Suppress)
End If
Next
Continue For
End If
AddWarnings(specificDiagnosticOptions, ReportDiagnostic.Suppress, ParseWarnings(value))
AddWarnings(specificDiagnosticOptionsFromNoWarnArguments, ReportDiagnostic.Suppress, ParseWarnings(value))
Continue For
Case "langversion"
......@@ -983,6 +1013,20 @@ lVbRuntimePlus:
AddDiagnostic(diagnostics, ERRID.WRN_BadSwitch, arg)
Next
Dim specificDiagnosticOptions = New Dictionary(Of String, ReportDiagnostic)(specificDiagnosticOptionsFromRuleSet, CaseInsensitiveComparison.Comparer)
For Each item In specificDiagnosticOptionsFromGeneralArguments
specificDiagnosticOptions(item.Key) = item.Value
Next
For Each item In specificDiagnosticOptionsFromSpecificArguments
specificDiagnosticOptions(item.Key) = item.Value
Next
For Each item In specificDiagnosticOptionsFromNoWarnArguments
specificDiagnosticOptions(item.Key) = item.Value
Next
If Not IsInteractive AndAlso Not hasSourceFiles AndAlso managedResources.IsEmpty() AndAlso outputKind.IsApplication Then
' VB displays help when there is nothing specified on the command line
If flattenedArgs.Any Then
......
......@@ -6808,6 +6808,239 @@ out
CleanupAllGeneratedFiles(src.Path)
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_GeneralCommandLineOptionOverridesGeneralRuleSetOption()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<IncludeAll Action=""Warning"" />
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=0, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_GeneralWarnAsErrorPromotesWarningFromRuleSet()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Warning"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_GeneralWarnAsErrorDoesNotPromoteInfoFromRuleSet()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Info"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Info, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_SpecificWarnAsErrorPromotesInfoFromRuleSet()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Info"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+:Test001", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Default, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_GeneralWarnAsErrorMinusResetsRules()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Warning"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+", "/WarnAsError-", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Default, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Warn, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_SpecificWarnAsErrorMinusResetsRules()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Warning"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+", "/WarnAsError-:Test001", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Warn, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_SpecificWarnAsErrorMinusDefaultsRuleNotInRuleSet()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Warning"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+:Test002", "/WarnAsError-:Test002", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Default, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=2, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Warn, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
Assert.Equal(expected:=ReportDiagnostic.Default, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test002"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_LastGeneralWarnAsErrorTrumpsNoWarn()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Warning"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/NoWarn", "/WarnAsError+", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_GeneralNoWarnTrumpsGeneralWarnAsErrorMinus()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Warning"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/WarnAsError+", "/NoWarn", "/WarnAsError-", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Suppress, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Warn, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_GeneralNoWarnTurnsOffAllButErrors()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Error"" />
<Rule Id=""Test002"" Action=""Warning"" />
<Rule Id=""Test003"" Action=""Info"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/NoWarn", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Suppress, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=3, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
Assert.Equal(expected:=ReportDiagnostic.Suppress, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test002"))
Assert.Equal(expected:=ReportDiagnostic.Suppress, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test003"))
End Sub
<Fact, WorkItem(468, "https://github.com/dotnet/roslyn/issues/468")>
Public Sub RuleSet_SpecificNoWarnAlwaysWins()
Dim dir = Temp.CreateDirectory()
Dim ruleSetSource = "<?xml version=""1.0"" encoding=""utf-8""?>
<RuleSet Name=""Ruleset1"" Description=""Test"" ToolsVersion=""12.0"">
<Rules AnalyzerId=""Microsoft.Analyzers.ManagedCodeAnalysis"" RuleNamespace=""Microsoft.Rules.Managed"">
<Rule Id=""Test001"" Action=""Warning"" />
</Rules>
</RuleSet>
"
Dim ruleSetFile = dir.CreateFile("Rules.ruleset").WriteAllText(ruleSetSource)
Dim arguments = VisualBasicCommandLineParser.Default.Parse({"/ruleset:Rules.RuleSet", "/NoWarn:Test001", "/WarnAsError+", "/WarnAsError-:Test001", "A.vb"}, dir.Path)
Assert.Empty(arguments.Errors)
Assert.Equal(expected:=ReportDiagnostic.Error, actual:=arguments.CompilationOptions.GeneralDiagnosticOption)
Assert.Equal(expected:=1, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions.Count)
Assert.Equal(expected:=ReportDiagnostic.Suppress, actual:=arguments.CompilationOptions.SpecificDiagnosticOptions("Test001"))
End Sub
End Class
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册