Index: src/Boo.Lang.Compiler/Steps/EmitAssembly.cs =================================================================== --- src/Boo.Lang.Compiler/Steps/EmitAssembly.cs (revision 2033) +++ src/Boo.Lang.Compiler/Steps/EmitAssembly.cs (working copy) @@ -478,6 +478,11 @@ return; } + if (((IMethod)GetEntity(method)).IsPInvoke) + { + return; + } + MethodBuilder methodBuilder = GetMethodBuilder(method); if (null != method.ExplicitInfo) { @@ -1184,8 +1189,8 @@ } private void EmitLogicalNot(UnaryExpression node) - { - Expression operand = node.Operand; + { + Expression operand = node.Operand; operand.Accept(this); IType typeOnStack = PopType(); if (IsBoolOrInt(typeOnStack) || EmitToBoolIfNeeded(operand)) @@ -3730,6 +3735,11 @@ { attributes |= MethodAttributes.NewSlot; } + if (((IMethod)GetEntity(method)).IsPInvoke) + { + attributes |= MethodAttributes.PinvokeImpl; + //was already made static earlier + } attributes |= GetMethodAttributesFromTypeMember(method); return attributes; } Index: src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs =================================================================== --- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs (revision 2033) +++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs (working copy) @@ -749,9 +749,14 @@ Visit(method.ReturnType); Visit(method.ReturnTypeAttributes); - if (method.IsRuntime) + bool ispinvoke = ((IMethod)GetEntity(method)).IsPInvoke; + if (method.IsRuntime || ispinvoke) { CheckRuntimeMethod(method); + if (ispinvoke) + { + method.Modifiers |= TypeMemberModifiers.Static; + } } else { @@ -5607,14 +5612,14 @@ } return _EnumeratorItemType_Constructor; } - } - - public bool OptimizeNullComparisons - { - get { return _optimizeNullComparisons; } - set { _optimizeNullComparisons = value; } - } - + } + + public bool OptimizeNullComparisons + { + get { return _optimizeNullComparisons; } + set { _optimizeNullComparisons = value; } + } + #endregion } } Index: src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs (revision 2033) +++ src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs (working copy) @@ -47,6 +47,8 @@ int _isExtension = -1; + int _isPInvoke = -1; + internal ExternalMethod(TypeSystemServices manager, MethodBase mi) { _typeSystemServices = manager; @@ -82,6 +84,20 @@ } } + public bool IsPInvoke + { + get + { + if (-1 == _isPInvoke) + { + _isPInvoke = MetadataUtil.IsAttributeDefined(_mi, Types.DllImportAttribute) + ? 1 + : 0; + } + return 1 == _isPInvoke; + } + } + public IType DeclaringType { get Index: src/Boo.Lang.Compiler/TypeSystem/IEntity.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/IEntity.cs (revision 2033) +++ src/Boo.Lang.Compiler/TypeSystem/IEntity.cs (working copy) @@ -294,10 +294,15 @@ get; } - bool IsExtension - { - get; + bool IsExtension + { + get; } + + bool IsPInvoke + { + get; + } } public interface IConstructor : IMethodBase Index: src/Boo.Lang.Compiler/TypeSystem/InternalMethod.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/InternalMethod.cs (revision 2033) +++ src/Boo.Lang.Compiler/TypeSystem/InternalMethod.cs (working copy) @@ -56,7 +56,7 @@ protected List _labelReferences; protected List _labels; - + internal InternalMethod(TypeSystemServices typeSystemServices, Method method) { _typeSystemServices = typeSystemServices; @@ -93,6 +93,26 @@ } } + public bool IsPInvoke + { + get + { + IType dllimporttype = _typeSystemServices.Map(Types.DllImportAttribute); + foreach (Boo.Lang.Compiler.Ast.Attribute att in _method.Attributes) + { + IConstructor constructor = TypeSystemServices.GetEntity(att) as IConstructor; + if (null != constructor) + { + if (constructor.DeclaringType == dllimporttype) + { + return true; + } + } + } + return false; + } + } + public IType DeclaringType { get Index: src/Boo.Lang.Compiler/TypeSystem/Types.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/Types.cs (revision 2033) +++ src/Boo.Lang.Compiler/TypeSystem/Types.cs (working copy) @@ -24,14 +24,14 @@ // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - +#endregion + namespace Boo.Lang.Compiler.TypeSystem { - using System; - using System.Collections; - using System.Text.RegularExpressions; - using Boo.Lang.Runtime; + using System; + using System.Collections; + using System.Text.RegularExpressions; + using Boo.Lang.Runtime; public class Types { @@ -116,6 +116,8 @@ public static readonly Type DuckTypedAttribute = typeof(Boo.Lang.DuckTypedAttribute); public static readonly Type ExtensionAttribute = typeof(Boo.Lang.ExtensionAttribute); + + public static readonly Type DllImportAttribute = typeof(System.Runtime.InteropServices.DllImportAttribute); public static readonly Type ModuleAttribute = typeof(Boo.Lang.ModuleAttribute); Index: src/Boo.Lang/Resources/strings.txt =================================================================== --- src/Boo.Lang/Resources/strings.txt (revision 2033) +++ src/Boo.Lang/Resources/strings.txt (working copy) @@ -75,7 +75,7 @@ BCE0073=Abstract method '{0}' cannot have a body. BCE0074='self' cannot be used outside a method. BCE0075='{0}' is a namespace. Namespaces cannot be used as expressions. -BCE0076=Runtime methods must have an empty body. +BCE0076=Runtime and PInvoke methods must have an empty body. BCE0077=It is not possible to invoke an expression of type '{0}'. BCE0078=A method reference was expected. BCE0079=__addressof__ builtin function can only be used in delegate constructors.