summaryrefslogtreecommitdiff
path: root/vala
diff options
context:
space:
mode:
authorSimon Werbeck <simon.werbeck@gmail.com>2013-03-31 22:30:07 +0200
committerRico Tzschichholz <ricotz@ubuntu.com>2021-10-30 13:28:07 +0200
commit554011b393cf9635e2990a589c6323925fe53090 (patch)
treeea3175a2845b09fc692b7fd4aca12b6590cfd166 /vala
parent1fdc269019539f998fffdeb53014afde755f5f8a (diff)
downloadvala-554011b393cf9635e2990a589c6323925fe53090.tar.gz
Add support for partial classes
Fixes https://gitlab.gnome.org/GNOME/vala/issues/370
Diffstat (limited to 'vala')
-rw-r--r--vala/valaclass.vala2
-rw-r--r--vala/valaparser.vala47
-rw-r--r--vala/valascanner.vala9
-rw-r--r--vala/valatokentype.vala2
4 files changed, 58 insertions, 2 deletions
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'";