Ewl » Canonical The canonical version of EWL Read More
Clone URL:  

Updated NDepend project.

Changeset a6f669ab1163

Parent 2704ba6c1648

by Profile picture of William GrossWilliam Gross

Changes to one file · Browse files at a6f669ab1163 Showing diff from parent 2704ba6c1648 Diff from another changeset...

 
1
2
3
 
4
5
6
 
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
60
61
62
63
 
 
 
64
65
66
 
114
115
116
117
 
 
118
119
120
 
127
128
129
130
131
 
 
 
132
133
134
 
519
520
521
522
 
523
524
525
 
550
551
552
553
554
 
 
 
 
555
556
557
 
608
609
610
611
 
612
613
614
615
 
616
617
618
 
645
646
647
648
 
649
650
651
 
904
905
906
907
 
908
909
910
 
911
912
913
 
941
942
943
 
 
 
 
944
945
946
 
1075
1076
1077
1078
 
1079
1080
1081
 
1453
1454
1455
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1456
1457
1458
 
1675
1676
1677
1678
 
1679
1680
1681
 
1893
1894
1895
1896
 
1897
1898
1899
 
1924
1925
1926
1927
 
1928
1929
1930
 
1969
1970
1971
1972
 
1973
1974
1975
 
1977
1978
1979
1980
 
 
1981
1982
1983
 
2053
2054
2055
2056
2057
 
 
 
 
 
 
 
 
 
 
2058
2059
2060
 
2071
2072
2073
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2074
2075
2076
2077
2078
2079
2080
2081
2082
 
 
 
 
 
 
 
2083
2084
2085
2086
 
 
 
 
2087
2088
 
 
 
 
 
2089
2090
2091
 
2096
2097
2098
2099
2100
2101
 
 
 
 
 
 
 
 
 
 
 
2102
2103
 
 
 
2104
2105
2106
 
2108
2109
2110
2111
2112
2113
 
2114
2115
2116
 
2182
2183
2184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2185
2186
2187
 
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2310
2311
2312
 
2398
2399
2400
2401
 
2402
2403
2404
 
2419
2420
2421
2422
 
2423
2424
2425
 
 
 
2426
2427
2428
2429
 
2430
2431
2432
 
2519
2520
2521
2522
 
2523
2524
2525
 
2549
2550
2551
2552
 
2553
2554
2555
2556
2557
2558
2559
 
 
2560
2561
2562
 
2584
2585
2586
2587
 
2588
2589
 
2590
2591
2592
 
2633
2634
2635
2636
 
 
 
2637
2638
2639
 
2757
2758
2759
2760
 
2761
2762
2763
 
3200
3201
3202
3203
 
 
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
 
 
 
 
 
3216
3217
3218
 
 
 
3219
3220
3221
3222
3223
3224
3225
3226
3227
 
 
 
 
3228
3229
3230
3231
 
 
3232
3233
3234
 
3283
3284
3285
3286
 
3287
3288
3289
 
3305
3306
3307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3308
3309
3310
 
3311
3312
3313
 
3317
3318
3319
3320
 
3321
3322
3323
 
3327
3328
3329
3330
 
3331
3332
3333
 
3334
3335
3336
 
3337
3338
3339
 
3340
3341
3342
 
3343
3344
3345
 
3346
3347
3348
 
3349
3350
3351
3352
3353
3354
3355
 
3356
3357
3358
3359
3360
3361
3362
 
3363
3364
3365
3366
3367
3368
3369
 
3370
3371
3372
 
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
 
 
1
2
 
3
4
5
6
 
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
60
61
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
 
144
145
146
 
147
148
149
150
151
 
158
159
160
 
 
161
162
163
164
165
166
 
551
552
553
 
554
555
556
557
 
582
583
584
 
 
585
586
587
588
589
590
591
 
642
643
644
 
645
646
647
648
 
649
650
651
652
 
679
680
681
 
682
683
684
685
 
938
939
940
 
941
942
943
 
944
945
946
947
 
975
976
977
978
979
980
981
982
983
984
 
1113
1114
1115
 
1116
1117
1118
1119
 
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
 
1731
1732
1733
 
1734
1735
1736
1737
 
1949
1950
1951
 
1952
1953
1954
1955
 
1980
1981
1982
 
1983
1984
1985
1986
 
2025
2026
2027
 
2028
2029
2030
2031
 
2033
2034
2035
 
2036
2037
2038
2039
2040
 
2110
2111
2112
 
 
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
 
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
 
 
 
 
 
 
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
 
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
 
2191
2192
2193
 
 
 
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
 
2214
2215
2216
 
 
 
2217
2218
2219
2220
 
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
 
2402
2403
2404
 
 
 
 
 
 
 
 
 
 
 
 
 
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
 
 
 
 
 
 
 
 
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
 
2600
2601
2602
 
2603
2604
2605
2606
 
2621
2622
2623
 
2624
2625
2626
 
2627
2628
2629
2630
2631
2632
 
2633
2634
2635
2636
 
2723
2724
2725
 
2726
2727
2728
2729
 
2753
2754
2755
 
2756
2757
2758
2759
2760
2761
2762
 
2763
2764
2765
2766
2767
 
2789
2790
2791
 
2792
2793
 
2794
2795
2796
2797
 
2838
2839
2840
 
2841
2842
2843
2844
2845
2846
 
2964
2965
2966
 
2967
2968
2969
2970
 
3407
3408
3409
 
3410
3411
3412
3413
 
 
 
 
 
 
 
 
 
 
3414
3415
3416
3417
3418
3419
 
 
3420
3421
3422
3423
3424
 
 
 
 
 
 
 
3425
3426
3427
3428
3429
3430
 
 
3431
3432
3433
3434
3435
 
3484
3485
3486
 
3487
3488
3489
3490
 
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
 
3859
3860
3861
3862
 
3866
3867
3868
 
3869
3870
3871
3872
 
3876
3877
3878
 
3879
3880
3881
 
3882
3883
3884
 
3885
3886
3887
 
3888
3889
3890
 
3891
3892
3893
 
3894
3895
3896
 
3897
3898
3899
3900
3901
3902
3903
 
3904
3905
3906
3907
3908
3909
3910
 
3911
3912
3913
3914
3915
3916
3917
 
3918
3919
3920
3921
 
