[w32handle] Stop returning 0 in every cases for locking/unlocking (#3926)
[mono.git] / mcs / tools / tuner / Mono.Tuner / CheckVisibility.cs
index 163086185cce82d7d03dc4806f18db579e2ce7a8..df553db5abe7470398c3518866735a875abd8bc3 100644 (file)
@@ -40,6 +40,22 @@ namespace Mono.Tuner {
 
        public class CheckVisibility : BaseStep {
 
+               bool throw_on_error;
+
+               protected override void Process ()
+               {
+                       throw_on_error = GetThrowOnVisibilityErrorParameter ();
+               }
+
+               bool GetThrowOnVisibilityErrorParameter ()
+               {
+                       try {
+                               return bool.Parse (Context.GetParameter ("throw_on_visibility_error"));
+                       } catch {
+                               return false;
+                       }
+               }
+
                protected override void ProcessAssembly (AssemblyDefinition assembly)
                {
                        if (assembly.Name.Name == "mscorlib" || assembly.Name.Name == "smcs")
@@ -58,22 +74,21 @@ namespace Mono.Tuner {
                void CheckType (TypeDefinition type)
                {
                        if (!IsVisibleFrom (type, type.BaseType)) {
-                               Report ("Base type `{0}` of type `{1}` is not visible",
+                               ReportError ("Base type `{0}` of type `{1}` is not visible",
                                        type.BaseType, type);
                        }
 
                        CheckInterfaces (type);
 
                        CheckFields (type);
-                       CheckConstructors (type);
                        CheckMethods (type);
                }
 
                void CheckInterfaces (TypeDefinition type)
                {
-                       foreach (TypeReference iface in type.Interfaces) {
-                               if (!IsVisibleFrom (type, iface)) {
-                                       Report ("Interface `{0}` implemented by `{1}` is not visible",
+                       foreach (var iface in type.Interfaces) {
+                               if (!IsVisibleFrom (type, iface.InterfaceType)) {
+                                       ReportError ("Interface `{0}` implemented by `{1}` is not visible",
                                                iface, type);
                                }
                        }
@@ -86,10 +101,10 @@ namespace Mono.Tuner {
 
                static bool AreInDifferentAssemblies (TypeDefinition type, TypeDefinition target)
                {
-                       if (type.Module.Assembly.Name.FullName != target.Module.Assembly.Name.FullName)
-                               return !IsInternalVisibleTo (target.Module.Assembly, type.Module.Assembly);
+                       if (type.Module.Assembly.Name.FullName == target.Module.Assembly.Name.FullName)
+                               return false;
 
-                       return false;
+                       return !IsInternalVisibleTo (target.Module.Assembly, type.Module.Assembly);
                }
 
                static bool IsInternalVisibleTo (AssemblyDefinition assembly, AssemblyDefinition candidate)
@@ -98,10 +113,10 @@ namespace Mono.Tuner {
                                if (!IsInternalsVisibleToAttribute (attribute))
                                        continue;
 
-                               if (attribute.ConstructorParameters.Count == 0)
+                               if (attribute.ConstructorArguments.Count == 0)
                                        continue;
 
-                               string signature = (string) attribute.ConstructorParameters [0];
+                               string signature = (string) attribute.ConstructorArguments [0].Value;
 
                                if (InternalsVisibleToSignatureMatch (signature, candidate.Name))
                                        return true;
@@ -146,7 +161,7 @@ namespace Mono.Tuner {
                        if (reference == null)
                                return true;
 
-                       if (reference is GenericParameter || reference.GetOriginalType () is GenericParameter)
+                       if (reference is GenericParameter || reference.GetElementType () is GenericParameter)
                                return true;
 
                        TypeDefinition other = reference.Resolve ();
@@ -178,7 +193,7 @@ namespace Mono.Tuner {
                        if (meth.IsPublic)
                                return true;
 
-                       if (type == dec || type.DeclaringType == dec)
+                       if (type == dec || IsNestedIn (type, dec))
                                return true;
 
                        if (meth.IsFamily && InHierarchy (type, dec))
@@ -212,7 +227,7 @@ namespace Mono.Tuner {
                        if (field.IsPublic)
                                return true;
 
-                       if (type == dec || type.DeclaringType == dec)
+                       if (type == dec || IsNestedIn (type, dec))
                                return true;
 
                        if (field.IsFamily && InHierarchy (type, dec))
@@ -230,7 +245,23 @@ namespace Mono.Tuner {
                        return false;
                }
 
-               bool InHierarchy (TypeDefinition type, TypeDefinition other)
+               static bool IsNestedIn (TypeDefinition type, TypeDefinition other)
+               {
+                       TypeDefinition declaring = type.DeclaringType;
+
+                       if (declaring == null)
+                               return false;
+
+                       if (declaring == other)
+                               return true;
+
+                       if (declaring.DeclaringType == null)
+                               return false;
+
+                       return IsNestedIn (declaring, other);
+               }
+
+               static bool InHierarchy (TypeDefinition type, TypeDefinition other)
                {
                        if (type.BaseType == null)
                                return false;
@@ -248,21 +279,24 @@ namespace Mono.Tuner {
                        Console.WriteLine ("[check] " + pattern, parameters);
                }
 
+               void ReportError (string pattern, params object [] parameters)
+               {
+                       Report (pattern, parameters);
+
+                       if (throw_on_error)
+                               throw new VisibilityErrorException (string.Format (pattern, parameters));
+               }
+
                void CheckFields (TypeDefinition type)
                {
                        foreach (FieldDefinition field in type.Fields) {
                                if (!IsVisibleFrom (type, field.FieldType)) {
-                                       Report ("Field `{0}` of type `{1}` is not visible from `{2}`",
+                                       ReportError ("Field `{0}` of type `{1}` is not visible from `{2}`",
                                                field.Name, field.FieldType, type);
                                }
                        }
                }
 
-               void CheckConstructors (TypeDefinition type)
-               {
-                       CheckMethods (type, type.Constructors);
-               }
-
                void CheckMethods (TypeDefinition type)
                {
                        CheckMethods (type, type.Methods);
@@ -271,15 +305,15 @@ namespace Mono.Tuner {
                void CheckMethods (TypeDefinition type, ICollection methods)
                {
                        foreach (MethodDefinition method in methods) {
-                               if (!IsVisibleFrom (type, method.ReturnType.ReturnType)) {
-                                       Report ("Method return type `{0}` in method `{1}` is not visible",
-                                               method.ReturnType.ReturnType, method);
+                               if (!IsVisibleFrom (type, method.ReturnType)) {
+                                       ReportError ("Method return type `{0}` in method `{1}` is not visible",
+                                               method.ReturnType, method);
                                }
 
                                foreach (ParameterDefinition parameter in method.Parameters) {
                                        if (!IsVisibleFrom (type, parameter.ParameterType)) {
-                                               Report ("Parameter `{0}` of type `{1}` in method `{2}` is not visible.",
-                                                       parameter.Sequence, parameter.ParameterType, method);
+                                               ReportError ("Parameter `{0}` of type `{1}` in method `{2}` is not visible.",
+                                                       parameter.Index, parameter.ParameterType, method);
                                        }
                                }
 
@@ -294,7 +328,7 @@ namespace Mono.Tuner {
 
                        foreach (VariableDefinition variable in method.Body.Variables) {
                                if (!IsVisibleFrom ((TypeDefinition) method.DeclaringType, variable.VariableType)) {
-                                       Report ("Variable `{0}` of type `{1}` from method `{2}` is not visible",
+                                       ReportError ("Variable `{0}` of type `{1}` from method `{2}` is not visible",
                                                variable.Index, variable.VariableType, method);
                                }
                        }
@@ -319,7 +353,7 @@ namespace Mono.Tuner {
                                                error = !IsVisibleFrom (type, field_ref);
 
                                        if (error) {
-                                               Report ("Operand `{0}` of type {1} at offset 0x{2} in method `{3}` is not visible",
+                                               ReportError ("Operand `{0}` of type {1} at offset 0x{2} in method `{3}` is not visible",
                                                        instr.Operand, instr.OpCode.OperandType, instr.Offset.ToString ("x4"), method);
                                        }
 
@@ -329,5 +363,13 @@ namespace Mono.Tuner {
                                }
                        }
                }
+
+               class VisibilityErrorException : Exception {
+
+                       public VisibilityErrorException (string message)
+                               : base (message)
+                       {
+                       }
+               }
        }
 }