[vala/switch-to-gir] girparser: Implement push_metadata, pop_metadata and check for hidden



commit a5a513ad2c0ce633d88e990c6856eb723de3fc84
Author: Luca Bruno <lethalman88 gmail com>
Date:   Tue Aug 24 23:16:53 2010 +0200

    girparser: Implement push_metadata, pop_metadata and check for hidden

 vala/valagirparser.vala |  138 +++++++++++++++++++++++++++++++++-------------
 1 files changed, 99 insertions(+), 39 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 2350970..cd34a63 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -33,7 +33,13 @@ public class Vala.GirParser : CodeVisitor {
 	}
 
 	class Metadata : Attribute {
-		public Metadata? parent;
+		private static Metadata _empty = new Metadata ("");
+		public static Metadata empty {
+			get {
+				return _empty;
+			}
+		}
+
 		public MetadataType type;
 		private ArrayList<Metadata> children = new ArrayList<Metadata> ();
 		public bool used = false;
@@ -44,29 +50,19 @@ public class Vala.GirParser : CodeVisitor {
 		}
 
 		public void add_child (Metadata metadata) {
-			if (get_child (metadata.name, metadata.type) != null) {
-				Report.error (metadata.source_reference, "duplicate metadata pattern `%s'".printf (metadata.to_string ()));
+			if (get_child (metadata.name, metadata.type) != Metadata.empty) {
+				Report.error (metadata.source_reference, "duplicate metadata pattern");
 			}
-
-			metadata.parent = this;
 			children.add (metadata);
 		}
 
-		public Metadata? get_child (string name, MetadataType type = MetadataType.GENERIC) {
+		public Metadata get_child (string name, MetadataType type = MetadataType.GENERIC) {
 			foreach (var metadata in children) {
 				if (metadata.name == name && metadata.type == type) {
 					return metadata;
 				}
 			}
-			return null;
-		}
-
-		public override string to_string () {
-			if (parent.name == "") {
-				return name;
-			} else {
-				return "%s.%s".printf (parent.to_string (), name);
-			}
+			return Metadata.empty;
 		}
 	}
 
@@ -132,12 +128,14 @@ public class Vala.GirParser : CodeVisitor {
 
 		Metadata? parse_pattern () {
 			Metadata metadata;
+			bool is_relative = false;
 			MetadataType? type = MetadataType.GENERIC;
 			if (current == TokenType.IDENTIFIER) {
 				parent_metadata = tree;
 			} else {
 				// relative pattern
 				type = parse_metadata_access ();
+				is_relative = true;
  			}
 
 			if (type == null) {
@@ -174,7 +172,9 @@ public class Vala.GirParser : CodeVisitor {
 				metadata.add_child (child);
 				metadata = child;
 			}
-			parent_metadata = metadata;
+			if (!is_relative) {
+				parent_metadata = metadata;
+			}
 
 			return metadata;
 		}
@@ -266,7 +266,8 @@ public class Vala.GirParser : CodeVisitor {
 
 	string[] cheader_filenames;
 
-	Metadata metadata;
+	ArrayList<Metadata> metadata_stack;
+	Metadata metadata = Metadata.empty;
 
 	HashMap<string,ArrayList<Method>> gtype_callbacks = new HashMap<string,ArrayList<Method>> (str_hash, str_equal);
 
@@ -307,15 +308,17 @@ public class Vala.GirParser : CodeVisitor {
 		}
 
 		if (source_file.filename.has_suffix (".gir")) {
+			metadata_stack = new ArrayList<Metadata> ();
+			metadata = Metadata.empty;
+
 			string metadata_filename = "%s.metadata".printf (source_file.filename.ndup (source_file.filename.length - ".gir".length));
 			if (FileUtils.test (metadata_filename, FileTest.EXISTS)) {
 				var metadata_parser = new MetadataParser ();
+				metadata_stack.add (metadata);
 				metadata = metadata_parser.parse_metadata (new SourceFile (context, metadata_filename, true));
 			}
 
 			parse_file (source_file);
-
-			metadata = null;
 		}
 	}
 
@@ -361,6 +364,44 @@ public class Vala.GirParser : CodeVisitor {
 		return new SourceReference (this.current_source_file, begin.line, begin.column, end.line, end.column);
 	}
 
+	Metadata get_metadata_from_element () {
+		var name = reader.name;
+		var child_name = reader.get_attribute ("name");
+		if (child_name == null) {
+			return Metadata.empty;
+		}
+
+		var type = MetadataType.GENERIC;
+		if (name == "glib:signal") {
+			type = MetadataType.SIGNAL;
+		} else if (name == "property") {
+			type = MetadataType.PROPERTY;
+		}
+
+		return metadata.get_child (child_name, type);
+	}
+
+
+	bool push_metadata () {
+		// hidden?
+		if (reader.get_attribute ("introspectable") == "0") {
+			return false;
+		}
+		var new_metadata = get_metadata_from_element ();
+		if (new_metadata.has_argument ("hidden") && new_metadata.get_bool ("hidden")) {
+			return false;
+		}
+
+		metadata_stack.add (metadata);
+		metadata = new_metadata;
+		return true;
+	}
+
+	void pop_metadata () {
+		metadata = metadata_stack[metadata_stack.size - 1];
+		metadata_stack.remove_at (metadata_stack.size - 1);
+	}
+
 	void parse_repository () {
 		start_element ("repository");
 		next ();
@@ -476,7 +517,7 @@ public class Vala.GirParser : CodeVisitor {
 		}
 		next ();
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -516,7 +557,7 @@ public class Vala.GirParser : CodeVisitor {
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `namespace'".printf (reader.name));
-				break;
+				skip_element ();
 			}
 
 			if (sym is Class) {
@@ -535,9 +576,9 @@ public class Vala.GirParser : CodeVisitor {
 				ns.add_method ((Method) sym);
 			} else if (sym is Constant) {
 				ns.add_constant ((Constant) sym);
-			} else if (sym == null) {
-				continue;
 			}
+
+			pop_metadata ();
 		}
 		end_element ("namespace");
 
@@ -598,7 +639,7 @@ public class Vala.GirParser : CodeVisitor {
 		string common_prefix = null;
 		
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -609,8 +650,11 @@ public class Vala.GirParser : CodeVisitor {
 				calculate_common_prefix (ref common_prefix, ev.get_cname ());
 			} else {
 				// error
-				break;
+				Report.error (get_current_src (), "unknown child element `%s' in `enumaration'".printf (reader.name));
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 
 		en.set_cprefix (common_prefix);
@@ -635,7 +679,7 @@ public class Vala.GirParser : CodeVisitor {
 		string common_prefix = null;
 
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -646,8 +690,11 @@ public class Vala.GirParser : CodeVisitor {
 				calculate_common_prefix (ref common_prefix, ec.get_cname ());
 			} else {
 				// error
-				break;
+				Report.error (get_current_src (), "unknown child element `%s' in `enumeration'".printf (reader.name));
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 
 		ed.set_cprefix (common_prefix);
@@ -662,7 +709,7 @@ public class Vala.GirParser : CodeVisitor {
 		en.access = SymbolAccessibility.PUBLIC;
 		next ();
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -671,8 +718,11 @@ public class Vala.GirParser : CodeVisitor {
 				en.add_value (parse_enumeration_member ());
 			} else {
 				// error
-				break;
+				Report.error (get_current_src (), "unknown child element `%s' in `bitfield'".printf (reader.name));
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 		end_element ("bitfield");
 		return en;
@@ -885,7 +935,7 @@ public class Vala.GirParser : CodeVisitor {
 		st.access = SymbolAccessibility.PUBLIC;
 		next ();
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -918,8 +968,10 @@ public class Vala.GirParser : CodeVisitor {
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `record'".printf (reader.name));
-				break;
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 		end_element ("record");
 
@@ -1020,7 +1072,7 @@ public class Vala.GirParser : CodeVisitor {
 		var vmethods = new ArrayList<Method> ();
 		var fields = new ArrayList<Field> ();
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -1057,8 +1109,10 @@ public class Vala.GirParser : CodeVisitor {
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `class'".printf (reader.name));
-				break;
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 
 		// signal merging
@@ -1138,7 +1192,7 @@ public class Vala.GirParser : CodeVisitor {
 		var methods = new ArrayList<Method> ();
 		var vmethods = new ArrayList<Method> ();
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -1163,8 +1217,10 @@ public class Vala.GirParser : CodeVisitor {
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `interface'".printf (reader.name));
-				break;
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 
 		// virtual method merging
@@ -1565,7 +1621,7 @@ public class Vala.GirParser : CodeVisitor {
 		next ();
 
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -1579,8 +1635,10 @@ public class Vala.GirParser : CodeVisitor {
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `class'".printf (reader.name));
-				break;
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 
 		if (current_token != MarkupTokenType.END_ELEMENT) {
@@ -1599,7 +1657,7 @@ public class Vala.GirParser : CodeVisitor {
 		next ();
 
 		while (current_token == MarkupTokenType.START_ELEMENT) {
-			if (reader.get_attribute ("introspectable") == "0") {
+			if (!push_metadata ()) {
 				skip_element ();
 				continue;
 			}
@@ -1621,8 +1679,10 @@ public class Vala.GirParser : CodeVisitor {
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `union'".printf (reader.name));
-				break;
+				skip_element ();
 			}
+
+			pop_metadata ();
 		}
 
 		end_element ("union");



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]