提交 c8d684d2 编写于 作者: J John Hamby

Moved system language analyzers to separate files.

上级 d70a522f
......@@ -34,13 +34,13 @@ void M1()
}";
CreateCompilationWithMscorlib45(source)
.VerifyDiagnostics()
.VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new EmptyArrayOperationAnalyzer() }, null, null, false,
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0]").WithLocation(6, 22),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "{ }").WithLocation(7, 23),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "new C[] { }").WithLocation(8, 20),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][]").WithLocation(12, 24),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][][][]").WithLocation(13, 28),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][,]").WithLocation(15, 26)
.VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new EmptyArrayAnalyzer() }, null, null, false,
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0]").WithLocation(6, 22),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "{ }").WithLocation(7, 23),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new C[] { }").WithLocation(8, 20),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][]").WithLocation(12, 24),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][][][]").WithLocation(13, 28),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][,]").WithLocation(15, 26)
);
}
......
......@@ -29,9 +29,10 @@
<Compile Include="Collections\ByteSequenceComparerTests.cs" />
<Compile Include="Diagnostics\BoxingOperationAnalyzer.cs" />
<Compile Include="Diagnostics\DiagnosticLocalizationTests.cs" />
<Compile Include="Diagnostics\EmptyArrayOperationAnalyzer.cs" />
<Compile Include="Diagnostics\EmptyArrayAnalyzer.cs" />
<Compile Include="Diagnostics\LocalCouldBeConstAnalyzer.cs" />
<Compile Include="Diagnostics\OperationTestAnalyzer.cs" />
<Compile Include="Diagnostics\SystemLanguageAnalyzer.cs" />
<Compile Include="Diagnostics\FieldCouldBeReadOnlyAnalyzer.cs" />
<Compile Include="Emit\EmitOptionsTests.cs" />
<Compile Include="Emit\CustomDebugInfoTests.cs" />
<Compile Include="InternalUtilities\StreamExtensionsTests.cs" />
......@@ -184,4 +185,4 @@
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
<Import Project="..\..\..\..\build\Targets\Roslyn.Toolsets.Xunit.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -5,13 +5,12 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Semantics;
namespace Microsoft.CodeAnalysis.UnitTests.Diagnostics
namespace Microsoft.CodeAnalysis.UnitTests.Diagnostics.SystemLanguage
{
/// <summary>Base type for an analyzer that looks for empty array allocations and recommends their replacement.</summary>
public class EmptyArrayOperationAnalyzer : DiagnosticAnalyzer
/// <summary>Analyzer that looks for empty array allocations and recommends their replacement.</summary>
public class EmptyArrayAnalyzer : DiagnosticAnalyzer
{
/// <summary>Diagnostic category "Performance".</summary>
private const string PerformanceCategory = "Performance";
private const string SystemCategory = "System";
/// <summary>The name of the array type.</summary>
internal const string ArrayTypeName = "System.Array"; // using instead of GetSpecialType to make more testable
......@@ -27,7 +26,7 @@ public class EmptyArrayOperationAnalyzer : DiagnosticAnalyzer
"EmptyArrayRule",
localizableTitle,
localizableMessage,
PerformanceCategory,
SystemCategory,
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
......
......@@ -132,118 +132,4 @@ void Report(CompilationAnalysisContext context, IFieldSymbol field, DiagnosticDe
context.ReportDiagnostic(Diagnostic.Create(descriptor, field.Locations.FirstOrDefault()));
}
}
/// <summary>Analyzer used to identify local variables that could be declared Const.</summary>
public class LocalCouldBeConstAnalyzer : DiagnosticAnalyzer
{
private const string SystemCategory = "System";
public static readonly DiagnosticDescriptor LocalCouldBeConstDescriptor = new DiagnosticDescriptor(
"LocalCouldBeReadOnly",
"Local Could Be Const",
"Local variable is never modified and so could be const.",
SystemCategory,
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
/// <summary>Gets the set of supported diagnostic descriptors from this analyzer.</summary>
public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get { return ImmutableArray.Create(LocalCouldBeConstDescriptor); }
}
public sealed override void Initialize(AnalysisContext context)
{
context.RegisterOperationBlockStartAction(
(operationBlockContext) =>
{
IMethodSymbol containingMethod = operationBlockContext.OwningSymbol as IMethodSymbol;
if (containingMethod != null)
{
HashSet<ILocalSymbol> mightBecomeConstLocals = new HashSet<ILocalSymbol>();
HashSet<ILocalSymbol> assignedToLocals = new HashSet<ILocalSymbol>();
operationBlockContext.RegisterOperationAction(
(operationContext) =>
{
IAssignmentExpression assignment = (IAssignmentExpression)operationContext.Operation;
AssignTo(assignment.Target, assignedToLocals, mightBecomeConstLocals);
},
OperationKind.AssignmentExpression,
OperationKind.CompoundAssignmentExpression,
OperationKind.IncrementExpression);
operationBlockContext.RegisterOperationAction(
(operationContext) =>
{
IInvocationExpression invocation = (IInvocationExpression)operationContext.Operation;
foreach (IArgument argument in invocation.ArgumentsInParameterOrder)
{
if (argument.Parameter.RefKind == RefKind.Out || argument.Parameter.RefKind == RefKind.Ref)
{
AssignTo(argument.Value, assignedToLocals, mightBecomeConstLocals);
}
}
},
OperationKind.InvocationExpression);
operationBlockContext.RegisterOperationAction(
(operationContext) =>
{
IVariableDeclarationStatement declaration = (IVariableDeclarationStatement)operationContext.Operation;
foreach (IVariable variable in declaration.Variables)
{
ILocalSymbol local = variable.Variable;
if (!local.IsConst)
{
var localType = local.Type;
if ((!localType.IsReferenceType || localType.SpecialType == SpecialType.System_String) && localType.SpecialType != SpecialType.None)
{
if (variable.InitialValue != null && variable.InitialValue.ConstantValue != null)
{
mightBecomeConstLocals.Add(local);
}
}
}
}
},
OperationKind.VariableDeclarationStatement);
operationBlockContext.RegisterOperationBlockEndAction(
(operationBlockEndContext) =>
{
foreach (ILocalSymbol couldBeConstLocal in mightBecomeConstLocals)
{
Report(operationBlockEndContext, couldBeConstLocal, LocalCouldBeConstDescriptor);
}
});
}
});
}
static void AssignTo(IExpression target, HashSet<ILocalSymbol> assignedToLocals, HashSet<ILocalSymbol> mightBecomeConstLocals)
{
if (target.Kind == OperationKind.LocalReferenceExpression)
{
ILocalSymbol targetLocal = ((ILocalReferenceExpression)target).Local;
assignedToLocals.Add(targetLocal);
mightBecomeConstLocals.Remove(targetLocal);
}
else if (target.Kind == OperationKind.FieldReferenceExpression)
{
IFieldReferenceExpression fieldReference = (IFieldReferenceExpression)target;
if (fieldReference.Instance != null && fieldReference.Instance.ResultType.IsValueType)
{
AssignTo(fieldReference.Instance, assignedToLocals, mightBecomeConstLocals);
}
}
}
void Report(OperationBlockAnalysisContext context, ILocalSymbol local, DiagnosticDescriptor descriptor)
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, local.Locations.FirstOrDefault()));
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Semantics;
namespace Microsoft.CodeAnalysis.UnitTests.Diagnostics.SystemLanguage
{
/// <summary>Analyzer used to identify local variables that could be declared Const.</summary>
public class LocalCouldBeConstAnalyzer : DiagnosticAnalyzer
{
private const string SystemCategory = "System";
public static readonly DiagnosticDescriptor LocalCouldBeConstDescriptor = new DiagnosticDescriptor(
"LocalCouldBeReadOnly",
"Local Could Be Const",
"Local variable is never modified and so could be const.",
SystemCategory,
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
/// <summary>Gets the set of supported diagnostic descriptors from this analyzer.</summary>
public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get { return ImmutableArray.Create(LocalCouldBeConstDescriptor); }
}
public sealed override void Initialize(AnalysisContext context)
{
context.RegisterOperationBlockStartAction(
(operationBlockContext) =>
{
IMethodSymbol containingMethod = operationBlockContext.OwningSymbol as IMethodSymbol;
if (containingMethod != null)
{
HashSet<ILocalSymbol> mightBecomeConstLocals = new HashSet<ILocalSymbol>();
HashSet<ILocalSymbol> assignedToLocals = new HashSet<ILocalSymbol>();
operationBlockContext.RegisterOperationAction(
(operationContext) =>
{
IAssignmentExpression assignment = (IAssignmentExpression)operationContext.Operation;
AssignTo(assignment.Target, assignedToLocals, mightBecomeConstLocals);
},
OperationKind.AssignmentExpression,
OperationKind.CompoundAssignmentExpression,
OperationKind.IncrementExpression);
operationBlockContext.RegisterOperationAction(
(operationContext) =>
{
IInvocationExpression invocation = (IInvocationExpression)operationContext.Operation;
foreach (IArgument argument in invocation.ArgumentsInParameterOrder)
{
if (argument.Parameter.RefKind == RefKind.Out || argument.Parameter.RefKind == RefKind.Ref)
{
AssignTo(argument.Value, assignedToLocals, mightBecomeConstLocals);
}
}
},
OperationKind.InvocationExpression);
operationBlockContext.RegisterOperationAction(
(operationContext) =>
{
IVariableDeclarationStatement declaration = (IVariableDeclarationStatement)operationContext.Operation;
foreach (IVariable variable in declaration.Variables)
{
ILocalSymbol local = variable.Variable;
if (!local.IsConst && !assignedToLocals.Contains(local))
{
var localType = local.Type;
if ((!localType.IsReferenceType || localType.SpecialType == SpecialType.System_String) && localType.SpecialType != SpecialType.None)
{
if (variable.InitialValue != null && variable.InitialValue.ConstantValue != null)
{
mightBecomeConstLocals.Add(local);
}
}
}
}
},
OperationKind.VariableDeclarationStatement);
operationBlockContext.RegisterOperationBlockEndAction(
(operationBlockEndContext) =>
{
foreach (ILocalSymbol couldBeConstLocal in mightBecomeConstLocals)
{
Report(operationBlockEndContext, couldBeConstLocal, LocalCouldBeConstDescriptor);
}
});
}
});
}
static void AssignTo(IExpression target, HashSet<ILocalSymbol> assignedToLocals, HashSet<ILocalSymbol> mightBecomeConstLocals)
{
if (target.Kind == OperationKind.LocalReferenceExpression)
{
ILocalSymbol targetLocal = ((ILocalReferenceExpression)target).Local;
assignedToLocals.Add(targetLocal);
mightBecomeConstLocals.Remove(targetLocal);
}
else if (target.Kind == OperationKind.FieldReferenceExpression)
{
IFieldReferenceExpression fieldReference = (IFieldReferenceExpression)target;
if (fieldReference.Instance != null && fieldReference.Instance.ResultType.IsValueType)
{
AssignTo(fieldReference.Instance, assignedToLocals, mightBecomeConstLocals);
}
}
}
void Report(OperationBlockAnalysisContext context, ILocalSymbol local, DiagnosticDescriptor descriptor)
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, local.Locations.FirstOrDefault()));
}
}
}
\ No newline at end of file
......@@ -39,13 +39,13 @@ End Class
Dim comp = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New EmptyArrayOperationAnalyzer}, Nothing, Nothing, False,
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer(-1) { }").WithLocation(3, 33),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "{ }").WithLocation(4, 30),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "New C(-1) { }").WithLocation(5, 27),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer(-1)() { }").WithLocation(9, 35),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer( -1)()()() { }").WithLocation(10, 39),
Diagnostic(EmptyArrayOperationAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer(-1)(,) { }").WithLocation(12, 37))
comp.VerifyAnalyzerDiagnostics({New EmptyArrayAnalyzer}, Nothing, Nothing, False,
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer(-1) { }").WithLocation(3, 33),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "{ }").WithLocation(4, 30),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "New C(-1) { }").WithLocation(5, 27),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer(-1)() { }").WithLocation(9, 35),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer( -1)()()() { }").WithLocation(10, 39),
Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "New Integer(-1)(,) { }").WithLocation(12, 37))
End Sub
<Fact>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册