Skip to content

Commit e2ed9d4

Browse files
committed
Chained wrapper analyzer
1 parent c1c2ea3 commit e2ed9d4

File tree

7 files changed

+257
-34
lines changed

7 files changed

+257
-34
lines changed

Rubberduck.sln

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,8 @@ Global
485485
{D488071E-EDCB-4601-B734-1A3109ED903C}.Release64|x64.Build.0 = Release|Any CPU
486486
{D488071E-EDCB-4601-B734-1A3109ED903C}.Release64|x86.ActiveCfg = Release|Any CPU
487487
{D488071E-EDCB-4601-B734-1A3109ED903C}.Release64|x86.Build.0 = Release|Any CPU
488-
{F83B6746-49A6-4CFD-9A29-3D7BBD4F0323}.Debug|Any CPU.ActiveCfg = Release|Any CPU
489-
{F83B6746-49A6-4CFD-9A29-3D7BBD4F0323}.Debug|Any CPU.Build.0 = Release|Any CPU
488+
{F83B6746-49A6-4CFD-9A29-3D7BBD4F0323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
489+
{F83B6746-49A6-4CFD-9A29-3D7BBD4F0323}.Debug|Any CPU.Build.0 = Debug|Any CPU
490490
{F83B6746-49A6-4CFD-9A29-3D7BBD4F0323}.Debug|x64.ActiveCfg = Release|Any CPU
491491
{F83B6746-49A6-4CFD-9A29-3D7BBD4F0323}.Debug|x64.Build.0 = Release|Any CPU
492492
{F83B6746-49A6-4CFD-9A29-3D7BBD4F0323}.Debug|x86.ActiveCfg = Release|Any CPU
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System.Collections.Immutable;
2+
using System.Linq;
3+
using Microsoft.CodeAnalysis;
4+
using Microsoft.CodeAnalysis.CSharp;
5+
using Microsoft.CodeAnalysis.CSharp.Syntax;
6+
using Microsoft.CodeAnalysis.Diagnostics;
7+
8+
namespace RubberduckCodeAnalysis
9+
{
10+
[DiagnosticAnalyzer(LanguageNames.CSharp)]
11+
public class ChainedWrapperAnalyzer : DiagnosticAnalyzer
12+
{
13+
private const string ChainedWrapperId = "ChainedWrapper";
14+
private static readonly DiagnosticDescriptor ChainedWrapperRule = new DiagnosticDescriptor(
15+
ChainedWrapperId,
16+
new LocalizableResourceString(nameof(Resources.ChainedWrapperTitle), Resources.ResourceManager, typeof(Resources)),
17+
new LocalizableResourceString(nameof(Resources.ChainedWrapperMessageFormat), Resources.ResourceManager, typeof(Resources)),
18+
new LocalizableResourceString(nameof(Resources.AnalyzerCategory), Resources.ResourceManager, typeof(Resources)).ToString(),
19+
DiagnosticSeverity.Error,
20+
true,
21+
new LocalizableResourceString(nameof(Resources.ChainedWrapperDescription), Resources.ResourceManager, typeof(Resources))
22+
);
23+
24+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
25+
ImmutableArray.Create(ChainedWrapperRule);
26+
27+
public override void Initialize(AnalysisContext context)
28+
{
29+
context.RegisterSyntaxNodeAction(AnalyzeSymbol, SyntaxKind.SimpleMemberAccessExpression);
30+
}
31+
32+
private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
33+
{
34+
var node = (MemberAccessExpressionSyntax)context.Node;
35+
36+
if (!(node.Expression is InvocationExpressionSyntax || node.Expression is MemberAccessExpressionSyntax))
37+
{
38+
return;
39+
}
40+
41+
var expInterfaces = context.SemanticModel.GetTypeInfo(node.Expression).Type?.AllInterfaces;
42+
var nameInterfaces = context.SemanticModel.GetTypeInfo(node.Name).Type?.AllInterfaces;
43+
44+
if (expInterfaces?.Any(a => a.ToDisplayString() == "Rubberduck.VBEditor.SafeComWrappers.Abstract.ISafeComWrapper") == true ||
45+
nameInterfaces?.Any(a => a.ToDisplayString() == "Rubberduck.VBEditor.SafeComWrappers.Abstract.ISafeComWrapper") == true)
46+
{
47+
var diagnostic = Diagnostic.Create(ChainedWrapperRule, node.GetLocation());
48+
context.ReportDiagnostic(diagnostic);
49+
}
50+
}
51+
}
52+
}

RubberduckCodeAnalysis/Resources.Designer.cs

Lines changed: 52 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

RubberduckCodeAnalysis/Resources.resx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,15 @@
120120
<data name="AnalyzerCategory" xml:space="preserve">
121121
<value>COM Management</value>
122122
</data>
123+
<data name="ChainedWrapperDescription" xml:space="preserve">
124+
<value>Chained Wrappers</value>
125+
</data>
126+
<data name="ChainedWrapperMessageFormat" xml:space="preserve">
127+
<value>Chained Wrappers</value>
128+
</data>
129+
<data name="ChainedWrapperTitle" xml:space="preserve">
130+
<value>Chained Wrappers</value>
131+
</data>
123132
<data name="MissingClassInterfaceDescription" xml:space="preserve">
124133
<value>COM-visible classes must have an explicit ClassInterface attribute and be set to `None`. This is required to avoid verisoning problems.</value>
125134
</data>

RubberduckCodeAnalysis/RubberduckCodeAnalysis.csproj

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,14 @@
144144
</Reference>
145145
</ItemGroup>
146146
<ItemGroup>
147+
<Compile Include="ChainedWrapperAnalyzer.cs" />
147148
<Compile Include="ComVisibleTypeAnalyzer.cs" />
148149
<Compile Include="Properties\AssemblyInfo.cs" />
149-
<Compile Include="Resources.Designer.cs" />
150+
<Compile Include="Resources.Designer.cs">
151+
<AutoGen>True</AutoGen>
152+
<DesignTime>True</DesignTime>
153+
<DependentUpon>Resources.resx</DependentUpon>
154+
</Compile>
150155
<Compile Include="RubberduckCodeAnalysisCodeFixProvider.cs" />
151156
</ItemGroup>
152157
<ItemGroup>
@@ -156,7 +161,11 @@
156161
<None Include="tools\uninstall.ps1" />
157162
</ItemGroup>
158163
<ItemGroup>
159-
<EmbeddedResource Include="Resources.resx" />
164+
<EmbeddedResource Include="Resources.resx">
165+
<Generator>PublicResXFileCodeGenerator</Generator>
166+
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
167+
<SubType>Designer</SubType>
168+
</EmbeddedResource>
160169
</ItemGroup>
161170
<ItemGroup>
162171
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />

0 commit comments

Comments
 (0)