Index: src/Boo.Lang.Compiler/Steps/MergePartialClasses.cs =================================================================== --- src/Boo.Lang.Compiler/Steps/MergePartialClasses.cs (revision 0) +++ src/Boo.Lang.Compiler/Steps/MergePartialClasses.cs (revision 0) @@ -0,0 +1,119 @@ +#region license +// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org) +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Rodrigo B. de Oliveira nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// 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 + +namespace Boo.Lang.Compiler.Steps +{ + using System; + using System.Collections; + using Boo.Lang.Compiler; + using Boo.Lang.Compiler.Ast; + using Boo.Lang.Compiler.TypeSystem; + using Attribute=Boo.Lang.Compiler.Ast.Attribute; + + public class MergePartialClasses : AbstractNamespaceSensitiveTransformerCompilerStep + { + Hashtable _partials = new Hashtable(); + ClassDefinition _current = null; + + override public void Run() + { + Visit(CompileUnit.Modules); + } + + override public bool EnterClassDefinition(ClassDefinition node) + { + if (_partials.Contains(node.FullName)) + { + _current = (ClassDefinition)_partials[node.FullName]; + RemoveCurrentNode(); + return true; + } + else + { + _partials[node.FullName] = node; + return false; + } + } + + override public void LeaveClassDefinition(ClassDefinition node) + { + _current = null; + } + + override public void OnAttribute(Attribute node) + { + if (_current != null) + { + //attributes for the merged class contain any and all attributes declared on each partial definition + _current.Attributes.Add(node); + } + } + + private void AddMember(TypeMember member) + { + if (_current != null) + { + _current.Members.Add(member); + } + } + + override public void OnStructDefinition(StructDefinition node) { AddMember(node); } + override public void OnInterfaceDefinition(InterfaceDefinition node) { AddMember(node); } + override public void OnEnumDefinition(EnumDefinition node) { AddMember(node); } + override public void OnField(Field node) { AddMember(node); } + override public void OnProperty(Property node) { AddMember(node); } + override public void OnEvent(Event node) { AddMember(node); } + override public void OnMethod(Method node) { AddMember(node); } + override public void OnConstructor(Constructor node) { AddMember(node); } + + + /* the simple type references that happen while visiting a + * class defintion are its base class and implemented interfaces + * */ + override public void OnSimpleTypeReference(SimpleTypeReference node) + { + if (_current != null && !IsAlreadyAdded(_current.BaseTypes, node)) + { + _current.BaseTypes.Add(node); + } + } + + private bool IsAlreadyAdded(TypeReferenceCollection col, SimpleTypeReference node) + { + foreach (SimpleTypeReference refer in col) + { + if (node.Name == refer.Name) + { + return true; + } + } + + return false; + } + } +} Index: src/Boo.Lang.Compiler/Pipelines/ResolveExpressions.cs =================================================================== --- src/Boo.Lang.Compiler/Pipelines/ResolveExpressions.cs (revision 1897) +++ src/Boo.Lang.Compiler/Pipelines/ResolveExpressions.cs (working copy) @@ -36,6 +36,7 @@ { Add(new InitializeTypeSystemServices()); Add(new PreErrorChecking()); + Add(new MergePartialClasses()); Add(new InitializeNameResolutionService()); Add(new IntroduceGlobalNamespaces()); Add(new TransformCallableDefinitions()); @@ -59,5 +60,5 @@ Add(new ExpandAstLiterals()); Add(new ProcessMethodBodiesWithDuckTyping()); } - } + } } Index: tests/testcases/integration/partial-1.boo =================================================================== --- tests/testcases/integration/partial-1.boo (revision 0) +++ tests/testcases/integration/partial-1.boo (revision 0) @@ -0,0 +1,44 @@ +""" +method1 +field1 +property1 +property2 +inheritedmethod +method1 +""" + +interface ITest: + def method1() + +class BaseClass: + def inheritedmethod(): + print "inheritedmethod" + +class C: + def method1(): + print "method1" + + Property1: + get: + return "property1" + +//this can be in a separate file +class C(BaseClass, ITest): + public fld1 = "field1" + + def method2(): + print "method2" + + Property2: + get: + return "property2" + +c = C() +c.method1() +print c.fld1 +print c.Property1 +print c.Property2 +c.inheritedmethod() +test = c as ITest +test.method1() +