5 // Jb Evain (jbevain@novell.com)
7 // (C) 2007 Novell, Inc.
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
33 using Mono.Linker.Steps;
38 namespace Mono.Tuner {
40 public class CheckVisibility : BaseStep {
42 protected override void ProcessAssembly (AssemblyDefinition assembly)
44 if (assembly.Name.Name == "smcs")
47 foreach (ModuleDefinition module in assembly.Modules)
48 foreach (TypeDefinition type in module.Types)
52 void CheckType (TypeDefinition type)
54 if (!IsVisibleFrom (type, type.BaseType)) {
55 Report ("Base type {0} of type {1} is not visible",
59 CheckInterfaces (type);
62 CheckConstructors (type);
66 void CheckInterfaces (TypeDefinition type)
68 foreach (TypeReference iface in type.Interfaces) {
69 if (!IsVisibleFrom (type, iface)) {
70 Report ("Interface {0} implemented by {1} is not visible",
76 static bool IsPublic (TypeDefinition type)
78 return (type.Attributes & TypeAttributes.Public) != 0;
81 static bool AreInDifferentAssemblies (TypeDefinition lhs, TypeDefinition rhs)
83 return lhs.Module.Assembly.Name.FullName != rhs.Module.Assembly.Name.FullName;
86 bool IsVisibleFrom (TypeDefinition type, TypeReference reference)
88 // Report ("[is-visible-from] {0}:{1}", type, reference);
90 if (reference == null)
93 if (reference is GenericParameter || reference.GetOriginalType () is GenericParameter)
96 TypeDefinition other = Context.Resolver.Resolve (reference);
100 if (!AreInDifferentAssemblies (type, other))
103 if (IsPublic (other))
109 void Report (string pattern, params object [] parameters)
111 Console.WriteLine ("[check] " + pattern, parameters);
114 void CheckFields (TypeDefinition type)
116 foreach (FieldDefinition field in type.Fields) {
117 if (!IsVisibleFrom (type, field.FieldType)) {
118 Report ("Field {0} of type {1} is not visible from {2}",
119 field.Name, field.FieldType, type);
124 void CheckConstructors (TypeDefinition type)
126 CheckMethods (type, type.Constructors);
129 void CheckMethods (TypeDefinition type)
131 CheckMethods (type, type.Methods);
134 void CheckMethods (TypeDefinition type, ICollection methods)
136 foreach (MethodDefinition method in methods) {
137 if (!IsVisibleFrom (type, method.ReturnType.ReturnType)) {
138 Report ("Method return type {0} in method {1} is not visible",
139 method.ReturnType.ReturnType, method);
142 foreach (ParameterDefinition parameter in method.Parameters) {
143 if (!IsVisibleFrom (type, parameter.ParameterType)) {
144 Report ("Parameter {0} of type {1} in method {2} is not visible.",
145 parameter.Sequence, parameter.ParameterType, method);
154 void CheckBody (MethodDefinition method)
156 foreach (VariableDefinition variable in method.Body.Variables) {
157 if (!IsVisibleFrom ((TypeDefinition) method.DeclaringType, variable.VariableType)) {
158 Report ("Variable {0} of type {1} from method {2} is not visible",
159 variable.Index, variable.VariableType, method);
163 foreach (Instruction instr in method.Body.Instructions) {
164 switch (instr.OpCode.OperandType) {
165 case OperandType.InlineType:
166 case OperandType.InlineMethod:
167 case OperandType.InlineField:
168 case OperandType.InlineTok: