Index: src/Boo.Lang/Resources/pt/strings.txt =================================================================== --- src/Boo.Lang/Resources/pt/strings.txt (revision 1895) +++ src/Boo.Lang/Resources/pt/strings.txt (working copy) @@ -126,6 +126,7 @@ BCE0125=Invalid declaration type '{0}'. BCE0126=It is not possible to evaluate an expression of type '{0}'. BCE0127=A ref or out argument must be an lvalue: '{0}' +BCE0128='partial' can only be applied to class definitions. ;Compiler warnings BCW0001=AVISO: O tipo '{0}' não possui uma implementação para '{1}' e será marcado como abstrato. Index: src/Boo.Lang/Resources/strings.txt =================================================================== --- src/Boo.Lang/Resources/strings.txt (revision 1895) +++ src/Boo.Lang/Resources/strings.txt (working copy) @@ -126,6 +126,7 @@ BCE0125=Invalid declaration type '{0}'. BCE0126=It is not possible to evaluate an expression of type '{0}'. BCE0127=A ref or out argument must be an lvalue: '{0}' +BCE0128='partial' can only be applied to class definitions. ;Compiler warnings BCW0001=WARNING: Type '{0}' does not provide an implementation for '{1}' and will be marked abstract Index: src/Boo.Lang/Resources/it/strings.txt =================================================================== --- src/Boo.Lang/Resources/it/strings.txt (revision 1895) +++ src/Boo.Lang/Resources/it/strings.txt (working copy) @@ -126,6 +126,7 @@ BCE0125=Invalid declaration type '{0}'. BCE0126=It is not possible to evaluate an expression of type '{0}'. BCE0127=A ref or out argument must be an lvalue: '{0}' +BCE0128='partial' can only be applied to class definitions. ;Compiler warnings BCW0001=WARNING: Il tipo '{0}' non fornisce una implementazione per '{1}' e' verra' marcato come abstract Index: src/Boo.Lang.Compiler/Ast/TypeMember.cs =================================================================== --- src/Boo.Lang.Compiler/Ast/TypeMember.cs (revision 1895) +++ src/Boo.Lang.Compiler/Ast/TypeMember.cs (working copy) @@ -191,6 +191,14 @@ } } + public bool IsPartial + { + get + { + return IsModifierSet(TypeMemberModifiers.Partial); + } + } + public bool IsModifierSet(TypeMemberModifiers modifiers) { return modifiers == (_modifiers & modifiers); 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,124 @@ +#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 (!node.IsPartial) + { + return false; + } + + 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/Steps/PreErrorChecking.cs =================================================================== --- src/Boo.Lang.Compiler/Steps/PreErrorChecking.cs (revision 1895) +++ src/Boo.Lang.Compiler/Steps/PreErrorChecking.cs (working copy) @@ -50,12 +50,14 @@ { CheckMemberName(node); CantBeMarkedAbstract(node); + CantBeMarkedPartial(node); } override public void LeaveProperty(Property node) { CheckMemberName(node); CantBeMarkedTransient(node); + CantBeMarkedPartial(node); CheckExplicitImpl(node); } @@ -63,12 +65,14 @@ { CheckMemberName(node); CantBeMarkedTransient(node); + CantBeMarkedPartial(node); CheckExplicitImpl(node); } override public void LeaveEvent(Event node) { CheckMemberName(node); + CantBeMarkedPartial(node); } override public void LeaveInterfaceDefinition(InterfaceDefinition node) @@ -76,6 +80,7 @@ CheckMemberName(node); CantBeMarkedAbstract(node); CantBeMarkedTransient(node); + CantBeMarkedPartial(node); } override public void LeaveCallableDefinition(CallableDefinition node) @@ -83,6 +88,7 @@ CheckMemberName(node); CantBeMarkedAbstract(node); CantBeMarkedTransient(node); + CantBeMarkedPartial(node); } override public void LeaveClassDefinition(ClassDefinition node) @@ -177,5 +183,13 @@ node.Name)); } } + + void CantBeMarkedPartial(TypeMember member) + { + if (member.IsPartial) + { + Error(CompilerErrorFactory.CantBeMarkedPartial(member)); + } + } } } Index: src/Boo.Lang.Compiler/CompilerErrorFactory.cs =================================================================== --- src/Boo.Lang.Compiler/CompilerErrorFactory.cs (revision 1895) +++ src/Boo.Lang.Compiler/CompilerErrorFactory.cs (working copy) @@ -671,6 +671,11 @@ return new CompilerError("BCE0127", node.LexicalInfo, node.ToString()); } + public static CompilerError CantBeMarkedPartial(Node node) + { + return new CompilerError("BCE0128", node.LexicalInfo); + } + public static string ToStringList(System.Collections.IEnumerable names) { StringBuilder builder = new StringBuilder(); Index: src/Boo.Lang.Compiler/Pipelines/ResolveExpressions.cs =================================================================== --- src/Boo.Lang.Compiler/Pipelines/ResolveExpressions.cs (revision 1895) +++ 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: src/Boo.Lang.Parser/boo.g =================================================================== --- src/Boo.Lang.Parser/boo.g (revision 1895) +++ src/Boo.Lang.Parser/boo.g (working copy) @@ -94,6 +94,7 @@ OVERRIDE="override"; PASS="pass"; NAMESPACE="namespace"; + PARTIAL="partial"; PUBLIC="public"; PROTECTED="protected"; PRIVATE="private"; @@ -895,7 +896,8 @@ TRANSIENT { _modifiers |= TypeMemberModifiers.Transient; } | OVERRIDE { _modifiers |= TypeMemberModifiers.Override; } | ABSTRACT { _modifiers |= TypeMemberModifiers.Abstract; } | - VIRTUAL { _modifiers |= TypeMemberModifiers.Virtual; } + VIRTUAL { _modifiers |= TypeMemberModifiers.Virtual; } | + PARTIAL { _modifiers |= TypeMemberModifiers.Partial; } )* ; 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" + +partial class C: + def method1(): + print "method1" + + Property1: + get: + return "property1" + +//this can be in a separate file +partial 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() + Index: tests/testcases/errors/BCE0128-1.boo =================================================================== --- tests/testcases/errors/BCE0128-1.boo (revision 0) +++ tests/testcases/errors/BCE0128-1.boo (revision 0) @@ -0,0 +1,15 @@ +""" +BCE0128-1.boo(7,13): BCE0128: 'partial' can only be applied to class definitions. +BCE0128-1.boo(9,13): BCE0128: 'partial' can only be applied to class definitions. +BCE0128-1.boo(13,17): BCE0128: 'partial' can only be applied to class definitions. +""" +class Foo: + partial fld1 as int + + partial Property1: + get: + return 3 + + partial def Method1(): + pass + Index: ast.model.boo =================================================================== --- ast.model.boo (revision 1895) +++ ast.model.boo (working copy) @@ -21,6 +21,7 @@ Virtual = 128 Override = 256 Abstract = 512 + Partial = 1024 VisibilityMask = 15 enum MethodImplementationFlags: Index: extras/boo-jedit41.xml =================================================================== --- extras/boo-jedit41.xml (revision 1895) +++ extras/boo-jedit41.xml (working copy) @@ -129,6 +129,7 @@ is isa mixin + partial namespace not or Index: extras/boo-jedit42.xml =================================================================== --- extras/boo-jedit42.xml (revision 1895) +++ extras/boo-jedit42.xml (working copy) @@ -140,6 +140,7 @@ or otherwise override + partial pass raise retry Index: extras/SharpDevelop/BooBinding/Boo.xshd =================================================================== --- extras/SharpDevelop/BooBinding/Boo.xshd (revision 1895) +++ extras/SharpDevelop/BooBinding/Boo.xshd (working copy) @@ -188,6 +188,7 @@ + Index: extras/boo.lang =================================================================== --- extras/boo.lang (revision 1895) +++ extras/boo.lang (working copy) @@ -109,6 +109,7 @@ private public internal + partial class struct Index: extras/boo.vim =================================================================== --- extras/boo.vim (revision 1895) +++ extras/boo.vim (working copy) @@ -42,7 +42,7 @@ syn keyword booStatement return try syn keyword booStatement assert syn keyword booStatement self -syn keyword booStatement internal final private override static public protected +syn keyword booStatement internal final private override static public protected virtual partial syn keyword booStatement ref syn keyword booStatement yield syn keyword booStatement enum