summaryrefslogtreecommitdiff
path: root/vala/valainterface.vala
diff options
context:
space:
mode:
authorMaciej Piechotka <uzytkownik2@gmail.com>2013-05-11 21:43:30 +0100
committerMaciej Piechotka <uzytkownik2@gmail.com>2013-07-25 09:11:25 +0200
commit2886366e6b5499b46e04029b9a257ae9dc880766 (patch)
tree6c65a24917700ed863f2dab842c1229f133e9b8d /vala/valainterface.vala
parentb31584b56a4dc3fb754bc3df096727b33f38306d (diff)
downloadvala-2886366e6b5499b46e04029b9a257ae9dc880766.tar.gz
Add CCode ordering attribute for interfaces
Diffstat (limited to 'vala/valainterface.vala')
-rw-r--r--vala/valainterface.vala76
1 files changed, 69 insertions, 7 deletions
diff --git a/vala/valainterface.vala b/vala/valainterface.vala
index 5780837ff..49bc0ae2c 100644
--- a/vala/valainterface.vala
+++ b/vala/valainterface.vala
@@ -33,6 +33,7 @@ public class Vala.Interface : ObjectTypeSymbol {
private List<Constant> constants = new ArrayList<Constant> ();
private List<Property> properties = new ArrayList<Property> ();
private List<Signal> signals = new ArrayList<Signal> ();
+ private List<Symbol> virtuals = new ArrayList<Symbol> ();
// inner types
private List<Class> classes = new ArrayList<Class> ();
@@ -231,6 +232,10 @@ public class Vala.Interface : ObjectTypeSymbol {
return signals;
}
+ public virtual List<Symbol> get_virtuals () {
+ return virtuals;
+ }
+
/**
* Adds the specified class as an inner class.
*
@@ -415,8 +420,11 @@ public class Vala.Interface : ObjectTypeSymbol {
foreach (Method m in methods) {
m.check (context);
+ if (m.is_virtual || m.is_abstract) {
+ virtuals.add (m);
+ }
}
-
+
foreach (Field f in fields) {
f.check (context);
}
@@ -425,18 +433,24 @@ public class Vala.Interface : ObjectTypeSymbol {
c.check (context);
}
- foreach (Property prop in properties) {
- prop.check (context);
- }
-
foreach (Signal sig in signals) {
sig.check (context);
+ if (sig.is_virtual) {
+ virtuals.add (sig);
+ }
}
-
+
+ foreach (Property prop in properties) {
+ prop.check (context);
+ if (prop.is_virtual || prop.is_abstract) {
+ virtuals.add (prop);
+ }
+ }
+
foreach (Class cl in classes) {
cl.check (context);
}
-
+
foreach (Struct st in structs) {
st.check (context);
}
@@ -445,6 +459,54 @@ public class Vala.Interface : ObjectTypeSymbol {
d.check (context);
}
+ Map<int, Symbol>? positions = new HashMap<int, Symbol> ();
+ bool ordered_seen = false;
+ bool unordered_seen = false;
+ foreach (Symbol sym in virtuals) {
+ int ordering = sym.get_attribute_integer ("CCode", "ordering", -1);
+ if (ordering < -1) {
+ Report.error (sym.source_reference, "%s: Invalid ordering".printf (sym.get_full_name ()));
+ // Mark state as invalid
+ error = true;
+ ordered_seen = true;
+ unordered_seen = true;
+ continue;
+ }
+ bool ordered = ordering != -1;
+ if (ordered && unordered_seen && !ordered_seen) {
+ Report.error (sym.source_reference, "%s: Cannot mix ordered and unordered virtuals".printf (sym.get_full_name ()));
+ error = true;
+ }
+ ordered_seen = ordered_seen || ordered;
+ if (!ordered && !unordered_seen && ordered_seen) {
+ Report.error (sym.source_reference, "%s: Cannot mix ordered and unordered virtuals".printf (sym.get_full_name ()));
+ error = true;
+ }
+ unordered_seen = unordered_seen || !ordered;
+ if (!ordered_seen || !unordered_seen) {
+ if (ordered) {
+ Symbol? prev = positions[ordering];
+ if (prev != null) {
+ Report.error (sym.source_reference, "%s: Duplicate ordering (previous virtual with the same position is %s)".printf (sym.get_full_name (), prev.name));
+ error = true;
+ }
+ positions[ordering] = sym;
+ }
+ }
+ }
+ if (ordered_seen) {
+ for (int i = 0; i < virtuals.size; i++) {
+ Symbol? sym = positions[i];
+ if (sym == null) {
+ Report.error (source_reference, "%s: Gap in ordering in position %d".printf (get_full_name (), i));
+ error = true;
+ }
+ if (!error) {
+ virtuals[i] = sym;
+ }
+ }
+ }
+
context.analyzer.current_source_file = old_source_file;
context.analyzer.current_symbol = old_symbol;