├── .gitattributes
├── .gitignore
├── CleanCode
└── src
│ ├── CleanCode.nuspec
│ ├── CleanCode.sln
│ ├── CleanCode.sln.DotSettings
│ └── CleanCode
│ ├── .gitignore
│ ├── CleanCode.csproj
│ ├── CleanCodeHighlightingGroupIds.cs
│ ├── Features
│ ├── ChainedReferences
│ │ ├── ChainedReferencesCheck.cs
│ │ └── MaximumChainedReferencesHighlighting.cs
│ ├── ClassTooBig
│ │ ├── ClassTooBigCheck.cs
│ │ └── ClassTooBigHighlighting.cs
│ ├── ComplexExpression
│ │ ├── ComplexConditionExpressionCheck.cs
│ │ └── ComplexConditionExpressionHighlighting.cs
│ ├── ExcessiveIndentation
│ │ ├── ExcessiveIndentHighlighting.cs
│ │ └── ExcessiveIndentationCheck.cs
│ ├── ExtensionMethods.cs
│ ├── FlagArguments
│ │ ├── FlagArgumentsCheck.cs
│ │ └── FlagArgumentsHighlighting.cs
│ ├── HollowNames
│ │ ├── HollowNamesCheck.cs
│ │ └── HollowTypeNameHighlighting.cs
│ ├── MethodNameNotMeaningful
│ │ ├── MethodNameNotMeaningfulCheck.cs
│ │ └── MethodNameNotMeaningfulHighlighting.cs
│ ├── MethodTooLong
│ │ ├── MethodTooLongCheck.cs
│ │ └── MethodTooLongHighlighting.cs
│ ├── TooManyDependencies
│ │ ├── TooManyDependenciesCheck.cs
│ │ └── TooManyDependenciesHighlighting.cs
│ └── TooManyMethodArguments
│ │ ├── TooManyArgumentsHighlighting.cs
│ │ └── TooManyMethodArgumentsCheck.cs
│ ├── InvalidateOnSettingsChange.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Resources
│ ├── Icons
│ │ └── Settings
│ │ │ ├── CleanCode.png
│ │ │ ├── ThemedIcons.Settings.Generated.Xaml
│ │ │ └── ThemedIcons.Settings.Generated.cs
│ ├── Settings.Designer.cs
│ ├── Settings.resx
│ ├── Warnings.Designer.cs
│ └── Warnings.resx
│ ├── Settings
│ ├── CleanCodeOptionsPage.cs
│ └── CleanCodeSettings.cs
│ ├── ZoneMarker.cs
│ └── packages.config
├── README.md
├── license.txt
└── logo.png
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Visual Studio
3 | #################
4 |
5 | # User-specific files
6 | *.suo
7 | *.user
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Rr]elease/
12 | [Bb]in/
13 | [Oo]bj/
14 |
15 | # NuGet Packages Directory
16 | packages/
17 |
18 | # Build artifacts
19 | *.nupkg
20 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CleanCode.CleanCode
5 | 5.1.0
6 | Clean Code
7 | Hadi Hariri, Matt Ellis, SuperJMN
8 | Hadi Hariri, Matt Ellis
9 | https://raw.githubusercontent.com/hhariri/CleanCode/master/logo.png
10 | https://github.com/hhariri/CleanCode
11 | https://raw.github.com/hhariri/CleanCode/master/license.txt
12 | false
13 | Automates some of the concepts in Uncle Bob's Clean Code book
14 |
15 | • Updated to ReSharper 2017.1
16 |
17 | From 5.0.3:
18 | • Stop marking abstract methods too long (#19)
19 |
20 | From 5.0.2:
21 | • Method parameter and type parameter declarations mistakenly used for "method too long" check (#12)
22 |
23 | From 5.0.1:
24 | • Updated to ReSharper 2016.2
25 | • Fix minor installer issue
26 |
27 | From 4.0.0:
28 | • Warning if a method uses flag parameters
29 | • Warning if a method contains too many nested blocks
30 | • Warning if a method name is too short to be meaningful
31 | • Warning if an epression is breaking the Law of Demeter
32 | • Warning if a constructor has too many parameters, indicating too many dependencies
33 | • Warning if a method has too many arguments
34 | • Suggestion highlight if class has too many methods
35 | • Suggestion highlight if method has too many statements
36 |
37 | Copyright 2014-2016 Hadi Hariri and Contributors
38 |
39 |
40 |
41 | clean code
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanCode", "CleanCode\CleanCode.csproj", "{5F96119C-2646-4298-AD40-30209E7E7BB2}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {5F96119C-2646-4298-AD40-30209E7E7BB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {5F96119C-2646-4298-AD40-30209E7E7BB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {5F96119C-2646-4298-AD40-30209E7E7BB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {5F96119C-2646-4298-AD40-30209E7E7BB2}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | ID
3 |
4 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/.gitignore:
--------------------------------------------------------------------------------
1 | *.nupkg
2 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/CleanCode.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | 8.0.30703
8 | 2.0
9 | {5F96119C-2646-4298-AD40-30209E7E7BB2}
10 | Library
11 | Properties
12 | CleanCode
13 | CleanCode
14 | v4.5
15 | 512
16 |
17 | aa44b150
18 |
19 |
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | TRACE;DEBUG;JET_MODE_ASSERT
25 | prompt
26 | 4
27 |
28 |
29 | pdbonly
30 | true
31 | TRACE
32 | prompt
33 | 4
34 | bin\Release\
35 |
36 |
37 |
38 | ..\packages\Antlr2.Runtime.2.7.7.02\lib\antlr.runtime.dll
39 | True
40 |
41 |
42 | ..\packages\Appccelerate.StateMachine.JetBrains.2.2.0.1\lib\net45\Appccelerate.Fundamentals.dll
43 | True
44 |
45 |
46 | ..\packages\Appccelerate.StateMachine.JetBrains.2.2.0.1\lib\net45\Appccelerate.StateMachine.dll
47 | True
48 |
49 |
50 | ..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll
51 | True
52 |
53 |
54 | ..\packages\JetBrains.Platform.Lib.DevExpress.2.0.20150224.0\lib\Net\DevExpress.Data.v7.1.dll
55 | True
56 |
57 |
58 | ..\packages\JetBrains.Platform.Lib.DevExpress.2.0.20150224.0\lib\Net\DevExpress.Utils.v7.1.dll
59 | True
60 |
61 |
62 | ..\packages\JetBrains.Platform.Lib.DevExpress.2.0.20150224.0\lib\Net\DevExpress.XtraEditors.v7.1.dll
63 | True
64 |
65 |
66 | ..\packages\JetBrains.Platform.Lib.DevExpress.2.0.20150224.0\lib\Net\DevExpress.XtraTreeList.v7.1.dll
67 | True
68 |
69 |
70 | ..\packages\SharpZipLib.JetBrains.Stripped.0.87.20161027.6\lib\net40\ICSharpCode.SharpZipLib.dll
71 | True
72 |
73 |
74 | ..\packages\DotNetZip.Reduced.1.9.1.8\lib\net20\Ionic.Zip.Reduced.dll
75 | True
76 |
77 |
78 | ..\packages\JetBrains.Annotations.10.4.0\lib\net\JetBrains.Annotations.dll
79 | True
80 |
81 |
82 | ..\packages\JetBrains.Platform.MSBuild.Logger.1.0.20170130.0\lib\net\JetBrains.MSBuild.Logger.dll
83 | True
84 | True
85 |
86 |
87 | ..\packages\JetBrains.System.Reflection.Metadata.1.0.0\lib\net45\JetBrains.System.Reflection.Metadata.dll
88 | True
89 |
90 |
91 | ..\packages\JetBrains.MahApps.Metro.1.3.1\lib\net45\MahApps.Metro.dll
92 | True
93 |
94 |
95 | ..\packages\JetBrains.Platform.Lib.Microsoft.Deployment.Compression.Cab.2.0.20140304.0\lib\Microsoft.Deployment.Compression.dll
96 | True
97 |
98 |
99 | ..\packages\JetBrains.Platform.Lib.Microsoft.Deployment.Compression.Cab.2.0.20140304.0\lib\Microsoft.Deployment.Compression.Cab.dll
100 | True
101 |
102 |
103 | ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
104 | True
105 |
106 |
107 | ..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll
108 | True
109 |
110 |
111 | ..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll
112 | True
113 |
114 |
115 | ..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll
116 | True
117 |
118 |
119 | ..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll
120 | True
121 |
122 |
123 | ..\packages\Microsoft.Web.Xdt.2.1.1\lib\net40\Microsoft.Web.XmlTransform.dll
124 | True
125 |
126 |
127 | ..\packages\Windows7APICodePack.JetBrains.Stripped.1.1.20150225.0\lib\Net\Microsoft.WindowsAPICodePack.dll
128 | True
129 |
130 |
131 | ..\packages\Windows7APICodePack.JetBrains.Stripped.1.1.20150225.0\lib\Net\Microsoft.WindowsAPICodePack.Shell.dll
132 | True
133 |
134 |
135 | ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
136 | True
137 |
138 |
139 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Client.dll
140 | True
141 |
142 |
143 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Commands.dll
144 | True
145 |
146 |
147 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Common.dll
148 | True
149 |
150 |
151 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Configuration.dll
152 | True
153 |
154 |
155 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.ContentModel.dll
156 | True
157 |
158 |
159 | ..\packages\JetBrains.NuGet.Core.2.14.1\lib\net40-Client\NuGet.Core.dll
160 | True
161 |
162 |
163 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.DependencyResolver.Core.dll
164 | True
165 |
166 |
167 | ..\packages\JetBrains.NuGet.Frameworks.4.0.0\lib\net45\NuGet.Frameworks.dll
168 | True
169 |
170 |
171 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.LibraryModel.dll
172 | True
173 |
174 |
175 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.PackageManagement.dll
176 | True
177 |
178 |
179 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Packaging.dll
180 | True
181 |
182 |
183 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Packaging.Core.dll
184 | True
185 |
186 |
187 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Packaging.Core.Types.dll
188 | True
189 |
190 |
191 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.ProjectManagement.dll
192 | True
193 |
194 |
195 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.ProjectModel.dll
196 | True
197 |
198 |
199 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Protocol.Core.Types.dll
200 | True
201 |
202 |
203 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Protocol.Core.v2.dll
204 | True
205 |
206 |
207 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Protocol.Core.v3.dll
208 | True
209 |
210 |
211 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Protocol.VisualStudio.dll
212 | True
213 |
214 |
215 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Repositories.dll
216 | True
217 |
218 |
219 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.Resolver.dll
220 | True
221 |
222 |
223 | ..\packages\JetBrains.NuGet.Ultimate.4.0.0\lib\net45\NuGet.RuntimeModel.dll
224 | True
225 |
226 |
227 | ..\packages\JetBrains.NuGet.Versioning.4.0.0\lib\net45\NuGet.Versioning.dll
228 | True
229 |
230 |
231 | ..\packages\NUnit.2.6.4\lib\nunit.framework.dll
232 | True
233 |
234 |
235 | ..\packages\NVelocity.1.0.3\lib\NVelocity.dll
236 | True
237 |
238 |
239 | ..\packages\Owin.1.0\lib\net40\Owin.dll
240 | True
241 |
242 |
243 |
244 |
245 | ..\packages\sharpcompress.0.11.6\lib\net40\SharpCompress.dll
246 | True
247 |
248 |
249 | ..\packages\Sprache.JetBrains.2.1.0\lib\net40\Sprache.dll
250 | True
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 | ..\packages\JetBrains.Platform.Lib.System.Windows.Interactivity.3.0.40218\lib\System.Windows.Interactivity.dll
264 | True
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 | ..\packages\Vestris.ResourceLib.JetBrains.1.4.20150303.0\lib\Net\Vestris.ResourceLib.dll
275 | True
276 |
277 |
278 |
279 | ..\packages\JetBrains.Platform.Lib.WpfContrib.2.0.20150225.0\lib\Net\WpfContrib.dll
280 | True
281 |
282 |
283 | ..\packages\xunit.JetBrains.1.9.2\lib\net20\xunit.dll
284 | True
285 |
286 |
287 | ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll
288 | True
289 |
290 |
291 | ..\packages\xunit.runner.utility.2.2.0\lib\net35\xunit.runner.utility.net35.dll
292 | True
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 | Code
313 |
314 |
315 |
316 | Code
317 |
318 |
319 |
320 |
321 | Code
322 |
323 |
324 |
325 |
326 |
327 |
328 | True
329 | True
330 | Settings.resx
331 |
332 |
333 | Warnings.resx
334 | True
335 | True
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 | PublicResXFileCodeGenerator
344 | Designer
345 | Settings.Designer.cs
346 |
347 |
348 | PublicResXFileCodeGenerator
349 | Warnings.Designer.cs
350 | Designer
351 |
352 |
353 |
354 |
355 | MSBuild:Compile
356 | Designer
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 | CleanCode.nuspec
365 | Designer
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/CleanCodeHighlightingGroupIds.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using JetBrains.ReSharper.Feature.Services.Daemon;
3 |
4 | [assembly: RegisterConfigurableHighlightingsGroup(CleanCodeHighlightingGroupIds.CleanCode, "Clean Code")]
5 |
6 | namespace CleanCode
7 | {
8 | public static class CleanCodeHighlightingGroupIds
9 | {
10 | public const string CleanCode = "CleanCode";
11 | }
12 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ChainedReferences/ChainedReferencesCheck.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using CleanCode.Resources;
3 | using CleanCode.Settings;
4 | using JetBrains.Application.Settings;
5 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
6 | using JetBrains.ReSharper.Feature.Services.Daemon;
7 | using JetBrains.ReSharper.Psi;
8 | using JetBrains.ReSharper.Psi.CSharp.Tree;
9 | using JetBrains.ReSharper.Psi.Tree;
10 |
11 | namespace CleanCode.Features.ChainedReferences
12 | {
13 | [ElementProblemAnalyzer(typeof(ICSharpStatement), HighlightingTypes = new []
14 | {
15 | typeof(MaximumChainedReferencesHighlighting)
16 | })]
17 | public class ChainedReferencesCheck : ElementProblemAnalyzer
18 | {
19 | protected override void Run(ICSharpStatement element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
20 | {
21 | if (!element.CanBeEmbedded)
22 | {
23 | var threshold = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumChainedReferences);
24 | HighlightMethodChainsThatAreTooLong(element, consumer, threshold);
25 | }
26 | }
27 |
28 | private void HighlightMethodChainsThatAreTooLong(ITreeNode statement, IHighlightingConsumer consumer, int threshold)
29 | {
30 | var children = statement.Children();
31 |
32 | foreach (var treeNode in children)
33 | {
34 | var referenceExpression = treeNode as IReferenceExpression;
35 | if (referenceExpression != null)
36 | {
37 | HighlightReferenceExpressionIfNeeded(referenceExpression, consumer, threshold);
38 | }
39 | else
40 | {
41 | HighlightMethodChainsThatAreTooLong(treeNode, consumer, threshold);
42 | }
43 | }
44 | }
45 |
46 | private void HighlightReferenceExpressionIfNeeded(IReferenceExpression referenceExpression, IHighlightingConsumer consumer, int threshold)
47 | {
48 | var types = new HashSet();
49 |
50 | var nextReferenceExpression = referenceExpression;
51 | var chainLength = 0;
52 |
53 | while (nextReferenceExpression != null)
54 | {
55 | var childReturnType = ExtensionMethods.TryGetClosedReturnTypeFrom(nextReferenceExpression);
56 |
57 | if (childReturnType != null)
58 | {
59 | types.Add(childReturnType);
60 | chainLength++;
61 | }
62 |
63 | nextReferenceExpression = ExtensionMethods.TryGetFirstReferenceExpression(nextReferenceExpression);
64 | }
65 |
66 | var isFluentChain = types.Count == 1;
67 |
68 | if (!isFluentChain)
69 | {
70 | if (chainLength > threshold)
71 | {
72 | AddHighlighting(referenceExpression, consumer);
73 | }
74 | }
75 | }
76 |
77 | private static void AddHighlighting(IReferenceExpression reference, IHighlightingConsumer consumer)
78 | {
79 | var nameIdentifier = reference.NameIdentifier;
80 | var documentRange = nameIdentifier.GetDocumentRange();
81 | var highlighting = new MaximumChainedReferencesHighlighting(Warnings.ChainedReferences, documentRange);
82 | consumer.AddHighlighting(highlighting);
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ChainedReferences/MaximumChainedReferencesHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.ChainedReferences;
3 | using JetBrains.DocumentModel;
4 | using JetBrains.ReSharper.Feature.Services.Daemon;
5 | using JetBrains.ReSharper.Psi.CSharp;
6 |
7 | [assembly: RegisterConfigurableSeverity(MaximumChainedReferencesHighlighting.SeverityID, null,
8 | CleanCodeHighlightingGroupIds.CleanCode, "Too many chained references", "Too many chained references can break the Law of Demeter.",
9 | Severity.WARNING)]
10 |
11 | namespace CleanCode.Features.ChainedReferences
12 | {
13 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
14 | public class MaximumChainedReferencesHighlighting : IHighlighting
15 | {
16 | internal const string SeverityID = "TooManyChainedReferences";
17 |
18 | private readonly DocumentRange documentRange;
19 |
20 | public MaximumChainedReferencesHighlighting(string toolTip, DocumentRange documentRange)
21 | {
22 | ToolTip = toolTip;
23 | this.documentRange = documentRange;
24 | }
25 |
26 | public DocumentRange CalculateRange() => documentRange;
27 | public string ToolTip { get; }
28 | public string ErrorStripeToolTip => ToolTip;
29 | public bool IsValid() => true;
30 | }
31 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ClassTooBig/ClassTooBigCheck.cs:
--------------------------------------------------------------------------------
1 | using CleanCode.Resources;
2 | using CleanCode.Settings;
3 | using JetBrains.Application.Settings;
4 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp.Tree;
7 | using JetBrains.ReSharper.Psi.Tree;
8 |
9 | namespace CleanCode.Features.ClassTooBig
10 | {
11 | [ElementProblemAnalyzer(typeof(IClassDeclaration), HighlightingTypes = new []
12 | {
13 | typeof(ClassTooBigHighlighting)
14 | })]
15 | public class ClassTooBigCheck : ElementProblemAnalyzer
16 | {
17 | protected override void Run(IClassDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
18 | {
19 | var maxLength = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumMethodsInClass);
20 |
21 | var statementCount = element.CountChildren();
22 | if (statementCount > maxLength)
23 | {
24 | var declarationIdentifier = element.NameIdentifier;
25 | var documentRange = declarationIdentifier.GetDocumentRange();
26 | var highlighting = new ClassTooBigHighlighting(Warnings.ClassTooBig, documentRange);
27 | consumer.AddHighlighting(highlighting);
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ClassTooBig/ClassTooBigHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.ClassTooBig;
3 | using JetBrains.DocumentModel;
4 | using JetBrains.ReSharper.Feature.Services.Daemon;
5 | using JetBrains.ReSharper.Psi.CSharp;
6 |
7 | [assembly: RegisterConfigurableSeverity(ClassTooBigHighlighting.SeverityID, null,
8 | CleanCodeHighlightingGroupIds.CleanCode, "Class too big", "This class contains too many methods",
9 | Severity.SUGGESTION)]
10 |
11 | namespace CleanCode.Features.ClassTooBig
12 | {
13 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
14 | public class ClassTooBigHighlighting : IHighlighting
15 | {
16 | internal const string SeverityID = "ClassTooBig";
17 |
18 | private readonly DocumentRange documentRange;
19 |
20 | public ClassTooBigHighlighting(string toolTip, DocumentRange documentRange)
21 | {
22 | ToolTip = toolTip;
23 | this.documentRange = documentRange;
24 | }
25 |
26 | public DocumentRange CalculateRange() => documentRange;
27 | public string ToolTip { get; }
28 | public string ErrorStripeToolTip => ToolTip;
29 | public bool IsValid() => true;
30 | }
31 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ComplexExpression/ComplexConditionExpressionCheck.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using CleanCode.Settings;
3 | using JetBrains.Application.Settings;
4 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp.Tree;
7 | using JetBrains.ReSharper.Psi.Tree;
8 |
9 | namespace CleanCode.Features.ComplexExpression
10 | {
11 | // TODO: This might be better working with IOperatorExpression
12 | // Walk up from the operator to the highest containing expression
13 | // and count depth?
14 | [ElementProblemAnalyzer(typeof(IIfStatement),
15 | typeof(ILoopWithConditionStatement),
16 | typeof(IConditionalTernaryExpression),
17 | typeof(IAssignmentExpression),
18 | typeof(IExpressionInitializer),
19 | HighlightingTypes = new[]
20 | {
21 | typeof(ComplexConditionExpressionHighlighting)
22 | })]
23 | public class ComplexConditionExpressionCheck : ElementProblemAnalyzer
24 | {
25 | protected override void Run(ICSharpTreeNode element, ElementProblemAnalyzerData data,
26 | IHighlightingConsumer consumer)
27 | {
28 | var expression = GetExpression(element);
29 | if (expression != null)
30 | CheckExpression(expression, data, consumer);
31 | }
32 |
33 | private static IExpression GetExpression(ITreeNode node)
34 | {
35 | // Covers for, while and do
36 | var loopStatement = node as ILoopWithConditionStatement;
37 | if (loopStatement != null)
38 | return loopStatement.Condition;
39 |
40 | var ifStatement = node as IIfStatement;
41 | if (ifStatement != null)
42 | return ifStatement.Condition;
43 |
44 | var conditionalTernaryExpression = node as IConditionalTernaryExpression;
45 | if (conditionalTernaryExpression != null)
46 | return conditionalTernaryExpression.ConditionOperand;
47 |
48 | // TODO: Should these two be part of this check?
49 | // Perhaps they should also check the type of the resulting
50 | // variable to be bool?
51 | var assignmentExpression = node as IAssignmentExpression;
52 | if (assignmentExpression != null)
53 | return assignmentExpression.Source;
54 |
55 | var expressionInitializer = node as IExpressionInitializer;
56 | return expressionInitializer?.Value;
57 | }
58 |
59 | private static void CheckExpression(IExpression expression, ElementProblemAnalyzerData data,
60 | IHighlightingConsumer consumer)
61 | {
62 | var maxExpressions = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumExpressionsInCondition);
63 | var expressionCount = expression.GetChildrenRecursive().Count();
64 |
65 | if (expressionCount > maxExpressions)
66 | {
67 | var documentRange = expression.GetDocumentRange();
68 | var highlighting = new ComplexConditionExpressionHighlighting(documentRange);
69 | consumer.AddHighlighting(highlighting);
70 | }
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ComplexExpression/ComplexConditionExpressionHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.ComplexExpression;
3 | using CleanCode.Resources;
4 | using JetBrains.DocumentModel;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp;
7 |
8 | [assembly:RegisterConfigurableSeverity(ComplexConditionExpressionHighlighting.SeverityID, null,
9 | CleanCodeHighlightingGroupIds.CleanCode, "Condition expression too complex", "The expression in the condition is too complex.",
10 | Severity.WARNING)]
11 |
12 | namespace CleanCode.Features.ComplexExpression
13 | {
14 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
15 | public class ComplexConditionExpressionHighlighting : IHighlighting
16 | {
17 | internal const string SeverityID = "ComplexConditionExpression";
18 |
19 | private readonly DocumentRange documentRange;
20 |
21 | public ComplexConditionExpressionHighlighting(DocumentRange documentRange)
22 | {
23 | this.documentRange = documentRange;
24 | }
25 |
26 | public DocumentRange CalculateRange() => documentRange;
27 | public string ToolTip => Warnings.ExpressionTooComplex;
28 | public string ErrorStripeToolTip => ToolTip;
29 | public bool IsValid() => true;
30 | }
31 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ExcessiveIndentation/ExcessiveIndentHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.ExcessiveIndentation;
3 | using CleanCode.Resources;
4 | using JetBrains.DocumentModel;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp;
7 |
8 | [assembly:RegisterConfigurableSeverity(ExcessiveIndentHighlighting.SeverityID, null,
9 | CleanCodeHighlightingGroupIds.CleanCode, "Excessive indentation", "The nesting in this method is excessive.",
10 | Severity.WARNING)]
11 |
12 | namespace CleanCode.Features.ExcessiveIndentation
13 | {
14 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
15 | public class ExcessiveIndentHighlighting : IHighlighting
16 | {
17 | internal const string SeverityID = "ExcessiveIndentation";
18 | private readonly DocumentRange documentRange;
19 |
20 | public ExcessiveIndentHighlighting(DocumentRange documentRange)
21 | {
22 | this.documentRange = documentRange;
23 | }
24 |
25 | public DocumentRange CalculateRange() => documentRange;
26 | public string ToolTip => Warnings.ExcessiveDepth;
27 | public string ErrorStripeToolTip => ToolTip;
28 | public bool IsValid() => true;
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ExcessiveIndentation/ExcessiveIndentationCheck.cs:
--------------------------------------------------------------------------------
1 | using CleanCode.Settings;
2 | using JetBrains.Application.Settings;
3 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
4 | using JetBrains.ReSharper.Feature.Services.Daemon;
5 | using JetBrains.ReSharper.Psi.CSharp.Tree;
6 | using JetBrains.ReSharper.Psi.Tree;
7 |
8 | namespace CleanCode.Features.ExcessiveIndentation
9 | {
10 | [ElementProblemAnalyzer(typeof(IMethodDeclaration),
11 | HighlightingTypes = new []
12 | {
13 | typeof(ExcessiveIndentHighlighting)
14 | })]
15 | public class ExcessiveIndentationCheck : ElementProblemAnalyzer
16 | {
17 | protected override void Run(IMethodDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
18 | {
19 | var maxIndentation = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumIndentationDepth);
20 | var depth = element.GetChildrenDepth();
21 |
22 | if (depth > maxIndentation)
23 | {
24 | var documentRange = element.GetNameDocumentRange();
25 | var highlighting = new ExcessiveIndentHighlighting(documentRange);
26 | consumer.AddHighlighting(highlighting);
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/ExtensionMethods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using JetBrains.ReSharper.Psi;
5 | using JetBrains.ReSharper.Psi.CSharp.Tree;
6 | using JetBrains.ReSharper.Psi.ExtensionsAPI.Resolve;
7 | using JetBrains.ReSharper.Psi.Resolve;
8 | using JetBrains.ReSharper.Psi.Tree;
9 |
10 | namespace CleanCode.Features
11 | {
12 | public static class ExtensionMethods
13 | {
14 | public static int CountChildren(this ITreeNode node) where T : ITreeNode
15 | {
16 | var treeNodes = node.Children().ToList();
17 |
18 | var childOfType = treeNodes.OfType();
19 | var count = childOfType.Count();
20 |
21 | foreach (var childNodes in treeNodes)
22 | {
23 | count += CountChildren(childNodes);
24 | }
25 | return count;
26 | }
27 |
28 |
29 | public static int GetChildrenDepth(this ITreeNode node)
30 | {
31 | var childrenDepth = 0;
32 | var children = node.Children();
33 | foreach (var block in children)
34 | {
35 | var levelOfCurrentBlock = GetChildrenDepth(block);
36 | childrenDepth = Math.Max(levelOfCurrentBlock, childrenDepth);
37 | }
38 |
39 | if (IsNodeThatIncreasesDepth(node))
40 | {
41 | return childrenDepth + 1;
42 | }
43 | return childrenDepth;
44 | }
45 |
46 | public static IEnumerable GetFlattenedHierarchyOfType(this ITreeNode root) where T : class, ITreeNode
47 | {
48 | var list = new List();
49 |
50 | var rootAsType = root as T;
51 | if (rootAsType != null)
52 | {
53 | list.Add(rootAsType);
54 | }
55 |
56 | list.AddRange(root.GetChildrenRecursive());
57 |
58 | return list;
59 | }
60 |
61 | public static IEnumerable GetChildrenRecursive(this ITreeNode node) where T : ITreeNode
62 | {
63 | var nodeChildren = node.Children().ToList();
64 |
65 | var list = new List();
66 |
67 | var childOfType = nodeChildren.OfType();
68 | list.AddRange(childOfType);
69 |
70 | foreach (var childNode in nodeChildren)
71 | {
72 | var childrenOfType = GetChildrenRecursive(childNode);
73 | list.AddRange(childrenOfType);
74 | }
75 |
76 | return list;
77 | }
78 |
79 | private static bool IsNodeThatIncreasesDepth(ITreeNode node)
80 | {
81 | if (node is IIfStatement)
82 | {
83 | return true;
84 | }
85 | if (node is IForeachStatement)
86 | {
87 | return true;
88 | }
89 | if (node is IForStatement)
90 | {
91 | return true;
92 | }
93 | if (node is ISwitchStatement)
94 | {
95 | return true;
96 | }
97 |
98 | return false;
99 | }
100 |
101 | public static IType TryGetClosedReturnTypeFrom(ITreeNode treeNode)
102 | {
103 | IType type = null;
104 | var reference = treeNode as IReferenceExpression;
105 | if (reference != null)
106 | {
107 | type = TryGetClosedReturnTypeFromReference(reference.Reference);
108 | }
109 |
110 | var invocationExpression = treeNode as IInvocationExpression;
111 | if (invocationExpression != null)
112 | {
113 | type = TryGetClosedReturnTypeFromReference(invocationExpression.Reference);
114 | }
115 |
116 | return type;
117 | }
118 |
119 | public static IReferenceExpression TryGetFirstReferenceExpression(ITreeNode currentNode)
120 | {
121 | var childNodes = currentNode.Children();
122 | var firstChildNode = childNodes.FirstOrDefault();
123 |
124 | if (firstChildNode == null)
125 | return null;
126 |
127 | return firstChildNode as IReferenceExpression ??
128 | TryGetFirstReferenceExpression(firstChildNode);
129 | }
130 |
131 | private static IType TryGetClosedReturnTypeFromReference(IReference reference)
132 | {
133 | var resolveResultWithInfo = GetResolveResult(reference);
134 |
135 | var declaredElement = resolveResultWithInfo.DeclaredElement;
136 | var parametersOwner = declaredElement as IParametersOwner;
137 |
138 | if (parametersOwner != null)
139 | {
140 | var returnType = parametersOwner.ReturnType;
141 | return returnType.IsOpenType ? GetClosedType(resolveResultWithInfo, returnType) : returnType;
142 | }
143 |
144 | return null;
145 | }
146 |
147 | private static IType GetClosedType(ResolveResultWithInfo resolveResultWithInfo, IType returnType)
148 | {
149 | var closedType = resolveResultWithInfo.Result.Substitution.Apply(returnType);
150 | return closedType;
151 | }
152 |
153 | public static ResolveResultWithInfo GetResolveResult(this IReference reference)
154 | {
155 | return reference.Resolve();
156 | }
157 | }
158 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/FlagArguments/FlagArgumentsCheck.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using JetBrains.ReSharper.Psi;
3 | using JetBrains.ReSharper.Psi.CSharp.Tree;
4 | using JetBrains.ReSharper.Psi.Tree;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
8 | using JetBrains.ReSharper.Feature.Services.Daemon;
9 | using JetBrains.ReSharper.Psi.Util;
10 |
11 | namespace CleanCode.Features.FlagArguments
12 | {
13 | [ElementProblemAnalyzer(typeof(IMethodDeclaration),
14 | HighlightingTypes = new []
15 | {
16 | typeof(FlagArgumentsHighlighting)
17 | })]
18 | public class FlagArgumentsCheck : ElementProblemAnalyzer
19 | {
20 | protected override void Run(IMethodDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
21 | {
22 | var parameterDeclarations = element.ParameterDeclarations;
23 |
24 | foreach (var parameterDeclaration in parameterDeclarations)
25 | {
26 | if (IsFlagArgument(parameterDeclaration, element.Body))
27 | {
28 | AddHighlighting(consumer, parameterDeclaration);
29 | }
30 | }
31 | }
32 |
33 | private static bool IsFlagArgument(ITypeOwnerDeclaration typeOwnerDeclaration, ITreeNode node)
34 | {
35 | if (IsOfTypeThatCanBeUsedAsFlag(typeOwnerDeclaration))
36 | {
37 | var references = GetReferencesTo(typeOwnerDeclaration.DeclaredElement, node);
38 | return references.Any();
39 | }
40 |
41 | return false;
42 | }
43 |
44 | private static bool IsOfTypeThatCanBeUsedAsFlag(ITypeOwnerDeclaration arg)
45 | {
46 | var type = arg.Type;
47 | return type.IsBool() || type.IsEnumType();
48 | }
49 |
50 | private static IEnumerable GetReferencesTo(IDeclaredElement declaredElement, ITreeNode body)
51 | {
52 | var ifStatements = body.GetChildrenRecursive();
53 |
54 | var allConditions = ifStatements.Select(statement => statement.Condition);
55 |
56 | var allReferencesInConditions =
57 | allConditions.SelectMany(expression => expression.GetFlattenedHierarchyOfType());
58 |
59 | return GetReferencesToArgument(allReferencesInConditions, declaredElement);
60 | }
61 |
62 | private static IEnumerable GetReferencesToArgument(IEnumerable allReferencesInConditions, IDeclaredElement declaredElementInArgument)
63 | {
64 | return allReferencesInConditions.Where(reference => IsReferenceToArgument(reference, declaredElementInArgument));
65 | }
66 |
67 | private static bool IsReferenceToArgument(IReferenceExpression referenceExpression, IDeclaredElement toFind)
68 | {
69 | if (referenceExpression == null)
70 | {
71 | return false;
72 | }
73 |
74 | var resolveResultWithInfo = referenceExpression.Reference.GetResolveResult();
75 | var declaredElement = resolveResultWithInfo.DeclaredElement;
76 |
77 | Debug.Assert(declaredElement != null, "declaredElement != null");
78 |
79 | return declaredElement.ShortName == toFind.ShortName;
80 | }
81 |
82 | private static void AddHighlighting(IHighlightingConsumer consumer, ICSharpParameterDeclaration parameterDeclaration)
83 | {
84 | var documentRange = parameterDeclaration.GetDocumentRange();
85 | var highlighting = new FlagArgumentsHighlighting(documentRange);
86 | consumer.AddHighlighting(highlighting);
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/FlagArguments/FlagArgumentsHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.FlagArguments;
3 | using CleanCode.Resources;
4 | using JetBrains.DocumentModel;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp;
7 |
8 | [assembly: RegisterConfigurableSeverity(FlagArgumentsHighlighting.SeverityID, null,
9 | CleanCodeHighlightingGroupIds.CleanCode, "Flag argument", "An argument that is used as a flag.",
10 | Severity.WARNING)]
11 |
12 | namespace CleanCode.Features.FlagArguments
13 | {
14 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
15 | public class FlagArgumentsHighlighting : IHighlighting
16 | {
17 | internal const string SeverityID = "FlagArgument";
18 | private readonly DocumentRange documentRange;
19 |
20 | public FlagArgumentsHighlighting(DocumentRange documentRange)
21 | {
22 | this.documentRange = documentRange;
23 | }
24 |
25 | public DocumentRange CalculateRange() => documentRange;
26 | public string ToolTip => Warnings.FlagArgument;
27 | public string ErrorStripeToolTip => ToolTip;
28 | public bool IsValid() => true;
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/HollowNames/HollowNamesCheck.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using CleanCode.Resources;
5 | using CleanCode.Settings;
6 | using JetBrains.Application.Settings;
7 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
8 | using JetBrains.ReSharper.Feature.Services.Daemon;
9 | using JetBrains.ReSharper.Psi.CSharp.Tree;
10 | using JetBrains.ReSharper.Psi.Tree;
11 |
12 | namespace CleanCode.Features.HollowNames
13 | {
14 | [ElementProblemAnalyzer(typeof(IClassDeclaration),
15 | HighlightingTypes = new []
16 | {
17 | typeof(HollowTypeNameHighlighting)
18 | })]
19 | public class HollowNamesCheck : ElementProblemAnalyzer
20 | {
21 | protected override void Run(IClassDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
22 | {
23 | var suffixes = GetSuffixes(data.SettingsStore);
24 |
25 | var match = GetFirstMatchOrDefault(element.DeclaredName, suffixes);
26 | if (match != null)
27 | AddHighlighting(match, consumer, element);
28 | }
29 |
30 | private IEnumerable GetSuffixes(IContextBoundSettingsStore dataSettingsStore)
31 | {
32 | var suffixes = dataSettingsStore.GetValue((CleanCodeSettings s) => s.MeaninglessClassNameSuffixes);
33 | return suffixes.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
34 | }
35 |
36 | private static string GetFirstMatchOrDefault(string declaredName, IEnumerable suffixes)
37 | {
38 | return suffixes.FirstOrDefault(declaredName.EndsWith);
39 | }
40 |
41 | private void AddHighlighting(string bannedSuffix, IHighlightingConsumer consumer, IClassDeclaration typeExpression)
42 | {
43 | var identifier = typeExpression.NameIdentifier;
44 | var documentRange = identifier.GetDocumentRange();
45 | var highlighting = new HollowTypeNameHighlighting(string.Format(Warnings.HollowTypeName, bannedSuffix), documentRange);
46 | consumer.AddHighlighting(highlighting);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/HollowNames/HollowTypeNameHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.HollowNames;
3 | using JetBrains.DocumentModel;
4 | using JetBrains.ReSharper.Feature.Services.Daemon;
5 | using JetBrains.ReSharper.Psi.CSharp;
6 |
7 | [assembly: RegisterConfigurableSeverity(HollowTypeNameHighlighting.SeverityID, null,
8 | CleanCodeHighlightingGroupIds.CleanCode, "Hollow type name", "This type has a name that doesn't express its intent.",
9 | Severity.SUGGESTION)]
10 |
11 | namespace CleanCode.Features.HollowNames
12 | {
13 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
14 | public class HollowTypeNameHighlighting : IHighlighting
15 | {
16 | internal const string SeverityID = "HollowTypeName";
17 | private readonly DocumentRange documentRange;
18 |
19 | public HollowTypeNameHighlighting(string toolTip, DocumentRange documentRange)
20 | {
21 | ToolTip = toolTip;
22 | this.documentRange = documentRange;
23 | }
24 |
25 | public DocumentRange CalculateRange() => documentRange;
26 | public string ToolTip { get; }
27 | public string ErrorStripeToolTip => ToolTip;
28 | public bool IsValid() => true;
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/MethodNameNotMeaningful/MethodNameNotMeaningfulCheck.cs:
--------------------------------------------------------------------------------
1 | using CleanCode.Settings;
2 | using JetBrains.Application.Settings;
3 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
4 | using JetBrains.ReSharper.Feature.Services.Daemon;
5 | using JetBrains.ReSharper.Psi.CSharp.Tree;
6 | using JetBrains.ReSharper.Psi.Tree;
7 |
8 | namespace CleanCode.Features.MethodNameNotMeaningful
9 | {
10 | [ElementProblemAnalyzer(typeof(IMethodDeclaration), HighlightingTypes = new []
11 | {
12 | typeof(MethodNameNotMeaningfulHighlighting)
13 | })]
14 | public class MethodNameNotMeaningfulCheck : ElementProblemAnalyzer
15 | {
16 | protected override void Run(IMethodDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
17 | {
18 | if (element.NameIdentifier == null)
19 | return;
20 |
21 | var minimumMethodNameLength = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MinimumMeaningfulMethodNameLength);
22 |
23 | var name = element.NameIdentifier.GetText();
24 | var methodNameLength = name.Length;
25 | if (methodNameLength < minimumMethodNameLength)
26 | {
27 | var documentRange = element.GetNameDocumentRange();
28 | var highlighting = new MethodNameNotMeaningfulHighlighting(documentRange);
29 | consumer.AddHighlighting(highlighting);
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/MethodNameNotMeaningful/MethodNameNotMeaningfulHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.MethodNameNotMeaningful;
3 | using CleanCode.Resources;
4 | using JetBrains.DocumentModel;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp;
7 |
8 | [assembly: RegisterConfigurableSeverity(MethodNameNotMeaningfulHighlighting.SeverityID, null,
9 | CleanCodeHighlightingGroupIds.CleanCode, "Method name not meaningful",
10 | "This method name is too short to be meaningful.",
11 | Severity.WARNING)]
12 |
13 | namespace CleanCode.Features.MethodNameNotMeaningful
14 | {
15 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
16 | public class MethodNameNotMeaningfulHighlighting : IHighlighting
17 | {
18 | internal const string SeverityID = "MethodNameNotMeaningful";
19 | private readonly DocumentRange documentRange;
20 |
21 | public MethodNameNotMeaningfulHighlighting(DocumentRange documentRange)
22 | {
23 | this.documentRange = documentRange;
24 | }
25 |
26 | public DocumentRange CalculateRange() => documentRange;
27 | public string ToolTip => Warnings.MethodNameNotMeaningful;
28 | public string ErrorStripeToolTip => ToolTip;
29 | public bool IsValid() => true;
30 | }
31 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/MethodTooLong/MethodTooLongCheck.cs:
--------------------------------------------------------------------------------
1 | using CleanCode.Settings;
2 | using JetBrains.Application.Settings;
3 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
4 | using JetBrains.ReSharper.Feature.Services.Daemon;
5 | using JetBrains.ReSharper.Psi.CSharp.Tree;
6 | using JetBrains.ReSharper.Psi.Tree;
7 |
8 | namespace CleanCode.Features.MethodTooLong
9 | {
10 | [ElementProblemAnalyzer(typeof(IMethodDeclaration), HighlightingTypes = new []
11 | {
12 | typeof(MethodTooLongHighlighting)
13 | })]
14 | public class MethodTooLongCheck : ElementProblemAnalyzer
15 | {
16 | protected override void Run(IMethodDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
17 | {
18 | var maxStatements = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumMethodStatements);
19 | var maxDeclarations = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumDeclarationsInMethod);
20 |
21 | var statementCount = element.CountChildren();
22 | if (statementCount <= maxStatements)
23 | {
24 | // Only look in the method body for declarations, otherwise we see
25 | // parameters + type parameters. We can ignore arrow expressions, as
26 | // they must be a single expression and won't have declarations
27 | var declarationCount = element.Body?.CountChildren() ?? 0;
28 | if (declarationCount <= maxDeclarations)
29 | return;
30 | }
31 |
32 | var highlighting = new MethodTooLongHighlighting(element.GetNameDocumentRange());
33 | consumer.AddHighlighting(highlighting);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/MethodTooLong/MethodTooLongHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.MethodTooLong;
3 | using CleanCode.Resources;
4 | using JetBrains.DocumentModel;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp;
7 |
8 | [assembly: RegisterConfigurableSeverity(MethodTooLongHighlighting.SeverityID, null,
9 | CleanCodeHighlightingGroupIds.CleanCode, "Method too long", "The method is bigger than it should be.",
10 | Severity.SUGGESTION)]
11 |
12 | namespace CleanCode.Features.MethodTooLong
13 | {
14 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
15 | public class MethodTooLongHighlighting : IHighlighting
16 | {
17 | internal const string SeverityID = "MethodTooLong";
18 | private readonly DocumentRange documentRange;
19 |
20 | public MethodTooLongHighlighting(DocumentRange documentRange)
21 | {
22 | this.documentRange = documentRange;
23 | }
24 |
25 | public DocumentRange CalculateRange() => documentRange;
26 | public string ToolTip => Warnings.MethodTooLong;
27 | public string ErrorStripeToolTip => ToolTip;
28 | public bool IsValid() => true;
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/TooManyDependencies/TooManyDependenciesCheck.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using CleanCode.Settings;
3 | using JetBrains.Application.Settings;
4 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp.Tree;
7 | using JetBrains.ReSharper.Psi.Tree;
8 | using JetBrains.ReSharper.Psi.Util;
9 |
10 | namespace CleanCode.Features.TooManyDependencies
11 | {
12 | [ElementProblemAnalyzer(typeof(IConstructorDeclaration), HighlightingTypes = new []
13 | {
14 | typeof(TooManyDependenciesHighlighting)
15 | })]
16 | public class TooManyDependenciesCheck : ElementProblemAnalyzer
17 | {
18 | protected override void Run(IConstructorDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
19 | {
20 | var maxDependencies = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumConstructorDependencies);
21 |
22 | var dependencies = element.ParameterDeclarations.Select(
23 | declaration => declaration.DeclaredElement != null &&
24 | declaration.DeclaredElement.Type.IsInterfaceType());
25 |
26 | var dependenciesCount = dependencies.Count();
27 | if (dependenciesCount > maxDependencies)
28 | {
29 | var highlighting = new TooManyDependenciesHighlighting(element.GetNameDocumentRange());
30 | consumer.AddHighlighting(highlighting);
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/TooManyDependencies/TooManyDependenciesHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.TooManyDependencies;
3 | using CleanCode.Resources;
4 | using JetBrains.DocumentModel;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp;
7 |
8 | [assembly: RegisterConfigurableSeverity(TooManyDependenciesHighlighting.SeverityID, null,
9 | CleanCodeHighlightingGroupIds.CleanCode, "Too many dependencies", "Too many dependencies passed into constructor.",
10 | Severity.WARNING)]
11 |
12 | namespace CleanCode.Features.TooManyDependencies
13 | {
14 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
15 | public class TooManyDependenciesHighlighting : IHighlighting
16 | {
17 | internal const string SeverityID = "TooManyDependencies";
18 | private readonly DocumentRange documentRange;
19 |
20 | public TooManyDependenciesHighlighting(DocumentRange documentRange)
21 | {
22 | this.documentRange = documentRange;
23 | }
24 |
25 | public DocumentRange CalculateRange() => documentRange;
26 | public string ToolTip => Warnings.TooManyDependencies;
27 | public string ErrorStripeToolTip => ToolTip;
28 | public bool IsValid() => true;
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/TooManyMethodArguments/TooManyArgumentsHighlighting.cs:
--------------------------------------------------------------------------------
1 | using CleanCode;
2 | using CleanCode.Features.TooManyMethodArguments;
3 | using JetBrains.DocumentModel;
4 | using JetBrains.ReSharper.Feature.Services.Daemon;
5 | using JetBrains.ReSharper.Psi.CSharp;
6 |
7 | [assembly: RegisterConfigurableSeverity(TooManyArgumentsHighlighting.SeverityID, null,
8 | CleanCodeHighlightingGroupIds.CleanCode, "Too many arguments", "Too many arguments passed to a method.",
9 | Severity.WARNING)]
10 |
11 | namespace CleanCode.Features.TooManyMethodArguments
12 | {
13 | [ConfigurableSeverityHighlighting(SeverityID, CSharpLanguage.Name)]
14 | public class TooManyArgumentsHighlighting : IHighlighting
15 | {
16 | internal const string SeverityID = "TooManyArguments";
17 | private readonly DocumentRange documentRange;
18 |
19 | public TooManyArgumentsHighlighting(string toolTip, DocumentRange documentRange)
20 | {
21 | ToolTip = toolTip;
22 | this.documentRange = documentRange;
23 | }
24 |
25 | public DocumentRange CalculateRange() => documentRange;
26 | public string ToolTip { get; }
27 | public string ErrorStripeToolTip => ToolTip;
28 | public bool IsValid() => true;
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Features/TooManyMethodArguments/TooManyMethodArgumentsCheck.cs:
--------------------------------------------------------------------------------
1 | using CleanCode.Resources;
2 | using CleanCode.Settings;
3 | using JetBrains.Application.Settings;
4 | using JetBrains.ReSharper.Daemon.Stages.Dispatcher;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 | using JetBrains.ReSharper.Psi.CSharp.Tree;
7 | using JetBrains.ReSharper.Psi.Tree;
8 |
9 | namespace CleanCode.Features.TooManyMethodArguments
10 | {
11 | [ElementProblemAnalyzer(typeof(IMethodDeclaration), HighlightingTypes = new []
12 | {
13 | typeof(TooManyArgumentsHighlighting)
14 | })]
15 | public class TooManyMethodArgumentsCheck : ElementProblemAnalyzer
16 | {
17 | protected override void Run(IMethodDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
18 | {
19 | var maxParameters = data.SettingsStore.GetValue((CleanCodeSettings s) => s.MaximumMethodParameters);
20 | var parameterDeclarations = element.ParameterDeclarations;
21 |
22 | if (parameterDeclarations.Count > maxParameters)
23 | {
24 | var highlighting = new TooManyArgumentsHighlighting(Warnings.TooManyMethodArguments,
25 | element.GetNameDocumentRange());
26 | consumer.AddHighlighting(highlighting);
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/InvalidateOnSettingsChange.cs:
--------------------------------------------------------------------------------
1 | using CleanCode.Settings;
2 | using JetBrains.Application.Settings;
3 | using JetBrains.DataFlow;
4 | using JetBrains.ProjectModel;
5 | using JetBrains.ReSharper.Feature.Services.Daemon;
6 |
7 | namespace CleanCode
8 | {
9 | [SolutionComponent]
10 | public class InvalidateOnSettingsChange
11 | {
12 | public InvalidateOnSettingsChange(Lifetime lifetime, IDaemon daemon, ISettingsStore settingsStore)
13 | {
14 | var settingsKey = settingsStore.Schema.GetKey();
15 | settingsStore.AdviseChange(lifetime, settingsKey, daemon.Invalidate);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTitle("ReSharper Clean Code Plugin")]
5 | [assembly: AssemblyCompany("Hadi Hariri")]
6 | [assembly: AssemblyProduct("ReSharper Clean Code Plugin")]
7 | [assembly: AssemblyDescription("Automates some of the concepts in Uncle Bob's Clean Code book")]
8 | [assembly: AssemblyCopyright("Copyright ® 2016 Hadi Hariri and Contributors")]
9 | [assembly: AssemblyTrademark("")]
10 | [assembly: AssemblyCulture("")]
11 |
12 | [assembly: ComVisible(false)]
13 | [assembly: Guid("97927FF9-8C9C-4DC5-A309-29C23F41DA47")]
14 |
15 | [assembly: AssemblyVersion("5.1.0.0")]
16 | [assembly: AssemblyFileVersion("5.1.0.0")]
17 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Resources/Icons/Settings/CleanCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhariri/CleanCode/dccdf5b0c4c348485be3d3807efde1d5dc3c5872/CleanCode/src/CleanCode/Resources/Icons/Settings/CleanCode.png
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Resources/Icons/Settings/ThemedIcons.Settings.Generated.Xaml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3AQMCwQuopFIpgAAAAd0RVh0QXV0aG9yAKmuzEgAAAAMdEVYdERlc2NyaXB0aW9uABMJISMAAAAKdEVYdENvcHlyaWdodACsD8w6AAAADnRFWHRDcmVhdGlvbiB0aW1lADX3DwkAAAAJdEVYdFNvZnR3YXJlAF1w/zoAAAALdEVYdERpc2NsYWltZXIAt8C0jwAAAAh0RVh0V2FybmluZwDAG+aHAAAAB3RFWHRTb3VyY2UA9f+D6wAAAAh0RVh0Q29tbWVudAD2zJa/AAAABnRFWHRUaXRsZQCo7tInAAADI0lEQVQ4jW2TX2gbdQDHP3eXNG1imiWtJMvsOrBbaXWC1qldaZ3QVXwozKkI/unDZLPgg/TF5019UVBfZCiCTyIyBs7hoC3FEautXZcodI0sk6Wy1a5prrnLXS6/3OXufNjDKvP7/P1+nr4fSQjhsyOu5/JrYYn51QVul9ZRJIVk/EGG+gYZeWSIgKLsrCPtBCzfzHH2h69oFUEuXZvlYLqfrl17uLQyywuPjlJtmrzz0tsMHzx8P+D7qz8y/dMMDz/QzeXlDEWniJKQ8Zou5qZFf7SPZCpFuD3C4YFBJp5/7R5guZjj468/4aHQbuav/8yel9PEetoRrsAwDCzdQs2rKMtBepN9yBGFyVdOceSJYaSaVfPf+PQk+q0Kek2l790DdOzrQA7JVK0qallFLalsl7bZ/ruCO+Nz/KkXqQdtPn/vM5TnXj16+sZKAUcTRMcj7B3YSzKRItoSRQpJ2LZNuBFmvDlOXqyy6d1BW61iKy7pzt3Iv+WvkI6lWKutkehPEIvECEoBZEkGCRJKghPtJ1h0F9FkDb/TR22WaBESiytLyLIrUzE0/JhH3bXQHZ0ev4devxfd0jkmHWOuMke2nsW2bZCh4ldoaQ1Qr1nI/1Q20Ewd4QhMw6RULpHVshxyDjFoDFJWy0yXpxF1gWnX8GQX3/cxbAO70SCQiifRiiphEUHoAlVRUSsqmWiGbqubL9a/xDAMRFUg2aA4Cm1uG1pFo1UOEXjywOOcmz3PxsYW5D3C+9twAjYXty4SqofIVq+i6RoNq4HneVCC6q0qhY0CZ06dITDcP0Q03s5bz77J6W/fJxaIIMdkFqVFzIZJvVanYTeQXAm/6tNcajIwMoC4Ixg7Mnb3SPOrC0x8dJIOdmHWKmj7t3E7XWzPBo+74y0fKScRD8XZXN/kwtkL9wAA38x9x8KVBSJ+G7l8jj/VPEbAANdHMWUSwQ7C0TCOcJh6fYrJicn7Zcr88Q==
6 | C+dmztPiBlm7XUQ1VPaluygZWxT/ukk8kuDDqQ8YHRn9fxsBnKbD5WyG62s3yBZ+pyuWBs/nmceeZmz4KMFg8D86/wtO9pvksFBNEwAAAABJRU5ErkJggg==
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Resources/Icons/Settings/ThemedIcons.Settings.Generated.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | [assembly: global::System.Windows.Markup.XmlnsDefinitionAttribute("urn:shemas-jetbrains-com:ui-application-icons-settings", "CleanCode.Resources.Icons")]
12 | [assembly: global::JetBrains.UI.Icons.CompiledIcons.CompiledIconsPackAttribute(IconPackResourceIdentification="CleanCode;component/Resources/Icons/Settings/ThemedIcons.Settings.Generated.Xaml", IconNames=new string[] {
13 | "CleanCode"})]
14 |
15 | namespace CleanCode.Resources.Icons
16 | {
17 |
18 |
19 | ///
20 | ///
21 | /// Autogenerated identifier classes and identifier objects to Themed Icons registered with .
22 | /// Identifier classes should be used in attributes, XAML, or generic parameters. Where an value is expected, use the identifier object in the Id field of the identifier class.
23 | ///
24 | ///
25 | ///
26 | /// This code was compile-time generated to support Themed Icons in the JetBrains application.
27 | /// It has two primary goals: load the icons of this assembly to be registered with so that they were WPF-accessible and theme-sensitive; and emit early-bound accessors for referencing icons in codebehind in a compile-time-validated manner.
28 | ///
XAML
29 | /// For performance reasons, the icons are not individually exposed with application resources. There is a custom markup extension to bind an image source in markup.
30 | /// To use an icon from XAML, set an property to the markup extension, which takes an icon identifier class (nested in class) as a parameter.
31 | /// Example:
32 | /// <Image Source="{icons:ThemedIcon myres:SettingsThemedIcons+CleanCode}" />
33 | ///
Attributes
34 | /// Sometimes you have to reference an icon from a type attriute when you're defining objects in code. Typical examples are Options pages and Tool Windows.
35 | /// To avoid the use of string IDs which are not validated very well, we've emitted identifier classes to be used with typeof() expression, one per each icon. Use the attribute overload which takes a for an image, and choose your icon class from nested classes in the class.
36 | /// Example:
37 | /// [Item(Name="Sample", Icon=typeof(SettingsThemedIcons.CleanCode))]
38 | ///
CodeBehind
39 | /// In codebehind, we have two distinct tasks: (a) specify some icon in the APIs and (b) render icon images onscreen.
40 | /// On the APIs stage you should only manipulate icon identifier objects (of type , statically defined in in Id fields). Icon identifier classes (nested in ) should be turned into icon identifier objects as early as possible. Rendering is about getting an to assign to WPF, or to use with GDI+ / Windows Forms.
41 | /// You should turn an identifier object into a rendered image as late as possible. The identifier is static and lightweight and does not depend on the current theme, while the image is themed and has to be loaded or generated/rasterized. You need an instance to get the image out of an icon identifier object. Once you got the image, you should take care to change it with theme changes — either by using a live image property, or by listening to the theme change event. See and its extensions for the related facilities.
42 | /// Example:
43 | /// // Getting IconId identifier object to use with APIs
44 | ///IconId iconid = SettingsThemedIcons.CleanCode.Id;
45 | /// // Getting IconId out of an Icon Identifier Class type
46 | ///IconId iconid = CompiledIconClassAttribute.TryGetCompiledIconClassId(typeof(SettingsThemedIcons.CleanCode), OnError.Throw);
47 | /// // Getting image for screen rendering by IconId
48 | ///themediconmanager.Icons[icnoid]
49 | /// // Getting image for screen rendering by Icon Identifier Class
50 | ///themediconmanager.GetIcon<SettingsThemedIcons.CleanCode>()
51 | ///
Icons Origin
52 | /// This code was generated by a pre-compile build task from a set of input files which are XAML files adhering to a certain convention, as convenient for exporting them from the Illustrator workspace, plus separate PNG files with raster icons. In the projects, these files are designated with ThemedIconsXamlV3 and ThemedIconPng build actions and do not themselves get into the output assembly. All of such files are processed, vector images for different themes of the same icon are split and combined into the single list of icons in this assembly. This list is then written into the genearted XAML file (compiled into BAML within assembly), and serves as the source for this generated code.
53 | ///
54 | public sealed class SettingsThemedIcons
55 | {
56 |
57 | ///
58 | ///
59 | /// Autogenerated identifier class for the CleanCode Themed Icon.
60 | /// Identifier classes should be used in attributes, XAML, or generic parameters. Where an value is expected, use the identifier object in the field of the identifier class.
61 | ///
62 | ///
63 | ///
64 | /// For details on Themed Icons and their use, see Remarks on class.
65 | ///
66 | ///
67 | ///
68 | /// <Image Source="{icons:ThemedIcon myres:SettingsThemedIcons+CleanCode}" /> <!-- XAML -->
69 | ///
70 | ///
71 | /// [Item(Name="Sample", Icon=typeof(SettingsThemedIcons.CleanCode))] // C# Type attribute
72 | ///
73 | ///
74 | /// IconId iconid = SettingsThemedIcons.CleanCode.Id; // IconId identifier object
75 | ///
76 | ///
77 | /// themediconmanager.GetIcon<SettingsThemedIcons.CleanCode>() // Icon image for rendering
78 | ///
79 | [global::JetBrains.UI.Icons.CompiledIcons.CompiledIconClassAttribute("CleanCode;component/Resources/Icons/Settings/ThemedIcons.Settings.Generated.Xaml", 0, "CleanCode")]
80 | public sealed class CleanCode : global::JetBrains.UI.Icons.CompiledIcons.CompiledIconClass
81 | {
82 |
83 | ///
84 | ///
85 | /// Autogenerated identifier object for the CleanCode Themed Icon.
86 | /// Identifier objects should be used where an value is expected. In attributes, XAML, or generic parameters use the containing identifier class.
87 | ///
88 | ///
89 | ///
90 | /// For details on Themed Icons and their use, see Remarks on class.
91 | ///
92 | ///
93 | ///
94 | /// <Image Source="{icons:ThemedIcon myres:SettingsThemedIcons+CleanCode}" /> <!-- XAML -->
95 | ///
96 | ///
97 | /// [Item(Name="Sample", Icon=typeof(SettingsThemedIcons.CleanCode))] // C# Type attribute
98 | ///
99 | ///
100 | /// IconId iconid = SettingsThemedIcons.CleanCode.Id; // IconId identifier object
101 | ///
102 | ///
103 | /// themediconmanager.GetIcon<SettingsThemedIcons.CleanCode>() // Icon image for rendering
104 | ///
105 | public static global::JetBrains.UI.Icons.IconId Id = new global::JetBrains.UI.Icons.CompiledIcons.CompiledIconId("CleanCode;component/Resources/Icons/Settings/ThemedIcons.Settings.Generated.Xaml", 0, "CleanCode");
106 | }
107 | }
108 | }
109 |
110 |
111 | public sealed class RenderedIcons_ByPackResourceNameHash_E1185BB5DC155E8A999AD43CA329D4ED
112 | {
113 |
114 | public static byte[] CleanCode____png__x1 = new byte[] {
115 | 137,
116 | 80,
117 | 78,
118 | 71,
119 | 13,
120 | 10,
121 | 26,
122 | 10,
123 | 0,
124 | 0,
125 | 0,
126 | 13,
127 | 73,
128 | 72,
129 | 68,
130 | 82,
131 | 0,
132 | 0,
133 | 0,
134 | 16,
135 | 0,
136 | 0,
137 | 0,
138 | 16,
139 | 8,
140 | 6,
141 | 0,
142 | 0,
143 | 0,
144 | 31,
145 | 243,
146 | 255,
147 | 97,
148 | 0,
149 | 0,
150 | 0,
151 | 1,
152 | 115,
153 | 82,
154 | 71,
155 | 66,
156 | 0,
157 | 174,
158 | 206,
159 | 28,
160 | 233,
161 | 0,
162 | 0,
163 | 0,
164 | 4,
165 | 103,
166 | 65,
167 | 77,
168 | 65,
169 | 0,
170 | 0,
171 | 177,
172 | 143,
173 | 11,
174 | 252,
175 | 97,
176 | 5,
177 | 0,
178 | 0,
179 | 0,
180 | 9,
181 | 112,
182 | 72,
183 | 89,
184 | 115,
185 | 0,
186 | 0,
187 | 14,
188 | 195,
189 | 0,
190 | 0,
191 | 14,
192 | 195,
193 | 1,
194 | 199,
195 | 111,
196 | 168,
197 | 100,
198 | 0,
199 | 0,
200 | 0,
201 | 19,
202 | 73,
203 | 68,
204 | 65,
205 | 84,
206 | 56,
207 | 79,
208 | 99,
209 | 24,
210 | 5,
211 | 163,
212 | 96,
213 | 20,
214 | 140,
215 | 2,
216 | 48,
217 | 96,
218 | 96,
219 | 0,
220 | 0,
221 | 4,
222 | 16,
223 | 0,
224 | 1,
225 | 167,
226 | 68,
227 | 124,
228 | 99,
229 | 0,
230 | 0,
231 | 0,
232 | 0,
233 | 73,
234 | 69,
235 | 78,
236 | 68,
237 | 174,
238 | 66,
239 | 96,
240 | 130};
241 |
242 | public static byte[] CleanCode____png__x2 = new byte[] {
243 | 137,
244 | 80,
245 | 78,
246 | 71,
247 | 13,
248 | 10,
249 | 26,
250 | 10,
251 | 0,
252 | 0,
253 | 0,
254 | 13,
255 | 73,
256 | 72,
257 | 68,
258 | 82,
259 | 0,
260 | 0,
261 | 0,
262 | 32,
263 | 0,
264 | 0,
265 | 0,
266 | 32,
267 | 8,
268 | 6,
269 | 0,
270 | 0,
271 | 0,
272 | 115,
273 | 122,
274 | 122,
275 | 244,
276 | 0,
277 | 0,
278 | 0,
279 | 1,
280 | 115,
281 | 82,
282 | 71,
283 | 66,
284 | 0,
285 | 174,
286 | 206,
287 | 28,
288 | 233,
289 | 0,
290 | 0,
291 | 0,
292 | 4,
293 | 103,
294 | 65,
295 | 77,
296 | 65,
297 | 0,
298 | 0,
299 | 177,
300 | 143,
301 | 11,
302 | 252,
303 | 97,
304 | 5,
305 | 0,
306 | 0,
307 | 0,
308 | 9,
309 | 112,
310 | 72,
311 | 89,
312 | 115,
313 | 0,
314 | 0,
315 | 14,
316 | 195,
317 | 0,
318 | 0,
319 | 14,
320 | 195,
321 | 1,
322 | 199,
323 | 111,
324 | 168,
325 | 100,
326 | 0,
327 | 0,
328 | 0,
329 | 26,
330 | 73,
331 | 68,
332 | 65,
333 | 84,
334 | 88,
335 | 71,
336 | 237,
337 | 193,
338 | 1,
339 | 1,
340 | 0,
341 | 0,
342 | 0,
343 | 130,
344 | 32,
345 | 255,
346 | 175,
347 | 110,
348 | 72,
349 | 64,
350 | 0,
351 | 0,
352 | 0,
353 | 192,
354 | 185,
355 | 26,
356 | 16,
357 | 32,
358 | 0,
359 | 1,
360 | 157,
361 | 120,
362 | 73,
363 | 67,
364 | 0,
365 | 0,
366 | 0,
367 | 0,
368 | 73,
369 | 69,
370 | 78,
371 | 68,
372 | 174,
373 | 66,
374 | 96,
375 | 130};
376 | }
377 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Resources/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CleanCode.Resources {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public class Settings {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Settings() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CleanCode.Resources.Settings", typeof(Settings).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Maximum declarations per method.
65 | ///
66 | public static string DeclarationsMaximum {
67 | get {
68 | return ResourceManager.GetString("DeclarationsMaximum", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to Maximum chained references.
74 | ///
75 | public static string MaximumChainedReferences {
76 | get {
77 | return ResourceManager.GetString("MaximumChainedReferences", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to Maximum interface dependencies for a constructor.
83 | ///
84 | public static string MaximumConstructorDependencies {
85 | get {
86 | return ResourceManager.GetString("MaximumConstructorDependencies", resourceCulture);
87 | }
88 | }
89 |
90 | ///
91 | /// Looks up a localized string similar to Maximum expressions inside a condition.
92 | ///
93 | public static string MaximumExpressionsInsideACondition {
94 | get {
95 | return ResourceManager.GetString("MaximumExpressionsInsideACondition", resourceCulture);
96 | }
97 | }
98 |
99 | ///
100 | /// Looks up a localized string similar to Maximum level of nesting in a method.
101 | ///
102 | public static string MaximumLevelOfNestingInAMethod {
103 | get {
104 | return ResourceManager.GetString("MaximumLevelOfNestingInAMethod", resourceCulture);
105 | }
106 | }
107 |
108 | ///
109 | /// Looks up a localized string similar to Maximum method declaration parameters.
110 | ///
111 | public static string MaximumMethodDeclarationParameters {
112 | get {
113 | return ResourceManager.GetString("MaximumMethodDeclarationParameters", resourceCulture);
114 | }
115 | }
116 |
117 | ///
118 | /// Looks up a localized string similar to Maximum methods per class.
119 | ///
120 | public static string MaximumMethodsPerClass {
121 | get {
122 | return ResourceManager.GetString("MaximumMethodsPerClass", resourceCulture);
123 | }
124 | }
125 |
126 | ///
127 | /// Looks up a localized string similar to Maximum statements per method.
128 | ///
129 | public static string MaximumStatementsPerMethod {
130 | get {
131 | return ResourceManager.GetString("MaximumStatementsPerMethod", resourceCulture);
132 | }
133 | }
134 |
135 | ///
136 | /// Looks up a localized string similar to List of meaningless suffixes.
137 | ///
138 | public static string MeaninglessNameSuffixes {
139 | get {
140 | return ResourceManager.GetString("MeaninglessNameSuffixes", resourceCulture);
141 | }
142 | }
143 |
144 | ///
145 | /// Looks up a localized string similar to Separate items with commas.
146 | ///
147 | public static string MeaninglessNameSuffixesTooltip {
148 | get {
149 | return ResourceManager.GetString("MeaninglessNameSuffixesTooltip", resourceCulture);
150 | }
151 | }
152 |
153 | ///
154 | /// Looks up a localized string similar to Minimum method name length.
155 | ///
156 | public static string MinimumMethodNameLength {
157 | get {
158 | return ResourceManager.GetString("MinimumMethodNameLength", resourceCulture);
159 | }
160 | }
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Resources/Settings.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Maximum statements per method
122 |
123 |
124 | Maximum interface dependencies for a constructor
125 |
126 |
127 | Maximum method declaration parameters
128 |
129 |
130 | Maximum level of nesting in a method
131 |
132 |
133 | Maximum methods per class
134 |
135 |
136 | Maximum chained references
137 |
138 |
139 | Minimum method name length
140 |
141 |
142 | Maximum expressions inside a condition
143 |
144 |
145 | List of meaningless suffixes
146 |
147 |
148 | Separate items with commas
149 |
150 |
151 | Maximum declarations per method
152 |
153 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Resources/Warnings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace CleanCode.Resources {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public class Warnings {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Warnings() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CleanCode.Resources.Warnings", typeof(Warnings).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Too many chained references. This might be violating the Law of Demeter..
65 | ///
66 | public static string ChainedReferences {
67 | get {
68 | return ResourceManager.GetString("ChainedReferences", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to Class contains too many methods. This might be violating the Single Responsibility Principle..
74 | ///
75 | public static string ClassTooBig {
76 | get {
77 | return ResourceManager.GetString("ClassTooBig", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to Excessive depth of nested code blocks..
83 | ///
84 | public static string ExcessiveDepth {
85 | get {
86 | return ResourceManager.GetString("ExcessiveDepth", resourceCulture);
87 | }
88 | }
89 |
90 | ///
91 | /// Looks up a localized string similar to This expression is too complex..
92 | ///
93 | public static string ExpressionTooComplex {
94 | get {
95 | return ResourceManager.GetString("ExpressionTooComplex", resourceCulture);
96 | }
97 | }
98 |
99 | ///
100 | /// Looks up a localized string similar to This argument is used as a flag in the method. This might be violating the Single Responsibility Principle..
101 | ///
102 | public static string FlagArgument {
103 | get {
104 | return ResourceManager.GetString("FlagArgument", resourceCulture);
105 | }
106 | }
107 |
108 | ///
109 | /// Looks up a localized string similar to The usage of the suffix '{0}' is discouraged because it's too generic. Choose a meaningful name instead to clarify its intent and responsibilities..
110 | ///
111 | public static string HollowTypeName {
112 | get {
113 | return ResourceManager.GetString("HollowTypeName", resourceCulture);
114 | }
115 | }
116 |
117 | ///
118 | /// Looks up a localized string similar to The name of this method is too short to be meaningful..
119 | ///
120 | public static string MethodNameNotMeaningful {
121 | get {
122 | return ResourceManager.GetString("MethodNameNotMeaningful", resourceCulture);
123 | }
124 | }
125 |
126 | ///
127 | /// Looks up a localized string similar to This method is too long, indicating that it has too much responsibility..
128 | ///
129 | public static string MethodTooLong {
130 | get {
131 | return ResourceManager.GetString("MethodTooLong", resourceCulture);
132 | }
133 | }
134 |
135 | ///
136 | /// Looks up a localized string similar to There are too many interfaces being passed in to this constructor. It might be violating the Single Responsibility Principle..
137 | ///
138 | public static string TooManyDependencies {
139 | get {
140 | return ResourceManager.GetString("TooManyDependencies", resourceCulture);
141 | }
142 | }
143 |
144 | ///
145 | /// Looks up a localized string similar to This method requires too many arguments..
146 | ///
147 | public static string TooManyMethodArguments {
148 | get {
149 | return ResourceManager.GetString("TooManyMethodArguments", resourceCulture);
150 | }
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Resources/Warnings.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | There are too many interfaces being passed in to this constructor. It might be violating the Single Responsibility Principle.
122 |
123 |
124 | This method requires too many arguments.
125 |
126 |
127 | This method is too long, indicating that it has too much responsibility.
128 |
129 |
130 | Excessive depth of nested code blocks.
131 |
132 |
133 | Class contains too many methods. This might be violating the Single Responsibility Principle.
134 |
135 |
136 | Too many chained references. This might be violating the Law of Demeter.
137 |
138 |
139 | The name of this method is too short to be meaningful.
140 |
141 |
142 | This argument is used as a flag in the method. This might be violating the Single Responsibility Principle.
143 |
144 |
145 | This expression is too complex.
146 |
147 |
148 | The usage of the suffix '{0}' is discouraged because it's too generic. Choose a meaningful name instead to clarify its intent and responsibilities.
149 |
150 |
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Settings/CleanCodeOptionsPage.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using CleanCode.Resources.Icons;
3 | using JetBrains.DataFlow;
4 | using JetBrains.ReSharper.Feature.Services.Daemon.OptionPages;
5 | using JetBrains.UI.Options;
6 | using JetBrains.UI.Options.OptionsDialog2.SimpleOptions;
7 | using JetBrains.UI.RichText;
8 |
9 | namespace CleanCode.Settings
10 | {
11 | [OptionsPage(PageId, "Clean Code", typeof(SettingsThemedIcons.CleanCode), ParentId = CodeInspectionPage.PID)]
12 | public class CleanCodeOptionsPage : CustomSimpleOptionsPage
13 | {
14 | private const string PageId = "CleanCode";
15 |
16 | public CleanCodeOptionsPage(Lifetime lifetime, OptionsSettingsSmartContext optionsSettingsSmartContext)
17 | : base(lifetime, optionsSettingsSmartContext)
18 | {
19 | AddHeader("Single Responsibility");
20 | AddText("A class should only have a single responsibility. Do not do too much in a class or method.");
21 | AddIntOption((CleanCodeSettings s) => s.MaximumMethodsInClass,
22 | Resources.Settings.MaximumMethodsPerClass,
23 | "Too many method declarations in a class is an indicator that the class is doing too much.");
24 | AddIntOption((CleanCodeSettings s) => s.MaximumMethodParameters,
25 | Resources.Settings.MaximumMethodDeclarationParameters,
26 | "Too many parameters in a method declaration is an indicator of having more than one responsibility");
27 | AddIntOption((CleanCodeSettings s) => s.MaximumMethodStatements, Resources.Settings.MaximumStatementsPerMethod,
28 | "Long methods are indicator of having more than one responsibility.");
29 | AddIntOption((CleanCodeSettings s) => s.MaximumDeclarationsInMethod,
30 | Resources.Settings.DeclarationsMaximum,
31 | "Too many variables are an indicator of having more than one responsibility.");
32 | AddIntOption((CleanCodeSettings s) => s.MaximumIndentationDepth,
33 | Resources.Settings.MaximumLevelOfNestingInAMethod,
34 | "Too much nesting in a method is an indicator of having more than one responsibility.");
35 |
36 | AddHeader("Coupling");
37 | AddText("Avoid excessive coupling beween classes.");
38 | AddIntOption((CleanCodeSettings s) => s.MaximumConstructorDependencies,
39 | Resources.Settings.MaximumConstructorDependencies);
40 | AddIntOption((CleanCodeSettings s) => s.MaximumChainedReferences,
41 | Resources.Settings.MaximumChainedReferences,
42 | "Avoid breaking the Law of Demeter.");
43 |
44 | AddHeader("Legibility");
45 | AddText("Names should be meaningful.");
46 | AddIntOption((CleanCodeSettings s) => s.MinimumMeaningfulMethodNameLength,
47 | Resources.Settings.MinimumMethodNameLength);
48 | AddStringOption((CleanCodeSettings s) => s.MeaninglessClassNameSuffixes,
49 | Resources.Settings.MeaninglessNameSuffixes,
50 | Resources.Settings.MeaninglessNameSuffixesTooltip);
51 |
52 | AddHeader("Complexity");
53 | AddText("Reduce complexity in individual statements.");
54 | AddIntOption((CleanCodeSettings s) => s.MaximumExpressionsInCondition,
55 | Resources.Settings.MaximumExpressionsInsideACondition);
56 |
57 | AddRichText(
58 | new RichText(
59 | "Note: All references to Clean Code, including but not limited to the Clean Code icon are used with permission of Robert C. Martin (a.k.a. UncleBob)",
60 | new TextStyle(FontStyle.Italic)));
61 | FinishPage();
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/Settings/CleanCodeSettings.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Application.Settings;
2 | using JetBrains.ReSharper.Resources.Settings;
3 |
4 | namespace CleanCode.Settings
5 | {
6 | [SettingsKey(typeof(CodeInspectionSettings), "CleanCode")]
7 | public class CleanCodeSettings
8 | {
9 | [SettingsEntry(3, "MaximumConstructorDependencies")]
10 | public readonly int MaximumConstructorDependencies;
11 |
12 | [SettingsEntry(3, "MaximumMethodParameters")]
13 | public readonly int MaximumMethodParameters;
14 |
15 | [SettingsEntry(15, "MaximumMethodStatements")]
16 | public readonly int MaximumMethodStatements;
17 |
18 | [SettingsEntry(6, "MaximumDeclarationsInMethod")]
19 | public readonly int MaximumDeclarationsInMethod;
20 |
21 | [SettingsEntry(3, "MaximumIndentationDepth")]
22 | public int MaximumIndentationDepth { get; set; }
23 |
24 | [SettingsEntry(20, "MaximumMethodsInClass")]
25 | public int MaximumMethodsInClass { get; set; }
26 |
27 | [SettingsEntry(2, "MaximumChainedReferences")]
28 | public int MaximumChainedReferences { get; set; }
29 |
30 | [SettingsEntry(4, "MinimumMeaningfulMethodNameLength")]
31 | public int MinimumMeaningfulMethodNameLength { get; set; }
32 |
33 | [SettingsEntry("Handler,Manager,Processor,Controller,Helper", "MeaninglessClassNameSuffixes")]
34 | public string MeaninglessClassNameSuffixes { get; set; }
35 |
36 | [SettingsEntry(1, "MaximumExpressionsInCondition")]
37 | public int MaximumExpressionsInCondition { get; set; }
38 | }
39 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/ZoneMarker.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Application.BuildScript.Application.Zones;
2 |
3 | namespace CleanCode
4 | {
5 | [ZoneMarker]
6 | public class ZoneMarker
7 | {
8 | }
9 | }
--------------------------------------------------------------------------------
/CleanCode/src/CleanCode/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Clean Code ReSharper Plugin Project
2 |
3 | ### CleanCode
4 |
5 | An experiment in trying to automate some of concepts described in [Uncle Bob's books on Clean Code](http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882).
6 |
7 | This is a ReSharper extension to analyse your C# code to highlight a symptom that your code is becoming too complex, is not "clean" enough. Increased complexity can make your code harder to read, understand and maintain. The plugin currently checks:
8 |
9 | * **Too many dependencies** - warns when a constructor has too many interfaces passed in.
10 | * **Excessive indentation** - warns if a class contains members with too much indentation.
11 | * **Too many chained references** - warns if an expression has too many chained statements, is potentially violating the [Law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter). The check will try to ignore fluent APIs - if the type returned is the same as the type invoked, it doesn't count.
12 | * **Method too long** - warns when a method contains too many statements.
13 | * **Class too big** - warns if a class has too many method declarations.
14 | * **Too many method parameters** - warns if a method has too many parameters.
15 | * **Method name not meaningful** - simple check that a method name is longer than a certain threshold.
16 | * **Method flag parameters** - warns if a boolean or enum method parameter is used in an `if` statement with the method. This is an indication that the method has more than one responsibility.
17 | * **Condition complexity** - warns if the condition in an `if` statement contains too many expressions.
18 | * **Hollow type names** - warns if a class has a name with a suffix that is too general, e.g. `Handler`, `Manager`, `Controller`. The list of names is configurable.
19 |
20 | The limits used by each analysis are configurable in the options page.
21 |
22 | ### Upcoming features
23 |
24 | Please log feature requests and bugs in [Issues](https://github.com/hhariri/CleanCode/issues). Note that this version only supports C#.
25 |
26 | ## Installing
27 |
28 | Install from ReSharper → Extension Manager.
29 |
30 | ## License
31 |
32 | Licensed under MIT (c) 2012 - 2016 Hadi Hariri and Contributors
33 |
34 | Note: All references to [Clean Code](http://www.cleancoders.com/), including but not limited to the Clean Code icon are used with permission of Robert C. Martin (a.k.a. UncleBob)
35 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Hadi Hariri and Contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhariri/CleanCode/dccdf5b0c4c348485be3d3807efde1d5dc3c5872/logo.png
--------------------------------------------------------------------------------