[anjuta] language-support-vala: refactor to work with latest project manager



commit 2d5efbd7e6748c116407764d13c22f7740f53bb0
Author: Abderrahim Kitouni <akitouni src gnome org>
Date:   Fri Jan 7 22:43:40 2011 +0100

    language-support-vala: refactor to work with latest project manager
    
    Move everything to the current-editor value handler as the plugin
    is activated based on file load rather than project load. Also listen
    for the project_loaded signal if the project isn't loaded yet.
    
    This will also allow for more correct behaviour of only parsing vala
    files of the target that the currently loaded file belongs to.

 plugins/language-support-vala/plugin.vala |  212 ++++++++++++++++++-----------
 plugins/language-support-vala/report.vala |    2 +-
 2 files changed, 135 insertions(+), 79 deletions(-)
---
diff --git a/plugins/language-support-vala/plugin.vala b/plugins/language-support-vala/plugin.vala
index 053d708..a4489fa 100644
--- a/plugins/language-support-vala/plugin.vala
+++ b/plugins/language-support-vala/plugin.vala
@@ -22,6 +22,7 @@ public class ValaPlugin : Plugin {
 	internal weak IAnjuta.Editor current_editor;
 	internal GLib.Settings settings = new GLib.Settings ("org.gnome.anjuta.cpp");
 	uint editor_watch_id;
+	ulong project_loaded_id;
 
 	Vala.CodeContext context;
 	Cancellable cancel;
@@ -33,109 +34,174 @@ public class ValaPlugin : Plugin {
 	Vala.Parser parser;
 	Vala.Genie.Parser genie_parser;
 
+	Vala.Set<string> current_sources = new Vala.HashSet<string> (str_hash, str_equal);
 	ValaPlugin () {
 		Object ();
 	}
 	public override bool activate () {
-		//debug("Activating ValaPlugin");
-		context = new Vala.CodeContext();
+		debug("Activating ValaPlugin");
 		report = new AnjutaReport();
 		report.docman = (IAnjuta.DocumentManager) shell.get_object("IAnjutaDocumentManager");
-		context.report = report;
+		parser = new Vala.Parser ();
+		genie_parser = new Vala.Genie.Parser ();
+
+		init_context ();
+
+		provider = new ValaProvider(this);
+		editor_watch_id = add_watch("document_manager_current_document",
+		                            editor_value_added,
+		                            editor_value_removed);
+
+		return true;
+	}
+
+	public override bool deactivate () {
+		debug("Deactivating ValaPlugin");
+		remove_watch(editor_watch_id, true);
+
+		cancel.cancel ();
+		lock (context) {
+			context = null;
+		}
+
+		return true;
+	}
+
+	void init_context () {
+		context = new Vala.CodeContext();
 		context.profile = Vala.Profile.GOBJECT;
+		context.report = report;
+		report.clear_error_indicators ();
 
 		cancel = new Cancellable ();
-		parser = new Vala.Parser ();
-		genie_parser = new Vala.Genie.Parser ();
 
 		/* This doesn't actually parse anything as there are no files yet,
 		   it's just to set the context in the parsers */
 		parser.parse (context);
 		genie_parser.parse (context);
 
-		var project = (IAnjuta.ProjectManager) shell.get_object("IAnjutaProjectManager");
-		var packages = project.get_packages();
+		current_sources = new Vala.HashSet<string> (str_hash, str_equal);
 
-		Vala.CodeContext.push (context);
-		context.add_external_package("glib-2.0");
-		context.add_external_package("gobject-2.0");
+	}
 
-		foreach (var pkg in packages) {
-			if (!context.add_external_package(pkg))
-				/* TODO: try to look at VALAFLAGS */
-				debug ("package %s not found", pkg);
+	void parse () {
+		try {
+			Thread.create<void>(() => {
+				lock (context) {
+					Vala.CodeContext.push(context);
+					var report = context.report as AnjutaReport;
+
+					foreach (var src in context.get_source_files ()) {
+						if (src.get_nodes ().size == 0) {
+							debug ("parsing file %s", src.filename);
+							genie_parser.visit_source_file (src);
+							parser.visit_source_file (src);
+						}
+
+						if (cancel.is_cancelled ()) {
+							Vala.CodeContext.pop();
+							return;
+						}
+					}
+
+					if (report.errors_found () || cancel.is_cancelled ()) {
+						Vala.CodeContext.pop();
+						return;
+					}
+
+					context.check ();
+					Vala.CodeContext.pop();
+				}
+			}, false);
+		} catch (ThreadError err) {
+			warning ("cannot create thread : %s", err.message);
 		}
+	}
 
-		Vala.CodeContext.pop ();
+	void add_project_files () {
+		var project = (IAnjuta.ProjectManager) shell.get_object("IAnjutaProjectManager");
+		Vala.CodeContext.push (context);
 
 		var sources = project.get_elements(Anjuta.ProjectNodeType.SOURCE);
 		foreach (var src in sources) {
 			var path = src.get_path();
 			if (path == null)
 				continue;
-			if (path.has_suffix (".vala") || path.has_suffix (".vapi") || path.has_suffix (".gs"))
-				context.add_source_filename (src.get_path ());
-		}
-		ThreadFunc<void*> parse = () => {
-			lock (context) {
-				Vala.CodeContext.push(context);
-				var report = context.report as AnjutaReport;
-
-				foreach (var src in context.get_source_files ()) {
-					parser.visit_source_file (src);
-					genie_parser.visit_source_file (src);
-
-					if (cancel.is_cancelled ()) {
-						Vala.CodeContext.pop();
-						return null;
-					}
+			if (path.has_suffix (".vala") || path.has_suffix (".vapi") || path.has_suffix (".gs")) {
+				if (path in current_sources) {
+					debug ("file %s already added", path);
+				} else {
+					context.add_source_filename (path);
+					current_sources.add (path);
+					debug ("file %s added", path);
 				}
-
-				if (report.errors_found () || cancel.is_cancelled ()) {
-					Vala.CodeContext.pop();
-					return null;
-				}
-
-				context.check ();
-
-				Vala.CodeContext.pop();
+			} else {
+				debug ("file %s skipped", path);
 			}
-		};
-
-		try {
-			Thread.create<void*>(parse, false);
-			debug("Using threads");
-		} catch (ThreadError err) {
-			parse();
+		}
+		if (!context.has_package ("gobject-2.0")) {
+			context.add_external_package("glib-2.0");
+			context.add_external_package("gobject-2.0");
+			debug ("standard packages added");
+		} else {
+			debug ("standard packages already added");
 		}
 
-		provider = new ValaProvider(this);
-		editor_watch_id = add_watch("document_manager_current_document",
-									(PluginValueAdded) editor_value_added,
-									(PluginValueRemoved) editor_value_removed);
-
-		return true;
-	}
-
-	public override bool deactivate () {
-		//debug("Deactivating ValaPlugin");
-		remove_watch(editor_watch_id, true);
-
-		cancel.cancel ();
-		lock (context) {
-			context = null;
+		var packages = project.get_packages();
+		foreach (var pkg in packages) {
+			if (context.has_package (pkg)) {
+				debug ("package %s skipped", pkg);
+			} else if (context.add_external_package(pkg)) {
+				debug ("package %s added", pkg);
+			} else {
+				/* TODO: try to look at VALAFLAGS */
+				debug ("package %s not found", pkg);
+			}
 		}
+		Vala.CodeContext.pop();
+	}
 
-		return true;
+	public void on_project_loaded (IAnjuta.ProjectManager pm, Error? e) {
+		if (context == null)
+			return;
+		add_project_files ();
+		parse ();
+		pm.disconnect (project_loaded_id);
+		project_loaded_id = 0;
 	}
 
 	/* "document_manager_current_document" watch */
-	public void editor_value_added(string name, Value value) {
-		//debug("editor value added");
+	public void editor_value_added (Anjuta.Plugin plugin, string name, Value value) {
+		debug("editor value added");
 		assert (current_editor == null);
 		assert (value.get_object() is IAnjuta.Editor);
 
 		current_editor = value.get_object() as IAnjuta.Editor;
+		var current_file = value.get_object() as IAnjuta.File;
+
+		var pm = (IAnjuta.ProjectManager) shell.get_object("IAnjutaProjectManager");
+		var project = pm.get_current_project ();
+
+		if (!project.is_loaded()) {
+			if (project_loaded_id == 0)
+				project_loaded_id = pm.project_loaded.connect (on_project_loaded);
+		} else {
+			var cur_gfile = current_file.get_file ();
+			if (cur_gfile == null) {
+				// File hasn't been saved yet
+				return;
+			}
+
+			if (!(cur_gfile.get_path () in current_sources)) {
+				cancel.cancel ();
+				lock (context) {
+					init_context ();
+					add_project_files ();
+				}
+
+				parse ();
+			}
+		}
 		if (current_editor != null) {
 			if (current_editor is IAnjuta.EditorAssist)
 				(current_editor as IAnjuta.EditorAssist).add(provider);
@@ -148,8 +214,8 @@ public class ValaPlugin : Plugin {
 		}
 		report.update_errors (current_editor);
 	}
-	public void editor_value_removed(string name) {
-		//debug("editor value removed");
+	public void editor_value_removed (Anjuta.Plugin plugin, string name) {
+		debug("editor value removed");
 		if (current_editor is IAnjuta.EditorAssist)
 			(current_editor as IAnjuta.EditorAssist).remove(provider);
 		if (current_editor is IAnjuta.EditorTip)
@@ -315,20 +381,10 @@ public class ValaPlugin : Plugin {
 			file.current_using_directives = new Vala.ArrayList<Vala.UsingDirective>();
 			var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib"));
 			file.add_using_directive (ns_ref);
-			context.root.add_using_directive (ns_ref);
 
 			report.clear_error_indicators ();
 
-			Vala.CodeContext.push (context);
-
-			/* visit_source_file checks for the file extension */
-			parser.visit_source_file (file);
-			genie_parser.visit_source_file (file);
-
-			if (!report.errors_found ())
-				context.check ();
-
-			Vala.CodeContext.pop ();
+			parse ();
 
 			report.update_errors(current_editor);
 		}
diff --git a/plugins/language-support-vala/report.vala b/plugins/language-support-vala/report.vala
index 54af59f..4dc5374 100644
--- a/plugins/language-support-vala/report.vala
+++ b/plugins/language-support-vala/report.vala
@@ -57,7 +57,7 @@ public class AnjutaReport : Vala.Report {
 	}
 	public void clear_error_indicators () {
 		errors = new Vala.ArrayList<Error?>();
-		foreach (var doc in (List<Gtk.Widget>)docman.get_doc_widgets ()) {
+		foreach (var doc in docman.get_doc_widgets ()) {
 			if (doc is IAnjuta.Indicable)
 				((IAnjuta.Indicable)doc).clear ();
 			if (doc is IAnjuta.Markable)



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