~ubuntu-branches/ubuntu/utopic/monodevelop/utopic-proposed

« back to all changes in this revision

Viewing changes to external/mono-tools/gendarme/rules/Gendarme.Rules.Interoperability.Com/ReviewComRegistrationMethodsRule.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2012-05-27 18:08:20 UTC
  • mfrom: (19.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20120527180820-fydl21qnbnfr8w2t
Tags: 3.0.2+dfsg-3
* [fcecfe7] Fix monodevelop-core-addins.pc.in to point to actual 
  installed location of assemblies.
* [26e1a07] DebSrc 3.0 does not support Quilt's -p parameter, so 
  manually adjust the path in the patch file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// Gendarme.Rules.Interoperability.Com.ReviewComRegistrationMethodsRule
 
3
//
 
4
// Authors:
 
5
//      Yuri Stuken <stuken.yuri@gmail.com>
 
6
//
 
7
// Copyright (C) 2010 Yuri Stuken
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
//
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
//
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
 
 
27
using System;
 
28
 
 
29
using Mono.Cecil;
 
30
using Mono.Cecil.Cil;
 
31
 
 
32
using Gendarme.Framework;
 
33
using Gendarme.Framework.Engines;
 
34
using Gendarme.Framework.Helpers;
 
35
using Gendarme.Framework.Rocks;
 
36
 
 
37
namespace Gendarme.Rules.Interoperability.Com {
 
38
 
 
39
        /// <summary>
 
40
        /// This rule checks the correctness of COM register and unregister methods,
 
41
        /// i.e. they should not be externally visible and they should be matched 
 
42
        /// (both or none of them should exist ).
 
43
        /// </summary>
 
44
        /// <example>
 
45
        /// Bad example (public methods):
 
46
        /// <code>
 
47
        /// [ComVisible (true)
 
48
        /// class Bad {
 
49
        ///     [ComRegisterFunction]
 
50
        ///     public void Register ()
 
51
        ///     {
 
52
        ///     }
 
53
        ///     
 
54
        ///     [ComUnregisterFunction]
 
55
        ///     public void Unregister ()
 
56
        ///     {
 
57
        ///     }
 
58
        /// }
 
59
        /// </code>
 
60
        /// </example>
 
61
        /// <example>
 
62
        /// Bad example (only one of the methods exist)
 
63
        /// <code>
 
64
        /// [ComVisible (true)]
 
65
        /// class Bad {
 
66
        ///     [ComRegisterFunction]
 
67
        ///     public void Register ()
 
68
        ///     {
 
69
        ///     }
 
70
        /// }
 
71
        /// </code>
 
72
        /// </example>
 
73
        /// <example>
 
74
        /// Good example:
 
75
        /// <code>
 
76
        /// [ComVisible (true)]
 
77
        /// class Good {
 
78
        ///     [ComRegisterFunction]
 
79
        ///     private void Register ()
 
80
        ///     {
 
81
        ///     }
 
82
        ///     
 
83
        ///     [ComUnregisterFunction]
 
84
        ///     private void Unregister ()
 
85
        ///     {
 
86
        ///     }
 
87
        /// }
 
88
        /// </code>
 
89
        /// </example>
 
90
 
 
91
        [Problem ("COM registration methods should be matched (i.e. both or none of them should exist) and should not be externally visible.")]
 
92
        [Solution ("Add a missing method or change methods visibility to private or internal.")]
 
93
        [FxCopCompatibility ("Microsoft.Interoperability", "CA1410:ComRegistrationMethodsShouldBeMatched")]
 
94
        [FxCopCompatibility ("Microsoft.Interoperability", "CA1411:ComRegistrationMethodsShouldNotBeVisible")]
 
95
        public class ReviewComRegistrationMethodsRule : Rule, ITypeRule {
 
96
 
 
97
                public RuleResult CheckType (TypeDefinition type)
 
98
                {
 
99
                        if (type.HasGenericParameters || !type.IsVisible () || !type.IsTypeComVisible ())
 
100
                                return RuleResult.DoesNotApply;
 
101
 
 
102
                        bool foundRegister = false; // type level variables
 
103
                        bool foundUnregister = false;
 
104
 
 
105
                        foreach (MethodDefinition method in type.Methods) {
 
106
                                if (!method.HasCustomAttributes)
 
107
                                        continue;
 
108
 
 
109
                                bool foundRegisterUnregisterMethod = false; // method level variable
 
110
                                foreach (CustomAttribute attribute in method.CustomAttributes) {
 
111
                                        TypeReference atype = attribute.AttributeType;
 
112
                                        if (!foundRegister && atype.IsNamed ("System.Runtime.InteropServices", "ComRegisterFunctionAttribute")) {
 
113
                                                foundRegister = true;
 
114
                                                foundRegisterUnregisterMethod = true;
 
115
                                        }
 
116
                                        if (!foundUnregister && atype.IsNamed ("System.Runtime.InteropServices", "ComUnregisterFunctionAttribute")) {
 
117
                                                foundUnregister = true;
 
118
                                                foundRegisterUnregisterMethod = true;
 
119
                                        }
 
120
                                }
 
121
                                if (foundRegisterUnregisterMethod && method.IsVisible ()) {
 
122
                                        Runner.Report (method, Severity.High, Confidence.High,
 
123
                                                "Method is marked with the ComRegisterFunctionAttribute or with the ComUnregisterFunctionAttribute and is externally visible");
 
124
                                }
 
125
                        }
 
126
 
 
127
                        if (foundRegister ^ foundUnregister) { // only one of them is true
 
128
                                if (foundRegister)
 
129
                                        Runner.Report (type, Severity.High, Confidence.High,
 
130
                                                "Type contains has a method with ComRegisterFunctionAttribute but it doesn't contain a method with ComUnregisterFunctionAttribute");
 
131
                                if (foundUnregister)
 
132
                                        Runner.Report (type, Severity.High, Confidence.High,
 
133
                                                "Type contains has a method with ComUnregisterFunctionAttribute but it doesn't contain a method with ComRegisterFunctionAttribute");
 
134
                        }
 
135
 
 
136
                        return Runner.CurrentRuleResult;
 
137
                }
 
138
        }
 
139
}