Index: src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/ExternalMethod.cs (working copy) @@ -70,7 +70,12 @@ { if (-1 == _isExtension) { - _isExtension = IsStatic && MetadataUtil.IsAttributeDefined(_memberInfo, Types.ExtensionAttribute) + bool defined = MetadataUtil.IsAttributeDefined(_memberInfo, Types.BooExtensionAttribute); + if( defined == false && Types.ClrExtensionAttribute != null ) + { + defined = MetadataUtil.IsAttributeDefined(_memberInfo, Types.ClrExtensionAttribute); + } + _isExtension = IsStatic && defined ? 1 : 0; } Index: src/Boo.Lang.Compiler/TypeSystem/AnonymousCallablesManager.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/AnonymousCallablesManager.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/AnonymousCallablesManager.cs (working copy) @@ -143,7 +143,8 @@ Method extension = CodeBuilder.CreateMethod("BeginInvoke", TypeSystemServices.Map(typeof(IAsyncResult)), TypeMemberModifiers.Public | TypeMemberModifiers.Static); - extension.Attributes.Add(CodeBuilder.CreateAttribute(Types.ExtensionAttribute)); + extension.Attributes.Add(CodeBuilder.CreateAttribute(Types.BooExtensionAttribute)); + extension.Attributes.Add(CodeBuilder.CreateAttribute(Types.ClrExtensionAttribute)); ParameterDeclaration self = CodeBuilder.CreateParameterDeclaration(0, "self", beginInvokeEntity.DeclaringType); Index: src/Boo.Lang.Compiler/TypeSystem/ExternalProperty.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/ExternalProperty.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/ExternalProperty.cs (working copy) @@ -53,7 +53,7 @@ { if (-1 == _isExtension) { - _isExtension = IsStatic && MetadataUtil.IsAttributeDefined(_memberInfo, Types.ExtensionAttribute) + _isExtension = IsStatic && MetadataUtil.IsAttributeDefined(_memberInfo, Types.BooExtensionAttribute) ? 1 : 0; } Index: src/Boo.Lang.Compiler/TypeSystem/MetadataUtil.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/MetadataUtil.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/MetadataUtil.cs (working copy) @@ -30,6 +30,7 @@ using System; using System.Reflection; using Boo.Lang.Compiler.Ast; +using Boo.Lang.Compiler.Util; namespace Boo.Lang.Compiler.TypeSystem { @@ -54,6 +55,21 @@ return false; } + public static MemberInfo[] GetClrExtensions(Type type, string memberName) + { + if (type == null || + Types.ClrExtensionAttribute == null || + !IsAttributeDefined(type, Types.ClrExtensionAttribute) ) + return new MemberInfo[0]; + + return type.FindMembers(MemberTypes.Method, BindingFlags.Public | BindingFlags.Static, ClrExtensionFilter, memberName); + } + + private static bool ClrExtensionFilter(MemberInfo member, object memberName) + { + return TypeUtilities.TypeName(member.Name).Equals(memberName) && IsAttributeDefined(member, Types.ClrExtensionAttribute); + } + public static bool IsAttributeDefined(MemberInfo member, Type attributeType) { return System.Attribute.IsDefined(member, attributeType); Index: src/Boo.Lang.Compiler/TypeSystem/NamespaceEntity.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/NamespaceEntity.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/NamespaceEntity.cs (working copy) @@ -216,6 +216,18 @@ // Can't return right away, since we can have several types // with the same name but different number of generic arguments. } + else + { + MemberInfo[] members = MetadataUtil.GetClrExtensions(type, name); + if (members.Length > 0) + { + foreach(MethodInfo method in members) + { + targetList.Add(_typeSystemServices.Map(method)); + } + found = true; + } + } } return found; } Index: src/Boo.Lang.Compiler/TypeSystem/InternalMethod.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/InternalMethod.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/InternalMethod.cs (working copy) @@ -69,7 +69,12 @@ { get { - return IsAttributeDefined(Types.ExtensionAttribute); + bool defined = IsAttributeDefined(Types.BooExtensionAttribute); + if( defined == false && Types.ClrExtensionAttribute != null ) + { + defined = IsAttributeDefined(Types.ClrExtensionAttribute); + } + return defined; } } Index: src/Boo.Lang.Compiler/TypeSystem/InternalProperty.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/InternalProperty.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/InternalProperty.cs (working copy) @@ -50,7 +50,7 @@ { get { - return MetadataUtil.IsAttributeDefined(_property, _typeSystemServices.Map(Types.ExtensionAttribute)); + return MetadataUtil.IsAttributeDefined(_property, _typeSystemServices.Map(Types.BooExtensionAttribute)); } } Index: src/Boo.Lang.Compiler/TypeSystem/Types.cs =================================================================== --- src/Boo.Lang.Compiler/TypeSystem/Types.cs (revision 2804) +++ src/Boo.Lang.Compiler/TypeSystem/Types.cs (working copy) @@ -117,7 +117,9 @@ public static readonly Type DuckTypedAttribute = typeof(Boo.Lang.DuckTypedAttribute); - public static readonly Type ExtensionAttribute = typeof(Boo.Lang.ExtensionAttribute); + public static readonly Type BooExtensionAttribute = typeof(Boo.Lang.ExtensionAttribute); + + public static readonly Type ClrExtensionAttribute = Type.GetType("System.Runtime.CompilerServices.ExtensionAttribute, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); public static readonly Type DllImportAttribute = typeof(System.Runtime.InteropServices.DllImportAttribute); Index: src/Boo.Lang.Compiler/Util/TypeUtilities.cs =================================================================== --- src/Boo.Lang.Compiler/Util/TypeUtilities.cs (revision 2804) +++ src/Boo.Lang.Compiler/Util/TypeUtilities.cs (working copy) @@ -56,11 +56,15 @@ public static string TypeName(Type type) { - if (!type.IsGenericTypeDefinition) return type.Name; - string name = type.Name; - int index = name.LastIndexOf('`'); - if (index < 0) return name; - return name.Substring(0, index); + if (!type.IsGenericTypeDefinition) return type.Name; + return TypeName(type.Name); } + + public static string TypeName(string typeName) + { + int index = typeName.LastIndexOf('`'); + if (index < 0) return typeName; + return typeName.Substring(0, index); + } } } Index: tests/testcases/integration/clrextensions/ClrExtension.dll =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: tests\testcases\integration\clrextensions\ClrExtension.dll ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: tests/testcases/integration/clrextensions/clrextensions-1.boo =================================================================== --- tests/testcases/integration/clrextensions/clrextensions-1.boo (revision 0) +++ tests/testcases/integration/clrextensions/clrextensions-1.boo (revision 0) @@ -0,0 +1,9 @@ +""" +drawrof +""" +import ClrExtension + +forward = "forward" +reverse = forward.Reverse() + +print reverse \ No newline at end of file Index: tests/BooCompiler.Tests/ClrExtensionsIntegrationTestFixture.cs =================================================================== --- tests/BooCompiler.Tests/ClrExtensionsIntegrationTestFixture.cs (revision 0) +++ tests/BooCompiler.Tests/ClrExtensionsIntegrationTestFixture.cs (revision 0) @@ -0,0 +1,33 @@ +namespace BooCompiler.Tests +{ + using NUnit.Framework; + + [TestFixture] + public class ClrExtensionsIntegrationTestFixture : AbstractCompilerTestCase + { + override protected void RunCompilerTestCase(string name) + { + System.ResolveEventHandler resolver = InstallAssemblyResolver(BaseTestCasesPath); + try + { + base.RunCompilerTestCase(name); + } + finally + { + RemoveAssemblyResolver(resolver); + } + } + + [Test] + public void clrextensions_1() + { + RunCompilerTestCase(@"clrextensions-1.boo"); + } + + + override protected string GetRelativeTestCasesPath() + { + return "integration/clrextensions"; + } + } +} Index: tests/BooCompiler.Tests/BooCompiler.Tests-VS2005.csproj =================================================================== --- tests/BooCompiler.Tests/BooCompiler.Tests-VS2005.csproj (revision 2804) +++ tests/BooCompiler.Tests/BooCompiler.Tests-VS2005.csproj (working copy) @@ -1,4 +1,4 @@ - + Debug AnyCPU @@ -69,12 +69,12 @@ - +