objects/class-destroysinstance.vala \
objects/class-inner-types.vala \
objects/class-new-no-override.vala \
+ objects/class-partial.vala \
+ objects/class-partial-conflict-abstract.test \
+ objects/class-partial-conflict-access.test \
+ objects/class-partial-conflict-partial.test \
+ objects/class-partial-conflict-sealed.test \
objects/class-vfunc-base-access.vala \
objects/classes.vala \
objects/classes-interfaces.vala \
--- /dev/null
+public interface IFoo {
+ public abstract void i1 ();
+}
+
+public interface IBar {
+ public abstract void i2 ();
+}
+
+public partial class Foo : Object {
+ public string p0 { get; set; }
+ public string f0;
+ public void m0 () {
+ }
+ public virtual void v0 () {
+ }
+ public virtual signal void s0 () {
+ }
+}
+
+public partial class Foo : IFoo {
+ public string p1 { get; set; }
+ public string f1;
+ public void m1 () {
+ }
+ public virtual void v1 () {
+ }
+ public virtual signal void s1 () {
+ }
+ public void i1 () {
+ }
+}
+
+public partial class Foo : IBar {
+ public string p2 { get; set; }
+ public string f2;
+ public void m2 () {
+ }
+ public virtual void v2 () {
+ }
+ public virtual signal void s2 () {
+ }
+ public void i2 () {
+ }
+}
+
+void main () {
+ var foo = new Foo ();
+ foo.p0 = "p0";
+ foo.f0 = "f0";
+ foo.m0 ();
+ foo.v0 ();
+ foo.s0 ();
+
+ foo.p1 = "p1";
+ foo.f1 = "f1";
+ foo.m1 ();
+ foo.v1 ();
+ foo.s1 ();
+
+ foo.p2 = "p2";
+ foo.f2 = "f2";
+ foo.m2 ();
+ foo.v2 ();
+ foo.s2 ();
+
+ assert (foo is IFoo);
+ foo.i1 ();
+ assert (foo is IBar);
+ foo.i2 ();
+}
STATIC,
VIRTUAL,
ASYNC,
- SEALED
+ SEALED,
+ PARTIAL
}
public Parser () {
case TokenType.OVERRIDE:
case TokenType.OWNED:
case TokenType.PARAMS:
+ case TokenType.PARTIAL:
case TokenType.PRIVATE:
case TokenType.PROTECTED:
case TokenType.PUBLIC:
case TokenType.NAMESPACE:
case TokenType.NEW:
case TokenType.OVERRIDE:
+ case TokenType.PARTIAL:
case TokenType.PRIVATE:
case TokenType.PROTECTED:
case TokenType.PUBLIC:
if (ModifierFlags.SEALED in flags) {
cl.is_sealed = true;
}
+ if (ModifierFlags.PARTIAL in flags) {
+ if (!context.experimental) {
+ Report.warning (cl.source_reference, "`partial' classes are experimental");
+ }
+ cl.is_partial = true;
+ }
if (ModifierFlags.EXTERN in flags) {
cl.is_extern = true;
}
+
+ var old_cl = parent.scope.lookup (cl.name) as Class;
+ if (old_cl != null && old_cl.is_partial) {
+ if (cl.is_partial != old_cl.is_partial) {
+ Report.error (cl.source_reference, "conflicting partial and not partial declarations of `%s'".printf (cl.name));
+ cl.error = true;
+ }
+ if (cl.access != old_cl.access) {
+ Report.error (cl.source_reference, "partial declarations of `%s' have conflicting accessiblity modifiers".printf (cl.name));
+ cl.error = true;
+ }
+ if (cl.is_abstract != old_cl.is_abstract) {
+ Report.error (cl.source_reference, "partial declarations of `%s' have conflicting abstract modifiers".printf (cl.name));
+ cl.error = true;
+ }
+ if (cl.is_sealed != old_cl.is_sealed) {
+ Report.error (cl.source_reference, "partial declarations of `%s' have conflicting sealed modifiers".printf (cl.name));
+ cl.error = true;
+ }
+ if (cl.error) {
+ Report.notice (old_cl.source_reference, "previous declaration of `%s' was here", old_cl.name);
+ return;
+ }
+
+ cl = old_cl;
+ }
+
set_attributes (cl, attrs);
foreach (TypeParameter type_param in type_param_list) {
cl.add_type_parameter (type_param);
parse_declarations (cl);
+ if (old_cl != null && old_cl.is_partial) {
+ return;
+ }
+
// ensure there is always a default construction method
if (scanner.source_file.file_type == SourceFileType.SOURCE
&& cl.default_construction_method == null) {
next ();
flags |= ModifierFlags.EXTERN;
break;
+ case TokenType.PARTIAL:
+ next ();
+ flags |= ModifierFlags.PARTIAL;
+ break;
case TokenType.SEALED:
next ();
flags |= ModifierFlags.SEALED;
case TokenType.NAMESPACE:
case TokenType.NEW:
case TokenType.OVERRIDE:
+ case TokenType.PARTIAL:
case TokenType.PRIVATE:
case TokenType.PROTECTED:
case TokenType.PUBLIC: