[Mono-list] testing mcs (specifically: compiling protected internal methods)

Miguel de Icaza miguel@ximian.com
27 Mar 2002 19:25:44 -0500


> Today, I found something strange in the way protected internal methods
> are compiled and/or disassembled. This might be some combination of bugs
> (in mcs and monodis), so I'm not quite sure where to document this.

Thanks for finding this error, there were a couple of miss-placed if
statements in the computation of flags.

> B) Compile this to a dll using mcs under Linux, subsequently trying 
> to disassemble this using monodis results in an error message:

I will let Paolo answer this one.  

> D) It is probably not my discovery that mcs does not check
> accessibility. Is this what is meant with bug #21147 ("mcs should check
> accessibility if methods, fields, etc.")? The description of this bug
> seems rather specific, while this feature seems to be missing in
> general.

What you discovered was a bug in the logic that computes the
MethodAttributes.  Checking accessibility in MCS is the inverse process:
make sure that given the current scope we have permission to
access/export a type.

> E) Do we have any strategy for turning small compiler test cases like
> this into reusable regression tests? 

I have written a small test for all the flags (we should be fine now),
this is test-91.  Notice that this uses reflection to "inspect" itself,
kind of like checking yourself in the mirror before you go out:

http://construct.ximian.com/~miguel/gallery/ben-and-amy/aar

using System;
using System.Reflection;

class Test {

	static protected internal void MyProtectedInternal () { }
	static internal void MyInternal() { }
	static public void MyPublic () { }
	static void MyPrivate () {}
	      
	static int Main ()
	{
		Type myself = typeof (Test);
		BindingFlags bf = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
		MethodAttributes mpia;
		MethodInfo mpi;

		//
		// protected internal
		//
		mpi = myself.GetMethod ("MyProtectedInternal", bf);
		mpia = mpi.Attributes & MethodAttributes.MemberAccessMask;
		if (mpia != MethodAttributes.FamORAssem)
			return 1;

		//
		// internal
		//
		mpi = myself.GetMethod ("MyInternal", bf);
		mpia = mpi.Attributes & MethodAttributes.MemberAccessMask;
		if (mpia != MethodAttributes.Assembly)
			return 2;

		//
		// public
		//
		mpi = myself.GetMethod ("MyPublic", bf);
		mpia = mpi.Attributes & MethodAttributes.MemberAccessMask;
		if (mpia != MethodAttributes.Public)
			return 3;

		//
		// private
		//
		mpi = myself.GetMethod ("MyPrivate", bf);
		mpia = mpi.Attributes & MethodAttributes.MemberAccessMask;
		if (mpia != MethodAttributes.Private)
			return 4;

		Console.WriteLine ("All tests pass");
		return 0;
	}
}