4081
4082
4083
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4084
 
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <NDepend AppName="Enterprise Web Library" Platform="DotNet"> - <OutputDir KeepHistoric="False" KeepXmlFiles="True">.\NDependOut</OutputDir> + <OutputDir KeepXmlFiles="False">.\NDependOut</OutputDir>   <Assemblies>   <Name>EnterpriseWebLibrary</Name>   <Name>EnterpriseWebLibrary.DevelopmentUtility</Name> @@ -8,59 +8,89 @@
  <FrameworkAssemblies>   <Name>mscorlib</Name>   <Name>System.Web</Name> + <Name>System.Runtime.Serialization</Name>   <Name>Aspose.Words</Name> - <Name>System.Runtime.Serialization</Name>   <Name>System.ServiceProcess</Name> + <Name>System.Runtime.Caching</Name>   <Name>System.Data</Name> - <Name>ThoughtWorks.Selenium.Core</Name>   <Name>System</Name>   <Name>MiniProfiler</Name> + <Name>System.Drawing</Name> + <Name>System.Core</Name>   <Name>System.ServiceModel</Name> + <Name>System.Numerics</Name> + <Name>Aspose.Cells</Name>   <Name>System.Xml</Name> - <Name>System.Drawing</Name> - <Name>Aspose.Cells</Name>   <Name>ICSharpCode.SharpZipLib</Name> - <Name>System.Numerics</Name> - <Name>System.Core</Name> + <Name>ThoughtWorks.Selenium.Core</Name> + <Name>Aspose.Pdf</Name> + <Name>System.Web.Extensions</Name> + <Name>Stripe</Name> + <Name>Microsoft.CSharp</Name> + <Name>JetBrains.Annotations</Name>   <Name>nunit.framework</Name> - <Name>JetBrains.Annotations</Name> - <Name>Aspose.Pdf</Name> - <Name>Microsoft.Web.Administration</Name> - <Name>AjaxControlToolkit</Name> - <Name>System.Web.Extensions</Name> + <Name>NDepend.API</Name>   <Name>EnterpriseWebLibrary.Library</Name> - <Name>NDepend.API</Name>   </FrameworkAssemblies>   <Dirs>   <Dir>C:\Windows\Microsoft.NET\Framework\v4.0.30319</Dir>   <Dir>C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF</Dir>   <Dir>.\Standard Library\bin\Debug</Dir>   <Dir>.\Development Utility\bin\Debug</Dir> - <Dir>..\..\..\..\..\..\Windows\System32\inetsrv</Dir>   <Dir>.\Solution Files\Referenced Files</Dir>   </Dirs> - <Report Kind="0" SectionsEnabled="12287" XslPath="" Flags="64512"> - <Section Enabled="True">Application Metrics</Section> - <Section Enabled="True">.NET Assemblies Metrics</Section> - <Section Enabled="True">Treemap Metric View</Section> - <Section Enabled="True">.NET Assemblies Abstractness vs. Instability</Section> - <Section Enabled="True">.NET Assemblies Dependencies</Section> - <Section Enabled="True">.NET Assemblies Dependency Graph</Section> - <Section Enabled="True">.NET Assemblies Build Order</Section> - <Section Enabled="True">Analysis Log</Section> - <Section Enabled="True">CQL Rules Violated</Section> - <Section Enabled="True">Types Metrics</Section> - <Section Enabled="False">Types Dependencies</Section> - </Report> - <BuildComparisonSetting ProjectMode="DontCompare" BuildMode="MostRecentAnalysisResultAvailable" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="1" /> - <BaselineInUISetting ProjectMode="DontCompare" BuildMode="MostRecentAnalysisResultAvailable" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="1" /> + <Report Kind="0" SectionsEnabled="45055" XslPath="" Flags="64512" /> + <BuildComparisonSetting ProjectMode="DontCompare" BuildMode="MostRecentAnalysisResultAvailable" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="1" FocusOnRecentRulesViolations="False" /> + <BaselineInUISetting ProjectMode="DontCompare" BuildMode="MostRecentAnalysisResultAvailable" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="1" FocusOnRecentRulesViolations="False" />   <CoverageFiles UncoverableAttribute="" /> - <SourceFileRebasing FromPath="" ToPath="" /><Queries> + <TrendMetrics UseCustomLog="False" LogRecurrence="3" LogLabel="2" UseCustomDir="False" CustomDir=""> + <Chart Name="Lines of Code" ShowInReport="True"> + <Serie MetricName="# Lines of Code" MetricUnit="Loc" Color="#FF00BFFF" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="# Lines of Code Covered" MetricUnit="Loc" Color="#FF32CD32" ChartType="Area" ScaleExp="0" /> + <Serie MetricName="# Lines of Code (NotMyCode)" MetricUnit="Loc" Color="#FFA9A9A9" ChartType="Area" ScaleExp="0" /> + <Serie MetricName="# Lines of Comments" MetricUnit="Lines" Color="#FF008000" ChartType="Line" ScaleExp="0" /> + </Chart> + <Chart Name="Rules Violated" ShowInReport="True"> + <Serie MetricName="# Rules" MetricUnit="Rules" Color="#FF66CDAA" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="# Rules Violated" MetricUnit="Rules" Color="#FFFF8C00" ChartType="Area" ScaleExp="0" /> + <Serie MetricName="# Critical Rules Violated" MetricUnit="Rules" Color="#FFFF0000" ChartType="Area" ScaleExp="0" /> + </Chart> + <Chart Name="Rules Violations" ShowInReport="True"> + <Serie MetricName="# Rules Violations" MetricUnit="Violations" Color="#FFFF8C00" ChartType="Area" ScaleExp="0" /> + <Serie MetricName="# Critical Rules Violations" MetricUnit="Violations" Color="#FFFF0000" ChartType="Area" ScaleExp="0" /> + </Chart> + <Chart Name="Percentage Coverage by Tests" ShowInReport="True"> + <Serie MetricName="Percentage Code Coverage" MetricUnit="%" Color="#FF32CD32" ChartType="Area" ScaleExp="0" /> + </Chart> + <Chart Name="Max" ShowInReport="True"> + <Serie MetricName="Max IL Cyclomatic Complexity for Methods" MetricUnit="Paths" Color="#FFFF0000" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="Max # Lines of Code for Methods (JustMyCode)" MetricUnit="LoC" Color="#FF0000FF" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="Max # of Methods for Types" MetricUnit="Methods" Color="#FF32CD32" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="Max IL Nesting Depth for Methods" MetricUnit="Scopes" Color="#FFFFD700" ChartType="Line" ScaleExp="0" /> + </Chart> + <Chart Name="Average" ShowInReport="True"> + <Serie MetricName="Average IL Cyclomatic Complexity for Methods" MetricUnit="Paths" Color="#FFFF0000" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="Average # Lines of Code for Methods" MetricUnit="LoC" Color="#FF0000FF" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="Average # Methods for Types" MetricUnit="Methods" Color="#FF32CD32" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="Average IL Nesting Depth for Methods" MetricUnit="Scopes" Color="#FFFFD700" ChartType="Line" ScaleExp="0" /> + </Chart> + <Chart Name="Third-Party Usage" ShowInReport="True"> + <Serie MetricName="# Third-Party Types Used" MetricUnit="Types" Color="#FF0000FF" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="# Third-Party Methods Used" MetricUnit="Methods" Color="#FFFF0000" ChartType="Line" ScaleExp="0" /> + <Serie MetricName="# Third-Party Assemblies Used" MetricUnit="Assemblies" Color="#FF646464" ChartType="Line" ScaleExp="1" /> + <Serie MetricName="# Third-Party Namespaces Used" MetricUnit="Namespaces" Color="#FF32CD32" ChartType="Line" ScaleExp="1" /> + <Serie MetricName="# Third-Party Fields Used" MetricUnit="Fields" Color="#FFFFD700" ChartType="Line" ScaleExp="1" /> + </Chart> + </TrendMetrics> + <HistoricAnalysisResult PersistRecurrence="2" UseCustomDir="False" CustomDir="" /> + <SourceFileRebasing FromPath="" ToPath="" /> + <PathVariables /><Queries>   <Group Name="Code Quality" Active="True" ShownInReport="False">   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Types too big - critical</Name>  warnif count > 0 from t in JustMyCode.Types where - t.NbLinesOfCode > 500 || - t.NbILInstructions > 3000 + t.NbLinesOfCode > 500 + // We've commented # IL Instructions, because with LINQ syntax, a few lines of code can compile to hundreds of IL instructions. + // || t.NbILInstructions > 3000   orderby t.NbLinesOfCode descending  select new { t, t.NbLinesOfCode, t.NbILInstructions,   t.Methods, t.Fields } @@ -114,7 +144,8 @@
 warnif count > 0 from m in JustMyCode.Methods where   // Code Metrics' definitions   m.NbLinesOfCode > 30 || // http://www.ndepend.com/Metrics.aspx#NbLinesOfCode - m.NbILInstructions > 200 || // http://www.ndepend.com/Metrics.aspx#NbILInstructions + // We've commented # IL Instructions, because with LINQ syntax, a few lines of code can compile to hundreds of IL instructions. + // m.NbILInstructions > 200 || // http://www.ndepend.com/Metrics.aspx#NbILInstructions   m.CyclomaticComplexity > 20 || // http://www.ndepend.com/Metrics.aspx#CC   m.ILCyclomaticComplexity > 50 || // http://www.ndepend.com/Metrics.aspx#ILCC   m.ILNestingDepth > 5 || // http://www.ndepend.com/Metrics.aspx#ILNestingDepth @@ -127,8 +158,9 @@
  m.NbParameters, m.NbVariables, m.NbOverloads } ]]></Query>   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods too big</Name>  warnif count > 0 from m in JustMyCode.Methods where - m.NbLinesOfCode > 30 || - m.NbILInstructions > 200 + m.NbLinesOfCode > 30 + // We've commented # IL Instructions, because with LINQ syntax, a few lines of code can compile to hundreds of IL instructions. + // || m.NbILInstructions > 200   orderby m.NbLinesOfCode descending,   m.NbILInstructions descending  select new { m, m.NbLinesOfCode, m.NbILInstructions } @@ -519,7 +551,7 @@
  !t.IsSealed &&   !t.IsStatic   // && !t.IsPublic <-- You might want to add this condition - // if you are developping a framework + // if you are developing a framework   // with classes that are intended to be   // sub-classed by your clients.   orderby t.NbLinesOfCode descending @@ -550,8 +582,10 @@
 where !mOverride.IsUsing(mBase)  select new { mOverride, shouldCall = mBase, definedInBaseClass = mBase.ParentType }  ]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Do not hide base class methods</Name> -// Prefer override virtual methods + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Do not hide base class methods</Name> +// To fix a violation of this rule, remove or rename the method, or change the parameter signature +// so that the method does not hide the base method. +  // More on hiding vs. virtual usefulness here:  // http://www.artima.com/intv/nonvirtual.html  // http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx @@ -608,11 +642,11 @@
 warnif count > 0  from t in JustMyCode.Types  where t.IsClass && - //!t.IsPublic && // if you are developping a framework, + //!t.IsPublic && // if you are developing a framework,   // you might not want to match public classes   !t.IsStatic &&   !t.IsAttributeClass && // Attributes class are never seen as instantiated - !t.DeriveFrom("System.MarshalByRefObject".AllowNoMatch()) // Types instantiated through remoting infrstructure + !t.DeriveFrom("System.MarshalByRefObject".AllowNoMatch()) // Types instantiated through remoting infrastructure    // find the first constructor of t called  let ctorCalled = t.Constructors.FirstOrDefault(ctor => ctor.NbMethodsCallingMe > 0) @@ -645,7 +679,7 @@
  where !m.IsAbstract && !m.IsVirtual &&   !m.AccessThis && !m.IsExplicitInterfaceImpl &&   - // Optimization: Using FirstOrDefault() avoid do check all members, + // Optimization: Using FirstOrDefault() avoid to check all members,   // as soon as one member is found   // we know the method m cannot be made static.   m.MembersUsed.FirstOrDefault( @@ -904,10 +938,10 @@
   where instanceFieldsDisposable.Count() > 0  select new { t, instanceFieldsDisposable }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Disposable types with unmanaged resources should declare finalizer</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Disposable types with unmanaged resources should declare finalizer</Name>  // warnif count > 0  let iDisposable = ThirdParty.Types.WithFullName("System.IDisposable").SingleOrDefault() -where iDisposable != null // iDisposable can be null if the code base deosn't use at all System.IDisposable +where iDisposable != null // iDisposable can be null if the code base doesn't use at all System.IDisposable    let disposableTypes = Application.Types.ThatImplement(iDisposable)  let unmanagedResourcesFields = disposableTypes.ChildFields().Where(f => @@ -941,6 +975,10 @@
    t.NbChildren == 0 && // Must not have children   + // Must not implement interfaces to avoid boxing mismatch + // when structures implements interfaces. + t.InterfacesImplemented.Count() == 0 && +   // Must have no base class   t.DepthOfDeriveFrom("System.Object".AllowNoMatch()) == 1   @@ -1075,7 +1113,7 @@
 ]]></Query>   </Group>   <Group Name="Architecture and Layering" Active="True" ShownInReport="False"> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid namespaces mutually dependent</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid namespaces mutually dependent</Name>  warnif count > 0  // Foreach pair of namespace mutually dependent, this rule lists pairs.  // The pair { first, second } is formatted to show first namespace shouldn't use the second namespace. @@ -1453,6 +1491,24 @@
 select new { t, mutableFields }    ]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid changing enumerations Flags status</Name> + +// Being tagged with the Flags attribute is a strong property for an enumeration. +// Changing the Flags status of an enumeration has significant impact for its client. +warnif count > 0 + +let oldFlags = codeBase.OlderVersion().ThirdParty.Types.WithFullName("System.FlagsAttribute").SingleOrDefault() +let newFlags = ThirdParty.Types.WithFullName("System.FlagsAttribute").SingleOrDefault() +where oldFlags != null && newFlags != null + +from t in Application.Types where + t.IsEnumeration && + t.IsPresentInBothBuilds() +let isFlags = t.HasAttribute(newFlags) +let wasFlags = t.OlderVersion().HasAttribute(oldFlags) +where isFlags != wasFlags +select new { t, isFlags, wasFlags } +]]></Query>   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>API: New publicly visible types</Name>  // List types that are new in the public surface of your assemblies   @@ -1675,7 +1731,7 @@
  !f.ParentType.IsNotUsedAnymore()  select new { f, MethodsThatUsedMe = f.MethodsUsingMe }]]></Query>   </Group> - <Group Name="Test and Code Coverage" Active="False" ShownInReport="True"> + <Group Name="Test and Code Coverage" Active="True" ShownInReport="True">   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>C.R.A.P method code metric</Name>  // Change Risk Analyzer and Predictor (i.e. CRAP) code metric  // This code metric helps in pinpointing overly complex and untested code. @@ -1893,7 +1949,7 @@
 }]]></Query>   </Group>   <Group Name="Dead Code" Active="True" ShownInReport="True"> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Potentially dead Types</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Potentially dead Types</Name>  warnif count > 0  // Filter procedure for types that should'nt be considered as dead  let canTypeBeConsideredAsDeadProc = new Func<IType, bool>( @@ -1924,7 +1980,7 @@
   from t in deadTypesMetric.DefinitionDomain  select new { t, t.TypesUsingMe, depth = deadTypesMetric[t] }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Potentially dead Methods</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Potentially dead Methods</Name>  warnif count > 0  // Filter procedure for methods that should'nt be considered as dead  let canMethodBeConsideredAsDeadProc = new Func<IMethod, bool>( @@ -1969,7 +2025,7 @@
   from m in JustMyCode.Methods.Intersect(deadMethodsMetric.DefinitionDomain)  select new { m, m.MethodsCallingMe, depth = deadMethodsMetric[m] }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Potentially dead Fields</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Potentially dead Fields</Name>  warnif count > 0  from f in JustMyCode.Fields where   f.NbMethodsUsingMe == 0 && @@ -1977,7 +2033,8 @@
  !f.IsLiteral && // The IL code never explicitely uses literal fields.   !f.IsEnumValue && // The IL code never explicitely uses enumeration value.   f.Name != "value__" && // Field named 'value__' are relative to enumerations and the IL code never explicitely uses them. - !f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) + !f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) && + !f.IsGeneratedByCompiler   // If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute and adapt this rule.  select f]]></Query>   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Wrong usage of IsNotDeadCodeAttribute</Name> @@ -2053,8 +2110,16 @@
  !t.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&     // Static types that define only const fields cannot be seen as used in IL code. - // They don't have to be tagged with CannotDecreaseVisibilityAttribute. - !(t.IsStatic && t.NbMethods == 0 && !t.Fields.Where(f => !f.IsLiteral).Any()) + // They don't have to be tagged with CannotDecreaseVisibilityAttribute. + !( t.IsStatic && + !t.Methods.Any(m => !m.IsClassConstructor) && + !t.Fields.Any(f => !f.IsLiteral && !(f.IsStatic && f.IsInitOnly))) && + + // A type used by an interface that has the same visibility + // cannot have its visibility decreased, else a compilation error occurs! + !t.TypesUsingMe.Any(tUser => + tUser.IsInterface && + tUser.Visibility == t.Visibility)    select new { t, t.Visibility ,   CouldBeDeclared = t.OptimalVisibility, @@ -2071,21 +2136,51 @@
  f.Visibility ,   CouldBeDeclared = f.OptimalVisibility,   f.MethodsUsingMe }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types that could be declared as private, nested in a parent type</Name> +// The conditions for a type to be nested into a parent type +// is that the parent type is the only type using it, +// and that the parent type is declared in the same namespace. +// +// Declaring a type as private into a parent type helps enforcing encapsulation. +// But since nested private types are hardly testable, this rule might +// not be applied for types used directly by tests. + +warnif count > 0 +from t in Application.Types +where !t.IsGeneratedByCompiler && + !t.IsNested && + !t.IsPubliclyVisible && + // Only one type user... + t.TypesUsingMe.Count() == 1 +let couldBeNestedIn = t.TypesUsingMe.Single() +where !couldBeNestedIn.IsGeneratedByCompiler && + // ...declared in the same namespace + couldBeNestedIn.ParentNamespace == t.ParentNamespace +select new { t, couldBeNestedIn }]]></Query>   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid publicly visible constant fields</Name>    // Match constant fields which are visible outside their parent assembly. -// Such field, if used outside the parent assembly, -// will have its constant value hard-coded into the other assembly. -// Changing the field's value requires that all assemblies -// that use the field to be recompiled. -// Declaring the field as static readonly instead, allows the value -// to be changed without the need to recompile client assemblies. +// Such field, when used outside its parent assembly, +// has its constant value hard-coded into the client assembly. +// Changing the field's value requires to recompile all assemblies +// that use the field. + +// Declare the field as static readonly instead. This way, the value can be +// safely changed, without the need to recompile client assemblies.    warnif count > 0  from f in Application.Fields -where f.IsLiteral && f.IsPubliclyVisible +where f.IsLiteral && f.IsPubliclyVisible + && !f.IsEnumValue // This situation also applies to enumeration values + // but to avoid too many false positives, per default + // this rule doesn't match these particular fields.  select f]]></Query>   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Fields should be declared as private</Name> +// Fields should be considered as implementation details +// and as a consequence they should be declared as private. +// When a field is private, the caller cannot get +// inappropriate direct access to the field. +  warnif count > 0 from f in Application.Fields where   !f.IsPrivate &&   @@ -2096,11 +2191,22 @@
  !f.IsInitOnly &&   !f.IsLiteral &&   !f.IsEnumValue -select new { f, f.SizeOfInst }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Constructors of abstract classes should be declared as protected or private</Name> -// Constructors of an abstract class can only be accessed from this class and derived class. + +// A non-private field assigned from outside its class, +// usually leads to complicated field state management. +let outsideMethodsAssigningMe = + f.MethodsAssigningMe.Where(m => m.ParentType != f.ParentType) + +select new { f, + f.Visibility, + outsideMethodsAssigningMe }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Constructors of abstract classes should be declared as protected or private</Name> +// Constructors of an abstract class can be accessed only from its class and derived class.  // Declaring such a constructor with another visibility level is useless and potentially misleading.   +// Notice that if a constructor of an abstract class is declared as private, +// it can only be accessed from derived classes nested in the abstract class. +  warnif count > 0  from t in Application.Types where   t.IsClass && @@ -2108,9 +2214,7 @@
 let ctors = t.Constructors.Where(c => !c.IsProtected && !c.IsPrivate)  where ctors.Count() > 0  select new { t, ctors } - -// Notice that if a constructor of an abstract class is declared as private, -// it can only be accessed from derived classes nested in the abstract class.]]></Query> +]]></Query>   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[//<Name>Avoid public methods not publicly visible</Name>  // Matched methods are declared public but are not publicly visible by assemblies consumers.  // Their visibility level must be decreased. @@ -2182,6 +2286,24 @@
   where types.Count() > 0 || methods.Count() > 0 || fields.Count() > 0  select new { tAttr, types , methods, fields }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Event handler methods should be declared private</Name> +warnif count > 0 +from m in Application.Methods where + !m.IsPrivate && + + // A method is considered as event handler if... + m.NbParameters==2 && // ...it has two parameters.. + m.Name.Contains("Object") && // ...of types Object... + m.Name.Contains("EventArgs") && // ...and EventArgs + + // Discard special cases + !m.ParentType.IsDelegate && + !m.IsGeneratedByCompiler + +select new { m,m.Visibility } +// This rule implementation relies on the facts that: +// -> A method name contains the type of its parameters. +// -> All EventArgs derived types have the suffix "EventArgs".]]></Query>   </Group>   <Group Name="Purity - Immutability - Side-Effects" Active="True" ShownInReport="False">   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Fields should be marked as ReadOnly when possible</Name> @@ -2280,33 +2402,113 @@
   where methodsAssignerOutsideOfMyType.Count() > 0  select new { f, methodsAssignerOutsideOfMyType }]]></Query> - <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types tagged with ImmutableAttribute must be immutable</Name> -warnif count > 0 from t in Application.Types where - t.HasAttribute ("NDepend.Attributes.ImmutableAttribute".AllowNoMatch()) && - !t.IsImmutable - -let mutableFields = t.Fields.Where(f =>!f.IsImmutable) - -// Notice that third-party base classes might be considered mutable -// while it is not actually mutable. -let mutableBaseClasses = t.BaseClasses.Where(b => !b.IsImmutable && b.FullName != "System.Object") - -select new { t, t.NbLinesOfCode, mutableFields, mutableBaseClasses } - + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Don't assign a field from many methods</Name> +warnif count > 0 +from f in JustMyCode.Fields where + !f.IsEnumValue && + !f.IsImmutable && + !f.IsInitOnly && + !f.IsGeneratedByCompiler && + !f.IsEventDelegateObject && + (f.IsPrivate || f.IsProtected) // Don't match fields assigned outside their classes. + +// The threshold 4 is arbitrary and it should avoid matching too many fields. +// Threshold is even lower for static fields because this reveals situations even more complex. +where f.MethodsAssigningMe.Count() >= (!f.IsStatic ? 4 : 2) +select new { f, + f.MethodsAssigningMe, + f.MethodsReadingMeButNotAssigningMe, + f.MethodsUsingMe, + f.ParentType } + +// A field assigned from many methods is a symptom of bug-prone code. +// This situation makes harder to anticipate the field state during runtime. +// The code is then hard to read, hard to debug and hard to maintain. +// Hard-to-solve bugs due to corrupted state are often the consequence of fields anarchically assigned. +// +// The situation is even more complex if the field is static. +// Indeed, this potentially involves global random accesses from different parts of the application. +// This is why this rule provides a lower threshold for static fields. +// +// If the object containing such field is meant to be used from multiple threads, +// there are alarming chances that the code is unmaintainable and bugged. +// When multiple threads are involved, the rule of thumb is to use immutable objects. +// +// If the field type is a reference type (interfaces, classes, strings, delegates) +// corrupted state might result in a NullReferenceException. +// If the field type is a value type (number, boolean, structure) +// corrupted state might result in wrong result not even signaled by an exception sent. +// +// There is no straight advice to refactor the number of methods responsible for assigning a field. +// Solutions often involve rethinking and then rewriting a complex algorithm. +// Such field can sometime become just a variable accessed locally by a method or a closure. +// Sometime, just rethinking the life-time and the role of the parent object allows the field to become immutable +// (i.e assigned only by the constructor). + +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Do not declare read only mutable reference types</Name> +warnif count > 0 from f in JustMyCode.Fields where + f.IsInitOnly && + !f.ParentType.IsPrivate && + !f.IsPrivate && + f.FieldType != null && + f.FieldType.IsClass && + !f.FieldType.IsThirdParty && + !f.FieldType.IsImmutable +select new { f, f.FieldType, FieldVisibility = f.Visibility } + +// This rule is violated when a public or internal +// type contains a public or internal read-only field +// that is a mutable reference type. +// +// This situation provides the wrong impression that the +// value can't change, when actually it's only the field +// value that can't change, rather than the object. +// +// To fix a violation of this rule, remove the read-only +// modifier or, if a breaking change is acceptable, +// replace the field with an immutable type. +//  // An object is immutable if its state doesn’t  // change once the object has been created.  // Consequently, a class or a structure is  // immutable if its instances are immutable.  // Immutable types naturally simplify code by  // limiting side-effects. -// See some explanations on immutability and how -// NDepend supports it here: -// http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx - -// NDepend.Attributes.ImmutableAttribute is defined in -// the redistributable assembly $NDependInstallDir$\Lib\NDepend.API.dll -// You can define your own attribute to tag 'immutable' types. - +]]></Query> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Array fields should not be read only</Name> +warnif count > 0 from f in Application.Fields where + f.IsInitOnly && + f.IsPubliclyVisible && + f.FieldType != null && + f.FieldType.FullName == "System.Array" +select new { f, FieldVisibility = f.Visibility } + +// This rule is violated when a publicly visible field +// that holds an array, is declared read-only. +// +// This situation represents a security vulnerability. +// Because the field is read-only it cannot be changed to refer +// to a different array. However, the elements of the array +// that are stored in a read-only field can be changed. +// Code that makes decisions or performs operations that are +// based on the elements of a read-only array that can be publicly +// accessed might contain an exploitable security vulnerability. +// +// To fix the security vulnerability that is identified by , +// this rule do not rely on the contents of a read-only array +// that can be publicly accessed. It is strongly recommended +// that you use one of the following procedures: +// +// -> Replace the array with a strongly typed collection +// that cannot be changed. For more information, +// see System.Collections.Generic.IReadOnlyList<T> +// System.Collections.Generic.IReadOnlyCollection<T> +// System.Collections.ReadOnlyCollectionBase. +// +// -> Replace the public field with a method that returns a clone +// of a private array. Because your code does not rely on +// the clone, there is no danger if the elements are modified.  ]]></Query>   <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types immutable should be tagged with ImmutableAttribute</Name>  from t in Application.Types where @@ -2398,7 +2600,7 @@
 // Don't hesitate to customize the regex of  // NameLike to your preference.  ]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Interface name should begin with a 'I'</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Interface name should begin with a 'I'</Name>  warnif count > 0 from t in Application.Types where  t.IsInterface   @@ -2419,14 +2621,16 @@
  ((!t.IsGeneric && !t.NameLike (@"Base$")) ||   ( t.IsGeneric && !t.NameLike (@"Base<")))  select new { t, t.DepthOfInheritance }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Exception class name should be suffixed with 'Exception'</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Exception class name should be suffixed with 'Exception'</Name>  warnif count > 0 from t in Application.Types where   t.IsExceptionClass && - !t.NameLike (@"Exception$") + !t.NameLike (@"Exception$") && + !t.NameLike (@"ExceptionBase$") // Allow the second suffix Base + // for base exception classes.  select new { t, t.NbLinesOfCode }    // The name of an exception class should end with 'Exception'.]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Attribute class name should be suffixed with 'Attribute'</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Attribute class name should be suffixed with 'Attribute'</Name>  warnif count > 0 from t in Application.Types where   t.IsAttributeClass &&   !t.NameLike (@"Attribute$") @@ -2519,7 +2723,7 @@
 // Field Name doesn't contain the type and  // namespace prefix, FullName does.   ]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[ // <Name>Avoid having different types with same name</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid having different types with same name</Name>  // Such practice typically creates confusion,  // and type naming collision inside a source file.   @@ -2549,14 +2753,15 @@
  let types= groupsFullName.SelectMany(g => g)   where types.Any(t => !t.IsThirdParty)   // Uncomment this line, to only gets naming collision involving - // both application adn third-party types. + // both application and third-party types.   // && types.Any(t => t.IsThirdParty)    orderby types.Count() descending    select new { t = types.First(),   // In the 'types' column, make sure to group matched types - // by parent assemblies and parent namespaces. + // by parent assemblies and parent namespaces, to get a result + // more readable.   types   }]]></Query>   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid prefixing type name with parent namespace name</Name> @@ -2584,9 +2789,9 @@
 from t in JustMyCode.Types  where hashsetShortNames.Contains(t.Name)  select new { t, namespaces = Namespaces.Where(n => n.SimpleName == t.Name) }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't call your method Dispose</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Don't call your method Dispose</Name>  // Methods shouldn't be called Dispose, -// this syntax is reserved for System.IDisposable ype usage. +// this syntax is reserved for System.IDisposable type usage.  from m in Application.Methods.WithSimpleName("Dispose")  where !m.ParentType.Implement("System.IDisposable".AllowNoMatch())  select m]]></Query> @@ -2633,7 +2838,9 @@
 // Prefer to factorize type definition in a library assembly.  warnif count > 0   -let groups = Application.Types.GroupBy(t => t.FullName) +let groups = Application.Types + .Where(t => !t.IsGeneratedByCompiler) + .GroupBy(t => t.FullName)  from @group in groups  where @group.Count() > 1   @@ -2757,7 +2964,7 @@
 // Are types of @namespaces declared in more than one directory?  where lookup.Count > 1   -// Infer the main directory, preferably the one that has the same name as the namespace. +// Infer the main folder, preferably the one that has the same name as the namespace.  let dirs = lookup.Select(types => types.Key)  let mainDirNullable = dirs.Where(d => d.DirectoryName == @namespace.SimpleName).FirstOrDefault()  let mainDir = mainDirNullable ?? dirs.First() @@ -3200,35 +3407,29 @@
 select new { m, calls = m.MethodsCalled.Intersect(wrongMethods) }    ]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Monitor TryEnter/Exit must be both called within the same method</Name> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Monitor TryEnter/Exit must be both called within the same method</Name> +// Else you expose yourself to complex error-prone scenarios.  warnif count > 0   -let enterMethods = ThirdParty.Methods.WithFullNameIn( - "System.Threading.Monitor.Enter(Object)", - "System.Threading.Monitor.TryEnter(Object)", - "System.Threading.Monitor.TryEnter(Object,Int32)", - "System.Threading.Monitor.TryEnter(Object,TimeSpan)", - "System.Threading.Monitor.TryEnter(Object,Boolean&)", - "System.Threading.Monitor.TryEnter(Object,Int32,Boolean&)", - "System.Threading.Monitor.TryEnter(Object,TimeSpan,Boolean&)") - -from m in Application.Methods.UsingAny(enterMethods ) where +let enterMethods = ThirdParty.Methods.WithFullNameWildcardMatchIn( + "System.Threading.Monitor.Enter(*", + "System.Threading.Monitor.TryEnter(*") + +from m in Application.Methods.UsingAny(enterMethods) where   !m.IsUsing ("System.Threading.Monitor.Exit(Object)".AllowNoMatch()) -select m]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>ReaderWriterLock Acquire[Reader/Writer]Lock/ReleaseLock must be both called within the same method</Name> +select new { m, enterMethodsCalled = m.MethodsCalled.Intersect(enterMethods) }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>ReaderWriterLock Acquire[Reader/Writer]Lock/ReleaseLock must be both called within the same method</Name> +// Else you expose yourself to complex error-prone scenarios.  warnif count > 0   -let acquireLockMethods = ThirdParty.Methods.WithFullNameIn( - "System.Threading.ReaderWriterLock.AcquireReaderLock(Int32)", - "System.Threading.ReaderWriterLock.AcquireReaderLock(TimeSpan)", - "System.Threading.ReaderWriterLock.AcquireWriterLock(Int32)", - "System.Threading.ReaderWriterLock.AcquireWriterLock(TimeSpan)") - -from m in Application.Methods.UsingAny(acquireLockMethods ) where +let acquireLockMethods = ThirdParty.Methods.WithFullNameWildcardMatch( + "System.Threading.ReaderWriterLock.AcquireReaderLock(*") + +from m in Application.Methods.UsingAny(acquireLockMethods) where   !m.IsUsing ("System.Threading.ReaderWriterLock.ReleaseReaderLock()".AllowNoMatch()) &&   !m.IsUsing ("System.Threading.ReaderWriterLock.ReleaseLock()".AllowNoMatch()) -select m]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't tag instance fields with ThreadStaticAttribute</Name> +select new { m, acquireLockMethods = m.MethodsCalled.Intersect(acquireLockMethods) }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Don't tag instance fields with ThreadStaticAttribute</Name>  // The ThreadStaticAttribute is designed to only works when it tags static fields.  warnif count > 0  from f in Application.Fields @@ -3283,7 +3484,7 @@
  <Group Name="Microsoft.Contracts" Active="True" ShownInReport="False">   <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Public methods returning a reference needs a contract to ensure that a non-null reference is returned</Name>   -// Contracts are useful to decrease ambiguity between callers and calles. +// Contracts are useful to decrease ambiguity between callers and callees.  // Not ensuring that a reference returned is not-null leaves ambiguity for the caller.  // Contract.Ensures(Contract.Result<***ReturnType***>() != null, "returned object is not null");   @@ -3305,9 +3506,357 @@
   select new { m, ReturnTypeReference = m.ReturnType }]]></Query>   </Group> + <Group Name="Third-Party Code Elements Used" Active="True" ShownInReport="False"> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third-Party Assemblies Used</Name> +ThirdParty.Assemblies.Select(a => a)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third-Party Namespaces Used</Name> +ThirdParty.Namespaces.Select(n => n)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third-Party Types Used</Name> +ThirdParty.Types.Select(t => t)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third-Party Methods Used</Name> +ThirdParty.Methods.Select(m => m)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third-Party Fields Used</Name> +ThirdParty.Fields.Select(f => f)]]></Query> + </Group> + </Group> + <Group Name="Trend Metrics" Active="True" ShownInReport="False"> + <Group Name="Code Size" Active="True" ShownInReport="False"> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code" Unit="LoC" /> +Application.Assemblies.Sum(a => a.NbLinesOfCode)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code (JustMyCode)" Unit="LoC" /> +JustMyCode.Methods.Sum(m => m.NbLinesOfCode) + +// JustMyCode is defined by code queries prefixed with 'notmycode' +// in the group 'Defining JustMyCode'. +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code (NotMyCode)" Unit="LoC" /> +Application.Methods.Where(m => !JustMyCode.Contains(m)) + .Sum(m => m.NbLinesOfCode) + +// JustMyCode is defined by code queries prefixed with 'notmycode' +// in the group 'Defining JustMyCode'. +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code Added since the Baseline" Unit="LoC" /> +( from a in Application.Assemblies + let nbLocAdded = !a.IsPresentInBothBuilds() + ? a.NbLinesOfCode + : (a.NbLinesOfCode != null && a.OlderVersion().NbLinesOfCode != null) + ? a.NbLinesOfCode - (int)a.OlderVersion().NbLinesOfCode + : 0 + select nbLocAdded) +.Sum(loc => loc) + +// A value is computed by this Trend Metric query +// only if a Baseline for Comparison is provided. +// See Project Properties > Analysis > Baseline for Comparison +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Source Files" Unit="Source Files" /> +Application.Assemblies.SelectMany( + a => a.SourceDecls.Select(sd => sd.SourceFile.FilePathString.ToLower())) +.Distinct() +.Count() + +// If a value 0 is obtained, it means that at analysis time, +// assemblies PDB files were not available. +// http://www.ndepend.com/Doc_CI_Inputs.aspx +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# IL Instructions" Unit="IL Instructions" /> +Application.Assemblies.Sum(a => a.NbILInstructions) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# IL Instructions (NotMyCode)" Unit="IL Instructions" /> +Application.Methods.Where(m => !JustMyCode.Contains(m)) + .Sum(m => m.NbILInstructions) + +// JustMyCode is defined by code queries prefixed with 'notmycode' +// in the group 'Defining JustMyCode'. +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Comments" Unit="Lines" /> +Application.Assemblies.Sum(a => a.NbLinesOfComment) + +// So far comments are only extracted from C# source code. +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Assemblies" Unit="Assemblies" /> +Application.Assemblies.Count() + +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Namespaces" Unit="Namespaces" /> +Application.Namespaces.Count()]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Types" Unit="Types" /> +Application.Types.Count()]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Public Types" Unit="Types" /> +Application.Types.Where(t => t.IsPubliclyVisible).Count()]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Classes" Unit="Types" /> +Application.Types.Count(t => t.IsClass && !t.IsGeneratedByCompiler) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Abstract Classes" Unit="Types" /> +Application.Types.Count(t => t.IsClass && t.IsAbstract) + +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Interfaces" Unit="Types" /> +Application.Types.Count(t => t.IsInterface)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Structures" Unit="Types" /> +Application.Types.Count(t => t.IsStructure)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Methods" Unit="Methods" /> +Application.Methods.Count(m => !m.IsGeneratedByCompiler)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Abstract Methods" Unit="Methods" /> +Application.Methods.Count(m => m.IsAbstract)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Concrete Methods" Unit="Methods" /> +Application.Methods.Count(m => !m.IsAbstract && !m.IsGeneratedByCompiler) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Fields" Unit="Fields" /> +Application.Fields.Count(f => + !f.IsEnumValue && + !f.IsGeneratedByCompiler && + !f.IsLiteral && + !f.ParentType.IsEnumeration) + +]]></Query> + </Group> + <Group Name="Maximum and Average" Active="True" ShownInReport="False"> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # Lines of Code for Methods (JustMyCode)" Unit="LoC" /> +JustMyCode.Methods + .Max(m => m.NbLinesOfCode) + .ToEnumerable().Sum(loc => loc) + +// Here is the code query to get the (JustMyCode) method with largest # Lines of Code +// JustMyCode.Methods.OrderByDescending(m => m.NbLinesOfCode).Take(1).Select(m => new {m, m.NbLinesOfCode}) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Lines of Code for Methods" Unit="LoC" /> +Application.Methods.Where(m => m.NbLinesOfCode > 0) + .Average(m => m.NbLinesOfCode)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Lines of Code for Methods with at least 3 Lines of Code" Unit="LoC" /> +Application.Methods.Where(m => m.NbLinesOfCode >= 3) + .Average(m => m.NbLinesOfCode) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # Lines of Code for Types (JustMyCode)" Unit="LoC" /> +JustMyCode.Types + .Max(t => t.NbLinesOfCode) + .ToEnumerable().Sum(loc => loc) + +// Here is the code query to get the (JustMyCode) type with largest # Lines of Code +// JustMyCode.Types.OrderByDescending(t => t.NbLinesOfCode).Take(1).Select(t => new {t, t.NbLinesOfCode}) + +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Lines of Code for Types" Unit="LoC" /> +Application.Types.Where(t => t.NbLinesOfCode > 0) + .Average(t => t.NbLinesOfCode)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max Cyclomatic Complexity for Methods" Unit="Paths" /> +Application.Methods + .Max(m => m.CyclomaticComplexity) + .ToEnumerable().Sum(loc => loc) + +// Here is the code query to get the most complex method, according to Cyclomatic Complexity +// Application.Methods.OrderByDescending(m => m.CyclomaticComplexity).Take(1).Select(m => new {m, m.CyclomaticComplexity}) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average Cyclomatic Complexity for Methods" Unit="Paths" /> +Application.Methods.Where(m => m.NbLinesOfCode> 0) + .Average(m => m.CyclomaticComplexity)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max IL Cyclomatic Complexity for Methods" Unit="Paths" /> +Application.Methods + .Max(m => m.ILCyclomaticComplexity) + .ToEnumerable().Sum(loc => loc) + +// Here is the code query to get the most complex method, according to Cyclomatic Complexity computed from IL code. +// Application.Methods.OrderByDescending(m => m.ILCyclomaticComplexity).Take(1).Select(m => new {m, m.CyclomaticComplexity}) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average IL Cyclomatic Complexity for Methods" Unit="Paths" /> +Application.Methods.Where(m => m.NbILInstructions> 0) + .Average(m => m.ILCyclomaticComplexity) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max IL Nesting Depth for Methods" Unit="Scopes" /> +Application.Methods + .Max(m => m.ILNestingDepth) + .ToEnumerable().Sum(loc => loc) + +// Here is the code query to get the method with highest ILNestingDepth. +// Application.Methods.OrderByDescending(m => m.ILNestingDepth).Take(1).Select(m => new {m, m.ILNestingDepth}) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average IL Nesting Depth for Methods" Unit="Scopes" /> +Application.Methods.Where(m => m.NbILInstructions> 0) + .Average(m => m.ILNestingDepth) +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # of Methods for Types" Unit="Methods" /> +Application.Types + .Max(t => t.NbMethods) + .ToEnumerable().Sum(loc => loc) + +// Here is the code query to get the (JustMyCode) type with largest # of Methods +// JustMyCode.Types.OrderByDescending(t => t.NbMethods).Take(1).Select(t => new {t, t.Methods}) + +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Methods for Types" Unit="Methods" /> +Application.Types.Average(t => t.NbMethods)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # of Methods for Interfaces" Unit="Methods" /> +Application.Types.Where(t => t.IsInterface) + .Max(t => t.NbMethods) + .ToEnumerable().Sum(loc => loc) + +// Here is the code query to get the (JustMyCode) type with largest # of Methods +// JustMyCode.Types.OrderByDescending(t => t.NbMethods).Take(1).Select(t => new {t, t.Methods})]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Methods for Interfaces" Unit="Methods" /> +JustMyCode.Types.Where(t => t.IsInterface) + .Average(t => t.NbMethods) +]]></Query> + </Group> + <Group Name="Code Coverage" Active="True" ShownInReport="False"> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Percentage Code Coverage" Unit="%" /> +((float)Application.Assemblies.Sum(a => a.NbLinesOfCodeCovered) / + Application.Assemblies.Sum(a => a.NbLinesOfCode) + * 100f) +.ToEnumerable().Sum() +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code Covered" Unit="LoC" /> +Application.Assemblies.Sum(a => a.NbLinesOfCodeCovered)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code Not Covered" Unit="LoC" /> +Application.Assemblies.Sum(a => a.NbLinesOfCodeNotCovered)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code in Types 100% Covered" Unit="LoC" /> +Application.Types.Where(t => t.PercentageCoverage == 100) + .Sum(t => t.NbLinesOfCodeCovered)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code in Methods 100% Covered" Unit="LoC" /> +Application.Methods.Where(m => m.PercentageCoverage == 100) + .Sum(m => m.NbLinesOfCodeCovered)]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max C.R.A.P Score" /> +// Change Risk Analyzer and Predictor (i.e. CRAP) code metric +// This code metric helps in pinpointing overly complex and untested code. +// Reference: http://www.artima.com/weblogs/viewpost.jsp?thread=215899 +// Formula: CRAP(m) = comp(m)^2 * (1 - cov(m)/100)^3 + comp(m) + +(from m in JustMyCode.Methods + +// Don't match too short methods +where m.NbLinesOfCode > 10 + +let CC = m.CyclomaticComplexity +let uncov = (100 - m.PercentageCoverage) / 100f +let CRAP = (CC * CC * uncov * uncov * uncov) + CC +where CRAP != null && CRAP > 30 select CRAP) +.Max(CRAP => CRAP) + +// To list methods with highest C.R.A.P scores, please refer to the default rule: +// Test and Code Coverage > C.R.A.P method code metric +]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average C.R.A.P Score" /> +// Change Risk Analyzer and Predictor (i.e. CRAP) code metric +// This code metric helps in pinpointing overly complex and untested code. +// Reference: http://www.artima.com/weblogs/viewpost.jsp?thread=215899 +// Formula: CRAP(m) = comp(m)^2 * (1 - cov(m)/100)^3 + comp(m) + +(from m in JustMyCode.Methods + +// Don't match too short methods +where m.NbLinesOfCode > 10 + +let CC = m.CyclomaticComplexity +let uncov = (100 - m.PercentageCoverage) / 100f +let CRAP = (CC * CC * uncov * uncov * uncov) + CC +where CRAP != null && CRAP > 30 select CRAP) +.Average(CRAP => CRAP) + +// To list methods with highest C.R.A.P scores, please refer to the default rule: +// Test and Code Coverage > C.R.A.P method code metric +]]></Query> + </Group> + <Group Name="Third-Party Usage" Active="True" ShownInReport="False"> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Assemblies Used" Unit="Assemblies" /> +ThirdParty.Assemblies.Count()]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Namespaces Used" Unit="Namespaces" /> +ThirdParty.Namespaces.Count()]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Types Used" Unit="Types" /> +ThirdParty.Types.Count()]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Methods Used" Unit="Methods" /> +ThirdParty.Methods.Count()]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Fields Used" Unit="Fields" /> +ThirdParty.Fields.Count()]]></Query> + </Group> + </Group> + <Group Name="Defining JustMyCode" Active="True" ShownInReport="False"> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Assemblies from JustMyCode</Name> +// --- Make sure to make this query richer to discard generated assemblies from NDepend rules results--- +notmycode +from a in Application.Assemblies where +// Assemblies generated for Xsl IL compilation for example are tagged with this attribute +a.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) +select new { a, a.NbILInstructions }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Types from JustMyCode</Name> +// --- Make sure to make this query richer to discard generated types from NDepend rules results --- +notmycode +from t in Application.Types where + + // Resources, Settings, or typed DataSet generated types for example, are tagged with this attribute + t.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) || + + // This attributes identifies a type or member that is not part of the user code for an application. + t.HasAttribute ("System.Diagnostics.DebuggerNonUserCodeAttribute".AllowNoMatch()) || + + // Delegate types are always generated + t.IsDelegate || + + // Discard ASP.NET page types generated by aspnet_compiler.exe + // See: http://www.ndepend.com/FAQ.aspx#ASPNET + t.ParentNamespace.Name.EqualsAny("ASP", "__ASP") || + + // Discard generated type ContractException + t.Name == "__ContractsRuntime+ContractException" || + t.FullName == "System.Diagnostics.Contracts.RuntimeContractsAttribute" || + t.FullName == "System.Diagnostics.Contracts.__ContractsRuntime" || + + // Discard all types declared in a folder path containing the word "generated" + (t.SourceFileDeclAvailable && + t.SourceDecls.All(s => s.SourceFile.FilePath.ParentDirectoryPath.ToString().ToLower().Contains("generated"))) + +select new { t, t.NbLinesOfCode }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated and designer Methods from JustMyCode</Name> +// --- Make sure to make this query richer to discard generated methods from NDepend rules results --- +notmycode + +// +// First define source files paths to discard +// +from a in Application.Assemblies +where a.SourceFileDeclAvailable +let asmSourceFilesPaths = a.SourceDecls.Select(s => s.SourceFile.FilePath) + +let sourceFilesPathsToDiscard = ( + from filePath in asmSourceFilesPaths + let filePathLower= filePath.ToString().ToLower() + where + filePathLower.EndsWithAny( + ".g.cs", // Popular pattern to name generated files. + ".g.vb", + ".xaml", // notmycode WPF xaml code + ".designer.cs", // notmycode C# Windows Forms designer code + ".designer.vb") // notmycode VB.NET Windows Forms designer code + || + // notmycode methods in source files in a directory containing generated + filePathLower.Contains("generated") + select filePath +).ToHashSet() + +// +// Second: discard methods in sourceFilesPathsToDiscard +// +from m in a.ChildMethods +where (m.SourceFileDeclAvailable && + sourceFilesPathsToDiscard.Contains(m.SourceDecls.First().SourceFile.FilePath)) || + // Generated methods might be tagged with this attribute + m.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) || + + // This attributes identifies a type or member that is not part of the user code for an application. + m.HasAttribute ("System.Diagnostics.DebuggerNonUserCodeAttribute".AllowNoMatch()) + +select new { m, m.NbLinesOfCode }]]></Query> + <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Fields from JustMyCode</Name> +// --- Make sure to make this query richer to discard generated fields from NDepend rules results --- +notmycode +from f in Application.Fields where + f.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) || + + // Eliminate "components" generated in Windows Form Conrol context + f.Name == "components" && f.ParentType.DeriveFrom("System.Windows.Forms.Control".AllowNoMatch()) +select f]]></Query>   </Group>   <Group Name="Statistics" Active="False" ShownInReport="False"> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used types (Rank)</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used types (Rank)</Name>  (from t in Application.Types orderby t.Rank descending   select new { t, t.Rank }).Take(50)   @@ -3317,7 +3866,7 @@
 // high Rank are the most used ones.  // See the definition of the TypeRank metric here:  // http://www.ndepend.com/Metrics.aspx#TypeRank]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used methods (Rank)</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used methods (Rank)</Name>  (from m in Application.Methods orderby m.Rank descending   select new { m, m.Rank }).Take(50)   @@ -3327,46 +3876,46 @@
 // are the most used ones. See the definition of  // the MethodRank metric here:  // http://www.ndepend.com/Metrics.aspx#MethodRank]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used namespaces (#NamespacesUsingMe )</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used namespaces (#NamespacesUsingMe )</Name>  (from n in Namespaces orderby n.NbNamespacesUsingMe descending   select new { n, n.NamespacesUsingMe }).Take(50)]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used types (#TypesUsingMe )</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used types (#TypesUsingMe )</Name>  (from t in Types orderby t.NbTypesUsingMe descending   select new { t, t.TypesUsingMe }).Take(50)]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used methods (#MethodsCallingMe )</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used methods (#MethodsCallingMe )</Name>  (from m in Methods orderby m.NbMethodsCallingMe descending   select new { m, m.MethodsCallingMe }).Take(50)]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespaces that use many other namespaces (#NamespacesUsed )</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespaces that use many other namespaces (#NamespacesUsed )</Name>  (from n in Application.Namespaces orderby n.NbNamespacesUsed descending   select new { n, n.NamespacesUsed }).Take(50)]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types that use many other types (#TypesUsed )</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types that use many other types (#TypesUsed )</Name>  (from t in Application.Types orderby t.NbTypesUsed descending   select new { t, t.TypesUsed }).Take(50)]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods that use many other methods (#MethodsCalled )</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods that use many other methods (#MethodsCalled )</Name>  (from m in Application.Methods orderby m.NbMethodsCalled descending   select new { m, m.MethodsCalled }).Take(50)]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level assemblies (Level)</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level assemblies (Level)</Name>  from a in Application.Assemblies orderby a.Level descending  select new { a, a.Level }    // Classify assemblies by their Level values.  // See the definition of the AssemblyLevel metric here:  // http://www.ndepend.com/Metrics.aspx#Level]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level namespaces (Level)</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level namespaces (Level)</Name>  from n in Application.Namespaces orderby n.Level descending  select new { n, n.Level }    // Classify namespaces by their Level values.  // See the definition of the NamespaceLevel metric here:  // http://www.ndepend.com/Metrics.aspx#Level]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level types (Level)</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level types (Level)</Name>  from t in Application.Types orderby t.Level descending  select new { t, t.Level }    // Classify types by their Level values.  // See the definition of the TypeLevel metric here:  // http://www.ndepend.com/Metrics.aspx#Level]]></Query> - <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level methods (Level)</Name> + <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level methods (Level)</Name>  from m in Application.Methods orderby m.Level descending  select new { m, m.Level }   @@ -3532,90 +4081,4 @@
 select new { n, n.NbLinesOfCode } ]]></Query>   </Group>   </Group> - <Group Name="Defining JustMyCode" Active="True" ShownInReport="False"> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Assemblies from JustMyCode</Name> -// --- Make sure to make this query richer to discard generated assemblies from NDepend rules results--- -notmycode -from a in Application.Assemblies where -// Assemblies generated for Xsl IL compilation for example are tagged with this attribute -a.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) -select new { a, a.NbILInstructions }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Types from JustMyCode</Name> -// --- Make sure to make this query richer to discard generated types from NDepend rules results --- -notmycode -from t in Application.Types where - - // Resources, Settings, or typed DataSet generated types for example, are tagged with this attribute - t.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) || - - // This attributes identifies a type or member that is not part of the user code for an application. - t.HasAttribute ("System.Diagnostics.DebuggerNonUserCodeAttribute".AllowNoMatch()) || - - // Delegate types are always generated - t.IsDelegate || - - // Discard ASP.NET page types generated by aspnet_compiler.exe - // See: http://www.ndepend.com/FAQ.aspx#ASPNET - t.ParentNamespace.Name.EqualsAny("ASP", "__ASP") || - - // Discard generated type ContractException - t.Name == "__ContractsRuntime+ContractException" || - t.FullName == "System.Diagnostics.Contracts.RuntimeContractsAttribute" || - t.FullName == "System.Diagnostics.Contracts.__ContractsRuntime" || - - // Discard all types declared in a folder path containing the word "generated" - (t.SourceFileDeclAvailable && - t.SourceDecls.All(s => s.SourceFile.FilePath.ParentDirectoryPath.ToString().ToLower().Contains("generated"))) - -select new { t, t.NbILInstructions }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated and designer Methods from JustMyCode</Name> -// --- Make sure to make this query richer to discard generated methods from NDepend rules results --- -notmycode - -// -// First define source files paths to discard -// -from a in Application.Assemblies -where a.SourceFileDeclAvailable -let asmSourceFilesPaths = a.SourceDecls.Select(s => s.SourceFile.FilePath) - -let sourceFilesPathsToDiscard = ( - from filePath in asmSourceFilesPaths - let filePathLower= filePath.ToString().ToLower() - where - filePathLower.EndsWithAny( - ".g.cs", // Popular pattern to name generated files. - ".g.vb", - ".xaml", // notmycode WPF xaml code - ".designer.cs", // notmycode C# Windows Forms designer code - ".designer.vb") // notmycode VB.NET Windows Forms designer code - || - // notmycode methods in source files in a directory containing generated - filePathLower.Contains("generated") - select filePath -).ToHashSet() - -// -// Second: discard methods in sourceFilesPathsToDiscard -// -from m in a.ChildMethods -where (m.SourceFileDeclAvailable && - sourceFilesPathsToDiscard.Contains(m.SourceDecls.First().SourceFile.FilePath)) || - // Generated methods might be tagged with this attribute - m.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) || - - // This attributes identifies a type or member that is not part of the user code for an application. - m.HasAttribute ("System.Diagnostics.DebuggerNonUserCodeAttribute".AllowNoMatch()) - -select new { m, m.NbLinesOfCode }]]></Query> - <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Fields from JustMyCode</Name> -// --- Make sure to make this query richer to discard generated fields from NDepend rules results --- -notmycode -from f in Application.Fields where - f.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) || - - // Eliminate "components" generated in Windows Form Conrol context - f.Name == "components" && f.ParentType.DeriveFrom("System.Windows.Forms.Control".AllowNoMatch()) -select f]]></Query> - </Group>   </Queries></NDepend> \ No newline at end of file