2009-04-22 Jb Evain <jbevain@novell.com>
authorJb Evain <jbevain@gmail.com>
Wed, 22 Apr 2009 16:45:12 +0000 (16:45 -0000)
committerJb Evain <jbevain@gmail.com>
Wed, 22 Apr 2009 16:45:12 +0000 (16:45 -0000)
* Mono.Tuner/CheckVisibility.cs: take InternalsVisibleTo into account.

svn path=/trunk/mcs/; revision=132376

mcs/tools/tuner/ChangeLog
mcs/tools/tuner/Mono.Tuner/CheckVisibility.cs

index cd03ab42757e1c93afe49215a63e482e42cf8ff3..3a9f4191b30b504903c2f865683458f91ad5a668 100644 (file)
@@ -1,3 +1,7 @@
+2009-04-22  Jb Evain  <jbevain@novell.com>
+
+       * Mono.Tuner/CheckVisibility.cs: take InternalsVisibleTo into account.
+
 2009-04-22  Jb Evain  <jbevain@novell.com>
 
        * Mono.Tuner/CheckVisibility.cs: take FamAndAssem into account.
index 757be40b1491f299e791bf23fe7b692ee37b30d1..163086185cce82d7d03dc4806f18db579e2ce7a8 100644 (file)
@@ -28,6 +28,7 @@
 
 using System;
 using System.Collections;
+using System.Text;
 
 using Mono.Linker;
 using Mono.Linker.Steps;
@@ -83,9 +84,61 @@ namespace Mono.Tuner {
                        return (type.DeclaringType == null && type.IsPublic) || type.IsNestedPublic;
                }
 
-               static bool AreInDifferentAssemblies (TypeDefinition lhs, TypeDefinition rhs)
+               static bool AreInDifferentAssemblies (TypeDefinition type, TypeDefinition target)
                {
-                       return lhs.Module.Assembly.Name.FullName != rhs.Module.Assembly.Name.FullName;
+                       if (type.Module.Assembly.Name.FullName != target.Module.Assembly.Name.FullName)
+                               return !IsInternalVisibleTo (target.Module.Assembly, type.Module.Assembly);
+
+                       return false;
+               }
+
+               static bool IsInternalVisibleTo (AssemblyDefinition assembly, AssemblyDefinition candidate)
+               {
+                       foreach (CustomAttribute attribute in assembly.CustomAttributes) {
+                               if (!IsInternalsVisibleToAttribute (attribute))
+                                       continue;
+
+                               if (attribute.ConstructorParameters.Count == 0)
+                                       continue;
+
+                               string signature = (string) attribute.ConstructorParameters [0];
+
+                               if (InternalsVisibleToSignatureMatch (signature, candidate.Name))
+                                       return true;
+                       }
+
+                       return false;
+               }
+
+               static bool InternalsVisibleToSignatureMatch (string signature, AssemblyNameReference reference)
+               {
+                       int pos = signature.IndexOf (",");
+                       if (pos == -1)
+                               return signature == reference.Name;
+
+                       string assembly_name = signature.Substring (0, pos);
+
+                       pos = signature.IndexOf ("=");
+                       if (pos == -1)
+                               throw new ArgumentException ();
+
+                       string public_key = signature.Substring (pos + 1).ToLower ();
+
+                       return assembly_name == reference.Name && public_key == ToPublicKeyString (reference.PublicKey);
+               }
+
+               static string ToPublicKeyString (byte [] public_key)
+               {
+                       StringBuilder signature = new StringBuilder (public_key.Length);
+                       for (int i = 0; i < public_key.Length; i++)
+                               signature.Append (public_key [i].ToString ("x2"));
+
+                       return signature.ToString ();
+               }
+
+               static bool IsInternalsVisibleToAttribute (CustomAttribute attribute)
+               {
+                       return attribute.Constructor.DeclaringType.FullName == "System.Runtime.CompilerServices.InternalsVisibleToAttribute";
                }
 
                bool IsVisibleFrom (TypeDefinition type, TypeReference reference)