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")
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);
}
}
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)
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;
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 ();
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))
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))
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;
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);
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);
}
}
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);
}
}
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);
}
}
}
}
+
+ class VisibilityErrorException : Exception {
+
+ public VisibilityErrorException (string message)
+ : base (message)
+ {
+ }
+ }
}
}