[vala/wip/issue/370: 44/44] Add support for partial classes
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/issue/370: 44/44] Add support for partial classes
- Date: Sat, 30 Oct 2021 11:29:48 +0000 (UTC)
commit 554011b393cf9635e2990a589c6323925fe53090
Author: Simon Werbeck <simon werbeck gmail com>
Date: Sun Mar 31 22:30:07 2013 +0200
Add support for partial classes
Fixes https://gitlab.gnome.org/GNOME/vala/issues/370
tests/Makefile.am | 5 ++
tests/objects/class-partial-conflict-abstract.test | 10 ++++
tests/objects/class-partial-conflict-access.test | 10 ++++
tests/objects/class-partial-conflict-partial.test | 10 ++++
tests/objects/class-partial-conflict-sealed.test | 10 ++++
tests/objects/class-partial.vala | 70 ++++++++++++++++++++++
vala/valaclass.vala | 2 +
vala/valaparser.vala | 47 ++++++++++++++-
vala/valascanner.vala | 9 ++-
vala/valatokentype.vala | 2 +
10 files changed, 173 insertions(+), 2 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d0062f879..518a22f43 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -451,6 +451,11 @@ TESTS = \
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 \
diff --git a/tests/objects/class-partial-conflict-abstract.test
b/tests/objects/class-partial-conflict-abstract.test
new file mode 100644
index 000000000..c34126d15
--- /dev/null
+++ b/tests/objects/class-partial-conflict-abstract.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+partial abstract class Foo {
+}
+
+partial class Foo {
+}
+
+void main () {
+}
diff --git a/tests/objects/class-partial-conflict-access.test
b/tests/objects/class-partial-conflict-access.test
new file mode 100644
index 000000000..d52e97532
--- /dev/null
+++ b/tests/objects/class-partial-conflict-access.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+public partial class Foo {
+}
+
+partial class Foo {
+}
+
+void main () {
+}
diff --git a/tests/objects/class-partial-conflict-partial.test
b/tests/objects/class-partial-conflict-partial.test
new file mode 100644
index 000000000..6ae9843c1
--- /dev/null
+++ b/tests/objects/class-partial-conflict-partial.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+class Foo {
+}
+
+partial class Foo {
+}
+
+void main () {
+}
diff --git a/tests/objects/class-partial-conflict-sealed.test
b/tests/objects/class-partial-conflict-sealed.test
new file mode 100644
index 000000000..16f7e8083
--- /dev/null
+++ b/tests/objects/class-partial-conflict-sealed.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+partial sealed class Foo {
+}
+
+partial class Foo {
+}
+
+void main () {
+}
diff --git a/tests/objects/class-partial.vala b/tests/objects/class-partial.vala
new file mode 100644
index 000000000..15477f01c
--- /dev/null
+++ b/tests/objects/class-partial.vala
@@ -0,0 +1,70 @@
+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 ();
+}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index ee4ed624f..a6f5ae633 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -37,6 +37,8 @@ public class Vala.Class : ObjectTypeSymbol {
*/
public bool is_abstract { get; set; }
+ public bool is_partial { get; set; }
+
/**
* Specifies whether this class is sealed. Sealed classes may not be
* sub-classed.
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index f71f6e89c..a2b99f9ed 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -61,7 +61,8 @@ public class Vala.Parser : CodeVisitor {
STATIC,
VIRTUAL,
ASYNC,
- SEALED
+ SEALED,
+ PARTIAL
}
public Parser () {
@@ -253,6 +254,7 @@ public class Vala.Parser : CodeVisitor {
case TokenType.OVERRIDE:
case TokenType.OWNED:
case TokenType.PARAMS:
+ case TokenType.PARTIAL:
case TokenType.PRIVATE:
case TokenType.PROTECTED:
case TokenType.PUBLIC:
@@ -2733,6 +2735,7 @@ public class Vala.Parser : CodeVisitor {
case TokenType.NAMESPACE:
case TokenType.NEW:
case TokenType.OVERRIDE:
+ case TokenType.PARTIAL:
case TokenType.PRIVATE:
case TokenType.PROTECTED:
case TokenType.PUBLIC:
@@ -2842,9 +2845,42 @@ public class Vala.Parser : CodeVisitor {
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);
@@ -2855,6 +2891,10 @@ public class Vala.Parser : CodeVisitor {
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) {
@@ -3530,6 +3570,10 @@ public class Vala.Parser : CodeVisitor {
next ();
flags |= ModifierFlags.EXTERN;
break;
+ case TokenType.PARTIAL:
+ next ();
+ flags |= ModifierFlags.PARTIAL;
+ break;
case TokenType.SEALED:
next ();
flags |= ModifierFlags.SEALED;
@@ -3872,6 +3916,7 @@ public class Vala.Parser : CodeVisitor {
case TokenType.NAMESPACE:
case TokenType.NEW:
case TokenType.OVERRIDE:
+ case TokenType.PARTIAL:
case TokenType.PRIVATE:
case TokenType.PROTECTED:
case TokenType.PUBLIC:
diff --git a/vala/valascanner.vala b/vala/valascanner.vala
index 36f274e6f..daeb97feb 100644
--- a/vala/valascanner.vala
+++ b/vala/valascanner.vala
@@ -533,7 +533,14 @@ public class Vala.Scanner {
}
break;
case 'p':
- if (matches (begin, "private")) return TokenType.PRIVATE;
+ switch (begin[1]) {
+ case 'r':
+ if (matches (begin, "private")) return TokenType.PRIVATE;
+ break;
+ case 'a':
+ if (matches (begin, "partial")) return TokenType.PARTIAL;
+ break;
+ }
break;
case 'u':
if (matches (begin, "unowned")) return TokenType.UNOWNED;
diff --git a/vala/valatokentype.vala b/vala/valatokentype.vala
index 9cc6d1c74..2c64ec1b0 100644
--- a/vala/valatokentype.vala
+++ b/vala/valatokentype.vala
@@ -115,6 +115,7 @@ public enum Vala.TokenType {
OVERRIDE,
OWNED,
PARAMS,
+ PARTIAL,
PERCENT,
PLUS,
PRIVATE,
@@ -249,6 +250,7 @@ public enum Vala.TokenType {
case OVERRIDE: return "`override'";
case OWNED: return "`owned'";
case PARAMS: return "`params'";
+ case PARTIAL: return "`partial'";
case PERCENT: return "`%'";
case PLUS: return "`+'";
case PRIVATE: return "`private'";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]