[anjuta] anjuta-tags: add support for parsing vala tags (using libvala if available)
- From: Johannes Schmid <jhs src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [anjuta] anjuta-tags: add support for parsing vala tags (using libvala if available)
- Date: Thu, 11 Feb 2010 21:54:55 +0000 (UTC)
commit 08e5aa77b6ba850274d77ebb4c639a3e6ddf9d3e
Author: Abderrahim Kitouni <a kitouni gmail com>
Date: Wed Feb 10 23:40:30 2010 +0100
anjuta-tags: add support for parsing vala tags (using libvala if available)
configure.in | 11 +
plugins/symbol-db/anjuta-tags/Makefile.am | 14 +-
plugins/symbol-db/anjuta-tags/ctags-visitor.vala | 369 ++++++++++++++++++++++
plugins/symbol-db/anjuta-tags/parsers.h | 48 +++
plugins/symbol-db/anjuta-tags/vala.c | 100 ++++++
5 files changed, 541 insertions(+), 1 deletions(-)
---
diff --git a/configure.in b/configure.in
index da0f555..db766ac 100644
--- a/configure.in
+++ b/configure.in
@@ -44,6 +44,7 @@ GTKSOURCEVIEW_REQUIRED=2.9.3
LIBWNCK_REQUIRED=2.12
GDA_REQUIRED=4.0.0
UNIQUE_REQUIRED=1.0.0
+VALA_REQUIRED=0.7.8
AC_SUBST(GLIB_REQUIRED)
AC_SUBST(GDK_PIXBUF_REQUIRED)
@@ -270,6 +271,16 @@ fi
AM_CONDITIONAL(HAVE_PLUGIN_SOURCEVIEW, [test x$sourceview = xyes])
+dnl Check for vala
+dnl -------------------------------------------------------------
+
+PKG_CHECK_MODULES(VALA,
+ [vala-1.0 >= $VALA_REQUIRED],
+ [enable_vala="yes"],
+ [enable_vala="no"])
+
+AM_CONDITIONAL(ENABLE_VALA, [test x$enable_vala = xyes])
+
PKG_CHECK_MODULES(PLUGIN_SYMBOL_DB,
[libgda-4.0 >= $GDA_REQUIRED])
diff --git a/plugins/symbol-db/anjuta-tags/Makefile.am b/plugins/symbol-db/anjuta-tags/Makefile.am
index 454fa30..d23e2a1 100644
--- a/plugins/symbol-db/anjuta-tags/Makefile.am
+++ b/plugins/symbol-db/anjuta-tags/Makefile.am
@@ -10,6 +10,7 @@ AM_CPPFLAGS = \
AM_CFLAGS =\
-Wall \
$(GLIB_CFLAGS) \
+ $(VALA_CFLAGS) \
$(LIBXML_CFLAGS)
bin_PROGRAMS = anjuta-tags
@@ -28,6 +29,9 @@ LEXCCFLAGS = -Cr -o js_parser/lex.yy.c --yylineno --bison-bridge
js_parser/lex.yy.c : ${LEXFILE}
${LEXER} ${LEXCCFLAGS} ${LEXFILE}
+ctags-visitor.c: ctags-visitor.vala
+ valac -g -h ctags-vala.h -C --pkg vala-1.0 $^
+
anjuta_tags_SOURCES = \
main.c \
acconfig.h \
@@ -126,6 +130,14 @@ anjuta_tags_LDFLAGS = \
anjuta_tags_LDADD = \
$(GLIB_LIBS) \
+ $(VALA_LIBS) \
$(LIBXML_LIBS)
-EXTRA_DIST = ${YACCFILE} ${LEXFILE}
+EXTRA_DIST = ${YACCFILE} ${LEXFILE} ctags-visitor.vala ctags-visitor.c ctags-vala.h
+
+if ENABLE_VALA
+anjuta_tags_SOURCES += vala.c ctags-visitor.c
+AM_CPPFLAGS += -DENABLE_VALA
+BUILT_SOURCES = ctags-visitor.c
+endif
+
diff --git a/plugins/symbol-db/anjuta-tags/ctags-visitor.vala b/plugins/symbol-db/anjuta-tags/ctags-visitor.vala
new file mode 100644
index 0000000..09ac68e
--- /dev/null
+++ b/plugins/symbol-db/anjuta-tags/ctags-visitor.vala
@@ -0,0 +1,369 @@
+/*
+ * ctags-visitor.vala
+ *
+ * Copyright 2008, 2010 Abderrahim Kitouni <a kitouni gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+using Vala;
+
+public class CTagsEntry {
+ public int line_number;
+ public string name;
+ public string kind_name;
+ public char kind;
+ public string access;
+ public string implementation;
+ public string inheritance;
+ public string signature;
+ public string typeref;
+}
+
+class DummyReport : Report {
+ public override void warn (SourceReference? source, string message) {}
+ public override void err (SourceReference? source, string message) {}
+}
+
+[CCode (has_target=false)]
+public delegate void CTagsEntryMaker (CTagsEntry entry);
+
+public class CTagsVisitor : CodeVisitor {
+ Parser vala_parser;
+ Genie.Parser genie_parser;
+ GLib.List<CTagsEntry> taglist;
+ public CTagsVisitor () {
+ vala_parser = new Parser();
+ genie_parser = new Genie.Parser();
+ }
+ /* helper functions */
+ static string get_access (Symbol sym) {
+ switch (sym.access) {
+ case SymbolAccessibility.PRIVATE : return "private";
+ case SymbolAccessibility.INTERNAL : return "internal";
+ case SymbolAccessibility.PROTECTED : return "protected";
+ case SymbolAccessibility.PUBLIC : return "public";
+ }
+ assert_not_reached ();
+ }
+ static string to_string (Iterable<DataType> seq, string sep = ",") {
+ var str = new StringBuilder();
+ var first = true;
+ foreach (var type in seq) {
+ if(first) {
+ first = false;
+ } else {
+ str.append(sep);
+ }
+ str.append(type.to_qualified_string());
+ }
+ return str.str;
+ }
+ static string? implementation (Symbol sym) {
+ var list = new GLib.List<string>();
+
+ if (sym is Vala.Signal) {
+ var sig = (Vala.Signal)sym;
+ if (sig.is_virtual)
+ list.append("virtual");
+ } else if (sym is Class) {
+ var cls = (Class)sym;
+ if (cls.is_abstract)
+ list.append("abstract");
+ } else if (sym is Method) {
+ var meth = (Method)sym;
+ if (meth.is_abstract)
+ list.append("abstract");
+ else if (meth.is_virtual)
+ list.append("virtual");
+ } else if (sym is Property) {
+ var prop = (Property)sym;
+ if (prop.is_abstract)
+ list.append("abstract");
+ else if (prop.is_virtual)
+ list.append("virtual");
+ } else
+ return_val_if_reached(null);
+
+ var ret = new StringBuilder();
+ var first = true;
+ foreach (var str in list) {
+ if(first) {
+ first = false;
+ } else {
+ ret.append(",");
+ }
+ ret.append(str);
+ }
+ return ret.str;
+ }
+ static string signature (Vala.List<Vala.FormalParameter> parameter) {
+ var ret = new StringBuilder("(");
+ var first = true;
+ foreach (var p in parameter) {
+ if(first) {
+ first = false;
+ } else {
+ ret.append(",");
+ }
+ if (p.ellipsis) {
+ ret.append("...");
+ } else {
+ ret.append (p.parameter_type.to_qualified_string());
+ ret.append (" ");
+ ret.append (p.name);
+ }
+ }
+ ret.append (")");
+ return ret.str;
+ }
+ /*static void print_tag(CTagsEntry en) {
+ stdout.printf("%s: %s at %d\n", en.name, en.kind_name, en.line_number);
+ }*/
+
+ public override void visit_source_file (SourceFile source_file) {
+ source_file.accept_children (this);
+ }
+
+ public override void visit_class (Class cl) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = cl.source_reference.first_line;
+ entry.name = cl.name;
+ entry.kind_name = "class";
+ entry.kind = 'c';
+ entry.access = get_access (cl);
+ entry.implementation = implementation(cl);
+ entry.inheritance = to_string(cl.get_base_types(), ",");
+
+ taglist.append(entry);
+// print_tag(entry);
+ cl.accept_children(this);
+ }
+ public override void visit_struct (Struct st) {
+ var entry = new CTagsEntry();
+ entry.line_number = st.source_reference.first_line;
+ entry.name = st.name;
+ entry.kind_name = "struct";
+ entry.kind = 's';
+ entry.access = get_access (st);
+
+ taglist.append(entry);
+// print_tag(entry);
+ st.accept_children(this);
+ }
+ public override void visit_interface (Interface iface) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = iface.source_reference.first_line;
+ entry.name = iface.name;
+ entry.kind_name = "interface";
+ entry.kind = 'i';
+ entry.access = get_access (iface);
+ entry.inheritance = to_string(iface.get_prerequisites());
+
+ taglist.append(entry);
+// print_tag(entry);
+ iface.accept_children(this);
+ }
+
+ public override void visit_enum (Vala.Enum en) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = en.source_reference.first_line;
+ entry.name = en.name;
+ entry.kind_name = "enum";
+ entry.kind = 'e';
+ entry.access = get_access (en);
+
+ taglist.append(entry);
+// print_tag(entry);
+ en.accept_children(this);
+ }
+ public override void visit_error_domain (ErrorDomain edomain) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = edomain.source_reference.first_line;
+ entry.name = edomain.name;
+ entry.kind_name = "errordomain";
+ entry.kind = 'E';
+ entry.access = get_access (edomain);
+
+ taglist.append(entry);
+// print_tag(entry);
+ edomain.accept_children(this);
+ }
+
+ public override void visit_enum_value (Vala.EnumValue ev) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = ev.source_reference.first_line;
+ entry.name = ev.name;
+ entry.kind_name = "enumvalue";
+ entry.kind = 'v';
+ entry.access = get_access (ev);
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_error_code (ErrorCode ecode) {
+ var entry = new CTagsEntry();
+
+ //entry.line_number = ecode.source_reference.first_line;
+ entry.name = ecode.name;
+ entry.kind_name = "errorcode";
+ entry.kind = 'r';
+ entry.access = get_access (ecode);
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public override void visit_delegate (Delegate d) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = d.source_reference.first_line;
+ entry.name = d.name;
+ entry.kind_name = "delegate";
+ entry.kind = 'd';
+ entry.access = get_access (d);
+ entry.typeref = d.return_type.to_qualified_string();
+ entry.signature = signature(d.get_parameters());
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_signal (Vala.Signal sig) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = sig.source_reference.first_line;
+ entry.name = sig.name;
+ entry.kind_name = "signal";
+ entry.kind = 'S';
+ entry.access = get_access (sig);
+ entry.implementation = implementation(sig);
+ entry.typeref = sig.return_type.to_qualified_string();
+ entry.signature = signature(sig.get_parameters());
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_field (Field f) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = f.source_reference.first_line;
+ entry.name = f.name;
+ entry.kind_name = "field";
+ entry.kind = 'f';
+ entry.access = get_access (f);
+ entry.typeref = f.field_type.to_qualified_string();
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_constant (Constant c) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = c.source_reference.first_line;
+ entry.name = c.name;
+ entry.kind_name = "field";
+ entry.kind = 'f';
+ entry.access = get_access (c);
+ entry.typeref = c.type_reference.to_qualified_string();
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+ public override void visit_property (Property prop) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = prop.source_reference.first_line;
+ entry.name = prop.name;
+ entry.kind_name = "property";
+ entry.kind = 'p';
+ entry.access = get_access (prop);
+ entry.implementation = implementation(prop);
+ entry.typeref = prop.property_type.to_qualified_string();
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public override void visit_method (Method m) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = m.source_reference.first_line;
+ entry.name = m.name;
+ entry.kind_name = "method";
+ entry.kind = 'm';
+ entry.access = get_access (m);
+ entry.implementation = implementation(m);
+ entry.typeref = m.return_type.to_qualified_string();
+ entry.signature = signature(m.get_parameters());
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public override void visit_local_variable (LocalVariable local) {
+ var entry = new CTagsEntry();
+
+ entry.line_number = local.source_reference.first_line;
+ entry.name = local.name;
+ entry.kind_name = "local";
+ entry.kind = 'l';
+ entry.access = get_access (local);
+
+ taglist.append(entry);
+// print_tag(entry);
+ }
+
+ public void parse_vala (string filename, CTagsEntryMaker maker ) {
+ taglist = new GLib.List<CTagsEntry>();
+ /* We create a context for every source file so that Parser.parse(context)
+ * don't parse a file multiple times causing errors. Parser.parse_file(source_file)
+ * assumes that Parser.context is the same as source_file.context anyway */
+ var context = new CodeContext();
+ context.report = new DummyReport();
+ var source_file = new SourceFile(context, filename, filename.has_suffix("vapi"));
+
+ CodeContext.push(context);
+ context.add_source_file(source_file);
+ vala_parser.parse(context);
+ context.accept(this);
+ foreach (var tagentry in taglist) {
+ maker(tagentry);
+ }
+ taglist = null;
+ CodeContext.pop();
+ }
+ public void parse_genie (string filename, CTagsEntryMaker maker ) {
+ taglist = new GLib.List<CTagsEntry>();
+ var context = new CodeContext();
+ context.report = new DummyReport();
+ var source_file = new SourceFile(context, filename);
+ context.add_source_file(source_file);
+
+ CodeContext.push(context);
+ genie_parser.parse(context);
+ context.accept(this);
+ foreach (var tagentry in taglist) {
+ maker(tagentry);
+ }
+ taglist = null;
+ CodeContext.pop();
+ }
+}
diff --git a/plugins/symbol-db/anjuta-tags/parsers.h b/plugins/symbol-db/anjuta-tags/parsers.h
index 44dd66f..bf5cb98 100644
--- a/plugins/symbol-db/anjuta-tags/parsers.h
+++ b/plugins/symbol-db/anjuta-tags/parsers.h
@@ -15,6 +15,7 @@
#define _PARSERS_H
/* Add the name of any new parser definition function here */
+#ifndef ENABLE_VALA
#define PARSER_LIST \
AntParser, \
AsmParser, \
@@ -58,6 +59,53 @@
VhdlParser, \
VimParser, \
YaccParser
+#else
+#define PARSER_LIST \
+ AntParser, \
+ AsmParser, \
+ AspParser, \
+ AwkParser, \
+ BasicParser, \
+ BetaParser, \
+ CParser, \
+ CppParser, \
+ CsharpParser, \
+ CobolParser, \
+ DosBatchParser, \
+ EiffelParser, \
+ ErlangParser, \
+ FlexParser, \
+ FortranParser, \
+ GenieParser, \
+ GirParser, \
+ HtmlParser, \
+ JavaParser, \
+ JavaScriptParser, \
+ LispParser, \
+ LuaParser, \
+ MakefileParser, \
+ MatLabParser, \
+ OcamlParser, \
+ PascalParser, \
+ PerlParser, \
+ PhpParser, \
+ PythonParser, \
+ RexxParser, \
+ RubyParser, \
+ SchemeParser, \
+ ShParser, \
+ SlangParser, \
+ SmlParser, \
+ SqlParser, \
+ TclParser, \
+ TexParser, \
+ ValaParse, \
+ VeraParser, \
+ VerilogParser, \
+ VhdlParser, \
+ VimParser, \
+ YaccParser
+#endif
#endif /* _PARSERS_H */
diff --git a/plugins/symbol-db/anjuta-tags/vala.c b/plugins/symbol-db/anjuta-tags/vala.c
new file mode 100644
index 0000000..075dd6b
--- /dev/null
+++ b/plugins/symbol-db/anjuta-tags/vala.c
@@ -0,0 +1,100 @@
+/*
+ * vala.c
+ *
+ * Copyright 2008 Abderrahim Kitouni <a kitouni gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/*
+ * INCLUDE FILES
+ */
+#include "general.h" /* must always come first */
+#include "parse.h"
+#include "read.h"
+
+#include "entry.h"
+#include "ctags-vala.h"
+
+CTagsVisitor *visitor;
+/* using different data structure because fpos_t isn't available in Vala*/
+static void make_ctags_entry (CTagsEntry* entry) {
+ tagEntryInfo tag;
+ initTagEntry(&tag, entry->name);
+
+ tag.lineNumberEntry = TRUE;
+ tag.lineNumber = entry->line_number;
+ tag.kindName = entry->kind_name;
+ tag.kind = entry->kind;
+ /* FIXME: add filePosition */
+ tag.extensionFields.access = entry->access;
+ tag.extensionFields.implementation = entry->implementation;
+ tag.extensionFields.inheritance = entry->inheritance;
+ tag.extensionFields.typeRef[0] = entry->typeref;
+ tag.extensionFields.signature = entry->signature;
+ makeTagEntry(&tag);
+}
+
+static kindOption ValaKinds [] = {
+ { TRUE, 'c', "class", "Classes" },
+ { TRUE, 's', "struct", "Structures" },
+ { TRUE, 'i', "interface", "Interfaces" },
+ { TRUE, 'e', "enum", "Enumerations" },
+ { TRUE, 'v', "enumvalue", "Enumeration Values" },
+ { TRUE, 'E', "errordomain", "Error domains" },
+ { TRUE, 'r', "errorcode", "Error codes" },
+ { TRUE, 'd', "delegate", "Delegates" },
+ { TRUE, 'S', "signal", "Signals" },
+ { TRUE, 'f', "field", "Fields" },
+ { TRUE, 'p', "property", "Properties" },
+ { TRUE, 'm', "method", "Methods" },
+ { FALSE, 'l', "local", "Local variables" },
+};
+
+static void findValaTags (void) {
+ if (visitor == NULL) {
+ visitor = ctags_visitor_new();
+ }
+ ctags_visitor_parse_vala (visitor, getSourceFileName(), (CTagsEntryMaker) make_ctags_entry);
+}
+
+extern parserDefinition *ValaParse(void) {
+ g_type_init();
+ static const char *const extensions [] = { "vala", "vapi", NULL };
+ parserDefinition* def = parserNew ("Vala");
+ def->kinds = ValaKinds;
+ def->kindCount = KIND_COUNT (ValaKinds);
+ def->extensions = extensions;
+ def->parser = findValaTags;
+ return def;
+}
+
+static void findGenieTags (void) {
+ if (visitor == NULL) {
+ visitor = ctags_visitor_new();
+ }
+ ctags_visitor_parse_genie (visitor, getSourceFileName(), (CTagsEntryMaker) make_ctags_entry);
+}
+
+extern parserDefinition *GenieParser(void) {
+ static const char *const extensions [] = { "gs", NULL };
+ parserDefinition* def = parserNew ("Genie");
+ def->kinds = ValaKinds;
+ def->kindCount = KIND_COUNT (ValaKinds);
+ def->extensions = extensions;
+ def->parser = findGenieTags;
+ return def;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]